EKYC 3.0 — Gap Analysis: New Backend vs Old Code

Stage 2 (OTP Verification) & Stage 3 (Email Verification) • Comparing D:\MO_Project\ekyc\backend vs D:\MO_Project\ekyc\existing_code
Scope: Stage 2 (OTP Verify + Background Checks) & Stage 3 (Email Verification) only New Backend: .NET 8 + PostgreSQL + Redis Old Backend: .NET + SQL Server + SOAP

Table of Contents

  1. Executive Summary
  2. Check-by-Check Comparison
  3. Missing Checks — Priority Action Items
  4. Old Tables NOT to Reuse (Stage 2 & 3)
  5. New Tables Needed
  6. Reference Tables — MUST Use / Sync
  7. Action Items

1. Executive Summary

28
Checks Present
5
Partial / Needs Enhancement
8
Missing from New Code
41
Total Checks Analysed
What the new backend does well OTP in Redis with TTL (not DB), 4-digit crypto random OTP, max 5 wrong attempts with lock, max 3 resends with 30-sec cooldown, SMS delivery via NetcoreSmsProvider, OTP cascade interface ready, CS Journey hold on all-channel fail, async background checks after OTP verify (Zintlr → HV+Csafe → NSDL+CVL pipeline), UTI fallback only on NSDL failure, CVL KRA status mapping, three email paths (KRA prefill / Google OAuth / manual OTP), email OTP in Redis (10-min TTL), email duplicate check (post-eSign), restricted domain check, suspicious email flag, delivery failure handling, comprehensive downstream events.
Critical gaps found (8 items) The old system performed several email-related checks not yet replicated: custom format validation (forbidden patterns), email whitelist bypass, OTP bypass for RM-assisted Zoho resume, email bypass for INACTIVE/PMS/OWNER, and configurable validation flags. Note: CYBRIDGE, Karza email validation, LeadSquare, and IIBL customer check are confirmed NOT required per Product team (April 2026). CRM = Zoho only.

2. Check-by-Check Comparison

Every check performed by the old code during Stage 2 (OTP Verification) and Stage 3 (Email Verification), mapped to the new backend.

