compctl 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # compctl
2
+
3
+ Lending compliance checks for TRID, ATR/QM, HMDA, and ECOA. Part of the **LendCtl Suite**.
4
+
5
+ ## Features
6
+
7
+ - **TRID Timing** — LE/CD disclosure deadline tracking
8
+ - **ATR/QM Check** — Qualified mortgage determination
9
+ - **Adverse Action** — ECOA-compliant denial notices
10
+ - **Risk Flags** — Identify compliance issues early
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install -g compctl
16
+ ```
17
+
18
+ ## Quick Start
19
+
20
+ ### Check TRID Timing
21
+
22
+ ```bash
23
+ compctl trid --app-date 2026-02-20 --closing-date 2026-03-15
24
+ ```
25
+
26
+ ### Check ATR/QM Compliance
27
+
28
+ ```bash
29
+ compctl atr --loan-amount 300000 --dti 42 --points-fees 5000
30
+ ```
31
+
32
+ ### Generate Adverse Action Notice
33
+
34
+ ```bash
35
+ # List standard reasons
36
+ compctl adverse --list-reasons
37
+
38
+ # Generate notice
39
+ compctl adverse --applicant "John Smith" --reasons "1,2,5"
40
+ ```
41
+
42
+ ## Commands
43
+
44
+ ### `compctl trid`
45
+ Check TRID timing compliance.
46
+
47
+ Options:
48
+ - `--app-date <date>` - Application date (required)
49
+ - `--le-date <date>` - Loan Estimate disclosure date
50
+ - `--cd-date <date>` - Closing Disclosure date
51
+ - `--closing-date <date>` - Scheduled closing date
52
+
53
+ ### `compctl atr`
54
+ Check ATR/QM compliance.
55
+
56
+ Options:
57
+ - `--loan-amount <amount>` - Loan amount
58
+ - `--dti <percent>` - Debt-to-income ratio
59
+ - `--points-fees <amount>` - Points and fees
60
+ - `--neg-am` - Has negative amortization
61
+ - `--interest-only` - Has interest-only period
62
+ - `--balloon` - Has balloon payment
63
+
64
+ ### `compctl adverse`
65
+ Generate adverse action notice.
66
+
67
+ Options:
68
+ - `--applicant <name>` - Applicant name
69
+ - `--reasons <codes>` - Reason codes (1-16) or text
70
+ - `--list-reasons` - Show standard reasons
71
+
72
+ ## Compliance Regulations
73
+
74
+ ### TRID (TILA-RESPA Integrated Disclosure)
75
+ - Loan Estimate within 3 business days of application
76
+ - Closing Disclosure 3 business days before closing
77
+
78
+ ### ATR/QM (Ability to Repay / Qualified Mortgage)
79
+ - No risky features (neg-am, interest-only, balloon)
80
+ - Points and fees under 3% (for loans ≥$100k)
81
+ - DTI ≤43% for safe harbor
82
+
83
+ ### ECOA (Equal Credit Opportunity Act)
84
+ - Specific reasons required for adverse action
85
+ - Maximum 4 primary factors
86
+ - Standard notices required
87
+
88
+ ## License
89
+
90
+ MIT © Avatar Consulting
@@ -0,0 +1,6 @@
1
+ /**
2
+ * compctl adverse command - Generate adverse action notice
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare function createAdverseCommand(): Command;
6
+ //# sourceMappingURL=adverse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adverse.d.ts","sourceRoot":"","sources":["../../src/commands/adverse.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,oBAAoB,IAAI,OAAO,CAkF9C"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ /**
3
+ * compctl adverse command - Generate adverse action notice
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createAdverseCommand = createAdverseCommand;
7
+ const commander_1 = require("commander");
8
+ const checks_1 = require("../lib/checks");
9
+ function createAdverseCommand() {
10
+ const adverse = new commander_1.Command('adverse')
11
+ .description('Generate ECOA-compliant adverse action notice')
12
+ .option('--applicant <name>', 'Applicant name', 'Applicant')
13
+ .option('--app-date <date>', 'Application date', new Date().toISOString().split('T')[0])
14
+ .option('--creditor <name>', 'Creditor name', 'Lender')
15
+ .option('--creditor-address <addr>', 'Creditor address', '123 Main St')
16
+ .option('--reasons <codes>', 'Comma-separated reason codes (1-16) or text')
17
+ .option('--list-reasons', 'List standard adverse action reasons', false)
18
+ .option('--format <type>', 'Output format (json|text)', 'text')
19
+ .action(async (options) => {
20
+ if (options.listReasons) {
21
+ console.log('═══════════════════════════════════════════════════════════════');
22
+ console.log('STANDARD ADVERSE ACTION REASONS');
23
+ console.log('═══════════════════════════════════════════════════════════════');
24
+ checks_1.ADVERSE_ACTION_REASONS.forEach((reason, i) => {
25
+ console.log(`${(i + 1).toString().padStart(2)}. ${reason}`);
26
+ });
27
+ console.log('═══════════════════════════════════════════════════════════════');
28
+ return;
29
+ }
30
+ let reasons = [];
31
+ if (options.reasons) {
32
+ const parts = options.reasons.split(',');
33
+ for (const part of parts) {
34
+ const trimmed = part.trim();
35
+ const num = parseInt(trimmed);
36
+ if (!isNaN(num) && num >= 1 && num <= checks_1.ADVERSE_ACTION_REASONS.length) {
37
+ reasons.push(checks_1.ADVERSE_ACTION_REASONS[num - 1]);
38
+ }
39
+ else {
40
+ reasons.push(trimmed);
41
+ }
42
+ }
43
+ }
44
+ const notice = (0, checks_1.generateAdverseAction)(options.applicant, options.appDate, options.creditor, options.creditorAddress, reasons);
45
+ if (options.format === 'json') {
46
+ console.log(JSON.stringify(notice, null, 2));
47
+ }
48
+ else {
49
+ console.log('═══════════════════════════════════════════════════════════════');
50
+ console.log('NOTICE OF ADVERSE ACTION');
51
+ console.log('═══════════════════════════════════════════════════════════════');
52
+ console.log('');
53
+ console.log(`Date: ${notice.decisionDate}`);
54
+ console.log(`To: ${notice.applicantName}`);
55
+ console.log('');
56
+ console.log(`Your application for credit dated ${notice.applicationDate} has been`);
57
+ console.log('denied based on the following reason(s):');
58
+ console.log('');
59
+ if (notice.reasons.length > 0) {
60
+ for (const reason of notice.reasons) {
61
+ console.log(` • ${reason}`);
62
+ }
63
+ }
64
+ else {
65
+ console.log(' [No specific reasons provided - COMPLIANCE WARNING]');
66
+ }
67
+ console.log('');
68
+ console.log('───────────────────────────────────────────────────────────────');
69
+ console.log('EQUAL CREDIT OPPORTUNITY ACT NOTICE');
70
+ console.log('───────────────────────────────────────────────────────────────');
71
+ console.log(notice.ecoaNotice);
72
+ console.log('');
73
+ console.log('───────────────────────────────────────────────────────────────');
74
+ console.log('FAIR CREDIT REPORTING ACT NOTICE');
75
+ console.log('───────────────────────────────────────────────────────────────');
76
+ console.log(notice.fcraNotice);
77
+ console.log('');
78
+ console.log(`${notice.creditorName}`);
79
+ console.log(`${notice.creditorAddress}`);
80
+ console.log('═══════════════════════════════════════════════════════════════');
81
+ }
82
+ });
83
+ return adverse;
84
+ }
85
+ //# sourceMappingURL=adverse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adverse.js","sourceRoot":"","sources":["../../src/commands/adverse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * compctl atr command - Check ATR/QM compliance
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare function createAtrCommand(): Command;
6
+ //# sourceMappingURL=atr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atr.d.ts","sourceRoot":"","sources":["../../src/commands/atr.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,gBAAgB,IAAI,OAAO,CA0F1C"}
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ /**
3
+ * compctl atr command - Check ATR/QM compliance
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.createAtrCommand = createAtrCommand;
40
+ const commander_1 = require("commander");
41
+ const fs = __importStar(require("fs"));
42
+ const checks_1 = require("../lib/checks");
43
+ function createAtrCommand() {
44
+ const atr = new commander_1.Command('atr')
45
+ .description('Check ATR/QM compliance')
46
+ .option('-f, --file <path>', 'Loan data JSON file')
47
+ .option('--loan-amount <amount>', 'Loan amount')
48
+ .option('--dti <percent>', 'Debt-to-income ratio')
49
+ .option('--points-fees <amount>', 'Total points and fees')
50
+ .option('--neg-am', 'Has negative amortization', false)
51
+ .option('--interest-only', 'Has interest-only period', false)
52
+ .option('--balloon', 'Has balloon payment', false)
53
+ .option('--prepay-penalty', 'Has prepayment penalty', false)
54
+ .option('--term <months>', 'Loan term in months', '360')
55
+ .option('--format <type>', 'Output format (json|table)', 'table')
56
+ .action(async (options) => {
57
+ let loan;
58
+ if (options.file) {
59
+ const content = fs.readFileSync(options.file, 'utf-8');
60
+ loan = JSON.parse(content);
61
+ }
62
+ else {
63
+ loan = {
64
+ loanId: 'CLI-INPUT',
65
+ applicationDate: new Date().toISOString().split('T')[0],
66
+ loanAmount: parseFloat(options.loanAmount || '300000'),
67
+ propertyValue: parseFloat(options.loanAmount || '300000') * 1.25,
68
+ interestRate: 6.5,
69
+ termMonths: parseInt(options.term),
70
+ monthlyPayment: 0,
71
+ dti: parseFloat(options.dti || '35'),
72
+ ltv: 80,
73
+ creditScore: 720,
74
+ pointsAndFees: parseFloat(options.pointsFees || '0'),
75
+ negativeAmortization: options.negAm,
76
+ interestOnly: options.interestOnly,
77
+ balloonPayment: options.balloon,
78
+ prepaymentPenalty: options.prepayPenalty,
79
+ borrowerIncome: 100000,
80
+ propertyType: 'single-family',
81
+ occupancy: 'primary',
82
+ loanPurpose: 'purchase',
83
+ loanType: 'conventional',
84
+ };
85
+ }
86
+ const result = (0, checks_1.checkAtrQm)(loan);
87
+ if (options.format === 'json') {
88
+ console.log(JSON.stringify(result, null, 2));
89
+ }
90
+ else {
91
+ console.log('═══════════════════════════════════════════════════════════════');
92
+ console.log('ATR/QM COMPLIANCE CHECK');
93
+ console.log('═══════════════════════════════════════════════════════════════');
94
+ console.log('');
95
+ const qmStatus = result.isQm ? '✓ QUALIFIED MORTGAGE' : '✗ NON-QM';
96
+ console.log(`QM Status: ${qmStatus}`);
97
+ if (result.qmType) {
98
+ console.log(`QM Type: ${result.qmType.toUpperCase()}`);
99
+ }
100
+ console.log('');
101
+ console.log('KEY METRICS');
102
+ console.log('───────────────────────────────────────────────────────────────');
103
+ const dtiStatus = result.dti <= result.dtiLimit ? '✓' : '⚠';
104
+ console.log(`${dtiStatus} DTI: ${result.dti}% (limit: ${result.dtiLimit}%)`);
105
+ const pfStatus = result.pointsAndFees <= result.pointsAndFeesLimit ? '✓' : '✗';
106
+ console.log(`${pfStatus} Points & Fees: $${result.pointsAndFees.toLocaleString()} (limit: $${result.pointsAndFeesLimit.toLocaleString()})`);
107
+ if (result.riskyFeatures.length > 0) {
108
+ console.log('');
109
+ console.log('RISKY FEATURES');
110
+ console.log('───────────────────────────────────────────────────────────────');
111
+ for (const feature of result.riskyFeatures) {
112
+ console.log(` ✗ ${feature}`);
113
+ }
114
+ }
115
+ if (result.findings.length > 0) {
116
+ console.log('');
117
+ console.log('FINDINGS');
118
+ console.log('───────────────────────────────────────────────────────────────');
119
+ for (const f of result.findings) {
120
+ const icon = f.severity === 'critical' ? '🚨' : f.severity === 'major' ? '⚠' : 'ℹ';
121
+ console.log(`${icon} [${f.code}] ${f.description}`);
122
+ if (f.remediation)
123
+ console.log(` → ${f.remediation}`);
124
+ }
125
+ }
126
+ console.log('═══════════════════════════════════════════════════════════════');
127
+ }
128
+ });
129
+ return atr;
130
+ }
131
+ //# sourceMappingURL=atr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atr.js","sourceRoot":"","sources":["../../src/commands/atr.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * compctl trid command - Check TRID timing compliance
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare function createTridCommand(): Command;
6
+ //# sourceMappingURL=trid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trid.d.ts","sourceRoot":"","sources":["../../src/commands/trid.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,iBAAiB,IAAI,OAAO,CAwD3C"}
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ /**
3
+ * compctl trid command - Check TRID timing compliance
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createTridCommand = createTridCommand;
7
+ const commander_1 = require("commander");
8
+ const checks_1 = require("../lib/checks");
9
+ function createTridCommand() {
10
+ const trid = new commander_1.Command('trid')
11
+ .description('Check TRID timing compliance')
12
+ .requiredOption('--app-date <date>', 'Application date (YYYY-MM-DD)')
13
+ .option('--le-date <date>', 'Loan Estimate disclosure date')
14
+ .option('--cd-date <date>', 'Closing Disclosure date')
15
+ .option('--closing-date <date>', 'Scheduled closing date')
16
+ .option('--format <type>', 'Output format (json|table)', 'table')
17
+ .action(async (options) => {
18
+ const result = (0, checks_1.checkTridTiming)({
19
+ applicationDate: options.appDate,
20
+ leDisclosureDate: options.leDate,
21
+ cdDisclosureDate: options.cdDate,
22
+ closingDate: options.closingDate,
23
+ });
24
+ if (options.format === 'json') {
25
+ console.log(JSON.stringify(result, null, 2));
26
+ }
27
+ else {
28
+ console.log('═══════════════════════════════════════════════════════════════');
29
+ console.log('TRID TIMING COMPLIANCE');
30
+ console.log('═══════════════════════════════════════════════════════════════');
31
+ console.log('');
32
+ console.log(`Application Date: ${result.applicationDate}`);
33
+ if (result.leDisclosureDate)
34
+ console.log(`LE Disclosure: ${result.leDisclosureDate}`);
35
+ if (result.cdDisclosureDate)
36
+ console.log(`CD Disclosure: ${result.cdDisclosureDate}`);
37
+ if (result.closingDate)
38
+ console.log(`Closing Date: ${result.closingDate}`);
39
+ console.log('');
40
+ console.log('STATUS');
41
+ console.log('───────────────────────────────────────────────────────────────');
42
+ const leStatus = result.leCompliant ? '✓ COMPLIANT' : '✗ NON-COMPLIANT';
43
+ const cdStatus = result.cdCompliant ? '✓ COMPLIANT' : '✗ NON-COMPLIANT';
44
+ console.log(`Loan Estimate: ${leStatus}`);
45
+ if (result.daysUntilLeDeadline) {
46
+ console.log(` Days until deadline: ${result.daysUntilLeDeadline}`);
47
+ }
48
+ console.log(`Closing Disclosure: ${cdStatus}`);
49
+ if (result.daysUntilCdDeadline) {
50
+ console.log(` Days until deadline: ${result.daysUntilCdDeadline}`);
51
+ }
52
+ if (result.findings.length > 0) {
53
+ console.log('');
54
+ console.log('FINDINGS');
55
+ console.log('───────────────────────────────────────────────────────────────');
56
+ for (const f of result.findings) {
57
+ const icon = f.severity === 'critical' ? '🚨' : f.severity === 'major' ? '⚠' : 'ℹ';
58
+ console.log(`${icon} [${f.code}] ${f.description}`);
59
+ if (f.remediation)
60
+ console.log(` → ${f.remediation}`);
61
+ }
62
+ }
63
+ console.log('═══════════════════════════════════════════════════════════════');
64
+ }
65
+ });
66
+ return trid;
67
+ }
68
+ //# sourceMappingURL=trid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trid.js","sourceRoot":"","sources":["../../src/commands/trid.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * compctl - Lending compliance checks
4
+ * Part of the LendCtl Suite
5
+ */
6
+ export * from './lib/checks';
7
+ export * from './types';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAoBH,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * compctl - Lending compliance checks
5
+ * Part of the LendCtl Suite
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
19
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ const commander_1 = require("commander");
23
+ const trid_1 = require("./commands/trid");
24
+ const atr_1 = require("./commands/atr");
25
+ const adverse_1 = require("./commands/adverse");
26
+ const program = new commander_1.Command();
27
+ program
28
+ .name('compctl')
29
+ .description('Lending compliance checks (TRID, ATR/QM, HMDA, ECOA) - part of the LendCtl Suite')
30
+ .version('0.1.0');
31
+ program.addCommand((0, trid_1.createTridCommand)());
32
+ program.addCommand((0, atr_1.createAtrCommand)());
33
+ program.addCommand((0, adverse_1.createAdverseCommand)());
34
+ program.parse();
35
+ __exportStar(require("./lib/checks"), exports);
36
+ __exportStar(require("./types"), exports);
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAEA;;;GAGG;;;;;;;;;;;;;;;;AAEH,yCAAoC;AACpC,0CAAoD;AACpD,wCAAkD;AAClD,gDAA0D;AAE1D,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,kFAAkF,CAAC;KAC/F,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,IAAA,wBAAiB,GAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,IAAA,sBAAgB,GAAE,CAAC,CAAC;AACvC,OAAO,CAAC,UAAU,CAAC,IAAA,8BAAoB,GAAE,CAAC,CAAC;AAE3C,OAAO,CAAC,KAAK,EAAE,CAAC;AAEhB,+CAA6B;AAC7B,0CAAwB"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Compliance check implementations
3
+ */
4
+ import { LoanData, TridTiming, AtrQmResult, ComplianceCheck, AdverseActionNotice } from '../types';
5
+ /**
6
+ * Check TRID timing requirements
7
+ */
8
+ export declare function checkTridTiming(data: {
9
+ applicationDate: string;
10
+ leDisclosureDate?: string;
11
+ cdDisclosureDate?: string;
12
+ closingDate?: string;
13
+ }): TridTiming;
14
+ /**
15
+ * Check ATR/QM requirements
16
+ */
17
+ export declare function checkAtrQm(loan: LoanData): AtrQmResult;
18
+ /**
19
+ * Check ECOA compliance and generate adverse action notice
20
+ */
21
+ export declare function checkEcoa(loan: LoanData, decision: 'approved' | 'denied' | 'countered', reasons?: string[]): ComplianceCheck;
22
+ /**
23
+ * Generate ECOA-compliant adverse action notice
24
+ */
25
+ export declare function generateAdverseAction(applicantName: string, applicationDate: string, creditorName: string, creditorAddress: string, reasons: string[]): AdverseActionNotice;
26
+ /**
27
+ * Standard adverse action reasons
28
+ */
29
+ export declare const ADVERSE_ACTION_REASONS: string[];
30
+ //# sourceMappingURL=checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../src/lib/checks.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAW,eAAe,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE5G;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,UAAU,CAyEb;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,WAAW,CA4EtD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,GAAG,QAAQ,GAAG,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,eAAe,CAwB5H;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EAAE,GAChB,mBAAmB,CAWrB;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB,UAiBlC,CAAC"}