JK
All work

Loan Management System

Full loan lifecycle platform for Kenyan SACCOs and microfinance institutions — member onboarding, KYC, application, approval, disbursement, repayments, and arrears. Dual-role routing between loan officers and members under a single application.

ReactTypeScriptTailwindRadix UI
Live site ↗

Overview

LAMS (Loan Application Management System) is a digital loan lifecycle platform built for microfinance institutions and SACCOs in Kenya. It serves two distinct user roles — loan officers managing the full portfolio and members tracking their own accounts — under a single application with branched routing.


The Problem

Many Kenyan SACCOs still process loan applications on paper or in spreadsheets. Approval workflows happen over email and phone, there's no audit trail, and members have no self-service way to check their balance or payment schedule. The system needed to handle the full lifecycle: member onboarding, application, approval, disbursement, repayments, and arrears.


Technical Decisions

Dual-role routing

The app branches at the route level: AdminRoutes and UserRoutes are entirely separate trees, resolved by the authenticated user's role. There's no permission-checking inside components — the wrong interface simply doesn't exist for a given role. A view context sync layer prevents leftover state from one role polluting another after role switches.

React Hook Form + Zod

Member registration is a multi-step form with 20+ fields covering KYC, employment, and bank details. React Hook Form keeps the component re-renders minimal while Zod schemas enforce validation at the field and form level. Errors surface inline without a round-trip to the server.

PDF and Excel export

Loan officers can export any table to PDF (via jsPDF + jsPDF-AutoTable) or Excel (via XLSX). This was a hard requirement — regulators and auditors expect physical documents. The export logic is encapsulated in utility functions and called from table action menus.

Radix UI primitives

The entire component library is built on Radix UI unstyled primitives with Tailwind classes. This gave full visual control without fighting a pre-styled component library, while Radix handles keyboard navigation, focus management, and ARIA attributes correctly out of the box.


Key Features

Admin:

  • Member registration with full KYC fields and document management
  • Loan product configuration — interest rates, repayment methods, eligibility rules, collateral and guarantor requirements
  • Loan portfolio view — all active loans, payment status, arrears
  • Application processing with approval workflows
  • Deposit and share capital account management
  • Transaction history and reconciliation
  • Audit logs for compliance
  • Staff user management with role assignment

Member portal:

  • Account overview and loan summaries
  • Payment history and upcoming due dates
  • Account statement downloads
  • Profile management

Tradeoffs

Two separate toast libraries (Sonner and React Toastify) are included — a byproduct of incremental development where different modules were built at different times. Consolidating to one is pending.

The PDF export generates client-side, which means large loan portfolios can be slow to render. For high-volume exports a server-side PDF service would be better.


Retrospective

The dual-role routing was the right architectural call. Keeping the two interfaces completely separate made permissions trivial and kept each interface focused. In hindsight, I'd have pushed for a design system earlier — the admin and member portals ended up with slight visual inconsistencies that a shared component spec would have prevented.