top of page

Digital Lending Jounery with all retail loan type

  • Writer: Anand Nerurkar
    Anand Nerurkar
  • Sep 13
  • 14 min read

Digital Lending – Unified Architecture Flow (Text Version)

1. Entry Points

  • Angular Frontend App

    • Loan type selection (Personal, Auto, Home, BNPL, Micro)

    • Captures user inputs → Sends REST/GraphQL request to Loan Origination API Gateway

  • API Gateway (Azure API Management)

    • AuthN via Azure AD / OAuth2

    • Routes to respective Loan Orchestration Service

2. Core Microservices (Deployed on AKS)

  • Loan Orchestration Service

    • Publishes loan.initiated event to Kafka with:

      • Loan Type

      • Customer ID

      • Correlation ID

      • Idempotency Key

  • KYC Service

    • Consumes loan.initiated

    • Performs eKYC (Aadhaar/PAN/DigiLocker)

    • Publishes kyc.completed

  • Credit Score Service

    • Consumes kyc.completed

    • Calls bureau / internal scorecard

    • Publishes creditscore.completed

  • Collateral Service (only for Auto/Home)

    • Consumes creditscore.completed (if loan type requires collateral)

    • Triggers:

      • Vehicle valuation + RTO lien marking (Auto)

      • Property valuation + legal verification (Home)

    • Publishes collateral.verified

  • Risk/Underwriting Service

    • Listens to creditscore.completed and collateral.verified

    • Applies rules engine (Drools/Decision Table)

    • Publishes loan.approved or loan.rejected

  • Agreement Service

    • Consumes loan.approved

    • Generates sanction letter & e-agreement

    • Publishes agreement.signed

  • Disbursement Service

    • Consumes agreement.signed

    • Triggers payment through Core Banking / Payment API

    • Publishes loan.disbursed

3. Kafka Event Topics

  • loan.initiated

  • kyc.completed

  • creditscore.completed

  • collateral.verified

  • loan.approved

  • loan.rejected

  • agreement.signed

  • loan.disbursed

  • loan.failed (for saga rollback scenarios)

4. Branching by Loan Type

Personal Loan

loan.initiated → kyc.completed → creditscore.completed → 
loan.approved → agreement.signed → loan.disbursed
  • No collateral check

  • Fully automated underwriting

BNPL / Consumer Durable Loan

loan.initiated → kyc.completed (OTP only) → lightweight score →
loan.approved → agreement.signed → loan.disbursed (merchant settlement)
  • Low friction, minimal KYC

  • Instant decisioning, sub-second SLAs

Auto Loan

loan.initiated → kyc.completed → creditscore.completed → 
collateral.verified (vehicle validation + lien marking) →
loan.approved → agreement.signed → loan.disbursed (dealer)
  • Adds vehicle data capture + lien step

  • Disbursement only after lien marking confirmed

Home Loan

loan.initiated → kyc.completed → creditscore.completed →
collateral.verified (property valuation + legal check) →
manual underwriting approval →
loan.approved → agreement.signed → 
loan.disbursed (tranches if construction linked)
  • Multi-step manual approvals

  • Collateral check may involve external legal vendor integration

  • Disbursement can be partial (multiple loan.disbursed events)

Micro Loans

loan.initiated → kyc.completed (alternate data) → 
alt.credit.score.completed → loan.approved → 
agreement.signed → loan.disbursed
  • Uses alternate data (UPI txn, mobile data, etc.)

  • Real-time scoring models (ML-based)

5. Saga / Compensation Flow

If any service fails:

  • loan.failed event is published

  • Orchestration service triggers rollback:

    • Reverse disbursement (if money already sent)

    • Cancel lien (Auto)

    • Void sanction letter (Home/Personal)

6. Cross-Cutting Concerns

  • Correlation ID + Idempotency Key generated at loan.initiated

  • Redis Cache to store intermediate state for idempotency & fast reads

  • Cosmos DB / Azure SQL stores loan application, events, decision logs

  • Azure Monitor + Grafana for observability

  • Security: Azure AD + API Gateway throttling + encrypted payloads (PII)

Key Advantage:This design is loan-type agnostic — same set of microservices are used, but behavior changes via:

  • Product Config Table (decides whether collateral step required)

  • Business Rules (auto vs manual underwriting)

  • Workflow Orchestration (skips/branches steps)


Home Loan Journey

===

