04 - Architecture

Clean Architecture at a glance. For full component diagrams and sequence flows, see Backend Architecture (diagrams).

Full diagrams elsewhere

This page is a quick summary. For component diagrams, request pipeline, provider chain sequence diagrams, and clean architecture circles, open backend-architecture.html.

The 5 Projects

#ProjectRoleDepends on
1Domain75 POCO entitiesNothing
2SharedApiRoutes, ErrorCodes, ApiResponse, helpersNothing
3ApplicationCQRS models, Interfaces (IJourneyTracker, IPaymentService, etc.)Domain, Shared
4InfrastructureEF Core, services, external providers, Hangfire, KafkaApplication, Domain, Shared
5ApiControllers, Filters, Middleware, Program.cs (composition root)Application, Infrastructure, Shared

Dependency Rule

Dependencies flow inward. The outermost layer (Api) depends on everything. The innermost layer (Domain) depends on nothing. Interfaces in Application let Infrastructure swap implementations without rippling back.

Interfaces go in Application, implementations in Infrastructure

Example: IJourneyTracker is defined in MO.Ekyc.Application/Interfaces/. The implementation JourneyTracker lives in MO.Ekyc.Infrastructure/Services/Common/. Services consume the interface, DI wires the implementation in Program.cs.

Request Flow (one sentence)

HTTP request → CorrelationId → Exception handler → Request logging → JWT auth → Session refresh → CORS → StageValidationFilterController actionServiceProviderChainExecutor (for external calls) → EF CoreApiResponse<T> JSON back to client.

Where Logic Lives

WhatWhere
HTTP routing + validationController action (minimal - delegates to service)
Stage enforcement[RequiresStage(N)] attribute + StageValidationFilter
Business logic + orchestrationStage-specific services (RegistrationService, BankVerificationService, etc.)
Database reads/writesEkycDbContext via services
External API callsExternal providers through ProviderChainExecutor
Journey state transitionsIJourneyTracker (Common service)
Audit loggingApiAuditLogger (for external calls), JourneyActivityLogger (for lead events)
Mock mode decisionsService constructors read MockMode:GlobalMockEnabled; ProviderChainExecutor reads provider_configurations.mock_mode

Full Diagrams