18.6 Daily batch — order of operations
The daily batch is the LMS’s heartbeat. Mis-ordered or missed batch operations cause material accounting / compliance problems. This page sets the standard order.
Overall daily cycle
Section titled “Overall daily cycle”00:00 Day rolls over │ ▼01:00 Tier-1 batch jobs start │ ├── Daily interest accrual (target: complete by 02:00) ├── Daily classification (target: complete by 02:30) ├── Daily provisioning (target: complete by 03:00) │ ▼03:00 Reconciliation prep ├── Reconciliation with prior-day sponsor-bank statement (target: 04:00) │ ▼06:00 Business-day ops batch starts ├── Co-lending settlement (per period; daily / weekly) ├── Borrower statement generation (on schedule) ├── Bureau monthly submission file (on monthly schedule) │ ▼Throughout day: real-time ops continue ├── Repayment receipts processed (real-time) ├── Charges applied (real-time) ├── Drawdowns processed (real-time) ├── Webhook handlers active (NACH ack incoming) │ ▼15:00 – 17:00 NACH file generation cut-off ├── Generate next-day's NACH presentation file ├── Submit to sponsor bank by 18:00 cut-off │ ▼18:00 – 19:00 End-of-business-day administrative batches ├── Daily MIS to partner lenders ├── EWS engine refresh │ ▼22:00 – 23:00 Pre-rollover housekeeping ├── Audit log integrity verification ├── Backup verification │ ▼23:30 Pre-rollover snapshot for next dayTier-1 jobs (financial-critical)
Section titled “Tier-1 jobs (financial-critical)”Job 1: Daily interest accrual
Section titled “Job 1: Daily interest accrual”Inputs: All loans in ACTIVE or any SMA state (not NPA, not closed).
Operation:
for each loan: if loan.classification in {NPA_SUBSTANDARD, NPA_DOUBTFUL_*, NPA_LOSS}: continue # accrual frozen
outstanding = loan.current_outstanding (after all yesterday's events) daily_interest = outstanding × loan.rate / 365
emit event: accrual(loan_id, date=yesterday, amount=daily_interest)
loan.accrued_interest += daily_interest (projection update)
post GL: Dr Accrued Interest Receivable, Cr Interest IncomeIdempotency: Each accrual event has key accrual:{loan_id}:{date}. Re-running the job doesn’t double-post.
Performance: For ~10,000 active loans, completes in < 5 minutes with parallel batch.
Audit: Per-loan accrual event in audit chain.
Job 2: Daily classification
Section titled “Job 2: Daily classification”Operation:
for each loan in {ACTIVE, SMA_*, NPA_*}: days_overdue = compute_DPD(loan) new_class = classify(days_overdue, current_class, time_in_NPA)
if new_class != loan.current_classification: emit event: classification_change(loan_id, old_class, new_class) loan.current_classification = new_class (projection) post classification_snapshot(loan_id, date=yesterday, class=new_class, dpd=days_overdue)DPD computation:
For each schedule_line in loan.schedule: if schedule_line.total_due > schedule_line.total_paid: overdue_amount += (schedule_line.total_due - schedule_line.total_paid) days_overdue = max(days_overdue, days_from(schedule_line.due_date, today))Classification logic:
if days_overdue == 0: return STANDARDelif days_overdue <= 30: return SMA_0elif days_overdue <= 60: return SMA_1elif days_overdue <= 90: return SMA_2elif days_overdue > 90: if time_since_NPA <= 12 months: return NPA_SUBSTANDARD elif time_since_NPA <= 24 months: return NPA_DOUBTFUL_D1 elif time_since_NPA <= 48 months: return NPA_DOUBTFUL_D2 else: return NPA_DOUBTFUL_D3# Loss assignment per separate workflowUpgrade gate (per Nov 2021 IRACP):
if loan.current_classification in NPA states: if days_overdue == 0 AND total_arrears_cleared == True: emit upgrade event (requires manual approval per board policy) new_class = STANDARDUpgrade is not automatic on DPD = 0 from partial payment; requires explicit clearance of all arrears.
Idempotency: snapshot per (loan_id, date) is unique; re-run is no-op.
Performance: ~20 minutes for ~10,000 loans with parallel batch.
Job 3: Daily provisioning
Section titled “Job 3: Daily provisioning”Operation:
for each loan: class = loan.current_classification outstanding = loan.current_outstanding
provision_amount = compute_provision(class, outstanding, secured)
emit event: provision(loan_id, date=yesterday, class, amount=provision_amount)
post GL: Dr Provision Expense, Cr Provision for NPA (Liability)Provisioning rates (illustrative; verify per SBR-MD):
| Class | Provisioning |
|---|---|
| Standard | 0.25 – 0.40% |
| SMA-0/1/2 | Standard-level (no separate prov) |
| Sub-standard | 10% of outstanding |
| Doubtful D1 | 100% of unsecured + 20% of secured |
| Doubtful D2 | 100% of unsecured + 30% of secured |
| Doubtful D3 | 100% of unsecured + 50% of secured |
| Loss | 100% |
Daily snapshot: per (loan_id, date).
Tier-2 jobs (recurring administrative)
Section titled “Tier-2 jobs (recurring administrative)”Job 4: Reconciliation with sponsor bank
Section titled “Job 4: Reconciliation with sponsor bank”Operation:
- Pull yesterday’s sponsor-bank statement (SFTP / API).
- For each statement entry:
- Match against expected LMS entries (disbursements, NACH credits, payouts).
- On match: confirm.
- On mismatch: route to exception queue.
Output: reconciled entries + exception list.
Job 5: NACH presentation file generation
Section titled “Job 5: NACH presentation file generation”Operation:
- Identify dues for tomorrow.
- Generate NACH file per format (5.14).
- Submit to sponsor bank by cut-off.
Order matters: must run after morning ops have processed any pre-day repayments that change tomorrow’s dues.
Job 6: Co-lending settlement (daily / per period)
Section titled “Job 6: Co-lending settlement (daily / per period)”Operation:
- Sum yesterday’s repayments by partner.
- Compute partner share.
- Generate settlement instruction.
- Submit to sponsor bank for settlement.
Job 7: EWS engine refresh
Section titled “Job 7: EWS engine refresh”Operation:
- For each active borrower, refresh EWS signals (drawing on latest data).
- Raise alerts on threshold breaches.
- Route to risk-team queue.
Job 8: Borrower statement generation (scheduled)
Section titled “Job 8: Borrower statement generation (scheduled)”- Generate monthly statements for borrowers per cycle.
- Email / WhatsApp / borrower-portal access.
Job 9: Bureau submission (monthly, on schedule)
Section titled “Job 9: Bureau submission (monthly, on schedule)”- On the 15th of each month (or per policy), generate file for all 4 CICs.
- Submit; track acks.
Job 10: Audit log integrity check
Section titled “Job 10: Audit log integrity check”- Recompute hash chain.
- Alert on any mismatch.
- Run at low-volume time (e.g., 22:00).
Ordering rationale
Section titled “Ordering rationale”Tier-1 jobs run before any other writes for the day to ensure:
- Accrual is based on settled outstanding (no mid-day repayments confuse).
- Classification reflects yesterday’s full picture.
- Provisioning is based on yesterday’s classification.
NACH file generation must run late enough to include any same-day repayments that change tomorrow’s dues, but early enough to meet sponsor-bank cut-off.
Failure handling
Section titled “Failure handling”Tier-1 failure
Section titled “Tier-1 failure”If accrual / classification / provisioning fails for some loans:
- Don’t proceed to dependent jobs without re-run.
- Alert immediately.
- Manual investigation; fix; re-run.
Tier-2 failure
Section titled “Tier-2 failure”If NACH file generation fails:
- Bypass for that day → borrowers’ dues continue but presentation delayed by a day.
- Notify ops.
- Fix and submit next day.
If reconciliation fails:
- Continue with exception queue.
- Don’t block other operations.
Performance
Section titled “Performance”For 100,000 active loans:
- Daily accrual:
< 30 minuteswith parallel batch. - Daily classification:
< 45 minutes. - Daily provisioning:
< 30 minutes. - NACH file generation:
< 15 minutesfor~5,000 daily debits.
Beyond 1 million loans, batch jobs are partitioned by loan_id range and parallelised across workers.
Day-N+1 reporting after batch
Section titled “Day-N+1 reporting after batch”By 06:00 of the next day, the platform’s dashboards show:
- Yesterday’s classification distribution.
- Yesterday’s roll-rate.
- Yesterday’s NPA additions.
- Yesterday’s repayments.
- Yesterday’s reconciliation exceptions.
Ops, risk, finance all consume this in the morning.
What the platform must enforce
Section titled “What the platform must enforce”- All Tier-1 jobs must complete daily — no skip.
- Idempotency so re-runs are safe.
- Audit trail for each batch run (start time, end time, records processed, exceptions).
- Monitoring of batch SLAs.
- Alerting on failures.
- Documented runbooks for batch failure scenarios.
Related
Section titled “Related”- 18.4 Interest conventions.
- 2.10 Asset classification.
- 5.4 Events and async — event sourcing context.
- 5.14 NACH file format.
- 18.11 Reconciliation algorithm.