🏠 Home Loan – Detailed Event-Driven Journey (Text Version)

1. Loan Initiation

  • Actor: Customer (via Angular Frontend)

  • Flow:

    • Customer fills loan application (loan amount, property details)

    • API Gateway (Azure API Mgmt) forwards request to Loan Orchestration Service

    • Loan Orchestration Service

      • Generates Correlation ID + Idempotency Key

      • Stores initial application in Cosmos DB

      • Publishes event:loan.initiated {loanType=HOME, correlationId, customerId, propertyDetails}

2. KYC Step

  • KYC Service

    • Consumes loan.initiated

    • Performs full eKYC (PAN + Aadhaar + Address Proof via DigiLocker)

    • Updates application status in DB

    • Publishes:kyc.completed {correlationId, kycStatus=PASS}

3. Credit Score + Affordability

  • Credit Score Service

    • Consumes kyc.completed

    • Calls Bureau API + internal affordability model (DTI, FOIR)

    • Persists score + decision data

    • Publishes:creditscore.completed {correlationId, cibilScore, dti, eligibility}

4. Collateral Verification (Property Validation)

  • Collateral Service

    • Consumes creditscore.completed

    • Triggers two external vendor workflows:

      1. Property Valuation Vendor API → receives valuation report

      2. Legal Vendor API → performs title search, encumbrance check

    • Both results stored in DB

    • Publishes:collateral.verified {correlationId, valuationReportId, legalClearanceStatus}

5. Multi-Step Manual Approval

  • Risk/Underwriting Service

    • Waits for both creditscore.completed & collateral.verified (Kafka Join)

    • Generates Underwriting Case in workflow queue (Camunda / Azure Logic App)

    • Manual approvers are notified (Credit Officer, Risk Head)

    • Steps:

      • Step 1: Credit Officer reviews & approves

        • Publishes: manual.approval.level1.completed

      • Step 2: Risk Head final approval

        • Publishes: manual.approval.level2.completed

    • Once all levels approved:

      • Publishes:loan.approved {correlationId, sanctionAmount, approvedTenor}

6. Agreement Generation

  • Agreement Service

    • Consumes loan.approved

    • Generates sanction letter & loan agreement PDF

    • Sends for e-sign (AADHAAR eSign / NSDL)

    • After successful sign:

      • Publishes:agreement.signed {correlationId, agreementDocId}

7. Partial / Tranche Disbursement

  • Disbursement Service

    • Consumes agreement.signed

    • Checks property construction stage from external vendor / builder API

    • Disburses first tranche (e.g., 20% of loan)

    • Publishes:loan.disbursed {correlationId, tranche=1, amount=20%}

  • Subsequent Tranches:

    • Triggered by builder demand letter upload / stage completion

    • Loan Orchestration Service republishes:disbursement.requested {correlationId, tranche=N}

    • Disbursement Service validates stage, releases funds

    • Publishes multiple events until:loan.disbursed {correlationId, tranche=FINAL, amount=remaining}

8. Saga / Rollback (if failure)

  • If legal clearance fails → loan.rejected

  • If customer drops application post-approval → publishes loan.cancelled

  • If partial disbursement already made → triggers compensation workflow (recall funds, notify risk)

9. Observability & Compliance

  • Audit Service subscribes to all events (loan.*) → stores in immutable audit store

  • Regulatory Reporting Service generates FIU-IND & RBI compliance reports

Complete Home Loan Event Sequence

loan.initiated →
kyc.completed →
creditscore.completed →
collateral.verified →
manual.approval.level1.completed →
manual.approval.level2.completed →
loan.approved →
agreement.signed →
loan.disbursed (tranche=1) →
loan.disbursed (tranche=2) →
...
loan.disbursed (tranche=FINAL)

Key Points

External Vendor Integration: property valuation & legal checks done asynchronously → no UI blocking

Multi-Level Manual Approvals: handled via workflow engine with human tasks

Partial Disbursement: multiple loan.disbursed events handled idempotently

Auditability: every event stored for compliance (RBI/SEBI)

Saga Rollbacks: prevent partial exposure risk if legal/credit fails mid-way


Yes — you are absolutely correct (and that is a better, production-grade approach).Let’s refine the design to reflect a transactional write + event outbox pattern instead of writing directly to Cosmos DB.

Here’s how it should work:


Corrected Data Flow – Home Loan (and Other Loan Types)