# Check / Logic Old Code (SP / Method) New Backend Status
STAGE 2 — OTP Verification (Checks 1–18)
1 OTP stored in Redis only (not DB) Old: stored in DB via SP ICacheService.StoreOtpAsync, TTL 5 min, Redis only PRESENT
2 4-digit OTP generation Generated in SP OtpGeneratorService, 4-digit cryptographic random PRESENT
3 Max 5 wrong attempts → DROPPED Attempt tracking in DB OtpVerificationService, MaxWrongAttempts=5, state → DROPPED, IsLocked=true PRESENT
4 Max 3 resends in 30 min Rate limiting in DB MaxResendCount=3, MinResendIntervalSeconds=30 PRESENT
5 30-sec cooldown between resends Embedded in SP Checks ResendCount timing in OtpVerificationService PRESENT
6 OTP delivery via SMS Netcore SOAP NetcoreSmsProvider, MOSL SMS PRESENT
7 OTP cascade (SMS → WhatsApp → Push → RCS) Old: SMS only Interface INotificationService.SendOtpCascadeAsync ready, only SMS implemented PARTIAL (interface ready, only SMS impl)
8 CS Journey on all OTP channels fail Not in old code ICsJourneyService.CreateHoldAsync PRESENT
9 Background checks fire async after OTP verify Called later in old flow FireBackgroundChecksAsync via Task.Run PRESENT
10 Zintlr phone-to-PAN with plain mobile Not in old reg code Uses lead.Mobile directly after fix PRESENT
11 Hyperverge name+DOB fetch Called at PAN stage in old code HypervergePanProvider.FetchPanDetailsAsync PRESENT
12 NSDL PAN validation PanAPI.VerifyPAN_NSDL() NsdlPanProvider.ValidatePanAsync PRESENT
13 UTI fallback when NSDL DOWN only Implicit fallback Fixed: checks IsSuccess=false AND exception path PRESENT
14 CVL KRA status fetch + data download USP_INSERT_KRA_LOGS_SJET CvlKraPanProvider with status mapping PRESENT
15 C-safe AML/SEBI/PEP check USP_INSERT_CSAFE_Req_Resp CsafeProvider.CheckPanAsync with PAN hash PRESENT
16 Pipeline order: Zintlr → (HV+Csafe) → (NSDL+CVL) Sequential in old SPs Fixed in BackgroundCheckService PRESENT
17 Downstream events after OTP verify (CleverTap, Zoho, Datalake, CDP) Inline calls in old code 4 events published via DownstreamEventPublisher PRESENT
18 KRA raw code mapping to internal status Hardcoded in SP MapKraRawCodeToStatusAsync with cvl_status_mapping table + hardcoded fallback PRESENT
STAGE 3 — Email Verification (Checks 19–41)
19 Three email paths (KRA prefill, Google OAuth, Manual OTP) Manual OTP only in old code EmailVerificationService with HandleKraPrefillVerificationAsync, HandleGoogleOAuthVerificationAsync, HandleManualOtpInitiationAsync PRESENT
20 KRA prefill email confirm (no OTP needed) Not in old code KraPrefillEmailUsed=true PRESENT
21 Google OAuth email capture (no OTP needed) Not in old code EmailSource="GOOGLE_OAUTH" PRESENT
22 Manual email entry with 4-digit OTP OTP via SP in old code OtpLength=4, OtpTtlMinutes=10 PRESENT
23 Email OTP in Redis (TTL 10 min) Old: stored in DB ICacheService, 10 min TTL PRESENT
24 Max 5 wrong email OTP attempts → must change email Attempt tracking in DB MaxOtpAttempts=5, IsLocked=true PRESENT
25 Max 3 email resends, 30-sec cooldown Rate limiting in DB MaxResends=3, ResendCooldownSeconds=30 PRESENT
26 Attempt counter resets on new email Implicit in old code New OtpVerification created per email PRESENT
27 Email duplicate check (post-eSign leads) Embedded in SP Checks CurrentStage >= Esign PRESENT
28 Restricted email domain check Embedded in SP RestrictedEmailDomain table query PRESENT
29 Suspicious email flag (don't block) Usp_GetSuspiciousPhoneOrEMailId SuspiciousContact check, logs warning PRESENT
30 Email delivery failure → continue with email_verified=false Block on failure in old code SendEmailOtpAsync catches exception, sets false PRESENT
31 Google OAuth failure → silent fallback Not in old code Handled in controller, returns to manual PRESENT
32 Downstream events on email verified (CleverTap, Zoho CRM, CDP, Datalake) Inline calls in old code 4 events: CLEVERTAP, ZOHO_CRM, CDP, DATALAKE PRESENT
33 Email bypass logic (INACTIVE/PMS/OWNER) USP_BYPASS_MOBILE_EMAIL_PAN_SJET checks MOSL_FEED for email bypass Not found in new backend. No email bypass check. MISSING
34 Real-time email validation (CYBRIDGE) REMOVED REALTIME_EMAIL_VALIDATION API to check deliverability No equivalent in new code MISSING
35 Karza email validation REMOVED KARZA_EMAIL_VALIDATION API Not required per Product team. N/A MISSING
36 Custom email validation (SP-based format check) USP_CUSTOM_EMAIL_VALIDATION_SJET — extensive checks: no @, multiple @, starts with number, ends with period, forbidden patterns New code only does basic format check MISSING
37 Email whitelist (TBL_ALLOW_EMAIL equivalent) TBL_ALLOW_EMAIL — whitelisted domains bypass all validation No whitelist table in new code MISSING
38 OTP bypass for RM-assisted Zoho resume USP_INSERT_UPDATE_MOBILE_EMAIL_OTP_BYPASS_SJETUpdated scope: bypass when RM resumes drop-off journey from Zoho CRM only (not franchise) No equivalent in new code MISSING
39 Email validation config flags GET_EMAILVALIDATION_FLAG SP controlling which validations to run No configurable validation flags in new code PARTIAL
40 Wait for KRA background check (max 3 sec) BRD: wait max 3 seconds for CVL result before rendering Stage 3 Background checks fire but no explicit wait/poll for KRA completion PARTIAL
41 IIBL customer check REMOVED ISUSER_IIBL_CUSTOMER — not required per Product team No equivalent in new code MISSING

3. Missing Checks — Priority Action Items

PriorityGapWhy It MattersRecommended Fix
P1 #33 — Email bypass logic (still needed) Without this, legitimate users whose email is in back-office (INACTIVE clients, PMS-only clients, branch/sub-broker OWNERs) will be blocked from proceeding. Add email bypass in BackOfficeCheckService. Check client_master for INACTIVE/PMS/OWNER conditions on email.
P1 #34 — Real-time email validation (Cybridge) Without deliverability check, OTPs may be sent to non-existent or undeliverable email addresses, wasting resources and creating poor user experience. CYBRIDGE/Karza email validationREMOVED per Product team. No action needed.
P1 #35 — Karza email validation Secondary validation layer for email deliverability. Provides redundancy when primary provider is down. REMOVED per Product team. No action needed.
P1 #36 — Custom email validation (format checks) Pattern checks prevent obviously fake emails (e.g., notprovided@, noemail@, xyz@, domains starting with numbers, trailing periods). Without these, fraudulent or junk emails pass through. Add validation rules to EmailVerificationService: forbidden patterns (notprovided, noemail, xyz), domain starts with number, ends with period, multiple @, etc.
P1 #37 — Email whitelist Known-good domains (corporate, government) should skip extended validation. Without this, legitimate corporate emails may be unnecessarily flagged or delayed. Create allowed_email_domains table and add whitelist check before blocking.
P2 #38 — OTP bypass for RM-assisted Zoho resume When an RM resumes a dropped-off journey from Zoho CRM, OTP should be bypassed so the RM can continue the application without waiting for customer OTP. Add IsRmResumeBypass flag on Lead. When source=ZOHO_RM_RESUME, skip OTP and proceed directly to last completed stage.
P2 #39 — Email validation config flags Runtime control of which validations run allows ops team to toggle checks without deployment. Without this, any validation change requires a code release. Use application_config table for flags: ENABLE_CUSTOM_FORMAT_CHECK, ENABLE_WHITELIST_CHECK, ENABLE_RESTRICTED_DOMAIN_CHECK. (CYBRIDGE/Karza flags removed.)
P2 #40 — KRA wait with 3-sec timeout Pre-fill works better with KRA data available. BRD says wait max 3 seconds for CVL result before rendering Stage 3. Without this, Stage 3 may render without KRA prefill even when data arrives 1-2 seconds later. Add polling with timeout in GetEmailDetailsAsync: check KRA result every 500ms up to 3 seconds.
P2 #41 — IIBL customer check REMOVED per Product team. Not required. No action needed.

4. Old Tables NOT to Reuse (Stage 2 & 3)

These are the old system's operational tables for Stage 2 and Stage 3. Your new backend has its own equivalents. Do NOT use these tables — they belong to the old EKYC system.

Old TablePurpose (Old System)New Equivalent
TBL_SEND_RESUME_OTP OTP storage and attempt tracking otp_verifications + Redis
TBL_KRAAPI_CALL_LOG KRA API call logging kra_records + api_audit_logs
TBL_CSAFE_Req_Resp C-safe request/response logging csafe_checks + api_audit_logs
TBL_REALTIME_EMAIL_RESPONSE Cybridge email validation response cache api_audit_logs (or new validation cache table)
TBL_KARZA_EMAIL_VALIDATE_RESPONSE Karza email validation response cacheNOT NEEDED. Karza removed. api_audit_logs
TBL_ALLOW_EMAIL Whitelisted email domains Needs equivalent: allowed_email_domains NEW TABLE NEEDED
TBL_RESTRICT_EMAIL_DOMAIN Blocked/restricted email domains restricted_email_domains (already exists)
TBL_MOBILE_EMAIL_OTP_BYPASS_DETAILS OTP bypass tracking — Updated: for RM-assisted Zoho resume only (not franchise) Not created yet NOT CREATED

5. New Tables Needed

One new table is required to support the missing email whitelist functionality This table replaces the old TBL_ALLOW_EMAIL and enables known-good domains to bypass extended email validation.
Table NameColumnsPurposeReplaces
allowed_email_domains EntryId (PK), Domain (varchar, unique), Reason (varchar), IsActive (bool), CreatedAt (timestamp) Whitelisted email domains that bypass extended validation checks (custom format). Corporate and government domains. (Deliverability checks via CYBRIDGE/Karza removed.) TBL_ALLOW_EMAIL

6. Reference Tables — MUST Use / Sync

Critical: These reference tables contain business data that must be populated or synced Your new backend already has entity definitions for most of these. The data must be loaded for Stage 2 and Stage 3 flows to work correctly.
TablePurposeSync StatusAction Needed
restricted_email_domains Blocked email domains (disposable services, spam) ALREADY SYNCED Maintain updates from security team.
suspicious_contacts Flagged phone/email for review (don't block) ALREADY SYNCED Maintain updates from fraud operations.
cvl_status_mapping Map raw CVL KRA codes to internal status DEFINED, NEEDS POPULATION P2: Populate from BRD Section 19 mapping table. Used by BackgroundCheckService.MapKraRawCodeToStatusAsync.
nsdl_error_master NSDL error code meanings and IsFatal flag DEFINED, NEEDS POPULATION P2: Populate from NSDL documentation. Determines if error is recoverable.
provider_configurations External provider URLs, keys, priorities, circuit breaker config DEFINED, NEEDS ALL ENTRIES P2: Ensure all provider config entries exist for email providers (Netcore Email, Google OAuth). (TheChecker/Karza removed.)

7. Action Items

#PriorityActionEffort
1 P1 Add email bypass logic in BackOfficeCheckService for EMAIL type (INACTIVE/PMS/OWNER). Check client_master for bypass conditions when email matches an existing back-office record. Allow with BypassReason flag. CRM integration = Zoho only (no LeadSquare). 1 day
2 P1 Add real-time email validation provider. TheChecker is already referenced in appsettings. Implement TheCheckerEmailProvider to call deliverability API before sending OTP. 1 day
3 P1 Integrate Karza email validation. REMOVED per Product team. No action needed. 0.5 day
4 P1 Add custom email format validation rules. Forbidden patterns: notprovided, noemail, xyz; domain starts with number; ends with period; multiple @ symbols. Add to EmailVerificationService. 0.5 day
5 P1 Create allowed_email_domains table and add whitelist check before blocking. Populate with known-good corporate/government domains from old TBL_ALLOW_EMAIL. Skip extended validation for whitelisted domains. 0.5 day
6 P2 Add OTP bypass for RM-assisted Zoho resume. Add IsRmResumeBypass flag on Lead. When lead is resumed by an RM from Zoho CRM (source=ZOHO_RM_RESUME), skip OTP verification and proceed directly to last completed stage. Log bypass in lead_state_transitions with TriggerAction=RM_RESUME_BYPASS. 0.5 day
7 P2 Add email validation config flags via application_config table. Keys: ENABLE_CUSTOM_FORMAT_CHECK, ENABLE_WHITELIST_CHECK, ENABLE_RESTRICTED_DOMAIN_CHECK. Allows ops to toggle without deploy. (CYBRIDGE/Karza flags removed.) 0.5 day
8 P2 Add 3-second polling wait for KRA result in GetEmailDetailsAsync. Poll kra_records every 500ms up to 3 seconds. If KRA data arrives, pre-fill email from KRA. If timeout, render Stage 3 without prefill. 0.5 day
9 P2 Populate cvl_status_mapping table from BRD mapping. Map all raw CVL codes to internal status values. Remove dependency on hardcoded fallback in BackgroundCheckService. 0.5 day
10 P2 Verify all provider_configurations entries exist for email providers. Ensure Netcore Email, Google OAuth providers are configured with URLs, keys, circuit breaker thresholds. (TheChecker/Karza removed.) 0.5 day
Summary: Stage 2 is nearly complete; Stage 3 has email validation gaps Stage 2 (OTP Verification + Background Checks) is well-implemented with 18/18 core checks present including the full background check pipeline (Zintlr → HV+Csafe → NSDL+CVL). The OTP cascade interface is ready but only SMS is implemented. Stage 3 (Email Verification) has the core three-path flow working (KRA prefill, Google OAuth, manual OTP) but is missing the old system's email validation layers: real-time deliverability (Cybridge/Karza), custom format checks, whitelist bypass, and the back-office email bypass logic. These are primarily email validation depth gaps — the flow itself is correct, but the validation before sending OTPs needs to be strengthened.