5.3 Core data model
This page is the conceptual entity catalogue — what entities exist, how they relate, and the key fields each carries. For the concrete DDL with types, indexes, and constraints, see 5.9 Schema reference. For a single borrower’s data shape through every stage, see 5.11 Worked data example.
Storage strategy
Section titled “Storage strategy”- PostgreSQL — primary OLTP store; one logical schema per module.
- Object storage (S3) — raw vendor responses, documents, evidence packages, V-CIP recordings, audit-log archives. Versioned + Object Lock for evidence.
- Vault / KMS — clear-text PII (PAN, Aadhaar, mobile, email, bank account). Tokens in main DB.
- Redis — cache (decision-engine policy, bureau-report TTL).
- OpenSearch — log + free-text search indexes.
- Event bus — Kafka / RabbitMQ for async coupling.
- Warehouse — Snowflake / ClickHouse for analytics, fed by CDC.
Entity families and relations
Section titled “Entity families and relations”Borrower ──┬── BusinessEntity ──┬── Promoter[] │ └── BeneficialOwner (graph) │ ├── Lead ───── Channel / Partner / SubAgent │ └── Application ──┬── ApplicationBankAccount[] ├── ExistingDebt[] ├── Consent[] ├── Document[] ├── KycRecord (via Promoter) ├── KybRecord (via BusinessEntity) ├── DataPull[] (bank, gst, bureau, tally, aa, mca) ├── DecisionRun[] (per policy version) └── Sanction ├── IssuedDocument[] (KFS, agreement, DPN, PG) ├── EsignSession[] ├── EstampSession ├── Mandate └── LoanAccount ├── LoanEvent[] (append-only) ├── ScheduleLine[] ├── Repayment[] ├── Charge[] ├── ClassificationSnapshot[] (daily) ├── Provision[] ├── LoanAllocation (if co-lent) │ └── PartnerLender + DlgAgreement ├── CollectionCase[] (per delinquency episode) ├── Restructuring[] ├── Writeoff[] └── GlPosting[] (accounting)
AuditEvent (cross-cutting; emitted by every state change; hash-chained)Entities — borrower and channel
Section titled “Entities — borrower and channel”borrower
Section titled “borrower”Top-level identity of a customer.
type— individual / proprietorship / partnership / llp / pvt_ltd / pub_ltd / huf / trust / society.display_name.primary_mobile_token,primary_email_token,pan_token— all tokenised; clear text in vault.kyc_status— pending / in_progress / verified / rejected.risk_category— low / medium / high (drives KYC refresh cadence).created_via_channel_id.
business_entity
Section titled “business_entity”For non-individual borrowers.
borrower_idFK.legal_name,trade_name.gstin_token,udyam_no,cin_or_llpin,pan_token.date_of_incorporation,date_of_commencement.industry_nic_code,business_sub_category.registered_address,principal_place_address,operational_locations[].annual_turnover_self_declared,turnover_validated_from_gst.num_employees,business_vintage_years,working_capital_cycle_days_estimated.
promoter
Section titled “promoter”Natural persons controlling the entity.
business_entity_idFK.name,dob,gender,nationality.pan_token,aadhaar_ref_token,mobile_token,email_token.role— director / partner / proprietor / authorised_signatory / karta / trustee.shareholding_pct,din_or_pin.permanent_address,current_address.kyc_status,kyc_method.
beneficial_owner
Section titled “beneficial_owner”Recursive graph for non-individual borrowers.
business_entity_id,parent_bo_id(nullable, for multi-tier).bo_natural_person_promoter_idFK to ultimate natural person.ownership_pct_direct,ownership_pct_effective.verification_status.
channel / partner / sub_agent
Section titled “channel / partner / sub_agent”Channel hierarchy for attribution.
channel.type— direct / dsa / ca / anchor / embedded / partner.partner— concrete instance under channel.sub_agent— individual under partner.
Top-of-funnel; converts to Application.
borrower_pan_token,mobile_token.channel_id,partner_id,sub_agent_id,campaign_id.utm_source,utm_medium,utm_campaign.status,stage.
Entities — application
Section titled “Entities — application”application
Section titled “application”Central record of a loan request.
borrower_id,lead_id.status— draft / submitted / under_review / approved / declined / withdrawn / disbursed.loan_product_id,loan_amount_sought,tenure_sought,purpose_code.channel_id,partner_id,sub_agent_id.decision_engine_decision_id,sanction_id.application_version.
application_section_data
Section titled “application_section_data”Per-section JSON blob for save-and-resume.
application_id,section_name,data_json,last_saved_at.
existing_debt
Section titled “existing_debt”Declared / bureau-derived debts.
application_id,lender,outstanding,emi,tenure,vintage_months.declared_or_bureau— source.
application_bank_account
Section titled “application_bank_account”Borrower bank accounts attached to application.
application_id,bank,ifsc,account_number_token.is_collection,is_disbursement.verified_via_penny_drop,penny_drop_at.
consent
Section titled “consent”Every consent ever granted.
borrower_id,purpose,data_categories[].granted_at,expires_at,revoked_at.version_of_policy,ip,device_fingerprint.vendor(e.g., AA name),vendor_consent_ref(consent handle).
document
Section titled “document”Borrower-uploaded artefacts (separate from generated documents).
application_idorloan_id,type,vendor_or_borrower_source.object_store_uri,hash.uploaded_at,verified_at,verified_by.
Entities — KYC / KYB
Section titled “Entities — KYC / KYB”kyc_record
Section titled “kyc_record”Per natural person.
promoter_id.method— vcip / aadhaar_offline / digilocker / in_person.ovd_type,ovd_proof_id.ckyc_kin,ckyc_uploaded_at,ckyc_status.sanctions_screen_id.verified_at,next_refresh_due_at.
kyb_record
Section titled “kyb_record”Per business entity.
business_entity_id.gstin_verification_id,udyam_verification_id,mca_verification_id.bo_graph_root_id.verified_at,next_refresh_due_at.
vcip_session
Section titled “vcip_session”Per V-CIP attempt.
kyc_record_id,vendor.started_at,completed_at,outcome.recording_uri,geo_tag_lat,geo_tag_lon.
sanctions_screen
Section titled “sanctions_screen”Per screen, per subject.
subject_type(person / entity),subject_id.vendor,screened_at,hits[].disposition,disposition_by,disposition_at.
Entities — data ingestion
Section titled “Entities — data ingestion”data_pull
Section titled “data_pull”One row per pull request.
borrower_id,data_type(bank / gst / mca / bureau / tally / aa / itr / udyam / invoice / marketplace).vendor,consent_ref.requested_at,completed_at,status.raw_object_uri,parsed_object_uri.
bank_statement
Section titled “bank_statement”borrower_id,account_ref,period_start,period_end.parser_vendor,parser_version.parsed_metrics_json— ABB, MAB, turnover, bounces, EMIs, etc.transactions_object_uri— full transactions in object store.
gst_report
Section titled “gst_report”business_entity_id,gstin,period_start,period_end.pulled_at,vendor.gstr1_metrics_json,gstr3b_metrics_json,gstr2a_metrics_json.
tally_export
Section titled “tally_export”business_entity_id,uploaded_at,object_uri.parsed_at,parsed_metrics_json— P&L, BS, ageing, inventory.
bureau_report
Section titled “bureau_report”subject_type(person / entity),subject_id.cic(cibil / experian / equifax / crif),report_type(consumer / commercial / msme).pulled_at,score,parsed_object_uri,enquiry_id_at_cic.
invoice / mca_snapshot / marketplace_settlement
Section titled “invoice / mca_snapshot / marketplace_settlement”As needed per product set.
Entities — decisioning
Section titled “Entities — decisioning”policy
Section titled “policy”Versioned credit policy.
product_id,partner_id(nullable for own-book),version.effective_from,effective_to.rules_object_uri— full rule set, immutable per version.created_by,approved_by.
decision_run
Section titled “decision_run”Per execution of the engine.
application_id,policy_id.inputs_snapshot_uri,outputs_json,trace_uri.decision(approve / decline / refer / defer),reason_codes[].recommended_sanction_amount,recommended_tenure,recommended_rate,risk_grade.started_at,completed_at.
deviation
Section titled “deviation”Per deviation request.
decision_run_id,reason,requested_by,requested_at.approved_by,approved_at,status.
Entities — sanction and documentation
Section titled “Entities — sanction and documentation”decision_run_id,valid_until.amount,tenure,rate,fees_json.accepted_at,accepted_via.
sanction
Section titled “sanction”application_id,offer_id,sanctioned_at,sanctioned_by.amount,tenure,rate,conditions_json,valid_until.
template
Section titled “template”name,type,language,product_id,partner_id.version,body_uri.
issued_document
Section titled “issued_document”loan_idorsanction_id,template_version_id.generated_at,object_uri.
esign_session
Section titled “esign_session”document_id,signer_promoter_id.vendor,started_at,completed_at.aadhaar_esign_txn_ref,audit_uri.
mandate
Section titled “mandate”loan_idorapplication_id,type(nach / enach / upi_autopay).vendor,npci_ref,status.borrower_account_id,max_debit_amount,frequency,valid_from,valid_to.
Entities — disbursement and LMS (event-sourced)
Section titled “Entities — disbursement and LMS (event-sourced)”disbursement_instruction
Section titled “disbursement_instruction”loan_id(set after first draw),sanction_id.created_at,approved_at,executed_at.amount,to_account_token,to_ifsc,to_account_name.purpose,co_lender_share_json(for co-lent).utr,status.
loan_account
Section titled “loan_account”borrower_id,sanction_id,product_id.activated_at,closed_at.current_outstanding,current_classification,current_dpd_days— derived from events.
loan_event (append-only)
Section titled “loan_event (append-only)”The event-sourced core.
loan_id,event_type(activate / disburse / accrual / repayment / allocation / charge / bounce / classification_change / provision / restructure / writeoff / close).event_at,posted_at.event_payload_json.idempotency_keyUNIQUE.
schedule_line
Section titled “schedule_line”loan_id,due_date,principal_due,interest_due,total_due.paid_principal,paid_interest,paid_at.
repayment
Section titled “repayment”loan_id,received_at,amount.source(nach / enach / upi_autopay / bank_transfer / pg / qr / manual).allocation_json— breakdown per waterfall.reconciled_with— sponsor bank ref.idempotency_key.
charge
Section titled “charge”loan_id,type(processing / servicing / late / bounce / penal / foreclosure / renewal / other).amount,levied_at,gst_invoice_id.
classification_snapshot
Section titled “classification_snapshot”Daily.
loan_id,snapshot_date.class(standard / sma_0 / sma_1 / sma_2 / npa / sub / doubt / loss).dpd_days,principal_overdue,interest_overdue.
provision
Section titled “provision”Daily.
loan_id,snapshot_date,class,provision_amount.
restructuring / writeoff
Section titled “restructuring / writeoff”- Per event with approvals + before/after snapshots.
Entities — collections
Section titled “Entities — collections”collection_case
Section titled “collection_case”loan_id,opened_at,closed_at.current_bucket,assigned_to.
collection_call, field_visit, ptp, settlement_offer, legal_notice
Section titled “collection_call, field_visit, ptp, settlement_offer, legal_notice”Per event; full agent / recording / disposition fields.
- Master of recovery agents with training, ID, status.
Entities — co-lending
Section titled “Entities — co-lending”partner_lender
Section titled “partner_lender”name,master_co_lending_agreement_ref.escrow_account_id,mis_format_config,status.
partner_policy
Section titled “partner_policy”partner_lender_id,version,rules_object_uri.
loan_allocation
Section titled “loan_allocation”loan_id,partner_lender_id.originator_share_pct,partner_share_pct.originator_share_outstanding,partner_share_outstanding.
dlg_agreement
Section titled “dlg_agreement”partner_lender_id,pool_definition.dlg_amount,instrument,instrument_ref.valid_from,valid_to,invocation_rules_json.
settlement
Section titled “settlement”partner_lender_id,period,direction.amount,breakdown_json,executed_at,bank_ref.
Entities — accounting
Section titled “Entities — accounting”gl_account / gl_posting
Section titled “gl_account / gl_posting”gl_account— code, name, type (asset / liability / equity / income / expense).gl_posting— transaction_date, description, source_module, source_ref, entries_json.
gst_invoice
Section titled “gst_invoice”loan_id,charge_id,borrower_id.invoice_no,invoice_date,taxable_value,cgst,sgst,igst,hsn_code.
tds_deduction, settlement, vendor_invoice, dsa_payout
Section titled “tds_deduction, settlement, vendor_invoice, dsa_payout”Per event.
Entities — admin
Section titled “Entities — admin”product / role / permission / user / user_role
Section titled “product / role / permission / user / user_role”- Standard admin master tables.
feature_flag
Section titled “feature_flag”name,enabled,rollout_pct,tenant_scope,metadata_json.
Entities — audit (cross-cutting)
Section titled “Entities — audit (cross-cutting)”audit_event
Section titled “audit_event”Every state change.
actor_user_idoractor_service_id,action,resource_type,resource_id.before_state_json,after_state_json.request_ip,request_user_agent,timestamp.prev_hash,this_hash— hash-chain integrity.
Field-level conventions
Section titled “Field-level conventions”- All amounts:
NUMERIC(18, 2)in rupees (neverFLOAT). - All rates:
NUMERIC(6, 4), e.g.,0.1950for19.50%. - All timestamps:
TIMESTAMPTZ(timezone-aware). - All identifiers:
BIGSERIALprimary key + business-meaningful natural keys where useful (GSTIN, PAN tokens). - All
*_tokencolumns: opaque tokens; clear text in vault. - All
*_uricolumns: full S3 URIs. - All JSON fields: validated via JSON Schema where shape stability matters.
For full DDL, see 5.9 Schema reference.
For a worked example of what these entities actually look like for one borrower, see 5.11 Worked data example.