1. Loan Initiation – Data Write

  • Loan Orchestration Service

    1. Accepts application request from API Gateway

    2. Starts a DB transaction on Azure Database for PostgreSQL

    3. Writes:

      • Loan application master record

      • Customer details (if new)

    4. Writes an outbox event (loan.initiated) in the same transaction✅ This guarantees atomicity (no loan without event / no event without loan)

2. Outbox → Kafka Publish

  • Outbox Event Publisher (Debezium / Custom Scheduler)

    • Reads unprocessed outbox events from Postgres

    • Publishes them to Kafka topic loan.initiated

    • Marks them as published in Postgres (idempotency-safe)

3. Event Consumers Update Caches + NoSQL

  • Cache Consumer

    • Consumes loan.initiated (and subsequent events)

    • Updates Redis cache for low-latency loan lookup

  • NoSQL Consumer

    • Consumes loan.initiated (and subsequent events)

    • Writes denormalized document into Cosmos DB

      • Purpose: fast query for UI dashboards, audit, analytics

      • Acts as a read replica of Postgres + derived events

4. Subsequent Steps

  • All other services (KYC, Credit Score, Collateral, etc.) consume Kafka events, perform their work, and write:

    • DB updates (Postgres → Outbox)

    • Next event (via outbox → Kafka)

  • Cache + NoSQL get updated continuously to reflect the latest loan state

Benefits of This Approach

Area

Direct Cosmos Write

Postgres + Outbox Pattern (Recommended)

Consistency

Eventual, can have drift

Strong — DB + event commit together

Transaction Safety

Risk of partial writes (DB vs Cosmos mismatch)

Atomic commit ensures no data loss

Idempotency

Manual deduplication needed

Outbox handles dedupe + replay

Cache Population

Manual triggers needed

Event-driven (auto updated)

Auditability

Harder (multiple DBs)

Easy — Postgres is source of truth

Corrected Initial Step in Home Loan Journey

POST /loan-application
 ↓
Loan Orchestration Service
  - Start TX in Postgres
  - Insert LoanApplication (status=INITIATED)
  - Insert OutboxEvent(loan.initiated)
  - Commit
 ↓
OutboxPublisher picks event → Kafka
 ↓
CacheConsumer → Redis
NoSQLConsumer → Cosmos DB
 ↓
KYC Service consumes event → next step

So yes — Cosmos DB is not the primary store, but a projection / query-optimized replica populated asynchronously.This is the CQRS + Outbox pattern, which is the industry best practice for a microservices-based lending platform.


1 — Canonical technical assumptions (applies to all flows)

  • Frontend: Angular SPA (Customer / Dealer / Agent) → calls API Gateway (APIM).

  • API Gateway: Authentication (Azure AD B2C), request validation, rate limiting; forwards to Loan Orchestration Service.

  • Source of truth DB: Azure Database for PostgreSQL (transactional).

  • Outbox: outbox_event table in Postgres written in the same transaction as application changes.

  • Outbox publisher: Debezium or a scheduled publisher reads outbox rows and publishes to Kafka, marks as published.

  • Event bus: Kafka (topics per domain event).

  • Consumers:

    • CacheConsumer → updates Redis (fast reads).

    • NoSQLConsumer → writes denormalized documents into Cosmos DB (read-model / UI).

    • Domain microservice consumers (KYC, Score, Collateral, Underwriting, etc.).

  • Microservices: Spring Boot services deployed on AKS, each owns its DB/aggregate or uses Postgres with proper aggregate boundaries.

  • Correlation & Idempotency:

    • correlation_id included in all events/DB rows.

    • idempotency_key required on client POSTs; services ensure idempotent handling.

  • Sagas / Compensation: Each step that changes external systems emits compensating events (example: disbursement.rollback.requested).

  • Manual tasks: Workflow engine (Temporal/Camunda) or workbench for human approvals; manual steps produce events when completed.

2 — Core domain events (canonical list)

(Version all event names, payloads should include correlation_id, app_id, customer_id, loan_type.)

  • loan.initiated

  • loan.application.persisted (outbox transitional)

  • document.uploaded

  • kyc.completed

  • creditscore.completed

  • eligibility.decided

  • collateral.verified

  • valuation.reported

  • legal.clearance.completed

  • manual.approval.requested

  • manual.approval.completed

  • loan.approved

  • agreement.generated

  • agreement.signed

  • disbursement.requested

  • loan.disbursed (include tranche number)

  • repayment.schedule.created

  • repayment.received

  • loan.rejected

  • loan.cancelled

  • compensation.requested

  • audit.event (for immutable audit store)

