# Step 21 — Management Dashboard — Implementation Report

**Status:** COMPLETED  
**Verified:** 12 August 2026  
**Pull request:** #33

## Overview

Step 21 replaces the original foundation/dashboard placeholder with a real management dashboard backed by the permanent financial and loan records already implemented in earlier modules.

The dashboard does not create a parallel reporting store or duplicate financial balances. Its figures are calculated from the same report engines and transaction ledgers used by Step 19 Financial Reports and Step 20 Loan and Branch Reports.

## Management KPI cards

The dashboard includes all required roadmap KPI cards:

1. Total Available Funds
2. Outstanding Principal
3. Expected Interest
4. Collections Today / selected period
5. Disbursements Today / selected period
6. Expenses Today / selected period
7. Overdue Amount
8. Profit This Month
9. Active Loans
10. Completed Loans
11. Written-Off Portfolio

### KPI semantics

- **Total Available Funds** is calculated from reconstructed financial-account closing balances derived from permanent account transactions. It does not trust a mutable `current_balance` value as the reporting source.
- **Outstanding Principal** is the current active-loan principal outstanding from the Step 20 portfolio report engine.
- **Expected Interest** is the current active-loan interest outstanding from the Step 20 report engine.
- **Collections**, **Disbursements** and **Expenses** follow the selected dashboard reporting period. The default period is Today.
- **Overdue Amount** is the current active-loan arrears snapshot.
- **Profit This Month** always uses the current calendar month's Step 19 Profit & Loss calculation, regardless of the selected dashboard activity filter.
- **Active Loans** is a current portfolio count.
- **Completed Loans** is the historical completed-loan count in the accessible branch scope.
- **Written-Off Portfolio** means the remaining recoverable balance on approved written-off loans, preserving the distinction between original write-off and later recovery.

## Account balances

The dashboard shows reconstructed account balances grouped as:

- Cash
- Mobile Money
- Bank
- Other

`Other` includes account types outside Cash, Mobile Money and Bank, such as Petty Cash, Safe, Collection and Other accounts.

An account-detail table also shows each underlying financial account, its type, branch and reconstructed closing balance.

## Charts and performance views

Step 21 includes the roadmap visual performance views:

- Collections vs Disbursements
- Income vs Expenses
- Portfolio Performance
- Branch Performance

### Collections vs Disbursements

Uses permanent financial-account transaction types that match Step 19 reporting semantics:

Collections:

- Loan payment
- Early settlement
- Written-off loan recovery

Disbursements:

- Normal loan disbursement
- Loan top-up cash disbursement

### Income vs Expenses

Uses the same P&L category treatment as Step 19.

Income categories include:

- Interest
- Fees
- Penalties
- Written-off loan recovery income
- Service income
- Other actual income / qualifying settlement adjustment

Expense categories include:

- Operating expenses
- Payroll
- Write-offs
- Expense-side settlement adjustments / other expenses

Loan principal is not treated as revenue.

### Adaptive chart buckets

Chart series automatically use:

- Daily buckets for ranges up to 31 days
- Weekly buckets for ranges up to 180 days
- Monthly buckets for longer ranges

No additional frontend chart library or dashboard-only financial table was introduced.

### Portfolio Performance

Shows:

- Current total outstanding
- Current overdue amount
- Scheduled due in selected period
- Collected in selected period
- Loan collection rate

The collection-rate value is taken from the same Step 20 report path rather than recalculated independently by the dashboard.

### Branch Performance

Shows each selected branch with:

- Collections
- Disbursed amount
- Current portfolio
- Collection rate

The underlying figures are generated by the Step 20 Branch Performance report engine.

## Filters

The management dashboard supports:

- Today
- Yesterday
- This Week
- This Month
- This Year
- Custom Range
- One branch
- Several branches
- All accessible branches

Custom ranges validate that the end date is not before the start date.

Selecting no explicit branch means all branches available to the authenticated user.

## Authorization and branch isolation

Management financial and portfolio figures require the existing `reports.view` permission.

This means management/reporting roles can access the real dashboard while ordinary operational users such as cashiers do not automatically receive owner-level financial figures.

Users without `reports.view` still retain a valid post-login `/dashboard` workspace containing their identity, primary branch, role and permission-appropriate operational shortcuts.

For management users:

- Super administrators can report across all branches.
- Other users are restricted to assigned branches.
- Requested branch IDs are validated on the backend.
- Selecting an unassigned branch returns a forbidden response instead of relying on UI hiding.

## Reconciliation with Steps 19 and 20

The dashboard service directly reuses:

- `FinancialReportService` from Step 19
- `LoanBranchReportService` from Step 20

Dashboard reconciliation tests explicitly compare dashboard KPI values with the corresponding report results.

Available funds are separately tested against transaction-reconstructed account balances while deliberately changing the mutable financial-account `current_balance`, proving that dashboard reporting is ledger-backed.

## Same-day date-range hardening

Step 21 testing exposed a cross-database edge case in pre-existing report date filters for columns stored as SQL `DATE` values.

To make one-day ranges such as Today reliable across SQLite CI and production database drivers:

- Step 19 Expense Report now applies date-aware inclusive lower/upper comparisons to `expense_date`.
- Step 20 loan collection-rate scheduled-due calculation now applies date-aware inclusive lower/upper comparisons to installment `due_date`.
- Step 20 early-settlement collection-rate inclusion now applies date-aware inclusive lower/upper comparisons to `settlement_date`.

These are report-query consistency fixes only. No financial posting behavior or historical data is altered.

All Step 19 and Step 20 regression tests remain green after the hardening.

## User interface

The dashboard follows the existing compact application UI system:

- Existing `mf-*` components/classes
- Compact KPI cards
- Minimal nested card use
- Responsive multi-column layout
- Reuses existing Finance report navigation
- No new frontend framework dependency

## Database changes

No migration is required.

Step 21 is a read-only reporting/orchestration layer over the existing transaction, accounting, loan, payment, expense, write-off and branch records.

## Verification

GitHub Actions Foundation CI on pull request #33:

- Fresh migrations: PASS
- All seeders: PASS
- Full Laravel test suite: **154 passed**
- Assertions: **1,592**
- Existing Step 1–20 regression tests: PASS
- Step 21 feature tests: **6 passed**

Step 21 tests cover:

1. Dashboard KPI reconciliation to Step 19 and Step 20 report outputs.
2. Available funds and account grouping reconstructed from permanent transactions rather than mutable account balances.
3. Chart totals, portfolio performance and branch performance reconciliation to period sources.
4. Today, Yesterday, This Week, This Month, This Year and Custom Range filters plus multi-branch scope.
5. Backend branch isolation for management users.
6. Safe operational workspace for authenticated users without management-report permission.

## Remaining Step 21 work

None.

## Next roadmap module

**Step 22 — Tasks, Calendar and Management Alerts**.
