## Loan Management System — Origination to closure, with an audit trail regulators can read. - URL: https://www.naveentehrpariya.dev/projects/loan-management-system - Industry: Fintech / Lending - Client type: Enterprise - Country: India - Role: Full Stack Product Engineer - Duration: 9 months - Status: Live - Year: 2023 A lending back office covering the whole life of a loan, application, KYC, credit decision, disbursal, EMI schedule, collections and closure, with every state change recorded and attributable. ### Problem Loans were tracked across three spreadsheets and a legacy desktop tool. EMI schedules were recalculated by hand after every part-payment, disputes took days to resolve, and nothing recorded who changed what. ### Objectives - Model the full loan lifecycle in one system - Generate and adjust amortisation schedules automatically - Record an immutable, attributable history of every change - Support role-separated approval workflows ### Solution A Laravel core with an explicit loan state machine and money handled in minor units as integers, never floats. Amortisation schedules regenerate deterministically from loan terms plus the payment history, so a part-payment or a moratorium reshapes the schedule without anyone editing a row. Every transition writes an append-only audit record with actor, timestamp and reason. ### Features - Application intake with document upload and KYC checks - Configurable interest models and amortisation schedules - Automated EMI generation, part-payment and foreclosure handling - Maker-checker approvals with role separation - Collections queue with ageing buckets - Append-only audit log across every entity ### Stack - Frontend: React, Next.js, Tailwind CSS - Backend: Laravel, PHP - Database: MySQL, Redis - Cloud: AWS, Docker - Integrations: Razorpay, KYC provider APIs, SMS gateway ### Engineering challenges ### Rounding that has to survive an auditor Problem: Floating-point interest across hundreds of instalments drifts, and a schedule that is a paisa short at the end is a compliance problem, not a rounding nit. Approach: All money is stored and computed in minor units as integers, with the rounding remainder deliberately assigned to a defined instalment rather than left to accumulate. ### Part-payments that invalidated the schedule Problem: A single early payment changes every instalment that follows, and recalculating in place destroyed the record of what was originally agreed. Approach: Schedules are derived from terms plus payment history and versioned on change, so the original agreement and the current position are both readable. ### Outcome - Manual EMI recalculation removed from the operations workflow - Every loan change became attributable to an actor with a reason - Disputes resolvable from the audit log rather than by reconstructing spreadsheets ### What it taught Never store money in a float, and never overwrite a schedule. Both shortcuts save an afternoon and cost a quarter. Case study: https://www.naveentehrpariya.dev/projects/loan-management-system More work: https://www.naveentehrpariya.dev/llms.txt