# Domain Message Flow: [Scenario name]

> Model of one business scenario as a numbered sequence of commands,
> events and queries passing between actors, bounded contexts and external
> systems. It tests whether a proposed set of bounded contexts can carry
> the scenario with clear ownership and few, well-named messages, before
> anyone writes an API or event contract. Structure informed by the Domain
> Message Flow Modelling technique of the DDD Crew. Replace every
> `[bracketed]` value and every row marked *Example*. Worked examples use
> the invented online grocery retailer from the Context Map template
> (`architecture/context-map`).

<!--
Guidance: How to use this template
- One document per scenario. Start from a candidate set of bounded
  contexts (from an EventStorming session or a context map), list the
  scenarios worth modelling, then model the riskiest one first.
- Build the flow message by message: who starts, what they send, who
  receives it, what comes back. Number every message in the order it
  happens.
- Aim for roughly 5 to 9 messages per diagram. A longer flow is usually
  two scenarios, or a sign that a boundary is in the wrong place.
- Name the messages first and add their data afterwards if detail slows
  the group down.
- Write the result into contracts only after the flow has survived
  section 6 (design checks).
-->

| Field | Value |
|---|---|
| Scenario ID | [MF-ORDER-01] |
| Scenario | [Shopper places an order with a delivery slot] |
| Trigger | [Shopper selects "Place order"] |
| Outcome | [Order accepted, slot reserved, payment authorised, picking planned] |
| Contexts involved | [Basket and Checkout, Catalogue, Slot Booking, Payments, Fulfilment] |
| Version | [0.1] |
| Status | [Draft / Agreed / Implemented / Superseded] |
| Owner | [@domain-architect] |
| Participants | [@team-leads], [@product-owner] |
| Last updated | YYYY-MM-DD |
| Related documents | Context Map (`architecture/context-map`), Bounded Context Canvases (`architecture/bounded-context-canvas`), Event API Specification (`architecture/event-api-specification`) |

## 1. Scenario description

<!-- Guidance: Describe the scenario in business language in three to six sentences: who starts it, what they want, what must be true at the end, and what the important variations are. Pitfall: describing the technical solution instead of the business story. -->

[Scenario narrative. *Example:* A signed-in shopper with a full basket
chooses a one-hour delivery slot and places the order. Prices are fixed at
the moment of ordering. The slot must be reserved, the payment authorised (not
yet captured) and the order handed to Fulfilment so picking can be
planned. If payment is declined the slot is released and the shopper
returns to checkout.]

**Assumptions for this flow**

- *Example:* The shopper is already signed in; authentication is out of
  scope.
- *Example:* The slot was offered on the basket page a few minutes earlier
  and may have filled up since.
- [Assumption]

## 2. Participants

<!-- Guidance: List every actor, bounded context and external system that sends or receives a message. Use the same names as the context map. A participant that only appears once may belong inside another context. -->

| ID | Participant | Type | Owning team | Notes |
|---|---|---|---|---|
| P-01 | *Example:* Shopper | Human actor | n/a | Uses web or mobile app |
| P-02 | *Example:* Basket and Checkout | Bounded context | Team Checkout | Coordinates the scenario |
| P-03 | *Example:* Catalogue | Bounded context | Team Range | Owns current prices |
| P-04 | *Example:* Slot Booking | Bounded context | Team Slots | Owns slot capacity |
| P-05 | *Example:* Payments | Bounded context | Team Payments | Wraps the payment provider |
| P-06 | *Example:* Payment provider | External system | Vendor | Card authorisation |
| P-07 | *Example:* Fulfilment | Bounded context | Team Fulfilment | Plans picking |
| [P-NN] | [Name] | [Human actor / Bounded context / External system] | [Team] | [Notes] |

## 3. Message notation

<!-- Guidance: Keep the notation small and agree it before modelling. The three message types below are enough for most flows. Colours are optional; if you use sticky notes, pick one colour per type and keep it for the whole organisation. -->

