Chapter 1 — a customer places an order and knows it was taken

As a customer I want to place an order and be told it was accepted, so that I know I will be charged for something that is actually coming.

An order that is silently dropped and an order that is quietly duplicated look identical to whoever placed it: nothing arrives, or two things do, and in both cases the shop knew and the customer did not. This flow is the moment between those two.

no

yes

exposes

tuned by

legend — shape carries the role

START / END — named in caps, so it reads in greyscale

action

sub-flow — drills down

decision

reached

REFUSED — a different shape, so it reads in greyscale

parameter — a value to discover

open unknown — a decision to take

START · somebody with a basket
and a card

ch1-1 · take the order —
what was asked for, and by whom

ch1-2
is every line
actually available?

REFUSED · said before the card is charged,
naming the line that is short

ch1-3 · charge once, and only
after the order is committed

ch1-4 · tell the customer,
with a reference they can quote

END · an order the shop can act on and
the customer can ask about

ch1-U1 what happens to a basket
abandoned mid-charge

ch1-P1 how long a reservation
is held

mermaid source for this flow
flowchart TD
    START([<b>START</b> · somebody with a basket<br/>and a card]):::terminal

    TAKE[<b>ch1-1</b> · take the order —<br/>what was asked for, and by whom]:::process
    STOCK{<b>ch1-2</b><br/>is every line<br/>actually available?}:::decision
    SHORT[/<b>REFUSED</b> · said before the card is charged,<br/>naming the line that is short/]:::bad

    CHARGE[<b>ch1-3</b> · charge once, and only<br/>after the order is committed]:::process
    TELL[<b>ch1-4</b> · tell the customer,<br/>with a reference they can quote]:::process
    DONE([<b>END</b> · an order the shop can act on and<br/>the customer can ask about]):::good

    START --> TAKE --> STOCK
    STOCK -->|no| SHORT
    STOCK -->|yes| CHARGE --> TELL --> DONE

    U1>"<b>ch1-U1</b> what happens to a basket<br/>abandoned mid-charge"]:::unknown
    P1>"<b>ch1-P1</b> how long a reservation<br/>is held"]:::parameter
    CHARGE -.exposes.-> U1
    STOCK -.tuned by.-> P1

    subgraph LEGEND["legend — shape carries the role"]
        direction LR
        LT([START / END — named in caps, so it reads in greyscale]):::terminal
        LA[action]:::process
        LS[[sub-flow — drills down]]:::subroutine
        LD{decision}:::decision
        LG([reached]):::good
        LB[/REFUSED — a different shape, so it reads in greyscale/]:::bad
        LP>parameter — a value to discover]:::parameter
        LU>open unknown — a decision to take]:::unknown
    end

    classDef terminal fill:#eef0ee,stroke:#52514e,color:#0b0b0b;
    classDef process fill:#e9eef5,stroke:#2a78d6,color:#0b0b0b;
    classDef decision fill:#e9eef5,stroke:#2a78d6,color:#0b0b0b;
    classDef subroutine fill:#e9eef5,stroke:#2a78d6,color:#0b0b0b;
    classDef good fill:#e2f2e2,stroke:#0ca30c,color:#0b0b0b;
    classDef bad fill:#f7e1e1,stroke:#d03b3b,color:#0b0b0b;
    classDef parameter fill:#f4f2ee,stroke:#8a6212,color:#0b0b0b,stroke-dasharray:2 2;
    classDef unknown fill:#f4f4f2,stroke:#898781,color:#0b0b0b,stroke-dasharray:2 2;

Elements

Defined here. The element's name is its id, and it is unique across the corpus.

Element Type Card. Domain Enforced Provenance
basket list<line> 1 at least one line yes authored
customer record 1 authored
line record 1..n per basket authored
line.quantity integer 1 per line 1 or more yes authored
order record 0..1 derived
order.reference string 1 per order unique across all orders yes generated
reservation record 0..1 per order derived
charge record 0..1 per order observed
refusal record 0..1 names one short line no derived
confirmation record 0..1 per order derived

There is no Imported. table here, and that is a fact about this example rather than an omission. This corpus is one chapter, so every element it moves is one it owns. An import names another part of this corpus — a chapter beside it, or a sibling spec the project declared — and one naming a corpus the gate cannot see resolves to nothing, which is ch15-4 with a row in front of it. goldspec/spec/'s own chapters carry real ones.

Nodes

ch1-1 · take the order

As a customer I want the shop to record what I actually chose, so that nothing is reconstructed from stock levels later and quietly changed.

In basket, line, line.quantity, customer
Held
Out order, order.reference

A basket is a customer's intent at one moment. A shop that rebuilds it at dispatch time is answering a different question from the one the customer asked.


ch1-2 · is every line actually available?

As a customer I want to be told a line is short before my card is touched, so that I am not refunding money I should never have paid.

In order, line, line.quantity
Held reservation
Out order, or refusal

The cost of getting this backwards is not symmetric. Refusing an order that could have been filled loses a sale; charging for one that cannot be filled takes money for nothing and spends the refund, the apology and the trust to put it back.

Parameter ch1-P1 — how long a reservation is held. Known to exist; the value is not. Too short and a slow card release stock somebody has already been promised; too long and a browsing customer holds stock nobody can sell. Model: the distribution of time from reservation to charge, measured over real orders, bounds it from below; the rate of stock held-and-abandoned bounds it from above.


ch1-3 · charge the card once

As a customer I want to be charged exactly once for one order, so that a retry somewhere in the shop's plumbing is not a second payment out of my account.

In order, order.reference, customer
Held
Out charge

The network between a shop and a payment processor drops responses as readily as requests, so the charge succeeded and the charge is unknown arrive as the same evidence. Idempotency is what makes the retry safe, and a retry always happens eventually.

NFR ch1-N1 — the processor's reconciliation window closes at 02:00. External, known, and restricting: a charge submitted near it may settle on either side of the boundary, so nothing here may assume same-day settlement. It is not this shop's to negotiate.


ch1-4 · tell the customer

As a customer I want a reference I can quote back, so that when I need to ask about my order there is something to ask about.

In order.reference, customer
Held
Out confirmation

A confirmation carrying no handle is a courtesy rather than a record: it cannot be searched for, cited in a complaint, or used by the shop to find the order it refers to.

Open unknowns

Glossary

Term Meaning
Basket What a customer chose, before it is an order. It has no reference and the shop owes nothing on it
Order A basket the shop has accepted responsibility for. It has a reference from the moment it exists
Short A line the shop cannot fill in the quantity asked for. Not the same as out of stock, which is a property of the item rather than of this order