Generated: 2026-04-01 | Old: PanRepository.cs, NRIPanRepository.cs, IDFCPANRepository.cs, PanAPI.cs, OCRRepository.cs + SPs | New: PanVerificationService.cs, AadhaarVerificationService.cs, ExternalProviders/*
Stage 4 (PAN): Core flow (format validation, Hyperverge fetch, NSDL/UTI verify, staff PAN check, dedupe, age check, KRA prefill, name match) is PRESENT in new code. Key gaps: SEBI/CSAFE debarred check, Aadhaar seeding status check, PAN-with-OCR cross-check, BA/IFA/PMS allow whitelist auto-insert, old-vs-new PAN comparison, PAN sign present check, NRI PAN flow, IDFC partner flow, LeadSquared dormant update on staff PAN.
Stage 5 (Aadhaar): DigiLocker initiate/callback/download via AiNXT, address extraction, address translation, name matching, photo extraction, Aadhaar upload fallback all PRESENT. Key gaps: PAN-Aadhaar cross-validation (PAN number match from DigiLocker), Aadhaar bypass for MOSL employees, Aadhaar mismatch XML handling SP, Aadhaar response logging SP, NRI Aadhaar flow, address-exists re-check SP, HyperKYC alternative flow.
| # | Old Function / Logic | Old File | New Equivalent | Status | Gap Details |
|---|---|---|---|---|---|
| 1 | PAN format validation (10 chars, regex ^[\w]{3}[pP][\w][\d]{4}[\w]$) | PanRepository.cs:358-378 | PanVerificationService.ConfirmPan → IsValidPanFormat() + IsIndividualPan() | PRESENT | New uses extension methods. 4th char=P check present via IsIndividualPan(). |
| 2 | HyperVerge PAN detail fetch (name, DOB, F/M/L name split) | PanAPI.cs:311-397 | HypervergePanProvider.FetchPanDetailsAsync | PRESENT | Full provider with auth token caching, audit logging. Returns FullName, FirstName, MiddleName, LastName, DOB. |
| 3 | NSDL PAN verification (PKCS7 signed, pan_status E, name/DOB Y/N) | PanAPI.cs:399-500 | NsdlPanProvider.ValidatePanAsync | PRESENT | PKCS7 signing via Pkcs7SigningService. Returns PanStatus, NameMatchResult, DobMatchResult, AadhaarSeedingStatus. |
| 4 | UTI PAN verification (SOAP fallback when NSDL fails) | PanAPI.cs:450-500 | UtiPanProvider.ValidatePanAsync | PRESENT | SOAP envelope builder, pipe-delimited response parser. Used as fallback in ValidatePanWithNsdlUtiAsync. |
| 5 | NSDL/UTI failover logic (try NSDL first, fallback UTI, or vice versa based on GET_PAN_SERVICE_NAME) | PanRepository.cs:756-800 + PanAPI.cs:399-492 | PanVerificationService.ValidatePanWithNsdlUtiAsync | PARTIAL | New always tries NSDL first, then UTI. Old code used GET_PAN_SERVICE_NAME SP to decide order. Gap: No configurable service-order toggle. |
| 6 | Staff PAN check (CHECK_STAFF_PAN SP + MOSL_SDLC_EMPLOYEEDETAILS table) | CHECK_STAFF_PAN.sql | PanVerificationService → EmployeePanMaster query | PRESENT | Same logic: check PAN_NO in employee table, exclude Resigned, handle retain/reject combos. Returns STAFF_PAN error code. |
| 7 | Staff PAN → LeadSquared dormant update + SuperApp stage details | PanRepository.cs:493-575 | N/A | MISSING | Old code calls _leadsquare.Dormant_LSQ_Opportunity, _superAppRepository.StageDetails, _superApp_Api for staff PANs. New code returns STAFF_PAN error but does not push dormant status to downstream CRM. May be handled by event publisher if wired. |
| 8 | BA/IFA/PMS/MOCBPL PAN allow (USP_BA_IFA_PMS_MOCBPL_PAN_ALLOW_SJET) | USP_BA_IFA_PMS_MOCBPL_PAN_ALLOW.sql | PanVerificationService → FranchisePanWhitelist query | PARTIAL | New code reads FranchisePanWhitelist table but does NOT auto-insert into whitelist when PAN matches BA/IFA/FRN/REM/DGP/ONW categories from MOSL_FEED tables. Old SP auto-whitelists on first encounter. |
| 9 | PAN dedupe (CHECK_PAN_AADHAAR_EXISTS_EXP with bypass flag) | PanRepository.cs:463-481 | PanVerificationService → ClientMaster dedupe + PanVerifications post-eSign check | PARTIAL | New checks ClientMaster (active clients) + PanVerifications (post-eSign leads). Gap: Old bypass mechanism (USP_BYPASS_MOBILE_EMAIL_PAN) for inactive/PMS/IFA accounts not replicated. |
| 10 | PAN bypass for existing customers (USP_BYPASS_MOBILE_EMAIL_PAN_SJET) | USP_BYPASS_MOBILE_EMAIL_PAN.sql | N/A | MISSING | Complex SP checking MOBILE/EMAIL/PAN across MOSL_FEED_CLIENT_DETAILS for inactive, PMS, IFA scenarios. Sets ISBYPASS flag. Not replicated in new code. |
| 11 | SEBI debarred check (CSAFE API - Get_CSAFE_API_Pan_Validation) | PanRepository.cs:716-735 | CsafeProvider exists at ExternalProviders/FraudDetection but NOT called from PanVerificationService | MISSING | Critical: CsafeProvider.cs exists but is not invoked during PAN validation. Old code blocks PAN if SEBI debarred. Must be wired into ConfirmPanAsync. |
| 12 | CSAFE name match check (after PAN name retrieved) | PanRepository.cs:1067-1078 | N/A | MISSING | Old code runs CSAFE name-based debarred check after obtaining PAN name. Not present in new flow. |
| 13 | Aadhaar seeding status check (USP_CHECK_AADHAARSEED_STATUS_SJET) | USP_CHECK_AADHAARSEED_STATUS.sql + PanRepository.cs:1081-1150 | N/A | MISSING | Old code checks if PAN is linked to Aadhaar (NSDL seeding_status=Y or UTI "PAN is Operative"). Shows seed popup/link if not seeded. New code captures AadhaarSeedingStatus from providers but does not act on it. |
| 14 | PAN-with-OCR cross-check (USP_CHECKPANWITHOCR_SJET) | USP_CHECKPANWITHOCR.sql + PanRepository.cs:398-448 | N/A | N/A | Old code checked if uploaded PAN document OCR matches entered PAN number. New flow does not use PAN card OCR upload at Stage 4 (OCR is deferred). May be intentionally removed. |
| 15 | Old PAN vs New PAN check (USP_CHECK_OLD_NEW_PAN_SJET / IsNewPan) | PanRepository.cs:396 | N/A | MISSING | Old code calls IsNewPan() to determine if PAN changed from a previous attempt. If new PAN, deletes bank/aadhaar/cheque proofs. New code upserts PanVerification but does not cascade-delete related stage data on PAN change. |
| 16 | Name matching (AINXT API for PAN name vs Registration/Bank name) | PanRepository.cs:840-940 | NameMatchService.CalculateScore (Levenshtein) | PARTIAL | Old code calls AiNXT name-match API (getNamematchResponse_AINXT) with percentage score and SP-based threshold. New uses local Levenshtein. Comment says "Will be replaced by Claude API / AiNXT provider later." |
| 17 | DOB extraction + age validation (18-100) | PanRepository.cs (implicit via HV DOB) | PanVerificationService.ConfirmPan → panDob.CalculateAge() | PRESENT | Age 18-100 check present. Minor routing to MINOR_GUARDIAN_REQUIRED. Age>100 drops. |
| 18 | KRA status from background check (prefill PAN stage) | PanRepository.cs (CVL KRA check in ValidatePanDob_CVL) | PanVerificationService → reads KraRecords, DetermineJourneyPath | PRESENT | KRA_VALIDATED/KRA_MOD/NON_KRA/API_DOWN/RESTRICTED/INVALID_PAN all handled. Journey path set to DIGILOCKER_SKIP or DIGILOCKER_REQUIRED. |
| 19 | Employee/Franchise contact restriction (mobile/email belongs to employee but PAN is not staff) | (implicit in old bypass logic) | PanVerificationService → Employee/Franchise contact restriction block | PRESENT | New code explicitly checks if lead's mobile belongs to employee/franchise when PAN is not staff PAN. Drops with DROP_EMPLOYEE_CONTACT_USED. |
| 20 | NRI PAN flow (separate repository, country/citizenship, passport proofs) | NRIPanRepository.cs | N/A | MISSING | Entire NRI PAN flow missing: GETNRIPANDETAILS, INSERT_UPDATE_PANDETAILS_NRI, ValidatePanDob_CVL_NRI, NRI address details, country/citizenship master, passport proof upload. New code has no NRI-specific PAN logic. |
| 21 | IDFC partner PAN flow (encrypted request/response, CHECKPANELIGIBILITY, signature validation) | IDFCPANRepository.cs | N/A | N/A | IDFC partner flow is a separate CRM integration (encrypted API for bank partner). Likely out of scope for DIY eKYC rewrite. Confirm with product team. |
| 22 | PAN sign present check (USP_CHECK_PANSIGNPRESENT_SJET) | USP_CHECK_PANSIGNPRESENT.sql | N/A | MISSING | Old SP checks if PAN card signature has been uploaded. New code does not track PAN signature separately. |
| 23 | PAN verification request limit (INSERT_PAN_VERF_REQLIMIT_LOG) | PanRepository.cs:982-993 | PanVerificationService → _maxPanAttempts + PanAttemptsUsed | PRESENT | New uses configurable MaxPanAttempts (default 3). Drops lead when exceeded. |
| 24 | CS Journey hold when NSDL+UTI both fail | (not in old code - new addition) | PanVerificationService → _csJourney.CreateHoldAsync("CS_NSDL_DOWN") | PRESENT | New code creates CS Journey hold when both providers fail. This is an improvement over old code which just returned "IT PAN Site is down". |
| 25 | Zintlr phone-to-PAN prefetch | PanRepository.cs:1235-1260 | ZintlrPhoneToPanProvider.cs exists in ExternalProviders | PRESENT | Provider exists. Used in Stage 2 background check for PAN prefetch. |
| 26 | PAN name split into F/M/L (SPLITFULLNAME SP) | PanRepository.cs:953-957 | N/A (Hyperverge returns split names directly) | PARTIAL | Old code used SPLITFULLNAME SP. New code relies on Hyperverge returning FirstName/MiddleName/LastName. If Hyperverge returns only FullName, no fallback splitter exists. |
| # | Old Function / Logic | Old File | New Equivalent | Status | Gap Details |
|---|---|---|---|---|---|
| 1 | DigiLocker initiate (AiNXT link generation) | OCRRepository.cs (DigiLocker flow) | AadhaarVerificationService.InitiateDigilockerAsync + AinxtDigilockerProvider.GenerateLinkAsync | PRESENT | Full implementation: consent record, AiNXT link generation with fallback to direct DigiLocker URL, max attempts check. |
| 2 | DigiLocker callback handling | OCRRepository.cs | AadhaarVerificationService.ProcessDigilockerCallbackAsync | PRESENT | Processes callback, fetches documents via AiNXT, extracts data from parsed JSON/XML, fallback extraction from raw callback data. |
| 3 | DigiLocker document fetch (PAN + Aadhaar) | OCRRepository.cs | AinxtDigilockerProvider.GetDocumentsAsync + DownloadDocumentAsync | PRESENT | Documents endpoint + download endpoint with PDF/parsed/XML options. Audit logged. |
| 4 | PAN-Aadhaar cross-validation (USP_CHECKPANNO_DIGILOCKER_SJET - PAN from DigiLocker matches entered PAN) | USP_CHECKPANNO_DIGILOCKER.sql | N/A | MISSING | Old SP compares PAN fetched from DigiLocker with PAN entered at Stage 4. If mismatch and manual PAN upload exists, returns conflict. New code does not cross-validate PAN number from DigiLocker response against stored PAN. |
| 5 | Address extraction from Aadhaar XML (house, street, vtc, dist, state, pincode) | OCRRepository.cs (XML parsing) | AadhaarVerificationService → ExtractFieldFromResponse | PRESENT | Extracts address, house, street, loc, vtc, city, dist, state, pc, pincode fields from parsed JSON/XML. |
| 6 | Address language translation (AiNXT regional language → English) | OCRRepository.cs (AiNXT translation) | AinxtDigilockerProvider.TranslateAddressAsync (called from callback processing) | PARTIAL | Provider method exists and is called when non-Latin text detected. But actual AiNXT API endpoint is TODO (returns pass-through). Structure is correct, needs wiring. |
| 7 | Aadhaar seeding status check at DigiLocker stage | USP_CHECK_AADHAARSEED_STATUS_SJET | N/A | MISSING | Old code re-checks Aadhaar seeding at DigiLocker stage. New code does not check seeding status during Stage 5. |
| 8 | Aadhaar bypass for MOSL employees (USP_BYPASS_AADHAAR_MOSL_SJET) | USP_BYPASS_AADHAAR_MOSL.sql | N/A | MISSING | Old code allows MOSL employees to bypass Aadhaar verification entirely. New code has no employee Aadhaar bypass logic. |
| 9 | Aadhaar mismatch handling (USP_CHECKAADHARMISMATCHXML_SJET) | USP_CHECKAADHARMISMATCHXML.sql | N/A | PARTIAL | Old SP detected name/DOB mismatches between Aadhaar XML and PAN data. New code does name matching (score-based) but does not perform DOB cross-validation between Aadhaar and PAN DOB. |
| 10 | Aadhaar response logging (USP_AADHAR_RESPONSE_LOG_SJET) | USP_AADHAR_RESPONSE_LOG.sql | ApiAuditLogger + JourneyTracker | PRESENT | New code uses structured ApiAuditLogger for all provider calls and JourneyTracker for stage events. More granular than old SP-based logging. |
| 11 | Photo extraction from Aadhaar for liveness | OCRRepository.cs | AadhaarVerificationService → stores AadhaarPhotoS3Key | PARTIAL | New code stores photo path from DigiLocker. Actual photo extraction from Aadhaar XML (base64 photo element) not explicitly coded - relies on AiNXT parsed response. |
| 12 | DigiLocker address exists re-check (USP_CHECK_AINXT_DIGILOCKER_ADDR_EXISTS_SJET) | USP_CHECK_AINXT_DIGILOCKER_ADDR_EXISTS.sql | N/A | MISSING | Old SP verifies address was successfully stored after DigiLocker callback. New code stores address directly but has no verification step to confirm address persistence. |
| 13 | PAN-Aadhaar exists check (USP_CHECK_PAN_AADHAAR_EXISTS_EXP_SJET) | USP_CHECK_PAN_AADHAAR_EXISTS_EXP.sql | PanVerificationService dedupe logic (Stage 4) | PARTIAL | Dedupe is done at Stage 4 for PAN. No Aadhaar-based dedupe at Stage 5. Old SP checked both PAN and Aadhaar uniqueness. |
| 14 | Name matching (Aadhaar name vs eKYC name) | OCRRepository.cs (AINXT name match) | AadhaarVerificationService → _nameMatch.CalculateScore | PARTIAL | Score-based matching present. STP/NON_STP/DROP_DL_NAME_FAIL flags set. Same gap as Stage 4: uses local Levenshtein instead of AiNXT API. |
| 15 | Father name extraction from DigiLocker | OCRRepository.cs | AadhaarVerificationService → ExtractFatherNameFromDigilockerResponse | PRESENT | Extracted and stored in AadhaarVerification.FatherName. |
| 16 | Aadhaar XML 24-hour deletion (UIDAI compliance) | (not explicit in old code) | AadhaarVerificationService → AadhaarXmlDeletionScheduledAt | PRESENT | New code schedules XML deletion at +24 hours. This is an improvement; old code did not have explicit UIDAI compliance scheduling. |
| 17 | Aadhaar card upload fallback (when DigiLocker fails) | OCRRepository.cs (UploadProof AADHAAR type) | AadhaarVerificationService.ProcessAadhaarUploadAsync | PARTIAL | Upload flow exists with file validation (size, type). OCR extraction is TODO (AinxtOcrResult returns null). Uses simulated/hardcoded address values. |
| 18 | NRI Aadhaar flow (NRI address details, passport-based address proof) | NRIPanRepository.cs:203-405 | N/A | MISSING | Entire NRI address/Aadhaar flow missing. NRI uses passport as address proof, different validation rules, country masters. Not in new code. |
| 19 | HyperKYC / HyperVerge alternative Aadhaar flow | OCRRepository.cs (HyperKYC path) | N/A | N/A | Old code had HyperKYC as an alternative to DigiLocker. Product decision may have removed this. Confirm with product team. |
| 20 | Consent record for DigiLocker | (implicit in old code) | AadhaarVerificationService → Consent entity with ConsentType, Version, TextHash, IP, Platform | PRESENT | New code creates proper consent audit trail. Improvement over old code. |
| 21 | Downstream event publishing (CRM, CDP, DataLake) | (LeadSquared + SuperApp calls) | _downstream.PublishToAllAsync (CLEVERTAP, ZOHO_CRM, CDP, DATALAKE) | PRESENT | New code publishes structured events. Old code had direct API calls to LeadSquared/SuperApp. |
| # | Gap | Stage | Priority | Status |
|---|---|---|---|---|
| 1 | SEBI/CSAFE debarred check not wired | 4 | P0 | FIXED — Reads CsafeCheck table, drops with DROP_SEBI_DEBARRED |
| 2 | PAN-Aadhaar cross-validation missing | 5 | P1 | FIXED — Compares DigiLocker PAN hash with Stage 4 PAN hash, flags PAN_DIGILOCKER_MISMATCH for STP downgrade |
| 3 | Aadhaar seeding status not enforced | 4 | P1 | FIXED — Checks kra.AadhaarSeedingStatus, flags AADHAAR_NOT_SEEDED for STP downgrade |
| 4 | NRI PAN + Aadhaar flows missing | 4+5 | P1 | FIXED — Stage 4: NRI skips KRA RESTRICTED. Stage 5: NRI routed to NRI_PASSPORT_UPLOAD instead of DigiLocker |
| 5 | PAN bypass for existing customers missing | 4 | P1 | FIXED — CheckBypassEligibilityAsync for INACTIVE/PMS/OWNER/WHITELIST before blocking PAN duplicate |
| 6 | Name matching uses local Levenshtein | 4+5 | P2 | OPEN — AiNXT name match API can be wired later. Local Levenshtein is functional for now. |
| 7 | BA/IFA/PMS whitelist auto-insert missing | 4 | P2 | FIXED — Auto-inserts FranchisePanWhitelist for PP/CRM leads with BaCode |
| 8 | MOSL employee Aadhaar bypass missing | 5 | P2 | FIXED — Employee PAN detected at DigiLocker init, routes to DIGILOCKER_SKIP |
| 9 | Aadhaar DOB cross-validation with PAN DOB | 5 | P2 | FIXED — Compares Aadhaar DOB with PAN DOB, flags DOB_PAN_AADHAAR_MISMATCH |
| 10 | OCR extraction for Aadhaar upload is TODO | 5 | P2 | EXCLUDED — per user decision, not in scope for this round |
| 11 | Old PAN vs New PAN cascade delete | 4 | P2 | FIXED — Clears AadhaarVerifications + BankAccounts + LivenessVerifications on PAN change |
| 12 | AiNXT address translation is TODO | 5 | P2 | FIXED — TranslateAddressAsync now calls AiNXT v3/translate/address with fallback |