| Type | Naming style | Meaning | Expected reply |
|---|---|---|---|
| Command | Imperative verb: `PlaceOrder` | Asks the receiver to do something; it may refuse | Accepted, rejected, or a later event |
| Event | Past tense: `OrderPlaced` | States a fact that has happened in the sender's context | None; receivers decide what to do |
| Query | Question form: `GetCurrentPrices` | Asks for information without changing state | The answer, treated as part of the same message |

For time-driven messages, say exactly which of these you mean: "within"
a period (a deadline), "after" a period (a delay) or "every" period (a
schedule). They lead to very different designs.

## 4. Message flow diagram

<!-- Guidance: Draw the happy path first. Each arrow is one message, labelled with its number, type and name. Arrows go from sender to receiver. Keep query replies on a dashed return arrow with the same number. The diagram must match section 5 row for row. -->

Happy path of the scenario. Solid arrows are commands and queries, dashed
arrows are events and query replies.

```mermaid
sequenceDiagram
  actor Shopper
  participant BAS as Basket and Checkout
  participant CAT as Catalogue
  participant SLOT as Slot Booking
  participant PAY as Payments
  participant PROV as Payment provider
  participant FUL as Fulfilment
  Shopper->>BAS: 1 Command PlaceOrder
  BAS->>CAT: 2 Query GetCurrentPrices
  CAT-->>BAS: 2 Reply prices
  BAS->>SLOT: 3 Command ReserveSlot
  SLOT-->>BAS: 4 Event SlotReserved
  BAS->>PAY: 5 Command AuthorisePayment
  PAY->>PROV: 6 Command CreateAuthorisation
  PAY-->>BAS: 7 Event PaymentAuthorised
  BAS-->>FUL: 8 Event OrderPlaced
  FUL-->>Shopper: 9 Event PickingPlanned (via notification)
```

## 5. Message register

<!-- Guidance: One row per numbered message. Record only the significant data: the fields the receiver needs to act, not the full payload. The owner is the context that defines the message and its schema: the receiver for commands and queries, the sender for events. -->

| No. | Type | Message | From | To | Significant data | Schema owner |
|---|---|---|---|---|---|---|
| 1 | Command | *Example:* `PlaceOrder` | Shopper | Basket and Checkout | basketId, slotId, paymentMethodToken | Basket and Checkout |
| 2 | Query | *Example:* `GetCurrentPrices` (reply: prices) | Basket and Checkout | Catalogue | productIds; reply: unit price per product, price valid-until time | Catalogue |
| 3 | Command | *Example:* `ReserveSlot` | Basket and Checkout | Slot Booking | slotId, orderId, reservation period 15 minutes | Slot Booking |
| 4 | Event | *Example:* `SlotReserved` | Slot Booking | Basket and Checkout | slotId, orderId, reservationExpiresAt | Slot Booking |
| 5 | Command | *Example:* `AuthorisePayment` | Basket and Checkout | Payments | orderId, amount, currency, paymentMethodToken | Payments |
| 6 | Command | *Example:* `CreateAuthorisation` | Payments | Payment provider | provider-specific request, built by the anticorruption layer | Payment provider |
| 7 | Event | *Example:* `PaymentAuthorised` | Payments | Basket and Checkout | orderId, authorisationId, amount | Payments |
| 8 | Event | *Example:* `OrderPlaced` | Basket and Checkout | Fulfilment | orderId, lines (productId, quantity, unit price), slotId, substitution preferences (added in v4, see MFF-02) | Basket and Checkout |
| 9 | Event | *Example:* `PickingPlanned` | Fulfilment | Shopper (via notification) | orderId, planned picking window | Fulfilment |
| [N] | [Type] | [Message] | [Sender] | [Receiver] | [Fields] | [Context] |

**Worked amount (*Example*)**: the basket holds 2 x 4.20, 1 x 12.50 and
3 x 3.15, so the goods total 8.40 + 12.50 + 9.45 = 30.35. With a delivery
fee of 4.99, message 5 carries amount 35.34 in the shop currency.

## 6. Design checks

<!-- Guidance: Walk through the flow and answer each question. A "no" usually means a boundary or a message needs to change. Record the change in section 8. -->

