← Back to gallery

U8 — Thermal Shift Report PROD

2026-05-27 Gate 2 ship. Item #13 on Narong's test-run Notion doc: "Print Shift Report from POS interface → Receipt Printer". Narrow 80mm thermal-receipt summary distinct from U7's A4 PDF. Prints via HTML iframe + window.print() — same path as order receipts, so the existing thermal-driver setup transfers and any future native-shell wrapper can intercept for silent print.

Summary

Status
9/9 prod · 51/51 regression · 60/60 total · awaiting Gate 2 approval
Commits
nix-outdoor-sales-backend 1fb3e36 · nix-cafe daad45d + fix 7a1162e + empty-retrigger 6ea7462
Files
1 new migration · 9 nix-cafe (4 new + 5 modified) · ~750 LOC net
Migration
Added cafe.sessions.shift_number INTEGER + backfill via ROW_NUMBER() OVER (PARTITION BY pos_config_id ORDER BY opened_at, id) + supporting index. Prod backfill: demo 4/4, get-coffee 72/72, lumiere 408/408 — 100% coverage.
Source
Notion: #13 on the 5-22-2026 Test-Run doc. Single spec image showing the receipt layout.

What shipped

Data layer

Builder + component + renderer + route

UI surfaces — 3 mounts (per scope decision)

End-to-end verification on prod (lumiere-coffee)

Test ran against closed session b967eb21 on shop Lumière BKK1, register Test 1, shift #30 under tenant Lumière Coffee Roasters:

9/9 prod checks

Prod: cafe.sessions.shift_number column exists
Prod: shift_number backfilled across all 3 tenants — demo 4/4, get-coffee 72/72, lumiere 408/408
Find a closed lumiere session w/ orders + branch + POS metadata — b967eb21, shift #30, "Lumière BKK1" / "Test 1"
SSO-login lumiere owner
Fetch shift-report HTML — 200 status, text/html, > 800 bytes
HTML contains title + section headings + store/POS metadata (20 expected strings)
HTML wrapped in @page 80mm thermal envelope
Gross sales + cash payments in HTML match raw prod SQL: gross=$3.00 cash=$0.00
No 5xx HTTP responses during the suite

Real rendered shift report from prod

Fetched live from lumiere-coffee.nixtech.app/cafe/api/cafe/sessions/b967eb21-…/shift-report via authenticated GET. Opens inline below or in a new tab.

Regression sweep 51/51

51/51 regression checks green — no regressions from this push.
test-phase1-prod.mjs11/11
test-phase2-sso-outdoor-prod.mjs6/6
test-m1-prod.mjs10/10
test-r7-prod.mjs14/14
test-r8-prod.mjs4/4
test-phase2-cafe-multishop-prod.mjs (solo)6/6

narongix chain ran sequentially, first-attempt green. phase2-cafe-multishop ran solo per feedback_phase2_cafe_multishop_solo_retry — first-attempt green (11th validation today).

Mid-Gate-2 finds