3 — Database + outbox pattern (text)

  1. Client (Angular) POSTs /v1/loan-applications with Idempotency-Key.

  2. Loan Orchestration Service:

    • Begin Postgres TX.

    • Insert into loan_application (status = INITIATED) — primary record.

    • Insert into outbox_event (event_type=loan.initiated, payload with app data).

    • Commit TX.

  3. OutboxPublisher reads outbox row, publishes loan.initiated to Kafka, updates outbox_event.published=true.

  4. Consumers (CacheConsumer, NoSQLConsumer, KYC, Score) pick up loan.initiated and proceed.

4 — Projection consumers (text)

  • CacheConsumer:

    • Consumes every loan.* event.

    • Updates Redis keys for quick UI read: loan:{appId}:status, loan:{appId}:nextStep, loan:{appId}:latestEvent.

    • TTLs for non-critical items, or immediate deletion on closure.

  • NoSQLConsumer (Cosmos DB):

    • Consumes every loan.* event.

    • Writes denormalized document loan_document combining application + latest events + collateral summary + KYC status for fast UI queries and analytics.

5 — Orchestrator behaviour (how product config is used)

  • Product Configuration Service (Postgres table product_config) contains:

    • product_code (PERSONAL, BNPL, AUTO, HOME, MICRO)

    • steps (ordered list of step ids)

    • flags (requires_collateral, requires_valuation, requires_legal, requires_manual_approval)

    • auto_approval_thresholds (score, ltv, dti)

    • disbursement_mode (LUMP_SUM, TRANCHE)

    • manual_approval_flow (levels & approvers)

    • sla_seconds_per_step

  • On loan.initiated the Loan Orchestration Service:

    • Reads product_config for product_code.

    • Creates the workflow instance (lightweight state record in Postgres workflow_instance) with the steps sequence and current pointer.

    • Emits initial domain event(s) corresponding to first step(s), e.g. document.uploaded if docs were included, else kyc.started / kyc.requested.

    • Workflow state is advanced by upstream events (e.g., when kyc.completed arrives, orchestrator marks step completed and triggers next event(s) based on config).

    • If steps include parallelism (KYC + Score) orchestrator can emit both initial requests or let consumers act on loan.initiated.

6 — Business rules engine integration (text)

  • Rules Engine options: Drools / Decision Tables / DMN, or embedded rules in Eligibility Service.

  • Where rules live:

    • Static rules (product thresholds) in product_config.

    • Dynamic rules (complex underwriting) in Drools knowledge base; rules are versioned and deployed separately.

  • Runtime:

    • Underwriting Service calls Rules Engine with input facts: cibilScore, dti, ltv, incomeDocsVerified, legalClearance.

    • Rules evaluate and output decision: AUTO_ACCEPT, REFER_MANUAL, AUTO_REJECT, plus sanctionAmount, interestRate.

  • Rule-driven branching:

    • If result AUTO_ACCEPT → Underwriting publishes loan.approved.

    • If REFER_MANUAL → Underwriting publishes manual.approval.requested (with required approvers & SLA).

    • If AUTO_REJECT → Underwriting publishes loan.rejected (reason codes).

7 — Concrete sequences (text) — all loan types

For each sequence I show: UI action → Postgres+Outbox → Kafka → Consumers (Cache, NoSQL) → Domain services → subsequent events → final disbursement/repayment.