| Check | Question | Result | Note |
|---|---|---|---|
| DC-01 | Does every message have exactly one owning context for its schema? | [Yes / No] | *Example:* Yes |
| DC-02 | Does any context ask another for data it needs on every request (chatty queries)? | [Yes / No] | *Example:* Message 2 runs on every order; consider a price snapshot in the basket |
| DC-03 | Are commands sent only to the context that owns the decision? | [Yes / No] | *Example:* Yes |
| DC-04 | Does any context need to know the internal model of another (leaking language)? | [Yes / No] | *Example:* Message 6 hides the provider model behind Payments |
| DC-05 | Can the scenario finish if one receiver is slow or down? | [Yes / No / Partly] | *Example:* Partly: Fulfilment can consume `OrderPlaced` later, payment cannot be skipped |
| DC-06 | Is the number of messages within about 5 to 9? | [Yes / No] | *Example:* Yes, 9 |
| DC-07 | Are time-driven rules stated as within, after or every? | [Yes / No] | *Example:* Slot reservation expires 15 minutes after message 4 |
| [DC-NN] | [Question] | [Result] | [Note] |

## 7. Alternative and failure paths

<!-- Guidance: Model the variations that change the set of messages, not every error code. Number alternative messages with a suffix on the step where the flow diverges (5a, 5b). -->

| Path | Diverges at | Messages | End state |
|---|---|---|---|
| ALT-01 *Example:* Payment declined | 7 | 7a Event `PaymentDeclined` (Payments to Basket and Checkout), 7b Command `ReleaseSlot` (Basket and Checkout to Slot Booking), 7c Event `SlotReleased` (Slot Booking to Basket and Checkout) | Shopper back at checkout, no order created |
| ALT-02 *Example:* Slot filled since it was offered | 4 | 4a Event `SlotUnavailable` (Slot Booking to Basket and Checkout) | Shopper asked to choose another slot; payment not attempted |
| ALT-03 *Example:* Price changed since basket was built | 2 | No new message; Basket and Checkout shows the new total and asks the shopper to confirm | Order waits for confirmation |
| [ALT-NN] | [Step] | [Messages] | [End state] |

## 8. Findings and boundary changes

<!-- Guidance: The flow exists to improve the design. Record what it taught you: a missing context, a message in the wrong place, a context that only forwards messages. Link each change to the context map or an ADR. -->

| ID | Finding | Change | Record |
|---|---|---|---|
| MFF-01 | *Example:* Basket and Checkout orchestrates four contexts in one request | Accept for now; review if a fifth context joins the flow | ADR-042 |
| MFF-02 | *Example:* Fulfilment needs substitution preferences that are not in `OrderPlaced` v3 | Add field in `OrderPlaced` v4, owned by Team Checkout | Context Map REL-03 |
| [MFF-NN] | [Finding] | [Change] | [Link] |

## References

<!-- Guidance: Link the scenario list, the context map and the contracts that implement this flow, so the model and the code can be compared later. -->

- DDD Crew, Domain Message Flow Modelling,
  https://github.com/ddd-crew/domain-message-flow-modelling (technique,
  variants and modelling tips; checked 2026-10-30).
- Related templates: Context Map (`architecture/context-map`), Core Domain
  Chart (`architecture/core-domain-chart`), EventStorming Summary
  (`architecture/event-storming-summary`), Ubiquitous Language
  (`architecture/ubiquitous-language`), Event API Specification
  (`architecture/event-api-specification`), Event Sourcing and CQRS
  (`architecture/event-sourcing-cqrs`).

## Standard and licence note

Structure informed by the Domain Message Flow Modelling technique
published by the DDD Crew (Kacper Gunia, Zsofia Herendi, Nick Tune and
contributors, https://github.com/ddd-crew/domain-message-flow-modelling).
As checked on 2026-10-30, the repository README states CC BY 4.0 while
its licence file states CC BY-SA 4.0. This template does not copy the
technique's text or images; the notation table, checks, examples and
guidance are original to this collection and the technique is cited by
name only. Commands, events and queries are general terms of
message-based design. Template licence: MIT.
