Domain Documentation
Living documentation generated from the Koine model. Each bounded context has its own page with the ubiquitous language, aggregates, and Mermaid diagrams of its lifecycles.
Bounded Contexts
Section titled “Bounded Contexts”- Delivery — version 1 — Delivery bounded context — getting a delivery order to the customer’s door. It owns the
Addressvalue object (supplied downstream to nobody else here, but a customer-supplier candidate) and enforces the rule that anchors this context: a delivery order must carry a delivery address. - Kitchen — version 1 — Kitchen bounded context — turning a placed order into a cooked pizza. It watches the orders Ordering publishes and runs each one through the kitchen workflow: a ticket is queued, prepped, baked, and put up on the pass. Kept in its own context so “how the kitchen cooks” evolves independently of “how an order is taken”.
- Menu — version 2 — Menu bounded context — the catalogue of pizzas, sizes and toppings the pizzeria sells. It is the upstream that publishes the ubiquitous language of money and toppings; Ordering shares its
Currencyas a shared kernel and conforms to itsToppingweight (see context-map.koi). Version 2 of the published model: akcalnutrition field was added in v2, demonstrating contract evolution with@since. - Ordering — version 1 — Ordering bounded context — taking and pricing a customer’s pizza order. This is the heart of the template: the
Salesaggregate (rootOrder) is the headline aggregate, its lifecycle is an explicit state machine, it is priced from its line items, and it publishesOrderPlacedso Kitchen, Delivery and Payment can react. - Payment — version 1 — Payment bounded context — charging the customer for an order and keeping the books. It is downstream of a third-party card gateway whose model we do NOT control, so it shields itself with an anti-corruption layer: the raw gateway result is translated into our own
PaymentReceipt(the acl block lives in context-map.koi). Two aggregates — Billing and Ledger — exercise a multi- aggregate context with a cross-aggregate policy. Naming note: the root entity isCharge, deliberately NOTPayment. A C# type must not share its enclosing namespace’s name, and this context emits into aPaymentnamespace; an entity calledPaymentwould collide with it, exactly as the demo avoided by pairing aPaymentscontext with aPaymententity. - Gateway — version 1 — Gateway bounded context — the external card processor whose model we do not control. Payment never references this directly; it goes through the generated anti-corruption translator interface (see the acl block in context-map.koi).
- Promotions — version 1 — Promotions bounded context — the deals and discounts the pizzeria runs. It owns the rule that anchors this context: a discount can lower an order’s total, but it can never drive that total below zero. The rule is enforced as an invariant on a
Discountvalue object, exposed as a reusable spec, and computed by a pure domain operation.
Strategic Views
Section titled “Strategic Views”- Context Map — the strategic relationships between contexts
- Integration Events — cross-context published-language flows