# Admin loan portfolio

Open `/loan-portfolio` in the admin app, or choose **View Portfolio** on Loans.
Access requires an admin account with `loans.read`.

## Scope and filters

`GET /api/v1/admin/loan-portfolio` includes `disbursed`, `paid`, `defaulting`, and `managed` loans. Drafts, submitted applications, pending approvals, and approved-but-unfunded loans are excluded.

Filters: `search`, `status`, `employer_id`, `product`, `source`, `collection_method`, `collection_held` (0/1), `disbursed_from`, `disbursed_to`, `amount_min`, `amount_max`, `duration_min`, `duration_max`, and `overdue_age` (`current`, `1_30`, `31_60`, `61_90`, `91_plus`). Date filters select a disbursement cohort; balances are current, rather than balances as of the chosen end date. The booked employer in loan metadata takes precedence over the borrower's current employer.

`months` selects the trailing 6, 12, or 24 months. `page` and `per_page` affect only the ledger. Summary cards, monthly series, and breakdowns always cover the entire matching set. `GET /api/v1/admin/loan-portfolio/export` accepts the same filters and exports every matching record, regardless of pagination.

## Calculations

- Disbursed amount: finalized disbursement metadata amount, then recorded net disbursal amount, then principal.
- Outstanding repayments: unpaid installment balances, including contractual interest.
- Recorded collections: paid installment original amounts plus partial reductions in outstanding balances. Successful activity logs date these amounts and duplicate references are counted once per installment. Failed/pending attempts are excluded.
- Early settlement: use the master `loan_settlement` activity amount, not installment logs that include waived future interest. A missing master record is flagged and waived balances are excluded from collections.
- Expected interest: contractual total repayment less booked principal; upfront management/insurance fees are excluded.
- Estimated collected income: ordinary collections multiplied by contractual interest / contractual total repayment, plus recorded settlement fees. This is an allocation estimate, not ledger-recognized income or net profit. Funding costs, payment fees, commissions, and losses are not deducted.
- Days overdue: days since the oldest unpaid installment due date, in Africa/Lagos time.
- Overdue amount: remaining balances of installments past their due dates.
- Portfolio at risk: all outstanding repayments on loans with any overdue installment.
- PAR >30 days: outstanding repayments on loans more than 30 days overdue / all outstanding repayments.
- Default rate: loans explicitly marked `defaulting` / matching funded loans. It is not an overdue-age proxy.

## Monthly charts and data quality

Charts show disbursements, scheduled repayments, recorded collections, expected interest, estimated collected income, and reconstructed overdue installment exposure. Scheduled values cover the full month; current-month collections are month-to-date and current risk is today's balance.

Disbursement dates use finalized metadata timestamps. Otherwise the booking/creation date is used and marked estimated. Historical paid installments without activity logs use `paid_at` as an approximate collection date. Undated cumulative partial collections remain in lifetime totals but are excluded from monthly collection charts. Historical overdue snapshots may be overstated when payment dates are unavailable.

The response and page disclose estimated dates, undated collections, missing repayment schedules, and settlements missing payoff records. Loans without schedules remain in funded counts and disbursement totals, but their repayment balances/collections are unknown; a prominent notice identifies incomplete totals. Legacy history and manual settlements are recorded collections, rather than independent evidence of provider-confirmed cash.

The service uses eager loading and chunks of 250 loans, with one activity query per chunk. It builds analytics on the matching set before ledger pagination. No payment, loan status, or collection processing is changed by this reporting view.
