07 Reference architecture
What one of these systems actually looks like.
The same six layers sit under both live systems. Reading down is the path a request takes; the four concerns underneath cut across every layer, which is why they are designed in at the start rather than added when someone asks.
L0
Client
What the user and the operator each see.
- React SPA
- Next.js (SSR)
- Operator console
L1
Edge
TLS terminates here, not inside the application.
- nginx
- TLS / certificates
- Rate limiting
- Static assets
L2
API
Identity and tenancy are resolved before any handler runs.
- ASP.NET Core 8
- JWT auth
- Tenant resolver
- Permission filter
L3
Domain
Business rules live here — not in controllers, not in the database.
- Services
- Validators
- Domain events
- Background jobs
L4
Data
Tenant scoping is enforced at the data layer, not remembered per query.
- EF Core
- PostgreSQL
- Query interceptors
- Redis cache
L5
Outbound
Every external call is treated as unreliable and replayable.
- Messaging (WhatsApp / SMS)
- OCR pipeline
- Payments
- Platform APIs
Request path — client to outbound, one direction, every layer accounted for
CCCuts across all six layers
Authentication
One identity, resolved once at the edge of the API.
Tenant isolation
Enforced in the data layer so a missed filter cannot leak.
Audit trail
Every write recorded, including who and from where.
Observability
Structured logs and health checks from the first deploy.
This is a starting point, not a template applied regardless of the problem. Layers get collapsed when a system does not need them — but the four concerns below the line stay, because retrofitting any of them into a running system is the expensive version of this conversation.