A) Personal Loan (fastest path — no collateral)

  1. UI → POST /v1/loan-applications (body includes product_code=PERSONAL) with Idempotency-Key.

  2. Loan Orchestration Service: write loan_application, write outbox_event (loan.initiated); commit.

  3. OutboxPublisher → publish loan.initiated to Kafka.

  4. CacheConsumer → Redis; NoSQLConsumer → Cosmos DB (application snapshot).

  5. KYC Service consumes loan.initiated:

    • performs eKYC (Aadhaar/PAN)

    • writes KYC result (Postgres) + outbox kyc.completed.

  6. Credit Score Service consumes kyc.completed:

    • calls bureau & internal models

    • writes result + outbox creditscore.completed.

  7. Eligibility Service consumes creditscore.completed (and kyc.completed):

    • fetches product_config(PERSONAL) (flags: no collateral, auto approval thresholds)

    • runs rules → decides AUTO_ACCEPT if score >= threshold

    • writes eligibility.decided event via outbox.

  8. Underwriting Service consumes eligibility.decided:

    • If auto → publishes loan.approved via outbox.

    • Else publishes manual.approval.requested.

  9. Agreement Service consumes loan.approved:

    • generates agreement, triggers eSign → on sign publishes agreement.signed.

  10. Disbursement Service consumes agreement.signed:

    • initiates payment via Payment Connector / CBS → on success publishes loan.disbursed (tranche=1).

  11. Repayment Service creates schedule on loan.approved or agreement.signed event and publishes repayment.schedule.created.

  12. UI queries read-model (Cosmos or Redis) for status updates.

Key notes:

  • All writes to Postgres use outbox for event emission.

  • Cache & NoSQL projections ensure UI remains snappy.

B) BNPL / Consumer Durable (merchant-embedded, low friction)

  1. Merchant Portal / UI triggers loan.initiated with product_code=BNPL and merchant metadata.

  2. Loan Application persisted w/ outbox → loan.initiated.

  3. Outbox → Kafka → Cache/NoSQL updates.

  4. Lightweight KYC step: kyc.completed may be OTP-only; sometimes skipped depending on merchant-level trust.

  5. Internal lightweight scoring service consumes (uses internal risk model, historical merchant settlement data) → creditscore.completed or altscore.completed.

  6. Eligibility Service uses product_config(BNPL) (low thresholds, instant approval policies) → typically AUTO_ACCEPT.

  7. Agreement generated (simplified) and agreement.signed emitted (may be implicit by merchant T&C acceptance).

  8. Disbursement to Merchant Settlement account via loan.disbursed event; settlement engine batches/clears later.

  9. Collections: Merchant settlement reconciles transactions; platform collects from borrower via scheduled EMIs/UPI.

Key differences:

  • Merchant context included in events: merchant_id, order_id.

  • Disbursement mode usually LUMP_SUM to merchant (or split by merchant settlement terms).

  • High-volume, low-latency processing; aggressive caching and partitioning.

C) Auto Loan (collateral + RTO/hypothecation)

  1. UI (Dealer/Customer) POSTs loan.initiated with product_code=AUTO + vehicle details.

  2. Postgres + Outbox → loan.initiated.

  3. Outbox → Kafka → Cache & Cosmos.

  4. KYC & Credit Score proceed as in Personal flow (kyc.completed, creditscore.completed).

  5. Collateral Service consumes creditscore.completed (or loan.initiated depending on config) and:

    • Validates vehicle details (VIN, chassis, engine) via Dealer / RTO connector → valuation.reported with market value.

    • Calculates LTV = requestedAmount / valuation.

    • If hypothecation required: triggers Hypothecation Service → calls RTO for lien registration.

    • On successful registration publishes collateral.verified (include lien_registration_id).

  6. Eligibility Service receives creditscore.completed + collateral.verified:

    • Runs rules: checks LTV <= product_config.auto.ltv_threshold; DTI; other checks.

    • Output: eligibility.decided.

  7. Underwriting executes business rules (may AUTO_ACCEPT or REFER_MANUAL).

  8. If accepted: Agreement Service produces lender & hypothecation docs → eSign & agreement.signed.

  9. Disbursement Service waits for collateral.verified & agreement.signed before issuing disbursement.requested → pays dealer (NEFT) → emits loan.disbursed.

  10. Any failure in lien registration → loan.rejected or compensation.requested if funds already moved.

Key differences:

  • Collateral & lien registration precondition for disbursement.

  • Extra external connectors: Dealer/DMS, RTO.

  • Compensation logic must handle partial external state (registered lien vs not).

D) Home Loan (multi-step manual approvals + external vendors + tranche disbursement) — FULL DETAILED SEQUENCE

(This is the full requested detailed flow — long-running, many external interactions.)

Step 0 — Client submission

  1. Customer submits home loan application with property metadata + document uploads (title docs, sale deed, NOC, builder letters).

  2. Loan Orchestration Service:

    • Begin TX in Postgres.

    • Insert loan_application (status=INITIATED).

    • Insert outbox_event (loan.initiated).

    • Commit.

