# 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.

```mermaid
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

- **ch1-U1 — what happens to a basket abandoned mid-charge.** The card was submitted and no response
  came back. The order is neither placed nor refused, and the customer has closed the tab. Settling
  it needs the processor's reconciliation behaviour, which nobody here has read yet. *A decision to
  take rather than a value to discover, which is why it is `U` and not `P`.*

## 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 |
