Coverage for domain/mismo_readiness.py: 100%
40 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-04 17:24 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-04 17:24 +0000
1"""Pre-export MISMO readiness check — pure, no Django.
3A different bucket list from ``domain/aus.py``'s AUS pre-flight (design.md D3): adds
4subject property, down-payment source, and loan identifiers, which AUS pre-flight never
5inspects. Every finding here is advisory — this module never blocks an export.
6"""
8from __future__ import annotations
10from dataclasses import dataclass, field
13@dataclass
14class MismoBorrowerReadiness:
15 first_name: str
16 last_name: str
17 has_declarations: bool = False
18 has_demographics: bool = False
19 has_current_residence: bool = False
22@dataclass
23class MismoReadinessContext:
24 borrowers: list[MismoBorrowerReadiness] = field(default_factory=list)
25 has_subject_property: bool = False
26 has_down_payment_source: bool = False
27 has_loan_identifier: bool = False
30@dataclass
31class MismoFinding:
32 bucket: str
33 code: str
34 message: str
37@dataclass
38class MismoReadiness:
39 findings: list[MismoFinding]
42def check_mismo_readiness(ctx: MismoReadinessContext) -> MismoReadiness:
43 findings: list[MismoFinding] = []
45 if not ctx.has_subject_property:
46 findings.append(
47 MismoFinding(
48 "subject_property",
49 "MISMO-PROP",
50 "Subject property detail is missing; the COLLATERAL/PROPERTY container "
51 "will be incomplete.",
52 )
53 )
54 if not ctx.has_down_payment_source:
55 findings.append(
56 MismoFinding(
57 "down_payment_source",
58 "MISMO-DOWNPAY",
59 "No down-payment source is recorded; the DOWN_PAYMENT container will be "
60 "empty.",
61 )
62 )
63 if not ctx.has_loan_identifier:
64 findings.append(
65 MismoFinding(
66 "loan_identifiers",
67 "MISMO-ULI",
68 "No Universal Loan Identifier is recorded; LOAN_IDENTIFIERS will be "
69 "incomplete.",
70 )
71 )
73 for b in ctx.borrowers:
74 who = f"{b.first_name} {b.last_name}"
75 if not b.has_declarations:
76 findings.append(
77 MismoFinding(
78 "declarations", "MISMO-DECL", f"Declarations missing for {who}."
79 )
80 )
81 if not b.has_demographics:
82 findings.append(
83 MismoFinding(
84 "demographics", "MISMO-DEMO", f"Demographics missing for {who}."
85 )
86 )
87 if not b.has_current_residence:
88 findings.append(
89 MismoFinding(
90 "residence", "MISMO-RES", f"Current residence missing for {who}."
91 )
92 )
94 return MismoReadiness(findings=findings)