Skip to content

5.8 Sequence diagrams — core flows

The architecture pages describe shape; this page shows mechanics. The eight sequence diagrams below cover the most-touched flows in the platform. Each runs from the triggering event to the terminal state.

For diagrams to render, the site uses astro-mermaid (configured in docs/astro.config.mjs).

The borrower’s application moves through KYC, ingestion, decisioning to the sanction proposal.

sequenceDiagram
    autonumber
    actor Borrower
    participant BFF as Borrower BFF
    participant App as Application Service
    participant KYC as KYC Service
    participant Ingest as Ingestion Service
    participant Decision as Decision Engine
    participant Bus as Event Bus

    Borrower->>BFF: POST /applications (with consents)
    BFF->>App: createApplication
    App->>Bus: application.created
    App-->>BFF: 201 application_id

    Borrower->>BFF: KYC initiate
    BFF->>KYC: vcip.schedule
    KYC-->>BFF: session_url
    Borrower->>KYC: complete V-CIP
    KYC->>App: kyc.completed
    App->>Bus: kyc.individual.completed

    Borrower->>BFF: AA consent
    BFF->>Ingest: aa.consent-request
    Ingest-->>Borrower: redirect to AA
    Borrower->>Ingest: consent granted
    Ingest->>Ingest: fetch bank statement
    Ingest->>App: data.bank_statement.parsed
    Ingest->>App: data.gst.pulled
    Ingest->>App: data.bureau.pulled

    Borrower->>BFF: submit application
    BFF->>App: applications.submit
    App->>Decision: run(applicationId)
    Decision->>Decision: load policy (vN)
    Decision->>Decision: execute scorecards
    Decision->>App: decision = APPROVE, grade=A2, sanction=35L
    App->>Bus: decision.approved
    BFF-->>Borrower: offer screen (KFS preview)

After APPROVE and borrower acceptance of the offer.

sequenceDiagram
    autonumber
    actor Borrower
    participant App as Application Service
    participant Sanction as Sanction Service
    participant Docs as Documentation Service
    participant ESign as eSign Adapter
    participant Stamp as eStamp Adapter
    participant Bus as Event Bus

    App->>Sanction: createSanction(decision_id)
    Sanction->>Bus: sanction.issued

    Sanction->>Docs: generate KFS + agreement + DPN + PG
    Docs->>Bus: document.generated
    Docs-->>App: docs ready

    App->>Borrower: KFS link (vernacular)
    Borrower->>Docs: acknowledge KFS
    Docs->>Bus: kfs.acknowledged

    Docs->>ESign: start multi-signer flow (D1, D2)
    ESign-->>Borrower: OTP to D1
    Borrower->>ESign: D1 signs
    ESign-->>Borrower: OTP to D2
    Borrower->>ESign: D2 signs
    ESign->>Docs: esign.completed
    Docs->>Bus: esign.completed

    Docs->>Stamp: issue eStamp
    Stamp-->>Docs: stamp certificate
    Docs->>Bus: document.stamped

    Docs-->>App: agreement fully executed

Runs in parallel with eSign on the application.

sequenceDiagram
    autonumber
    actor Borrower
    participant Mandate as Mandate Service
    participant NACH as NACH / eNACH Adapter
    participant Sponsor as Sponsor Bank
    participant NPCI as NPCI
    participant Bus as Event Bus

    Borrower->>Mandate: create eNACH (Aadhaar OTP)
    Mandate->>NACH: register mandate
    NACH->>Sponsor: SFTP file / API push
    Sponsor->>NPCI: submit mandate to NPCI
    NPCI-->>Sponsor: ack
    Sponsor-->>NACH: mandate active
    NACH->>Mandate: status active
    Mandate->>Bus: mandate.active

Pre-disbursement checklist → payout → UTR capture → LMS activation.

sequenceDiagram
    autonumber
    participant Disburse as Disbursement Service
    participant App as Application
    participant LMS as LMS
    participant Sanction as Sanction
    participant Mandate as Mandate
    participant KYC as KYC
    participant Payout as Payout Adapter
    participant Bank as Sponsor Bank
    participant Bus as Event Bus

    Disburse->>Disburse: run pre-disbursement checklist
    Disburse->>KYC: verify KYC valid & current
    Disburse->>Sanction: verify within validity
    Disburse->>Mandate: verify mandate active
    Disburse->>App: confirm cooling-off opted

    Disburse->>Payout: execute payout (IMPS/NEFT)
    Payout->>Bank: API call
    Bank-->>Payout: UTR
    Payout->>Disburse: utr_captured
    Disburse->>Bus: disbursement.executed

    Disburse->>LMS: activate loan account
    LMS->>LMS: create schedule, init accrual
    LMS->>Bus: loan.activated

Daily NACH cycle: presentation → bank processing → ack → allocation.

sequenceDiagram
    autonumber
    participant LMS as LMS Daily Job
    participant NACH as NACH Adapter
    participant Sponsor as Sponsor Bank
    participant NPCI as NPCI
    participant Recon as Reconciliation Service
    participant Bus as Event Bus

    LMS->>LMS: identify dues for today
    LMS->>NACH: generate presentation file
    NACH->>Sponsor: SFTP file
    Sponsor->>NPCI: present batch
    NPCI->>NPCI: process across banks
    NPCI-->>Sponsor: ack file (success/bounce per row)
    Sponsor-->>NACH: ack file (next day)
    NACH->>LMS: per loan: success or bounce

    alt success
        LMS->>LMS: record repayment
        LMS->>LMS: allocate (waterfall: penal/fees/interest/principal)
        LMS->>Bus: repayment.allocated
    else bounce
        LMS->>LMS: record bounce + apply bounce fee
        LMS->>Bus: bounce.received
    end

    Recon->>Sponsor: pull statement
    Recon->>LMS: reconcile expected vs actual
    Recon->>Bus: reconciliation.matched