Step 1 — Outbox → Initial projections

  1. OutboxPublisher publishes loan.initiated to Kafka.

  2. CacheConsumer updates Redis; NoSQLConsumer writes denormalized doc to Cosmos.

Step 2 — Document ingestion & OCR

  1. Document Service consumes loan.initiated and:

    • Stores uploads in Blob Storage.

    • Calls Form Recognizer/OCR asynchronously.

    • On OCR completion publishes document.uploaded events with document_id.

  2. NoSQLConsumer picks up docs and updates the read model.

Step 3 — KYC & Preliminary checks

  1. KYC Service consumes loan.initiated:

    • Performs full eKYC (Aadhaar, PAN, CKYC).

    • Performs AML/PEP screening.

    • Publishes kyc.completed {status}.

Step 4 — Credit Score & Affordability

  1. Credit Score Service consumes kyc.completed:

    • Calls bureau & internal affordability engine (DTI, FOIR).

    • Writes creditscore.completed event with score, affordability metrics.

Step 5 — Collateral: Valuation + Legal (two parallel external vendor flows)

  1. Collateral Service consumes creditscore.completed:

    • Property Valuation: calls Valuation Vendor API (third-party). Vendor returns valuation.report (market value, vtm).

    • Legal Title Search: calls Legal Vendor API. Vendor returns legal.clearance.status (CLEAR / EXCEPTIONS).

    • Collateral publishes valuation.reported & legal.clearance.completed.

  2. NoSQLConsumer updates read model with valuation & legal summaries.

Step 6 — Orchestration: prepare Underwriting Case

  1. Underwriting Service consumes valuation.reported and legal.clearance.completed + creditscore.completed:

    • Packages facts into Underwriting Case (cibilScore, valuation, legal exceptions, income verification).

    • Decides based on Rules Engine:

      • If AUTO_REJECT → publish loan.rejected.

      • If AUTO_ACCEPT → publish loan.approved.

      • If REFER_MANUAL → publish manual.approval.requested with work item details.

Step 7 — Manual multi-level approvals (human workflow)

  1. If manual.approval.requested:

    • Workflow engine / Workbench creates task(s) assigned per product_config.home.manual_approval_flow (e.g., Credit Officer → Legal Head → Risk Head).

    • Each approver logs into Workbench (UI) and completes their task:

      • On completion the Workbench emits manual.approval.completed {level, approverId, decision, comments}.

    • On final approval (all levels completed with APPROVE) Underwriting publishes loan.approved.

Step 8 — Sanction & Agreement

  1. On loan.approved:

    • Agreement Service creates sanction letter & loan agreement PDFs.

    • Agreement Service calls eSign providers (Aadhaar eSign / third-party).

    • On successful eSign publish agreement.signed.

Step 9 — Pre-disbursement validations

  1. Disbursement Service consumes agreement.signed and:

    • Reads product_config.home.disbursement_mode (TRANCHE vs LUMP_SUM).

    • For TRANCHE:

      • Waits for builder/buyer stage evidence:

      • Each tranche request is disbursement.requested {trancheNumber, amount, evidenceRef}.

    • Validates lien/registration status if applicable.

Step 10 — Disbursement (multiple loan.disbursed events)

  1. For each tranche:

    • Disbursement Service initiates payment via Payment Connector (NEFT/RTGS).

    • On success publishes loan.disbursed {tranche=N, amount, txnRef}.

    • Update Postgres loan_account outstanding balance.

    • NoSQLConsumer updates read-model.

Step 11 — Repayment scheduling & collections

  1. After first tranche (or on loan.approved), Repayment Service creates schedule:

    • Publish repayment.schedule.created.

    • Integrate with mandate provider (NACH/UPI) for auto-debit; create mandate.registered events.

  2. Repayment events (repayment.received) update loan_account and may lead to notifications and ledger entries.

Step 12 — Exceptions & compensations

  1. If legal vendor later reports encumbrance (post-disbursement), a legal.exception.raised event is emitted:

    • Risk team notified; may trigger compensation.requested (recall funds) if severe.

  2. If customer cancels after partial disbursements, compensation flow:

    • compensation.requested → Disbursement Service tries reversal; if reversal impossible creates manual collection task.

Step 13 — Closing

  1. On full repayment loan.closed event published and read-model updated.

