Two of Narong's relay items, built and verified on get-coffee.staging. Both follow a mockup he sent
(#67 and #68) rather than the one-line ticket.
"All Spin Chance need more details" (#67) was a request to rebuild the flat 50-row list under Loyalty Mobile App Settings → Orders & Spins into the table he mocked up: filter chips, search by ID or customer, and columns for Spin ID, POS/FD order, customer, date, status and a Void action.
The mockup shows SC-0001-style ids that don't exist in the data. Rather than a migration, the ids are
derived with row_number() over creation order — stable without a schema change,
because a spin chance is never deleted (cancelling one only changes its status). The backend also joins the member
for the customer name; filtering, search and pagination are client-side.

SC-0001…SC-0010 in creation order, customer joined, statuses chipped, Void only on the two Unclaimed rows.
Two normalisation calls, worth Narong confirming: the status enum also has claiming and
expired, which his six chips don't — claiming maps to Processing (same
phase) and expired to Cancelled (a dead chance), so every row lands under a chip. And
Void now shows only on Unclaimed/Processing (his mockup); it previously also appeared on Claimed.
The "Separate New Product & Variant Tabs" item (#68): the two stacked sections on the product editor become tabs. Product Details is active on arrival; switching hides General Information and shows Attributes & Variants, rather than both stacking on one long page.


This is the structural half of his Edit Product mockup. The rest — the Menu Display badges section, the Tracking dropdown, and the read-only Quantity-on-Hand field — needs a shared-nix-db migration and is a deliberate follow-up slice, not rushed in here.
| Suite | Result |
|---|---|
| Staging — All Spin Chances (SC-ids, customer, filter chips, search, Void visibility) | 5/5 |
| Staging — Edit Product tabs (both tabs, pane swaps) | 2/2 |
| Staging smoke | 5/5 |
tsc --noEmit (nix-cafe + nix-loyalty-backend) | clean |
Spin is a Get Coffee-only feature, so get-coffee.staging is the only tenant with spin data — this is an
internal Gate-2 surface, read-only (no Void clicks, no writes). The backend query was also proven directly against
loyalty_staging before deploy.
nix-cafe staging 6cb0d50 (Worker a40c3f64) · nix-loyalty-backend
staging 1d64649 (Fly, no migration) · localization main 0f015b8.
No migration. Parked for the scheduled prod promote.