File size: 2,677 Bytes
bbee61a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from decimal import Decimal
from typing import Any

from pydantic import BaseModel, ConfigDict, Field


class ApplicationDetails(BaseModel):
    leadId: str
    customerName: str | None = None
    mobile: str | None = None
    employmentType: str | None = None
    monthlyIncome: Decimal | None = None
    existingEMI: Decimal | None = None
    foir: Decimal | None = None
    loanAmount: Decimal | None = None
    assetCost: Decimal | None = None
    ltv: Decimal | None = None
    tenure: int | None = None
    dealerId: str | None = None
    state: str | None = None
    city: str | None = None
    pincode: str | None = None
    negativeArea: bool | None = None
    fraudFlag: bool | None = False
    blacklistMatch: bool | None = False
    fakeKyc: bool | None = False
    panMismatch: bool | None = False
    faceMatchScore: Decimal | None = None
    panVerified: bool | None = None
    aadhaarVerified: bool | None = None
    bankingSurrogate: bool | None = None
    coApplicant: bool | None = None


class BureauData(BaseModel):
    cibilScore: int | None = None
    creditVintageMonths: int | None = None
    activeAccounts: int | None = None
    closedAccounts: int | None = None
    overdueAmount: Decimal | None = None
    writtenOffAccounts: int | None = None
    settledAccounts: int | None = None
    suitFiledAccounts: int | None = 0
    active90PlusDpd: bool | None = False
    maxDPD: int | None = None
    dpd30Count: int | None = None
    dpd60Count: int | None = None
    dpd90Count: int | None = None
    creditEnquiries6M: int | None = None
    creditEnquiries12M: int | None = None
    activeUnsecuredLoans: int | None = None
    activeSecuredLoans: int | None = None
    jointAccounts: int | None = None
    creditUtilization: Decimal | None = None
    bureauRisk: str | None = None


class ScorecardRequest(BaseModel):
    application: ApplicationDetails
    bureau: BureauData
    tenantId: str = "default"
    productType: str = "TWO_WHEELER_LOAN"
    forceRecalculate: bool = False


class ScorecardResponse(BaseModel):
    leadId: str
    finalScore: Decimal
    decision: str
    underwritingRequired: bool
    rejectFlag: bool
    journeyAction: str
    bureauRisk: str
    reasonCodes: list[str]
    triggeredRules: list[str]
    scoreBreakup: dict[str, Decimal]

    model_config = ConfigDict(from_attributes=True)


class SimulationResponse(ScorecardResponse):
    persisted: bool = False


class StoredScorecardResponse(ScorecardResponse):
    tenantId: str
    productType: str
    createdAt: str


class HealthResponse(BaseModel):
    status: str
    database: str
    redis: str
    details: dict[str, Any] = Field(default_factory=dict)