2026-05-14 Gate 2 on Supabase prod + get-coffee. First slice of the POS Section Rework arc (Narong spec items 8 & 9): the session-scoped landing-summary data layer SHIPPED. The /cafe/pos landing cards were already session-scoped — the real defect was the summary query filtering state <> 'closed', so a register whose latest session had already closed showed a blank, all-zeros card. The data layer now takes the register's latest session of any state and surfaces its closing-side metrics. Pure data-layer change — the card UI is Slice 2. No migration.
'none' + zeros. They now carry their closed session's real numbers — e.g. register cfg 4: $11.50 / 3 orders; cfg 5: $5.00, theoretical closing $5.00; cfg 7: $3.00, tc $3.00. The open register (cfg 6) shows opening cash $100, cash sales $30, tc $130.fetchSessionSummariesFromMirror covers every Pro register and carries all 6 new closing-side fields; the latest-session pick matches an independent JS fetch-all-and-pick across get-coffee's 69-session history; canary session metrics match an independent recompute straight from cafe.orders / cafe.order_payments / cafe.cash_movements./cafe/pos renders the shop-grouped register cards with no 5xx; the manager-live drawer endpoint (which consumes the same reworked buildLandingFromConfigs) responds cleanly.3459a9e — 6 files, +444/−269, no migration. New shared fetchLatestSessionSummaries helper in cafe_sessions.ts; Pro mirror + Starter landing both unified onto it; redundant open-sessions-only nixCashByConfig overlay removed.
latest-session state spread: { closed: 4, open: 1 } (69 sessions total)
register state sold orders openingCash endingCash cashSales cashIn cashOut theoreticalClosing
cfg 4 closed 11.50 3 0.00 0.00 0.00 0.00 0.00 0.00
cfg 5 closed 5.00 1 0.00 — 5.00 0.00 0.00 5.00
cfg 6 opened 13.75 2 100.00 — 30.00 0.00 0.00 130.00
cfg 7 closed 3.00 1 0.00 0.00 3.00 0.00 0.00 3.00
cfg 8 closed 0.00 0 0.00 0.00 0.00 0.00 0.00 0.00
Pre-Slice-1: cfg 4 / 5 / 7 / 8 all returned state 'none' + zeros (filtered
out by `state <> 'closed'`). Now each surfaces its closed session's real
numbers. Some closed sessions carry $0 opening/ending cash — that's
get-coffee's actual seed/test data; the probe's independent recompute
matched the helper's output for every metric, so the helper is faithfully
reporting what's in the tables.
✓ Part A — prod DAO probe ran clean against get-coffee ✓ fetchSessionSummariesFromMirror covers every Pro register + carries all new fields ✓ Latest-session pick matches an independent JS fetch-all-and-pick (real history) ✓ Canary session metrics match an independent recompute from the tables ✓ Closed-latest register surfaces real numbers, not a blank card (the bug fix, real data) ✓ Part B — SSO login to get-coffee ✓ /cafe/pos landing renders register cards on the deployed Worker (no 5xx) ✓ Manager-live drawer endpoint responds (consumes the reworked data layer)
| test-phase1-prod.mjs — route/SSO smoke | 11/11 |
| test-phase2-sso-outdoor-prod.mjs | 6/6 |
| test-phase2-cafe-multishop-prod.mjs | 6/6 |
| test-m1-prod.mjs — shop scoping | 10/10 |
| test-r7-prod.mjs — dashboard + manager-live drawer | 14/14 |
| test-r8-prod.mjs — auth/security | 4/4 |
| test-r1-2-landing-prod.mjs — POS landing | 8/8 |
nix-cafe (6 files, no migration):
lib/db/cafe_sessions.ts (+ fetchLatestSessionSummaries, computeTheoreticalClosing,
landingStateForSession, SessionSummary type)
lib/db/pos_configs.ts (fetchSessionSummariesFromMirror reworked; type extended)
lib/db/starter_landing.ts (buildStarterLanding → shared helper)
lib/db/manager_live.ts (nixCashByConfig overlay removed; cardFor extended)
lib/odoo/queries.ts (PosConfigSummary extended + placeholder defaults)
app/(authed)/pos/pos-landing.tsx (LandingConfig type extended — UI consumes in Slice 2)
Slice 1 ships the DATA. The landing card UI still renders the old 3-cell layout (Cash opening / Sold today / Opened) and shows "—" for closed registers — it doesn't read the new closing-side fields yet. Slice 2 reworks RegisterCard to the Odoo-parity layout (Opening / Closing balance, Cash + Bank balance, Sold) and makes the closed-register card show its final numbers per the locked decision. The soldToday/bankToday → sold/bank rename also rides along in Slice 2's card rework.