fix(history): restore transfer detail fetch using self-service API#2040
fix(history): restore transfer detail fetch using self-service API#2040bhuvan-somisetty wants to merge 3 commits into
Conversation
Signed-off-by: bhuvan-somisetty <somisettybhuvan5@gmail.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe PR updates transaction history detail state handling. It improves error message formatting and restores transfer-detail loading when a transaction has a transfer ID. ChangesTransaction detail state updates
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@feature/history/src/commonMain/kotlin/org/mifospay/feature/history/transactions/SpecificTransactionsViewModel.kt`:
- Line 88: In SpecificTransactionsViewModel where you set viewState to Error
using result.exception.message (the line it.copy(viewState =
Error(result.exception.message.toString()))), avoid producing the literal "null"
by guarding the exception message: obtain a non-null string via a fallback
(e.g., use the exception message if non-null, else use exception.toString() or a
generic localized fallback like "Unknown error occurred") and pass that into
Error; update the it.copy call to construct the Error with this computed
safeMessage so users see a useful message when exception.message is null.
- Around line 86-90: The DataState.Error branch in SpecificTransactionsViewModel
currently replaces the entire viewState with
Error(result.exception.message.toString()), which hides the already-loaded
transaction; instead, update the existing mutableStateFlow to preserve the
current transaction and other viewState fields while clearing or nulling only
the transfer detail (e.g., set transferDetails = null or keep existing
viewState.transferDetails = null) and optionally record the error in a separate
field (e.g., transferDetailError) so UI can show the transaction without
transfer details; locate the DataState.Error handling in the method that
processes transfer detail results and modify the mutableStateFlow.update call to
copy the existing state rather than replacing it with Error(...).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 56e7580f-65d7-4fab-b0d1-b06b20d4ac7c
📒 Files selected for processing (1)
feature/history/src/commonMain/kotlin/org/mifospay/feature/history/transactions/SpecificTransactionsViewModel.kt
|
@bhuvan-somisetty create a jira ticket for this and update pr |
Preserve the loaded transaction when the transfer detail fetch errors instead of replacing the whole screen with a generic error, and avoid surfacing the literal string "null" when the exception has no message.
|
Pushed a follow-up commit addressing the CodeRabbit review feedback: the transaction now stays visible on the screen if the transfer detail fetch errors (only the detail card is dropped), and the error message no longer shows the literal string "null" when the exception has no message. Will create the Jira ticket and link it here shortly. |
Fixes #2039
What broke and why
The
SpecificTransactionsScreenhas had a silent regression since the self-service API migration. When a user taps a transfer transaction in the history list, the screen opens but the Transfer Detail card never appears — sender, receiver, reference number, and transfer metadata are all missing.The root cause was a commented-out block in
SpecificTransactionsViewModel.handleTransferDetailReceive()left behind during migration with a note that the self-service endpoint was unavailable:The endpoint is available.
AccountRepositoryImpl.getAccountTransfer()already routes throughselfManager.accountTransfersApi— the repository layer was updated during migration but the ViewModel was never revisited. The result:detailwas alwaysnull, the UI silently skipped the card, and no crash surfaced to signal the breakage.Feature Module Architecture
graph TD subgraph feature_history["feature:history module"] TL["TransactionList\n(Composable)"] STS["SpecificTransactionsScreen\n(Composable)"] STVM["SpecificTransactionsViewModel"] TDC["TransactionDetail\nCard (Composable)"] end subgraph core_data["core:data module"] AR["AccountRepository\n(interface)"] ARI["AccountRepositoryImpl"] end subgraph network["Network Layer"] SM["SelfServiceApiManager"] ATA["AccountTransfersApi\n(self-service ✓)"] end TL -->|"user taps transaction"| STS STS -->|"observes state"| STVM STVM -->|"getTransaction()"| AR STVM -->|"getAccountTransfer()"| AR AR -->|"implemented by"| ARI ARI -->|"selfManager.accountTransfersApi"| SM SM --> ATA STVM -->|"ViewState.Content(tx, detail)"| STS STS -->|"detail != null"| TDCData Flow — Before the Fix
flowchart TD A([User taps transaction]) --> B[getTransaction API call] B --> C{DataState} C -->|Success| D[handleTransferDetailReceive] C -->|Error| E[ViewState.Error] C -->|Loading| F[ViewState.Loading] D --> G["⚠️ Content(transaction, detail = null)\nalways — transferId never checked"] G --> H["SpecificTransactionsScreen renders"] H --> I["❌ TransactionDetail card missing\nTransfer metadata never shown"] style G fill:#ff4444,color:#fff style I fill:#ff4444,color:#fffData Flow — After the Fix
flowchart TD A([User taps transaction]) --> B[getTransaction API call] B --> C{DataState} C -->|Success| D[handleTransferDetailReceive] C -->|Error| E[ViewState.Error] C -->|Loading| F[ViewState.Loading] D --> G{transaction.transferId?} G -->|"null — not a transfer"| H["Content(transaction, detail = null)\nnon-transfer path — correct ✓"] G -->|"non-null — is a transfer"| I["accountRepository.getAccountTransfer(transferId)\nselfManager.accountTransfersApi ✓"] I --> J{DataState} J -->|Loading| K[ViewState.Loading] J -->|Error| L[ViewState.Error] J -->|Success| M["✅ Content(transaction, transferDetail)\nfull transfer metadata available"] M --> N["SpecificTransactionsScreen renders"] N --> O["✅ TransactionDetail card visible\nSender · Receiver · Reference · Amount"] style M fill:#00aa44,color:#fff style O fill:#00aa44,color:#fffViewModel State Machine
stateDiagram-v2 [*] --> Loading : screen opens Loading --> Loading : getAccountTransfer\n(if transferId present) Loading --> Content_with_detail : DataState.Success\n(transfer transaction) Loading --> Content_no_detail : no transferId\n(non-transfer transaction) Loading --> Error : DataState.Error Content_with_detail --> [*] : TransactionDetail card shown ✅ Content_no_detail --> [*] : screen shown without detail card ✅ Error --> [*] : error state shown note right of Content_with_detail detail = TransferDetail sender, receiver, reference, amount all populated end note note right of Content_no_detail detail = null non-transfer transactions unaffected — correct behavior end noteRepository Layer — Self-Service Routing
graph LR subgraph ViewModel STVM["SpecificTransactionsViewModel\ngetAccountTransfer(transferId)"] end subgraph Repository AR["AccountRepository\ninterface"] ARI["AccountRepositoryImpl"] end subgraph Network SM["SelfServiceApiManager"] API["accountTransfersApi\n/self-service/v1/accounttransfers"] RESP["TransferDetail response"] end STVM -->|calls| AR AR -->|delegates to| ARI ARI -->|"selfManager.accountTransfersApi\n✓ self-service endpoint"| SM SM --> API API --> RESP RESP -->|"DataState.Success(TransferDetail)"| STVMRepository layer — confirming self-service availability
AccountRepositoryImpl.getAccountTransfer()was already migrated:The API was always there. The ViewModel just never called it.
The fix
Files changed
feature/history/src/commonMain/kotlin/org/mifospay/feature/history/transactions/SpecificTransactionsViewModel.ktgetAccountTransferflow, removed stale TODO commentTesting
transferId):TransactionDetailcard renders with sender name, receiver name, reference number, and transfer amounttransferId): screen loads cleanly, no detail card, no errorsViewState.ErrorcorrectlySummary by CodeRabbit