Key home-loan specifics reiterated:

  • Long-running — workflow instances persisted; events may be days/weeks apart.

  • External vendor calls are asynchronous; platform does not block UI (use notifications to update applicant).

  • Tranche-based disbursement means multiple loan.disbursed events with idempotency checks (each tranche has unique trancheId).

  • Audit: every critical event is recorded in an immutable audit store for compliance.

E) Micro-loans (alternative-data, mobile-first)

  1. UI (mobile) POSTs loan.initiated with product_code=MICRO.

  2. Postgres + Outbox → loan.initiated published.

  3. NoSQL & Cache projections updated.

  4. Alt-Scoring Service consumes event:

    • Pulls UPI txn history, telco data, device signals (via integration service).

    • Produces altcreditscore.completed.

  5. Eligibility Service evaluates against product_config.micro (looser thresholds, limits).

  6. Underwriting typically AUTO_ACCEPT.

  7. Agreement implied or eSign via OTP; agreement.signed emitted.

  8. Disbursement instant to bank/UPI → loan.disbursed.

  9. Collections use UPI auto-debit or in-app repayment.

Key differences:

  • Uses alternate data connectors.

  • Extremely high throughput; needs optimized partitioning & caching.

8 — Product configuration example (JSON) — how to control flow

Store product configs in product_config table and optionally in a feature-flag service:

{
  "product_code": "HOME",
  "display_name": "Home Loan - Standard",
  "steps": [
    "DOCUMENT_UPLOAD",
    "KYC",
    "CREDIT_SCORE",
    "PROPERTY_VALUATION",
    "LEGAL_CHECK",
    "UNDERWRITING",
    "MANUAL_APPROVAL",
    "AGREEMENT",
    "DISBURSEMENT_TRANCHE"
  ],
  "flags": {
    "requires_collateral": true,
    "requires_valuation": true,
    "requires_legal": true,
    "requires_manual_approval": true
  },
  "auto_approval_thresholds": {
    "cibilScore": 750,
    "dti": 50,
    "ltv": 0.8
  },
  "disbursement": {
    "mode": "TRANCHE",
    "tranches": [
      { "percent": 0.2, "condition": "agreement_signed" },
      { "percent": 0.5, "condition": "builder_stage_2" },
      { "percent": 0.3, "condition": "building_completion" }
    ]
  },
  "manual_approval_flow": [
    { "level": 1, "role": "CreditOfficer" },
    { "level": 2, "role": "LegalHead" },
    { "level": 3, "role": "RiskHead" }
  ],
  "sla_seconds_per_step": {
    "KYC": 3600,
    "PROPERTY_VALUATION": 86400,
    "LEGAL_CHECK": 172800,
    "MANUAL_APPROVAL": 259200
  }
}

How it’s used:

  • Orchestrator reads steps and flags.

  • Orchestrator creates workflow_instance and issues initial events as needed.

  • Rules engine uses auto_approval_thresholds for auto-decision.

  • Disbursement service reads disbursement.tranches to know how many loan.disbursed events to expect and when to allow them.

9 — Rules / Decision Table example (text)

Decision table for UNDERWRITING_DECISION:

Condition: CIBIL >= 750

DTI <= 50%

LTV <= 80%

Legal Clear

Result

true

true

true

true

AUTO_ACCEPT

true

true

true

false

REFER_LEGAL

false

any

any

any

REFER_MANUAL

any

>70%

any

any

AUTO_REJECT

Rules can be authored in Drools and updated via CI/CD with versioning.

10 — Idempotency, retries, error handling (practical)

  • All endpoints require Idempotency-Key header; the Orchestration Service persists the key and ignores duplicate POSTs.

  • Outbox ensures events are published exactly-once (or at-least-once with idempotent consumers).

  • Consumers must be idempotent (check if event already applied using event_id).

  • Use exponential backoff + DLQ for failed event processing (human review for stuck items).

11 — Compensation examples (text)

  • Disbursement failed after agreement signed:

    • disbursement.failed → compensation.requested → Underwriting/Operations notified for manual fix.

  • Legal exception discovered post-disbursement:

    • legal.exception.raised → compensation.requested → Risk evaluates, may trigger recall event.

  • Partial funds reversed require ledger operations and manual.collection.task.

12 — Short operational note for UI developers

  • The UI should consume from the read-model (Cosmos/Redis) and poll or subscribe to push notifications for status change (websocket).

  • Each loan card should show currentStep (from read-model) and ETA based on sla_seconds_per_step.

  • For manual approvals, Workbench UI shows taskId, approverRole, SLA, supportingDocs links (pointing to Blob SAS URLs).

