mifos-mobile/claude-product-cycle/design-spec-layer/features/accounts/SPEC.md
Rajan Maurya fdc2ff5d57
feat: add v2.0 MOCKUP.md designs and gap analysis commands (#3044)
Co-authored-by: therajanmaurya <therajanmaurya@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 06:26:29 -05:00

21 KiB

Accounts - Feature Specification

Purpose: Unified account listing with type-specific filtering for savings, loans, and shares User Value: Browse and manage all financial accounts with powerful filtering capabilities Last Updated: 2025-12-29 Status: Production Design


1. Overview

1.1 Feature Summary

The Accounts feature provides a comprehensive view of user accounts organized by type (Savings, Loan, Share). Users can browse account lists, apply multi-criteria filters (by account type and status), view transactions history, and access detailed transaction information. The feature supports pull-to-refresh for real-time data updates and maintains filter state across sessions.

1.2 User Stories

  • As a user, I want to view all my savings accounts in one place
  • As a user, I want to filter accounts by type (wallet, bank, group, NB)
  • As a user, I want to filter accounts by status (active, pending, closed, matured, approved)
  • As a user, I want to see transaction history for each account
  • As a user, I want to filter transactions by type (credit/debit) and duration
  • As a user, I want to view detailed information about a specific transaction
  • As a user, I want to refresh account data with pull-to-refresh gesture

1.3 Design Principles

  • Consistency: Same filter pattern across all account types
  • Efficiency: Quick access to filtered views with minimal taps
  • Clarity: Clear distinction between account types and statuses
  • Responsiveness: Real-time updates via pull-to-refresh

2. Screen Layout

2.1 Accounts List Screen

+-------------------------------------------------------------+
|  <- Savings Accounts                                    ...  |
+-------------------------------------------------------------+
|                                                             |
|  +-------------------------------------------------------+  |
|  |  [FILTER ICON]                                 Filter |  |
|  +-------------------------------------------------------+  |
|                                                             |
|  +-------------------------------------------------------+  |
|  |  Wallet Savings Account                               |  |
|  |  SA-0001234567  |  Active                             |  |
|  |  Balance: $12,500.00                                  |  |
|  |  Interest: 4.5% p.a.                                  |  |
|  +-------------------------------------------------------+  |
|                                                             |
|  +-------------------------------------------------------+  |
|  |  Bank Savings Account                                 |  |
|  |  SA-0001234568  |  Active                             |  |
|  |  Balance: $8,750.00                                   |  |
|  |  Interest: 3.2% p.a.                                  |  |
|  +-------------------------------------------------------+  |
|                                                             |
|  +-------------------------------------------------------+  |
|  |  Group Savings Account                                |  |
|  |  SA-0001234569  |  Pending                            |  |
|  |  Balance: $0.00                                       |  |
|  |  Interest: 2.5% p.a.                                  |  |
|  +-------------------------------------------------------+  |
|                                                             |
|  +-------------------------------------------------------+  |
|  |            [Powered by Mifos]                         |  |
|  +-------------------------------------------------------+  |
+-------------------------------------------------------------+

2.2 Filter Bottom Sheet

+-------------------------------------------------------------+
|                          Filters                             |
+-------------------------------------------------------------+
|                                                             |
|  [Reset Filters]                              [Apply]       |
|                                                             |
|  ---------------------------------------------------------  |
|                                                             |
|  Account Type                               (2 selected) v  |
|  ---------------------------------------------------------  |
|    [ ] Wallet Account                                       |
|    [x] Bank Account                                         |
|    [x] Group Account                                        |
|    [ ] NB Account                                           |
|                                                             |
|  ---------------------------------------------------------  |
|                                                             |
|  Account Status                             (1 selected) v  |
|  ---------------------------------------------------------  |
|    [x] Active                                               |
|    [ ] Pending                                              |
|    [ ] Closed                                               |
|    [ ] Matured                                              |
|    [ ] Approved                                             |
|                                                             |
+-------------------------------------------------------------+

2.3 Transaction History Screen

+-------------------------------------------------------------+
|  <- Transaction History                                      |
+-------------------------------------------------------------+
|                                                             |
|                                              [Filter]       |
|                                                             |
|  Today                                                      |
|  +-------------------------------------------------------+  |
|  |  v Deposit                              + $4,500.00   |  |
|  |    Dec 29, 2025                                       |  |
|  +-------------------------------------------------------+  |
|  |  ^ Withdrawal                           - $150.00     |  |
|  |    Dec 29, 2025                                       |  |
|  +-------------------------------------------------------+  |
|                                                             |
|  Yesterday                                                  |
|  +-------------------------------------------------------+  |
|  |  v Interest Posting                     + $125.50     |  |
|  |    Dec 28, 2025                                       |  |
|  +-------------------------------------------------------+  |
|  |  ^ Transfer Out                         - $500.00     |  |
|  |    Dec 28, 2025                                       |  |
|  +-------------------------------------------------------+  |
|                                                             |
|  +-------------------------------------------------------+  |
|  |            [Powered by Mifos]                         |  |
|  +-------------------------------------------------------+  |
+-------------------------------------------------------------+

2.4 Transaction Details Screen

+-------------------------------------------------------------+
|  <- Transaction Details                                      |
+-------------------------------------------------------------+
|                                                             |
|              +------------------+                           |
|              |       v          |                           |
|              |   (Credit Icon)  |                           |
|              +------------------+                           |
|                                                             |
|                   $4,500.00                                 |
|                    Deposit                                  |
|                                                             |
|  +-------------------------------------------------------+  |
|  |  Transaction ID           12345                       |  |
|  |  -------------------------------------------------    |  |
|  |  Date                     Dec 29, 2025                |  |
|  |  -------------------------------------------------    |  |
|  |  Status                   Success                     |  |
|  |  -------------------------------------------------    |  |
|  |  Account Ref              SA-0001234567               |  |
|  |  -------------------------------------------------    |  |
|  |  Type                     Deposit                     |  |
|  |  -------------------------------------------------    |  |
|  |  External ID              EXT-12345                   |  |
|  |  -------------------------------------------------    |  |
|  |                                                       |  |
|  |  BREAKDOWN                                            |  |
|  |  -------------------------------------------------    |  |
|  |  Principal                $4,400.00                   |  |
|  |  -------------------------------------------------    |  |
|  |  Interest                 $100.00                     |  |
|  |  -------------------------------------------------    |  |
|  |  Fees                     $0.00                       |  |
|  |  -------------------------------------------------    |  |
|  |  Penalties                $0.00                       |  |
|  |  -------------------------------------------------    |  |
|  |                                                       |  |
|  |  Balance                  $12,500.00                  |  |
|  +-------------------------------------------------------+  |
|                                                             |
+-------------------------------------------------------------+

3. Sections Table

Section Description Components
Top Bar Navigation and screen title Back button, title (Savings/Loan/Share Accounts)
Filter Action Opens filter bottom sheet Filter button with icon
Account List Scrollable list of accounts Account cards with balance, status, interest rate
Filter Bottom Sheet Multi-criteria filter dialog Type filters, status filters, reset/apply buttons
Transaction List Grouped by date Transaction items with type, amount, date
Transaction Filter Transaction-specific filters Type (Credit/Debit), Duration (1mo/3mo/6mo/1yr/2yr)
Transaction Details Full transaction information Header, details table, breakdown section
Powered Footer Branding footer Mifos branding card

4. User Interactions Table

Interaction Action Result
Tap Back Button OnNavigateBack Navigate to previous screen
Tap Filter Button ToggleFilter Open filter bottom sheet
Tap Account Card OnAccountClicked Navigate to account details
Toggle Checkbox ToggleCheckbox Update filter selection
Tap Reset Filters ResetFilters Clear all filter selections
Tap Apply Filters GetFilterResults Apply filters and close sheet
Pull to Refresh Refresh Reload account data from API
Tap Transaction Item OnTransactionClick Navigate to transaction details
Expand/Collapse Filter Section ToggleTypeExpanded/ToggleStatusExpanded Show/hide filter options

5. State Model

5.1 AccountsState (from AccountsViewModel.kt)

internal data class AccountsState(
    val isRefreshing: Boolean = false,
    val checkboxOptions: List<CheckboxStatus> = emptyList(),
    val selectedFilters: List<CheckboxStatus> = emptyList(),
    val accountType: AccountType = AccountType.SAVINGS,
    val toggleFilterDialog: Boolean = false,
    val accountTypeFiltersCount: Int? = 0,
    val accountStatusFiltersCount: Int? = 0,
    val refreshSignal: Long = Clock.System.now().epochSeconds,
    val dialogState: DialogState? = null,
    val uiState: ScreenUiState = ScreenUiState.Loading,
    val isTypeExpanded: Boolean = true,
    val isStatusExpanded: Boolean = true,
) {
    sealed interface DialogState {
        data class Error(val message: String) : DialogState
        data object Filters : DialogState
    }

    val isAnyFilterSelected = checkboxOptions.any { it.isChecked }
}

5.2 AccountTransactionState (from TransactionViewModel.kt)

internal data class AccountTransactionState(
    val clientId: Long,
    val accountType: String,
    val accountId: Long,
    val isRefreshing: Boolean = false,
    val data: List<UiTransaction> = emptyList(),
    val filteredData: Map<String, List<UiTransaction>> = emptyMap(),
    val dialogState: DialogState? = null,
    val checkboxOptions: List<TransactionCheckboxStatus> = emptyList(),
    val selectedFilters: List<TransactionCheckboxStatus> = emptyList(),
    val toggleFilterDialog: Boolean = false,
    val accountTypeFiltersCount: Int? = 0,
    val accountDurationFiltersCount: Int? = 0,
    val selectedRadioButton: StringResource? = null,
    val isFilteredRecordsEmpty: Boolean = false,
    val networkStatus: Boolean = false,
    val uiState: ScreenUiState? = ScreenUiState.Loading,
) {
    sealed interface DialogState {
        data class Error(val message: String) : DialogState
        data object Filters : DialogState
    }

    val isAnyFilterSelected = checkboxOptions.any { it.isChecked } || selectedRadioButton != null
}

5.3 TransactionDetailsState (from TransactionDetailsViewModel.kt)

data class TransactionDetailsState(
    val transactionId: Long,
    val accountId: Long,
    val accountType: String,
    val uiState: ScreenUiState = ScreenUiState.Loading,
    val transaction: UiTransactionDetails? = null,
)

5.4 Actions

// Accounts Actions
sealed interface AccountsAction {
    data object ToggleFilter : AccountsAction
    data object ToggleTypeExpanded : AccountsAction
    data object ToggleStatusExpanded : AccountsAction
    data object ResetFilters : AccountsAction
    data object DismissDialog : AccountsAction
    data object GetFilterResults : AccountsAction
    data object OnNavigateBack : AccountsAction
    data object Refresh : AccountsAction
    data object RefreshCompleted : AccountsAction
    data class OnAccountClicked(val accountId: Long, val accountType: String) : AccountsAction
    data class SetCheckboxFilterList(val checkBoxList: List<CheckboxStatus>, val accountType: String) : AccountsAction
    data class ToggleCheckbox(val label: StringResource, val type: FilterType) : AccountsAction
}

// Transaction Actions
sealed interface AccountTransactionAction {
    data object Refresh : AccountTransactionAction
    data object DismissDialog : AccountTransactionAction
    data object OnNavigateBackClick : AccountTransactionAction
    data object ToggleFilter : AccountTransactionAction
    data object ResetFilters : AccountTransactionAction
    data object GetFilterResults : AccountTransactionAction
    data class ReceiveNetworkResult(val isOnline: Boolean) : AccountTransactionAction
    data class OnTransactionClick(val id: Long?) : AccountTransactionAction
    data class ToggleCheckbox(val label: StringResource, val type: TransactionFilterType) : AccountTransactionAction
    data class ToggleRadioButton(val label: StringResource) : AccountTransactionAction
}

// Transaction Details Actions
sealed interface TransactionDetailsAction {
    data object OnNavigateBack : TransactionDetailsAction
    data object Retry : TransactionDetailsAction
}

5.5 Events

// Accounts Events
sealed interface AccountsEvent {
    data object NavigateBack : AccountsEvent
    data class AccountClicked(val accountId: Long, val accountType: String) : AccountsEvent
}

// Transaction Events
sealed interface AccountTransactionEvent {
    data object OnNavigateBack : AccountTransactionEvent
    data class NavigateToDetails(val id: String) : AccountTransactionEvent
}

// Transaction Details Events
sealed interface TransactionDetailsEvent {
    data object NavigateBack : TransactionDetailsEvent
}

6. Filter Options

6.1 Savings Account Filters

Filter Type Options
Account Type Wallet Account, Bank Account, Group Account, NB Account
Account Status Active, Pending, Closed, Matured, Approved

6.2 Loan Account Filters

Filter Type Options
Account Type Personal, Bronze
Account Status Active, Approval Pending, Closed, Disburse, Overpaid, In Arrears, Withdrawn, Matured, Rejected

6.3 Share Account Filters

Filter Type Options
Account Type Wallet Account, Bank Account
Account Status Active, Approval Pending, Closed, Disburse, Overpaid, In Arrears, Withdrawn, Matured, Rejected

6.4 Transaction Filters

Filter Type Options
Transaction Type Credit, Debit
Duration Past Month, Past 3 Months, Past 6 Months, Past 1 Year, Past 2 Years

7. API Requirements Table

Endpoint Method Purpose Priority
/self/clients/{clientId}/accounts GET Fetch all accounts P0
/self/savingsaccounts/{accountId} GET Fetch savings details with transactions P0
/self/loans/{loanId} GET Fetch loan details with transactions P0
/self/shareaccounts/{accountId} GET Fetch share account details P0
/self/clients/{clientId}/transactions GET Fetch recent transactions P0
/self/savingsaccounts/{accountId}/transactions/{transactionId} GET Fetch savings transaction details P1
/self/loans/{loanId}/transactions/{transactionId} GET Fetch loan transaction details P1

8. Edge Cases & Error Handling

Scenario UI Behavior Recovery
No internet Show network error state Retry button, auto-retry on reconnect
API timeout Show error state with message Pull-to-refresh or Retry button
No accounts Show empty state Display "No accounts found" message
No transactions Show empty state Display "No transactions found"
No filtered results Show empty filtered state Display "No matching transactions"
Invalid transaction ID Show error state Navigate back or retry
Auth expired Navigate to login Re-authenticate
Partial data load Show available data Silent background retry

9. Performance Requirements

Metric Target Implementation
First paint < 500ms Skeleton loading
Data load < 2s Parallel API calls
Filter apply < 100ms Client-side filtering
Scroll 60fps LazyColumn with keys
Pull-to-refresh Responsive Optimistic UI update

10. Navigation Routes

// Account Navigation
@Serializable
data class AccountNavRoute(val accountType: String)

// Transaction Navigation
@Serializable
data class AccountTransactionsNavRoute(
    val accountId: Long,
    val accountType: String,
)

// Transaction Details Navigation
@Serializable
data class TransactionDetailsNavRoute(
    val transactionId: String,
    val accountType: String,
    val accountId: Long,
)

11. Data Models

11.1 CheckboxStatus

data class CheckboxStatus(
    val statusLabel: StringResource,
    val isChecked: Boolean = false,
    val type: FilterType = FilterType.ACCOUNT_STATUS,
)

enum class FilterType {
    ACCOUNT_TYPE,
    ACCOUNT_STATUS,
}

11.2 TransactionCheckboxStatus

data class TransactionCheckboxStatus(
    val statusLabel: StringResource,
    val isChecked: Boolean = false,
    val type: TransactionFilterType = TransactionFilterType.TRANSACTION_TYPE,
)

enum class TransactionFilterType {
    TRANSACTION_TYPE,
    DURATION,
}

11.3 UiTransaction

data class UiTransaction(
    val id: Long?,
    val date: List<Int>,
    val amount: Double?,
    val type: TransactionType? = null,
    val typeValue: String? = null,
    val isCredit: Boolean?,
    val currency: String,
)

11.4 UiTransactionDetails

data class UiTransactionDetails(
    val id: Long?,
    val date: List<Int>,
    val amount: Double?,
    val status: String,
    val typeValue: String? = null,
    val isCredit: Boolean?,
    val currency: String,
    val accountNo: String? = null,
    val principal: Double? = null,
    val interest: Double? = null,
    val fees: Double? = null,
    val penalties: Double? = null,
    val externalId: String? = null,
    val outstandingBalance: Double? = null,
)

12. Credit/Debit Logic

fun getTransactionCreditStatus(transactionType: TransactionType?): Boolean {
    return transactionType?.run {
        when {
            deposit == true -> true
            dividendPayout == true -> false
            withdrawal == true -> false
            interestPosting == true -> true
            feeDeduction == true -> false
            initiateTransfer == true -> false
            approveTransfer == true -> false
            withdrawTransfer == true -> false
            rejectTransfer == true -> true
            overdraftFee == true -> false
            else -> true
        }
    } ?: false
}

Changelog

Date Change
2025-12-29 Initial specification based on existing implementation