-- Closes KYC exceptions left open by verifications that actually passed. -- -- The KYC tab wrote the exception columns *before* calling the vendor, when the check was by -- definition still outstanding, and nothing rewrote them once the check passed. So a client could -- end up with pan_verified / aadhaar_verified set while is_exception stayed true — the KYC tab -- read the verified flags and showed "Verified", the exceptions register read is_exception and -- kept the client in its Pending tab. -- -- The frontend no longer leaves records in that state (it re-derives the exception columns on each -- verification success), but rows written before that fix still carry it. This closes exactly -- those, using the same rule the application derives: an exception whose every outstanding item -- has since been settled is resolved. -- -- Settled means verified by the vendor, or closed by paperwork — a signed PAN declaration or a -- UIDAI enrolment receipt — which is what the application counts too. Aadhaar is not applicable to -- non-individual clients (legal_form_enum = 2), which is why it is excluded rather than treated as -- an outstanding item that can never pass. -- -- exception_reason is deliberately left as-is: the Resolved tab shows what was resolved, so -- clearing it would erase the record of why the exception was ever raised. -- -- Safe to re-run — the WHERE clause matches nothing once the rows are closed. -- -- Review first, then run: -- SELECT ... (the SELECT below) to see what will change -- then the UPDATE. -- ── Review: the rows this will close ───────────────────────────────────────── SELECT k.id AS kyc_id, c.id AS client_id, c.display_name, k.exception_reason, k.pan_verified, k.aadhaar_verified, k.pan_declaration_taken, k.aadhaar_receipt_taken, c.legal_form_enum FROM m_client_kyc k JOIN m_client c ON c.id = k.client_id WHERE k.is_exception = TRUE AND k.exception_resolved = FALSE -- Only the two reasons the application manages automatically. A record also carrying an -- officer-entered reason is left alone: only a human knows whether that item is settled. AND k.exception_reason IS NOT NULL AND TRIM(k.exception_reason) IN ( 'PAN Card Verification Failed', 'Aadhaar Verification Failed', 'PAN Card Verification Failed, Aadhaar Verification Failed', 'Aadhaar Verification Failed, PAN Card Verification Failed' ) -- PAN settled: verified, or closed by a signed declaration. AND (k.pan_verified = TRUE OR COALESCE(k.pan_declaration_taken, FALSE) = TRUE) -- Aadhaar settled: verified, closed by an enrolment receipt, or not applicable. AND (k.aadhaar_verified = TRUE OR COALESCE(k.aadhaar_receipt_taken, FALSE) = TRUE OR c.legal_form_enum = 2); -- ── Fix ────────────────────────────────────────────────────────────────────── UPDATE m_client_kyc k SET is_exception = FALSE, exception_resolved = TRUE, exception_resolved_on = CURRENT_DATE FROM m_client c WHERE c.id = k.client_id AND k.is_exception = TRUE AND k.exception_resolved = FALSE AND k.exception_reason IS NOT NULL AND TRIM(k.exception_reason) IN ( 'PAN Card Verification Failed', 'Aadhaar Verification Failed', 'PAN Card Verification Failed, Aadhaar Verification Failed', 'Aadhaar Verification Failed, PAN Card Verification Failed' ) AND (k.pan_verified = TRUE OR COALESCE(k.pan_declaration_taken, FALSE) = TRUE) AND (k.aadhaar_verified = TRUE OR COALESCE(k.aadhaar_receipt_taken, FALSE) = TRUE OR c.legal_form_enum = 2);