13 — Final summary (one-liner)

Use Postgres + Outbox → Kafka → Cache (Redis) + NoSQL (Cosmos) as the canonical data flow; control per-loan behavior via a product_config + rules engine; orchestration uses workflow instances to sequence and branch steps (parallel & sequential) — this supports all retail loan types including home loan multi-step manual approvals, external vendor property checks, and tranche-based disbursement (multiple loan.disbursed events).

If you want, I can now:

  • Produce a compact tabular matrix mapping each loan type to required product_config flags & expected events, or

  • Generate a sample SQL DDL for loan_application, outbox_event, and workflow_instance, or

  • Provide a Java Spring Boot pseudo-code snippet showing the Postgres transaction + outbox insert + publishing logic.


🏠 Home Loan – New Property vs. Resale Property Journey

1. Common Steps for Both

  • Loan Initiation → Capture applicant details, property info (builder/project ID or resale property address)

  • KYC → Aadhaar/PAN + address verification

  • Credit Score & Affordability Check → Bureau score, income calculation

  • Underwriting / Risk Assessment → Evaluate eligibility, FOIR/DTI

2. New Property (Approved Project) Flow

If the builder project is pre-approved:

  1. Property Verification Step Is Skipped

    • No legal opinion needed (already cleared during project approval)

    • No separate valuation needed (project’s unit pricing is known)

  2. Loan Approval → Agreement → Disbursement

    • Disbursement typically linked to construction stage

    • Multiple tranches are still possible (based on builder demand letters)

Event Sequence for New Property:

loan.initiated →
kyc.completed →
creditscore.completed →
loan.approved →
agreement.signed →
loan.disbursed (tranche 1 … tranche N)

3. Resale Property (Secondary Market) Flow

For resale (buying from an existing owner):

  1. Property Verification Step is Mandatory

    • Property Valuation: Market value vs. sale deed value

    • Legal Opinion: Encumbrance, title search, chain of ownership

  2. Underwriting Approval waits for property clearance

  3. Agreement → Disbursement

    • Usually single disbursement at sale deed registration

Event Sequence for Resale Property:

loan.initiated →
kyc.completed →
creditscore.completed →
collateral.verified (valuation + legal opinion) →
manual.approval.completed →
loan.approved →
agreement.signed →
loan.disbursed (one-shot)

4. Product Configuration Example

LoanType

CollateralCheck

ValuationRequired

LegalOpinionRequired

DisbursementMode

Home (New Project)

FALSE

FALSE

FALSE

MULTIPLE-TRANCHES

Home (Resale)

TRUE

TRUE

TRUE

SINGLE-SHOT

Auto

TRUE

TRUE (vehicle valuation)

FALSE (RTO lien check)

SINGLE

Personal

FALSE

FALSE

FALSE

SINGLE

BNPL

FALSE

FALSE

FALSE

INSTANT

Microloan

FALSE

ALT-DATA

FALSE

SINGLE

5. Business Rule Engine (Drools / DMN Table)

You configure rules like:

if loanType == HOME and propertyType == "NEW" and projectApproved == true:
    skipPropertyVerification = true
    disbursementMode = MULTIPLE
else if loanType == HOME and propertyType == "RESALE":
    skipPropertyVerification = false
    requireLegalOpinion = true
    disbursementMode = SINGLE

This ensures the same orchestration service dynamically decides which steps to execute.

6. Benefits

  • Dynamic Workflow: No hardcoding for each loan type

  • Simplified Maintenance: Add new loan products by just updating configuration + rules

  • Faster Approvals for New Projects: Skip redundant checks

  • Full Compliance for Resale: Ensure all legal/valuation steps are done


 
 
 

Recent Posts

See All
How to replan- No outcome after 6 month

⭐ “A transformation program is running for 6 months. Business says it is not delivering the value they expected. What will you do?” “When business says a 6-month transformation isn’t delivering value,

 
 
 
EA Strategy in case of Merger

⭐ EA Strategy in Case of a Merger (M&A) My EA strategy for a merger focuses on four pillars: discover, decide, integrate, and optimize.The goal is business continuity + synergy + tech consolidation. ✅

 
 
 

Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
  • Facebook
  • Twitter
  • LinkedIn

©2024 by AeeroTech. Proudly created with Wix.com

bottom of page