sud-life-insurance/scripts/kyc-match.check.ts
2026-07-03 14:52:45 +05:30

65 lines
3.1 KiB
TypeScript

// Runnable assertions for src/lib/kyc-match.ts (no test runner is configured).
// node scripts/kyc-match.check.ts
// Lives outside src/ so it isn't part of the `tsc -b` app build.
import assert from 'node:assert/strict';
import { crossCheck, dobVerdict, nameVerdict, normName } from '../src/lib/kyc-match.ts';
let n = 0;
const ok = (label: string, cond: boolean) => {
n++;
if (!cond) {
console.error('FAIL:', label);
process.exitCode = 1;
}
};
// normName: order-insensitive, honorific/punct strip
assert.equal(normName('Mr. Ravi Kumar'), 'kumar ravi');
assert.equal(normName('KUMAR, RAVI'), 'kumar ravi');
// name: exact / case / order → match
ok('exact name', nameVerdict('Ravi Kumar', 'ravi kumar').status === 'match');
ok('reordered name', nameVerdict('Ravi Kumar', 'Kumar Ravi').status === 'match');
// initials → match
ok('initial expands', nameVerdict('R Kumar', 'Ravi Kumar').status === 'match');
ok('middle initial', nameVerdict('Ravi K Sharma', 'Ravi Kumar Sharma').status === 'match');
// typo / wrong person → mismatch
ok('typo name', nameVerdict('Rabi Kumar', 'Ravi Kumar').status === 'mismatch');
ok('wrong person', nameVerdict('Ravi Kumar', 'Suresh Patel').status === 'mismatch');
ok('extra surname missing', nameVerdict('Ravi', 'Ravi Kumar').status === 'mismatch');
// empty side → unknown
ok('empty ocr', nameVerdict('Ravi Kumar', '').status === 'unknown');
ok('empty captured', nameVerdict('', 'Ravi Kumar').status === 'unknown');
// DOB: captured IST-midnight instant ("…T18:30Z" → 1990-05-15 IST) vs OCR YYYY-MM-DD
// (literal compare, no tz shift). Normalization is pinned to Asia/Kolkata.
ok('dob match', dobVerdict('1990-05-14T18:30:00.000Z', '1990-05-15') === 'match');
ok('dob mismatch day', dobVerdict('1990-05-14T18:30:00.000Z', '1990-05-16') === 'mismatch');
ok('dob mismatch year', dobVerdict('1990-05-14T18:30:00.000Z', '1991-05-15') === 'mismatch');
// DD/MM/YYYY as a card may print
ok('dob dd/mm/yyyy', dobVerdict('1990-05-14T18:30:00.000Z', '15/05/1990') === 'match');
// null / unparseable → unknown
ok('dob null', dobVerdict('1990-05-14T18:30:00.000Z', null) === 'unknown');
ok('dob garbage', dobVerdict('1990-05-14T18:30:00.000Z', 'unknown') === 'unknown');
// aggregate
const clean = crossCheck(
{ name: 'Ravi Kumar', dob: '1990-05-14T18:30:00.000Z' },
{ pan: { name: 'RAVI KUMAR', dob: '1990-05-15' }, aadhaar: { name: 'Ravi Kumar', dob: '1990-05-15' } },
);
ok('clean: 4 checked', clean.fields.length === 4);
ok('clean: no mismatch', !clean.hasMismatch && clean.anyChecked);
const bad = crossCheck(
{ name: 'Ravi Kumar', dob: '1990-05-14T18:30:00.000Z' },
{ pan: { name: 'Ravi Kumar', dob: '1990-05-15' }, aadhaar: { name: 'Suresh Patel', dob: '1985-01-01' } },
);
ok('bad: hasMismatch', bad.hasMismatch);
ok('bad: 2 aadhaar mismatches', bad.fields.filter((f) => f.status === 'mismatch').length === 2);
// nothing OCR'd yet
const empty = crossCheck({ name: 'Ravi Kumar', dob: '1990-05-14T18:30:00.000Z' }, {});
ok('empty: nothing checked', !empty.anyChecked && !empty.hasMismatch);
if (!process.exitCode) console.log(`kyc-match: all checks passed (${n} cases)`);