Skip to content

18.3 LMS overview and state machine

The Loan Management System owns the loan post-disbursement through its entire lifecycle to closure.

LMS responsibilities:

  1. Loan account creation and activation.
  2. Schedule generation per draw / per loan.
  3. Daily interest accrual.
  4. Repayment processing with waterfall allocation.
  5. Charge application and ledger.
  6. Daily classification and provisioning.
  7. Bounce handling (NACH re-presentation).
  8. Drawdown handling for revolving lines.
  9. Prepayment / foreclosure.
  10. Restructuring workflow.
  11. Write-off workflow.
  12. Closure + NOC.
  13. Co-lending share ledger maintenance.
  14. GL postings for every event.
  15. GST invoice generation.
  16. Statement generation.
  17. Bureau submission data preparation.
  18. RBI returns data preparation.
PENDING_ACTIVATION — between disbursement and LMS activation (transitional)
ACTIVE — loan is performing or in normal lifecycle
SMA_0 — 1-30 DPD
SMA_1 — 31-60 DPD
SMA_2 — 61-90 DPD
NPA_SUBSTANDARD — > 90 DPD, within 12 months of NPA
NPA_DOUBTFUL_D1 — 12-24 months from NPA
NPA_DOUBTFUL_D2 — 24-48 months
NPA_DOUBTFUL_D3 — > 48 months
NPA_LOSS — confirmed loss
RESTRUCTURED_OBSERVATION — restructured, in observation period
WRITTEN_OFF — written off; recovery continues on cash basis
SETTLED — closed via OTS settlement
CLOSED — paid in full and closed

Note: SMA / NPA states are classification status managed by the daily classification engine. They aren’t transitions in the strict state-machine sense — they’re recomputed daily from DPD.

PENDING_ACTIVATION ──auto──→ ACTIVE (on first event after handoff)
ACTIVE ──[daily classification job]──→ ACTIVE / SMA_0 / SMA_1 / SMA_2 / NPA_SUBSTANDARD
(depending on current DPD)
NPA_SUBSTANDARD ──[time in NPA = 12 months]──→ NPA_DOUBTFUL_D1
NPA_DOUBTFUL_D1 ──[12 more months]──→ NPA_DOUBTFUL_D2
NPA_DOUBTFUL_D2 ──[24 more months]──→ NPA_DOUBTFUL_D3
[Any NPA] ──[identified loss]──→ NPA_LOSS
[Any classification] ──restructure approved──→ RESTRUCTURED_OBSERVATION
RESTRUCTURED_OBSERVATION ──[12-month performance OK]──→ ACTIVE
RESTRUCTURED_OBSERVATION ──[performance fails]──→ NPA category appropriate
[Any NPA] ──writeoff approved──→ WRITTEN_OFF
[Any NPA] ──settlement executed──→ SETTLED
ACTIVE / RESTRUCTURED_OBSERVATION ──[full repayment + closure]──→ CLOSED
[Any state with full clearance per NPA upgrade rule] ──upgrade approved──→ ACTIVE

Each loan accumulates events daily; these are the core event types in loan_event:

  • activate — loan account created (Day 0).
  • disburse — funds released (Day 0; may be repeated for revolving line draws).
  • accrual — daily interest accrued (Days 1 to maturity for performing; frozen for NPA).
  • classification_change — when classification status changes.
  • provision — daily provisioning update.
  • repayment — borrower payment received.
  • allocation — waterfall allocation of the repayment.
  • bounce — NACH presentation failed.
  • re_present — re-presentation attempted.
  • charge — per charge type (processing fee at sanction; servicing fee periodically; bounce fee on bounce; late fee on late payment; penal charges per policy).
  • drawdown — borrower requests further draw within line.
  • drawdown_schedule_generated — per-draw schedule.
  • mandate_active — NACH mandate active.
  • mandate_inactive — NACH mandate cancelled / expired.
  • restructure — restructure applied.
  • prepayment — partial prepayment.
  • foreclosure_request — borrower requests foreclosure.
  • foreclosure_completed.
  • writeoff — write-off applied.
  • recovery_post_writeoff — recovery received after write-off.
  • upgrade — NPA upgraded to standard (only on full clearance).
  • settlement — OTS executed.
  • closure — loan closed.
  • noc_issued.

The LMS is event-sourced for accounting-affecting flows. The loan_event table is append-only. Current state (current_outstanding, current_classification, etc.) is derived from events.

  • Auditability — every state change is explicit and immutable.
  • Time-travel — query state at any past timestamp.
  • Reconciliation — replay against alternative projection.
  • Compliance — IRACP audit-ability.
  • Every state-affecting write goes through loan_event first.
  • Projections (loan_account table, schedule_line, classification_snapshot) maintained as side effect.
  • Idempotency keys on every event prevent duplicates.

Many events happen concurrently for an active book:

  • Daily accrual job runs for thousands of loans in parallel.
  • Classification job runs for the entire book each day.
  • Bounce file processing happens during business hours.
  • Multiple repayments arrive simultaneously from various rails.

The platform’s design must handle this:

  • Per-loan ordering preserved (Kafka partitioning by loan_id).
  • Cross-loan operations can parallelise.
  • Daily-batch sequencing (see 18.6).
OperationTarget
Activation post-disbursement< 5 minutes
Daily accrual for whole book< 30 minutes
Daily classification< 60 minutes
Daily provisioning< 30 minutes
NACH presentation file generation< 60 minutes
Repayment allocation per repayment< 5 seconds
Statement on-demand< 5 seconds
Co-lending settlement (per period)< 4 hours
  • No silent state mutations — every change is an event.
  • Daily classification cannot skip days — even weekends/holidays the job runs.
  • Upgrade only on full clearance per Nov 2021 IRACP.
  • Restructure downgrades immediately unless special scheme.
  • Penal charges separate from interest per Aug 2023 circular.
  • Co-lending lockstep — both lenders’ classification updates same day.
  • Idempotency on every repayment / charge / drawdown.