Credit module — architecture & flow (Task 10.3)

Status: ✅ Complete

Plan reference: Task 10.3 in the Credit module implementation plan (operations workspace root)

Architecture-layer view of the Credit module: how its three products (Murabaha, Ijarah, Diminishing Musharakah) fit together, the facility lifecycle, how postings flow through the existing finance pipeline, and the AAOIFI principles the design enforces. For per-feature technical detail see the credit technical docs; for the staff-facing flow see the credit operations guide.

Where credit sits

Credit is a financing product that posts through the existing finance pipeline. It does not own a ledger; it emits typed posting requests with sourceModule = credit and lets the finance PostingEngine handle validation, Shariah checks, and atomic GL writes.

The facility lifecycle state machine

Key transitions:

  • Maker-checker sits between pending_review and shariah_review — the creator cannot approve their own facility.
  • rejected is reachable from both pending_review and shariah_review.
  • activate is gated by VR-001 and is the only transition that posts a journal.

VR-001 — "no sale before ownership"

A facility can only be activated once Ethica actually owns the asset:

AAOIFI rationale: you cannot sell or lease what you do not own. Murabaha is a genuine sale (Ethica must hold title first); Ijarah leases an asset Ethica owns; DM requires the co-ownership to actually exist. VR-001 enforces this in software — there is no path to active that skips ownership.

Posting flow through the finance PostingEngine

Credit never hardcodes GL accounts. It resolves them from the CFO-configurable credit_posting_account_map and emits a typed PostingRequest that the finance engine turns into a balanced, halal-tagged journal.

What each event posts

EventJournal
DM/Ijarah origination (on activate)Dr financing-asset/investment Cr cash (facilityAmount)
DM/Ijarah paymentDr cash (total) Cr rental-income (rent) Cr investment (principal)
Murabaha sale (on activate)Dr Receivable (cost+profit) Cr cash (cost) Cr Deferred Profit (profit)
Murabaha paymentDr cash (total) Cr Receivable (total) and Dr Deferred Profit (profit) Cr Income (profit)
Non-accrual paymentDr cash Cr principal only — no income recognised

Every journal is balanced within ₦0.01 and tagged halal; the origination posting is atomic with the approved → active transition.

Deferred-profit recognition (Murabaha)

AAOIFI rationale: the Murabaha profit is a fixed sale margin, but it is recognised as income only as the customer pays — never up front and never rate-derived. Until then it sits in a Deferred Profit liability. This makes profit invariant to payment pace (the anti-riba guarantee): see the engine doc.

Ownership winding down (Diminishing Musharakah)

In DM, Ethica and the customer co-own the asset; each period the customer buys out a straight-line slice of Ethica's share and pays rent only on the share Ethica still holds. Ethica's ownership declines to zero.

Because rent is charged on Ethica's remaining share, it falls every period (golden example: ₦8.0m in P1 → ~₦0.53m in P15; Σ rent ≈ ₦64m). On early settlement the remaining buy-out is paid and future rent is waived — the customer never pays rent for ownership periods they bought out early.

Invariants the credit module preserves

  1. No sale before ownership (VR-001). No path reaches active unless the asset is owned (owned_by_ethica / co_owned).
  2. Profit fixed at signing (Murabaha). fixedTotalProfit is contractual input; never rate-derived; Σ recognised profit === fixedTotalProfit regardless of pace.
  3. Accounts from config, fail-closed. Every GL account resolves from credit_posting_account_map; an unmapped leg blocks the posting.
  4. Balanced, halal, atomic. Every journal balances within ₦0.01, is tagged halal, and origination commits atomically with activation.
  5. No riba on arrears. Overdue lines carry no penalty/compounding; impaired facilities go non-accrual (principal-only recognition).

Open / gated items (pending Shari'ah & finance confirmation)

ItemStatus
Late-payment penalty (as charity, non-income)Not built — formula pending Shari'ah board
Early-settlement rebate (ibra') for MurabahaNot built — all remaining profit currently recognised on settlement
Ijarah asset depreciation methodPending finance confirmation