feat: add KYC document renewal alerts, Aadhaar/PAN exceptions, and AML recurring alerts UI; remove old journal AML marking
build-run / Run Lint, Build and Deploy (push) Canceled after 0s
Publish Image in Docker Hub / build (push) Canceled after 0s
Playwright E2E Tests / Run Playwright Tests (push) Canceled after 0s
Tests / testRigor (push) Canceled after 0s

This commit is contained in:
2026-08-11 11:11:18 +05:30
parent 01e86173c1
commit 7b895a0e2b
77 changed files with 10046 additions and 1130 deletions
+25 -2
View File
@@ -29,8 +29,28 @@ export const AUTO_MANAGED_KYC_EXCEPTION_REASONS: string[] = [
export interface KycExceptionInput {
/** PAN verified against the Income Tax database. Unverified OR simply not entered → exception. */
panVerified: boolean;
/**
* A signed customer declaration has been accepted in place of a passing PAN check.
*
* The Income Tax check matches on name *and* date of birth, so a client whose PAN card carries a
* different spelling — or a different DOB — can never clear it, however many times the officer
* retries. Once the branch holds a declaration recording exactly what differs, the outstanding
* item is closed by paperwork rather than by the API, and it must not keep the client sitting in
* the exception list. PAN still reads as unverified everywhere else; only the exception is waived.
*/
panDeclarationTaken?: boolean;
/** Aadhaar verified against UIDAI. Unverified OR simply not entered → exception. */
aadhaarVerified: boolean;
/**
* The customer's Aadhaar enrolment slip has been sighted and recorded.
*
* A customer who has applied for Aadhaar but has not been issued one yet holds only a UIDAI
* enrolment receipt. There is no Aadhaar number to put through the OTP flow, so the check cannot
* pass however long the branch waits — the same dead end the PAN declaration exists to resolve.
* Once the receipt is on file the outstanding item is closed by paperwork, and the client must
* not keep sitting in the exception list. Aadhaar still reads as unverified everywhere else.
*/
aadhaarReceiptTaken?: boolean;
/**
* False for non-individual clients, where no Aadhaar is collected (the payload sends a dummy
* masked value). Without this guard every company would carry a permanent Aadhaar exception.
@@ -69,10 +89,13 @@ export interface KycExceptionFields {
export function deriveKycExceptionFields(input: KycExceptionInput): KycExceptionFields {
const outstanding: string[] = [];
if (!input.panVerified) {
// A declaration settles the PAN item without the API ever passing — see `panDeclarationTaken`.
if (!input.panVerified && !input.panDeclarationTaken) {
outstanding.push(KYC_EXCEPTION_PAN);
}
if (input.aadhaarApplicable && !input.aadhaarVerified) {
// An enrolment receipt settles the Aadhaar item when the OTP check has nothing to run against —
// see `aadhaarReceiptTaken`.
if (input.aadhaarApplicable && !input.aadhaarVerified && !input.aadhaarReceiptTaken) {
outstanding.push(KYC_EXCEPTION_AADHAAR);
}