# ADR 0004 — Order-edit concurrency without a schema change

- Status: accepted
- Date: 2026-10-20

## Context

Three parties can act on one pending Child Order at the same moment: the customer
(editing), the seller (confirming on the WhatsApp action page, the seller panel or the
seller app) and staff (admin quantity / remove screens, Confirm Orders, payment). The
seller's WhatsApp "Accept" page re-reads the order live on submit, so a seller can
confirm a basket the customer changed after the page was opened. The owner asked for no
database change.

## Decision

1. **Re-check under a lock.** The customer's save locks the `orders` row
   (`SELECT … FOR UPDATE`) and checks "Editable" (ADR 0001) again inside the transaction.
   If the seller answered, staff confirmed or a payment landed meanwhile, nothing changes
   and the customer is told why.
2. **Basket fingerprint.** A hash of the Child Order's lines (id, variation, quantity),
   computed on the fly, sent with the edit form and compared on save. A mismatch (for
   example an admin edit in between) refuses the save and reloads the current basket.
3. **The seller confirms what they saw.** The seller's WhatsApp action page and the
   seller web panel send the fingerprint of the basket they showed; if the customer
   changed it since, the confirm is refused with "The customer changed this order,
   check it again". The seller app sends no fingerprint until the app is updated, so
   there the seller confirms the live basket (accepted risk).

No column or table is added: the lock is on an existing row and the fingerprint is never
stored.

## Consequences

- Any new screen that confirms or edits a Child Order's basket should send and check the
  fingerprint.
- The seller-app gap closes only when the app sends the fingerprint (an optional new
  request field; old app builds keep working).
