Architecture
Commerce is one deployable: a single ASP.NET Core application containing nine domains and seven modules, over one database. There are no microservices and no message broker. That is a decision, not a stage it has not reached yet.
- Deployables 1 API, 1 migrator
- API surfaces 4, authenticated differently
- Domains 9
- Modules 7
- Databases 1, with 12 EF contexts
Commerce Core
- Commerce's own code
- Trader Core — framework, not ours
- External service
- Data
- Caller, outside Commerce
- ◆ owns a database context
Callers
Entry points — the route prefix decides the scheme, the scope and the error shape
/authCookie ⇄ Entra OIDC/api/uiCookie session · scoped/api/adminCookie + policy/api/integrationBearer JWT/api/publicAPI key · rate limitedCommerce Core
Host — the only executable in the request path
Domains — each owns a slice of the business, and its data
Modules — capabilities domains share
Cross-cutting — provided by Trader Core
External services — called out to
Data
Twelve blocks carry a ◆ — nine domains and three modules — and those are the twelve database contexts. Everything grey is framework rather than product, which is the distinction the next two sections are about.
Three rules hold it together
References point one way
Host → domain → module. Never back up, and never sideways: a domain does not reference another domain. Enforced by the project graph, so breaking it is a compile error rather than a code-review argument.
Composition happens at the edge
A basket needs pricing, tax, stock, freight and the catalogue. Rather than let one domain reach into four others, a broker in the host assembles the answer — so domains stay ignorant of each other.
Parts are discovered, not registered
Adding a domain is adding a project and a class. Startup finds it by reflection and the migrator picks up its database context through the same bootstrap. No central file to edit, so nobody collides in one.
Together these are what make a domain a unit you can clone. That is the whole productisation bet: the second client should add domains and configuration, not fork the codebase.
What is Trader Core, and what is ours
The grey blocks above. Commerce uses Trader Core as a framework but does not take all of it — each surface is an owned choice, which matters when you are reading unfamiliar code and wondering where a behaviour comes from.
| Taken from Trader Core | The module structure and discovery pattern · settings · caching · the durable event queue · background engines · key sequences · query criteria · the EF context base |
| Commerce's own | Authentication and session · the HTTP pipeline and its four surfaces · cross-domain composition · every domain model |
| Deliberately not used | The Essentials.Api meta-package, and with it Trader Core's authentication, authorization and context providers |
That last row surprises people. The host re-implements Trader Core's two bootstrapping methods itself rather than inheriting the meta-package, precisely so that authentication could be Commerce's own. It is not an oversight, and adding the meta-package back would quietly replace the auth model.
Entry points
Four API surfaces on one host — the UI API, the back office API, the integration API and
the public API — at /api/ui, /api/admin, /api/integration and /api/public, plus
/auth for sign-in. The route prefix decides everything: which scheme authenticates the caller,
whether the request is scoped to one customer, what shape responses take, and what a failure looks
like on the wire.
Only /api/ui is scoped. Everywhere else runs unscoped by design — an integration endpoint upserting
stock for every customer has no single customer to be scoped to. The same split reaches all the way
down into how queries are filtered.
→ API surfaces compares the four side by side and gives each one a page.
Go deeper
| Authentication | A cookie session in front of Entra External ID, the four schemes, and why the browser never holds a token |
| API surfaces | The four doors in, and how each behaves differently |
| Database | One database, twelve contexts, the conventions every entity inherits, and why it is not one database per domain |
| Patterns | The eleven ideas that recur, and when to reach for each |
| Decisions | What was chosen, what was rejected, and why. Planned. |