# Loan Management (Backend) - Approach & Step-by-Step

This guide proposes a backend-only approach for adding Loan Management to the POS backend. It focuses on a clean data model, consistent API design, and a safe migration path.

## Goals

- Create a loan profile per customer (account) to track principal, balance, and history.
- Allow disbursing new loans to an account.
- Allow payments against a loan, with clear paid amount history.
- Provide views that show outstanding balance and paid totals per loan/account.

## Best Approach (Recommended)

### 1) Model the domain explicitly
Use three core collections:

- Customer/Account (existing user or a new "LoanAccount" if you do not want to use the auth user model)
- Loan
- LoanPayment

This keeps reporting and audit history straightforward and avoids overwriting totals.

### 2) Track computed totals, but store history
Keep a running `balance` on the Loan document for fast queries, but store each payment in `LoanPayment` for audit and reconciliation.

### 3) Use transactions for financial integrity
When disbursing or paying a loan, update loan and payment in a single transaction session.

### 4) Enforce invariants at the API level
- Do not allow payments greater than outstanding balance unless you support overpayment.
- Only allow disbursement to active accounts.
- Only allow one active loan per account if your business rules require it.

### 5) Expose clear summary endpoints
Add endpoints that return:
- loan list per account
- loan details with payment history
- account-level totals (total principal, total paid, outstanding)

## Data Model (Suggested)

### LoanAccount (optional)
Use this only if you do not want to bind loans directly to your users.

- `_id`
- `displayName`
- `phone`
- `status` (active, closed)
- `createdAt`, `updatedAt`

### Loan

- `_id`
- `account` (ref to User or LoanAccount)
- `principal`
- `balance`
- `status` (active, closed, defaulted)
- `interestRate` (optional)
- `startDate`
- `endDate` (optional)
- `createdAt`, `updatedAt`

### LoanPayment

- `_id`
- `loan` (ref to Loan)
- `amount`
- `paidAt`
- `method` (cash, card, transfer, etc.)
- `note`
- `createdAt`, `updatedAt`

## API Design (Suggested)

### Accounts

- `POST /loan-accounts` - create account (if you are not using users)
- `GET /loan-accounts/:id` - account details and summary
- `GET /loan-accounts/:id/loans` - list loans for account

### Loans

- `POST /loans` - create/disburse loan
- `GET /loans/:id` - loan details
- `PATCH /loans/:id/close` - close loan when balance is zero

### Payments

- `POST /loans/:id/payments` - add payment
- `GET /loans/:id/payments` - list payments

## Step-by-Step Plan

1) Decide whether loans attach to `users` or a new `loanAccounts` collection.
2) Add Mongoose models for `Loan` and `LoanPayment` (and `LoanAccount` if needed).
3) Create validation schemas for create loan and add payment endpoints.
4) Implement controllers with transactional logic for:
   - Disburse loan: create Loan and set balance = principal
   - Pay loan: create LoanPayment and decrement Loan balance
5) Add routers and mount them in [app.js](../app.js).
6) Add summary endpoints for account and loan details.
7) Add tests for:
   - loan creation
   - payment reduces balance
   - payment cannot exceed balance
   - summary totals match history
8) Add indexes for performance (account, loan, paidAt).

## Transaction Flow (Example)

### Disburse loan
1) Validate account exists and is active.
2) Create Loan with principal and balance.
3) Commit transaction.

### Pay loan
1) Load loan by id and ensure status is active.
2) Validate payment amount.
3) Create LoanPayment.
4) Decrease loan balance.
5) If balance is 0, mark loan as closed.

## Notes & Tips
- If you already have `users` as customers, use `users` for `account` reference.
- Consider keeping a `totalPaid` on Loan (optional). It can be computed by aggregation, but storing it can speed up summaries.
- Always store timestamps for financial actions.
- If you need interest or schedules later, keep `interestRate` and an optional `schedule` array.
## What You Need to Provide Next
- Confirm whether loan accounts should be separate from users.
- Decide if multiple loans per account are allowed.
- Confirm if overpayments are allowed.
- Decide whether you need interest and schedules now or later.