15 - Master Dev Help
A single lookup sheet: "I want to change X — which file do I open?" Pick a category from the index below, scan the table, click through to the file or to the detailed page that explains the pattern.
This is a cheat-sheet, not a tutorial. Every row answers one question: where does this live? For the why and the how of a topic, click the "see also" link in each section to jump to the full guide.
Jump to
HTTP & Entry Point
| I want to change… | Open this file | Notes |
|---|---|---|
| DI registration, Hangfire, Swagger, auth wiring | src/MO.Ekyc.Api/Program.cs | Single top-level file; all builder.Services.Add* calls live here. |
| Dev-only / prod-only config | src/MO.Ekyc.Api/appsettings.json src/MO.Ekyc.Api/appsettings.Development.json | Env-specific overrides merge over the base file. |
| Manually fire requests against the API | src/MO.Ekyc.Api/MO.Ekyc.Api.http | VS / Rider HTTP client format; Swagger is at /swagger in dev. |
Controllers & Routes
Controllers are grouped by stage under src/MO.Ekyc.Api/Controllers/<StageN>/. The Admin and WarRoom subfolders host admin-only endpoints. See 07 - Controllers for the full list.
| I want to… | Open this file | Notes |
|---|---|---|
| Add a new customer-facing endpoint | Controllers/Stage<N>/<Thing>Controller.cs | Copy an existing controller in the same stage. Add [RequiresStage(<N>)]. |
| Add an admin/WarRoom endpoint | Controllers/Admin/*.cs Controllers/WarRoom/*.cs | Use [AdminAuthorize(Roles="...")]. |
| Change the URL of an existing endpoint | src/MO.Ekyc.Shared/Constants/ApiRoutes.cs | All routes are constants here so the Flutter app and backend stay in sync. |
| Change the stage unlock order | src/MO.Ekyc.Shared/Constants/StageDefinitions.cs | Source of truth for the current/minimum stage numbers. |
| Enforce a stage gate on an endpoint | src/MO.Ekyc.Api/Filters/StageValidationFilter.cs | Filter reads the lead's current_stage from DB. |
Services (business logic)
Services live in src/MO.Ekyc.Infrastructure/Services/<StageN>/. Common/ hosts cross-cutting services like HashingService, JourneyTracker, OtpGeneratorService, SmsTemplateService, NameMatchService, StpDecisionService. See 08 - Services.
| I want to… | Open this file | Notes |
|---|---|---|
| Add a new business-logic service | Services/Stage<N>/<Thing>Service.cs | Register it in Program.cs (or the Service Extensions file if present). |
| Change name-match scoring | Services/Common/NameMatchService.cs | Fuzzy match used by Stages 6, 7, 11. |
| Change STP decision rules | Services/Common/StpDecisionService.cs | Based on cumulative reason codes stored on the Lead row. |
| Change OTP length / expiry / cooldowns | Services/Common/OtpGeneratorService.cs Services/Stage2/OtpVerificationService.cs Services/Stage3/EmailVerificationService.cs | Constants at the top of each verification service. |
| Add a new stage-specific service method | Services/Stage<N>/<Thing>Service.cs | Controllers should call only one service per request; service calls providers. |
| Trigger a downstream CRM / CDP / Kafka event | Services/Common/DownstreamEventPublisher.cs | Fans out to Kafka + Zoho CRM + Clevertap via PublishToAllAsync. |
| Write a journey activity log entry | Services/Common/JourneyTracker.cs | Writes to lead_state_transitions and journey_stage_events. |
External Providers
All outbound HTTP, SOAP, Kafka and SDK integrations live under src/MO.Ekyc.Infrastructure/ExternalProviders/. Each category is a folder (Pan, Bank, Face, Esign, Liveness, Kra, …). See 09 - External Providers.
| I want to… | Open this file | Notes |
|---|---|---|
| Change how a PAN is verified | ExternalProviders/Pan/ (Ndml, Nsdl, CvlKra, Hyperverge, Uti, Zintlr) | Chain order comes from provider_configurations table (see DB section). |
| Change bank penny-drop provider | ExternalProviders/Bank/ (HypervergeRpd, SetuReversePenny, YesBankImps, Decentro, KarzaBank, DigitapOcr) | Provider chain executor picks based on priority + circuit breaker. |
| Change face-match / liveness provider | ExternalProviders/Face/ ExternalProviders/Liveness/ | Hyperverge, AINXT, Digio variants exist for both. |
| Change Aadhaar / DigiLocker integration | ExternalProviders/Aadhaar/AinxtDigilockerProvider.cs | Callback URL is configured per env in appsettings. |
| Change eSign provider | ExternalProviders/Esign/ (NsdlEsign, HypervergeEsign, EmudhraEsign) | Multi-provider fallback via ProviderChainExecutor. |
| Add a new provider category | ExternalProviders/<NewCategory>/I<New>Provider.cs + <Vendor>Provider.cs | Register in Program.cs. Add a row in provider_configurations with priority. |
| Change circuit breaker thresholds / windows | ExternalProviders/Common/CircuitBreaker.cs provider_configurations.circuit_breaker_threshold | Runtime thresholds come from the DB row, not code. |
| Change provider chain fallback behaviour | ExternalProviders/Common/ProviderChainExecutor.cs | Handles priority ordering, circuit-open skip, and AllProvidersFailedException. |
Database & Persistence
See 10 - Database & Sync Tables for the full entity map (75 tables across the ekyc schema).
| I want to… | Open this file | Notes |
|---|---|---|
| Add a new table / entity | src/MO.Ekyc.Domain/Entities/<Thing>.cs src/MO.Ekyc.Infrastructure/Persistence/Configurations/<Thing>Configuration.cs | Pure POCO + Fluent API config. Then add DbSet in EkycDbContext. |
| Change an existing entity schema | src/MO.Ekyc.Domain/Entities/<Thing>.cs | Add EF migration via dotnet ef migrations add <Name> in the Api project. |
| Change the DbContext or add a Set | src/MO.Ekyc.Infrastructure/Persistence/EkycDbContext.cs | Schema name ekyc is set here. |
| Add a migration | src/MO.Ekyc.Infrastructure/Persistence/Migrations/ | Run dotnet ef migrations add from the Api project. |
| Change the connection string | appsettings*.json → ConnectionStrings:EkycDb | Also set in the CI env. PostgreSQL only. |
| Seed reference data (lookup tables) | src/MO.Ekyc.Infrastructure/Persistence/SeedData/*.cs | Runs on startup in dev. |
| Run a raw SQL query safely | Use ExecuteSqlInterpolatedAsync, not ExecuteSqlRawAsync | EF1002: raw + string interpolation is a SQL-injection finding (see Sonar analysis). |
Auth, Filters & Middleware
| I want to… | Open this file | Notes |
|---|---|---|
| Change JWT issuance / validation | src/MO.Ekyc.Api/Program.cs (AddJwtBearer)src/MO.Ekyc.Api/Controllers/WarRoom/WarRoomAuthController.cs | Secret key comes from Jwt:SecretKey config (min 32 chars). |
| Gate an endpoint behind a stage | [RequiresStage(N)] attribute → Filters/StageValidationFilter.cs | Returns 409 if the lead's current_stage < N. |
| Gate an admin endpoint by role | [AdminAuthorize(Roles="...")] → Filters/AdminAuthorizationFilter.cs | Roles come from the JWT claim. |
| Change request-level logging | Middleware/RequestLoggingMiddleware.cs Middleware/CorrelationIdMiddleware.cs | Correlation ID is attached here and flows to Serilog + DB audit. |
| Change global exception handling | Middleware/ExceptionHandlingMiddleware.cs | Returns structured ApiResponse.Fail on any unhandled exception. |
| Change session sliding-refresh rules | Middleware/SessionRefreshMiddleware.cs | Extends JWT expiry on every authenticated call. |
Background Jobs
Hangfire-backed jobs live under src/MO.Ekyc.Infrastructure/BackgroundJobs/. Dashboard at /hangfire in dev.
| Job | File | What it does |
|---|---|---|
| Dropoff detection + nudge SMS | BackgroundJobs/DropoffDetectionJob.cs | Marks stale leads as DROPPED, sends one-time nudge SMS. |
| CS journey retry (agent hand-off) | BackgroundJobs/CsJourneyRetryJob.cs | Retries CS_* trigger codes with cooldown. |
| Downstream event publisher | BackgroundJobs/DownstreamEventPublisherJob.cs | Flushes queued downstream_events to Kafka / CRM / CDP. |
| Analytics snapshot | BackgroundJobs/AnalyticsSnapshotJob.cs | Hourly rollup into analytics tables. |
| Session cleanup | BackgroundJobs/SessionCleanupJob.cs | Expires sessions past their timeout. |
| Aadhaar deletion (compliance) | BackgroundJobs/AadhaarDeletionJob.cs | Purges raw Aadhaar data after retention window. |
| Human-readable activity log writer | BackgroundJobs/ActivityLogWriterService.cs | Consumer side of journey_activity_logs. |
Config & Environment
| Setting | Location | Notes |
|---|---|---|
| Global mock mode | appsettings.Development.json → MockMode:GlobalMockEnabled | When true, every provider returns canned data. See 02 - Mock Mode. |
| Per-provider mock mode | DB: provider_configurations.mock_mode | Overrides the global flag for one provider at a time. |
| SMS mode (REAL / FIXED_OTP) | appsettings → Sms:Mode | FIXED_OTP logs the OTP instead of sending. |
| JWT signing key | appsettings → Jwt:SecretKey (min 32 chars) | Hard-fails at startup if missing or too short. |
| Provider endpoints & credentials | appsettings → ExternalProviders:<Vendor> | Do not commit real creds — use env vars / secret store. |
| Stage unlock thresholds / timeouts | appsettings → Journey:* | E.g. MaxBankAttempts, PanReverifyDaysThreshold, FaceMatchStpMinScore. |
| Kafka topics / brokers | appsettings → Kafka:* | See Infrastructure/Kafka/KafkaProducer.cs. |
Logging, Audit & Telemetry
| I want to… | Open this file / table | Notes |
|---|---|---|
| Change Serilog sinks / levels | Program.cs (UseSerilog)appsettings → Serilog:* | Console sink in dev, file sink in prod. |
| See external API call history | Query table ekyc.api_audit_log | Every provider call is logged here by ApiAuditLogger. |
| See the user-facing journey timeline | Query table ekyc.journey_activity_logs | Written by ActivityLogWriterService → used by WarRoom UI. |
| See state transitions | Query table ekyc.lead_state_transitionsekyc.journey_stage_events | Written by JourneyTracker. |
| See EF-generated SQL in console | appsettings → Logging:Microsoft.EntityFrameworkCore.Database.Command:Information | Dev only. See 11 - Debugging. |
| Inspect correlation IDs across services | Middleware/CorrelationIdMiddleware.cs | Header: X-Correlation-Id. Flows to Serilog + audit log. |
Testing
| Test type | Project | Notes |
|---|---|---|
| Unit tests (services, mocks, fast) | tests/MO.Ekyc.UnitTests/ | xUnit + Moq + FluentAssertions + InMemory EF. |
| Integration tests (real DB via EF InMemory, multi-service flows) | tests/MO.Ekyc.IntegrationTests/ | FullJourneyFlowTests runs Stages 11 → 15 end-to-end. |
| Api-level tests (WebApplicationFactory) | tests/MO.Ekyc.Api.Tests/ | Uses CustomWebApplicationFactory<Program> — that's why Program is public partial class not static. |
| Run all tests | dotnet test MO.Ekyc.sln | From the backend/ folder. |
Build, Analysis & CI
| I want to… | Open this file | Notes |
|---|---|---|
| Add a global MSBuild property | backend/Directory.Build.props | Currently registers SonarAnalyzer.CSharp + SARIF error log for every project. |
| Run Sonar static analysis locally | dotnet build + node scripts/aggregate-sonar.js | See 14 - Sonar Analysis for the full HTML report workflow. |
| Apply bulk Sonar auto-fixers | backend/scripts/fix-*.js | S2139, S6667, unused logger/field, IDisposable. Each script is self-documenting. |
| Build the whole solution | dotnet build MO.Ekyc.sln -c Debug | From the backend folder. Stop any running Api first to avoid file locks. |
| Publish a release build | dotnet publish src/MO.Ekyc.Api -c Release -o out/ | Self-contained publish is not enabled by default. |
Common "Where do I add…"
These are the questions that come up most in code review:
| New thing | Add it here | Don't forget |
|---|---|---|
| A new HTTP route | ApiRoutes.cs constant → Controllers/Stage<N>/<Name>Controller.cs → service method → optional [RequiresStage] | Swagger picks it up automatically; update frontend ApiService. |
| A new Stage service | Services/Stage<N>/<Name>Service.cs | Register in Program.cs; inject IJourneyTracker + IDownstreamEventPublisher if it transitions state. |
| A new external provider | ExternalProviders/<Category>/I<Name>Provider.cs + <Vendor><Name>Provider.cs | Register + insert row in provider_configurations. |
| A new DB table | Domain/Entities/<Name>.cs → Persistence/Configurations/<Name>Configuration.cs → DbSet in EkycDbContext | Generate migration with dotnet ef migrations add. |
| A new downstream event type | Services/Common/DownstreamEventPublisher.cs + event class | Add subscriber in the consumer (Kafka / CRM handler). |
| A new Hangfire job | BackgroundJobs/<Name>Job.cs | Register with RecurringJob.AddOrUpdate in Program.cs. |
| A new admin role | AdminAuthorizationFilter.cs + update WarRoomAuthController login | Roles are plain strings in the JWT. |
| A new SMS / email template | Services/Common/SmsTemplateService.cs (or email equivalent) | Templates live in the service; placeholders replaced at send time. |
Open 03 - Project Tour for the folder-by-folder walkthrough, 06 - Stage Walkthrough for an end-to-end HTTP→DB trace, or 12 - How-To Guides for task-oriented recipes.