2026-04-24 on prod (get-coffee.nixtech.app). First sub-phase of NIX-OS-69.
NIX-owned cafe.kitchen_orders table with a state machine
(new → preparing → ready → served), a per-shop
kitchen_display_secret on commerce.shops, a POS order-validate
hook that enqueues a denormalized payload after Odoo returns, and a POS TopBar ChefHat
pill showing queue depth. The visual Kitchen Display route + status-transition UI ships
in 69.2.
cafe.kitchen_orders row lands with
status='new', non-empty payload.lines[], and the NIX-stamped
order_name (POS6-NNNNN) → refresh POS shell → TopBar
ChefHat pill shows 1. No 5xx observed during the flow. Fire-and-forget
insert never blocks the cashier path.
| test-nix-os-69-1-prod.mjs — NIX-OS-69.1 Kitchen Display foundation (new) | 10/10 |
| test-phase1-prod.mjs — SSO smoke + route auth | 11/11 |
| test-phase2-sso-outdoor-prod.mjs — Outdoor SSO bridge | 6/6 |
| test-phase2-cafe-multishop-prod.mjs — Cafe multi-shop | 6/6 |
| test-m1-prod.mjs — Dashboard/Orders/Reports shop scoping | 10/10 |
| test-r1-1-cashiers-prod.mjs — R1.1 cashier PIN admin | 9/9 |
| test-r1-4-drafts-prod.mjs — R1.4 crash-recoverable drafts | 9/9 |
| test-r1-9-daily-report-prod.mjs — NIX-OS-72 Daily Sale Report | 11/11 |
| test-r1-10-cash-movements-prod.mjs — NIX-OS-71 Cash In/Out | 12/12 |
| test-r1-11-telegram-events-prod.mjs — NIX-OS-73 Telegram Events (transient) | see below |
test-r1-11-telegram-events-prod
landed 8/11, 8/11, 5/11 — all failures were Worker 503s on heavy-Odoo endpoints
(/cafe/pos, /cafe/team, /cafe/telegram) after
the Cafe Worker + Odoo got hammered by ~12 parallel/serial test suites in a row.
When isolated (like r1-9 which also 503'd once and then passed 11/11 on retry), the
route works fine. The telegram dispatcher wiring assertion itself passed on all 3 runs.
Not a 69.1 regression.
20260424100000_cafe_kitchen_orders applied via
node migrate.js against Render DB —
cafe.kitchen_orders created + commerce.shops.kitchen_display_secret
added.eda143d).af67eef (migration + migrate.js entry).lib/db/kitchen.ts —
createKitchenOrder, listActiveByShop,
countActiveByShop, getKitchenOrderById,
advanceStatus, ensureShopKitchenDisplaySecret,
getShopByKitchenSecret. All reads wrap db.transaction()
to bypass Hyperdrive's ~60s SELECT cache./api/odoo/order — accepts an
optional kitchen snapshot in the POST body and inserts a
cafe.kitchen_orders row after Odoo returns. Fire-and-forget, wrapped in
its own try/catch so a kitchen insert failure never unwinds a paid order.
POS6-NNNNN order number is visible; the kitchen_orders insert fired in the background.
router.reload(). The amber ChefHat pill in the TopBar shows 1 — that's the freshly-queued order from step 01. Count comes from countActiveByShop(tenantId, shopId) on the server component.Loading…