Skip to content

Phases and notes

A long scenario is easier to follow when it is broken into phases: “Record it”, “Charge the card”, “Finish”. Phases appear as numbered bands in the step list, as sections in the sequence diagram and as horizontal bands in the story view.

Scenario

The shopper pays. We write the payment down first, charge the card second, and tell the rest of the system last, so a crash never loses money.

HTTP request / responseData accessPersistent channel (websocket, gRPC)Queue / brokerDashed: planned
Loading diagram…
IRecord itbefore any money moves
1
Web app→Payments APIPOST /payments

The request carries an idempotency key, so a retry cannot charge twice.

2
Payments API→Ledger databaseINSERT payment (pending)
IICharge the card
3
Payments API→Stripecreate payment intent
4
Stripeauthorise card

This is the only step we do not control, and the slowest one.

5
Stripe→Payments APIsucceeded
IIIFinish
6
Payments API→Ledger databasemark paid
7
Payments API→RabbitMQpayment.succeeded
8
Payments API→Web app201 Created
9
RabbitMQ→Receipt mailerpayment.succeededplanned

Receipts are planned. Today the shopper only sees the on-screen confirmation.

scenarios:
pay:
title: Pay with a card
summary: |
The shopper pays. We write the payment down **first**, charge the card **second**,
and tell the rest of the system **last**, so a crash never loses money.
phases:
- title: Record it
caption: before any money moves
steps:
- web -> api:
label: POST /payments
note: The request carries an idempotency key, so a retry cannot charge twice.
- api -> db: { label: INSERT payment (pending), kind: lookup }
- title: Charge the card
steps:
- api -> stripe: create payment intent
- at stripe:
label: authorise card
note: This is the only step we do not control, and the slowest one.
- stripe -> api: succeeded

A phase has a title, an optional caption and its steps.

Field Meaning
title Required. Plain words: “Submit”, “Charge”, “Finish”.
caption A short note shown after the title: “before any money moves”.
steps Required. At least one step.

Aim for two to five phases. A scenario may use steps: or phases:. Without phases, the step list is flat and no bands are drawn.

summary is Markdown shown above the diagram when the scenario is selected. Write the story in a sentence or two, with the one fact that matters in bold. In the story view it is framed as “The story in one breath”.

note is Markdown shown under the step in the step list. Use it for the why:

- browser -> orders:
label: POST /orders
note: >
The gateway has already checked the token, so the order service
trusts the `X-User-Id` header.

Notes support emphasis, inline code, lists and links. Raw HTML is dropped. A step with a note is the right place to say what could go wrong, who owns the step, or why it is ordered the way it is.

Everything in one picture. Letters on the edges match the interfaces table underneath.

Scenario

The payment provider refuses the card. The order stays pending and the shopper is told why.

HTTP request / responseData accessPersistent channel (websocket, gRPC)Queue / brokerDashed: planned
Loading diagram…
ISubmit and charge
1
Shopper browser→order-servicevia CDN, API gatewayPOST /orders
2
order-service→PostgreSQLINSERT order (pending)
3
order-service→Stripecreate payment intent
IIDeclined
4
Stripe→order-servicecard_declined
5
order-servicemark order failed
6
order-service→Shopper browservia API gateway, CDN402 Payment Required

The response carries the decline code so the storefront can show a helpful message.

KeyFrom → ToKindAuthWhat travels
AShopper browser → CDNhttp—HTTPS
BCDN → API gatewayhttp——
CAPI gateway → Keycloakdataclient credentialssigning keys
DAPI gateway → catalog-servicehttp—/products
EAPI gateway → cart-servicehttp—/cart
FAPI gateway → order-servicehttp—/orders
Gcatalog-service → Redisdata—cache
Hcatalog-service → PostgreSQLdata——
Icart-service → Redisdata——
Jorder-service → PostgreSQLdata——
Korder-service → StripechannelAPI keypayment intent
Lorder-service → RabbitMQqueue—order.created
MRabbitMQ → notification-workerqueue——

If you do not need phases, a flat steps: list is fine. Short stories read well that way.

scenarios:
load-page:
title: Load a page
steps:
- browser -> api: GET /items
- api -> browser: 200 OK