2026-04-22 on prod. Order numbers now follow spec §8.8 —
POS{configId}-{seq}, zero-padded, reset at midnight in the tenant's local
timezone. Atomic advance via UPSERT+RETURNING inside a transaction so concurrent cashiers
never collide. Falls back gracefully to Odoo's default name if sequencing fails, so a
flaky sequence DB can't block a sale.
get-coffee.nixtech.app/cafe/pos/register/6 printed POS06-0001 then
POS06-0002. Prod cafe.pos_sequences row below confirms
next_seq=3 after two orders (each advance is atomic).
cafe.pos_sequences✓ advance workspos_config_id | business_date | next_seq | updated_at
--------------+------------------------+----------+---------------------------
6 | 2026-04-22 (local PNH) | 3 | 2026-04-22T13:21:17.862Z
next_seq=3 means two orders were issued (1 and 2) with atomic advance. Each order's
pos.order.name and pos_reference in Odoo carry the NIX-issued
POS06-0001 / POS06-0002 — receipts print it, audit has it.
The order path was long-cold-code before R1.5 forced end-to-end exercise. Several fires revealed themselves during Gate 2 (in order of discovery):
db.execute shape mismatch — original
advanceSequence returned different shapes via pg vs Hyperdrive. Switched to
drizzle's typed insert().onConflictDoUpdate().returning(). Commit
f33453c.db.transaction() to bypass
the cache (same trick that fixed M3 and R1.1). Commit d1d5de1.sv-SE locale — Cloudflare Workers only bundle a
minimal Intl locale set. Switched businessDateForTimezone to
en-US + formatToParts. Commit 886995a.res.json()
was throwing on empty body with a cryptic parse error. Added outer try/catch on the
route (always returns JSON) + safer client-side text() + parse(). Commit
a7580f1, 0063238./api/... missing basePath (the real 405 root cause)
— fetch("/api/odoo/order") resolves to host root, bypassing the Cafe
Worker entirely and hitting the nix-router. Added /cafe prefix to all 6
client-side API fetches (register, team x3,
customer-picker x2, pos-selector x2, order-actions).
Commit dde4c60.state="none". Added
per-config fallback using current_session_state already returned by
fetchPosConfigs. Commit 886995a.cafe.sessions.beginning_cash wasn't being overlaid onto Odoo's
stale cashbox value; Odoo's read_group was flaky through Hyperdrive.
Switched sold-today to plain searchRead + client-side sum and added the
NIX cash overlay. Commit 68688e9.Takeaway: the Cafe production path through Hyperdrive is rich with surprises compared to local dev. Every new surface that touches DB-via-Hyperdrive now gets a transaction-wrap audit and a safer client JSON parser by default.