End-of-day job classifies every loan per IRACP norms.

sequenceDiagram
    autonumber
    participant Scheduler as Cron
    participant LMS as LMS Daily Job
    participant Classify as Classification Engine
    participant Provision as Provisioning Engine
    participant Bureau as Bureau Adapter
    participant Bus as Event Bus

    Scheduler->>LMS: trigger 23:30
    LMS->>Classify: compute DPD per loan (calendar days from due)
    Classify->>Classify: bucket: Std / SMA-0/1/2 / NPA / Sub / Doubt / Loss
    Classify->>LMS: write classification_snapshot

    loop per loan with status change
        Classify->>Bus: classification.changed
    end

    Classify->>Provision: compute provisioning
    Provision->>Provision: apply IRACP grid (secured/unsecured/sub/cure)
    Provision->>LMS: write provision

    LMS->>Bureau: queue for monthly submission (weekly best practice)

Daily / weekly partner settlement from escrow.

sequenceDiagram
    autonumber
    participant Scheduler as Cron (06:00)
    participant Settle as Settlement Engine
    participant LMS as LMS
    participant Escrow as Co-lending Escrow
    participant Bank as Sponsor Bank
    participant Partner as Partner System
    participant Bus as Event Bus

    Scheduler->>Settle: trigger daily
    Settle->>LMS: pull yesterday's repayments with share split
    Settle->>Settle: aggregate per partner
    Settle->>Settle: apply waterfall (servicing fee retention, etc.)
    Settle->>Bank: payout instruction (NEFT from escrow)
    Bank-->>Settle: UTR per partner
    Settle->>Bus: settlement.completed
    Settle->>Partner: webhook / SFTP MIS
    Partner-->>Settle: ack

When a co-lent loan turns NPA and a DLG arrangement covers the pool.

sequenceDiagram
    autonumber
    participant Classify as Classification Engine
    participant LMS as LMS
    participant DLG as DLG Service
    participant Partner as Partner / LSP
    participant Bus as Event Bus

    Classify->>LMS: borrower DPD = 91 → NPA
    LMS->>Bus: classification.changed (NPA)
    LMS->>Partner: NPA lockstep update (both lenders move same day)

    Note over LMS,DLG: T+120 days from NPA
    DLG->>LMS: check loans eligible for DLG invocation
    DLG->>DLG: build invocation batch for period
    DLG->>Partner: send invocation file (eligible loans + evidence)
    Partner-->>DLG: validate
    DLG->>DLG: execute draw (FD lien / cash deposit / BG)
    DLG->>LMS: post DLG recovery against NPA loans
    LMS->>Bus: dlg.invoked
    LMS->>LMS: reduce provision proportionately

Bonus: Restructuring workflow (long-running)

Section titled “Bonus: Restructuring workflow (long-running)”

Restructuring is multi-stage; uses workflow engine to coordinate.

sequenceDiagram
    autonumber
    actor Analyst
    actor CRO
    participant WFE as Workflow Engine
    participant Decision as Decision Engine
    participant LMS as LMS
    participant Docs as Documentation
    participant Bus as Event Bus

    Analyst->>WFE: initiate restructuring(loan_id, reason)
    WFE->>Decision: assess proposed terms
    Decision-->>WFE: assessment + recommended terms

    WFE->>CRO: approval request (per matrix)
    CRO-->>WFE: approved with conditions

    WFE->>LMS: downgrade loan per IRACP (immediate NPA if standard)
    LMS->>Bus: classification.changed (restructured)
    LMS->>LMS: write provision per restructured-asset grid

    WFE->>Docs: generate restructuring agreement
    Docs->>WFE: doc ready
    WFE->>LMS: apply new schedule + frozen rules

    Note over WFE: observation period (typically 12 months)
    WFE->>LMS: at obs-period-end, check performance
    alt satisfactory
        WFE->>LMS: upgrade
        LMS->>Bus: classification.changed (standard)
    else not satisfactory
        WFE->>LMS: keep classified
    end

Where the borrower’s data physically lives at each stage.

graph LR
    A[Borrower app/portal] -->|consent + PII| B[PII Tokenisation Vault]
    A -->|PAN/GSTIN| C[Verification adapters]
    A -->|AA consent| D[AA TSP - Setu/FinBox]
    D -->|encrypted| E[Bank FIP]
    E -->|encrypted statement| D
    D -->|decrypted to FIU| F[Ingestion Service]
    F -->|parsed metrics| G[(PostgreSQL OLTP)]
    F -->|raw + parsed| H[(S3 Object Store)]
    G -->|CDC| I[Warehouse]
    G --> J[Decision Engine]
    J --> K[Sanction]
    K --> L[LMS]
    L --> G
    L -->|GL postings| M[Accounting]
    L -->|MIS| N[Partner Bank]
  • Authoritative shape, not contract. The actual sequence may differ per partner / vendor — e.g., one partner may require synchronous booking confirmation before disbursement; another accepts batch ack.
  • Idempotency keys assumed on every mutating call across boundaries; not shown in diagrams for clarity.
  • Error / retry / DLQ paths are not shown but are part of every cross-service call per 5.4 Events and async.
  • Audit events are emitted at every state-change point; not shown but part of every flow.
  • Compliance gates (KYC valid, mandate active, cooling-off observed) are pre-checked at every gate; the diagrams show the happy path.

For sequence-level test artefacts (Postman / WireMock contracts), see the API catalogue in 5.10 API catalogue.