Reading a Loan Lifecycle as a State Machine
Origination, disbursal, servicing and closure are usually modelled as flags. Modelling them as explicit states removes a whole class of impossible bugs.
- Lending
- LOS
- LMS
- Domain Modelling
Ask how a loan application progresses and you often get a list of booleans: is_approved, is_disbursed, is_closed, is_written_off. Each is individually sensible. Together they describe far more combinations than actually exist.
A loan that is both closed and not yet disbursed is not a business case — it is a bug waiting for a race condition to produce it.
States, and the transitions between them
Naming the states explicitly, and enumerating which transitions are legal, collapses that space to the cases that are real. The illegal combinations stop being something you defend against in every query and start being something the model cannot represent.
It also gives operations a shared vocabulary. 'Stuck in pending disbursal' is a precise, queryable statement in a way that 'approved but the disbursed flag is false' never is.
- One state field rather than a constellation of independent flags
- Legal transitions declared and enforced in one place
- Every transition recorded with actor, timestamp and reason
- Reporting derived from state history, not reconstructed from flags
The history is the valuable part
Current state answers today's question. The transition log answers every question you have not thought of yet — how long approvals actually take, where applications stall, which step regressed after a release.
Thoughts on this?
Always happy to talk through the engineering trade-offs.