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

1"""Pre-export MISMO readiness check — pure, no Django. 

2 

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""" 

7 

8from __future__ import annotations 

9 

10from dataclasses import dataclass, field 

11 

12 

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 

20 

21 

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 

28 

29 

30@dataclass 

31class MismoFinding: 

32 bucket: str 

33 code: str 

34 message: str 

35 

36 

37@dataclass 

38class MismoReadiness: 

39 findings: list[MismoFinding] 

40 

41 

42def check_mismo_readiness(ctx: MismoReadinessContext) -> MismoReadiness: 

43 findings: list[MismoFinding] = [] 

44 

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 ) 

72 

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 ) 

93 

94 return MismoReadiness(findings=findings)