Opening
$100
2026-05-14 Gate 1 local. Second slice of the POS Section Rework arc (Narong spec item 8): the landing card UI rework. Slice 1 made the data layer surface the register's latest session of any state with all the closing-side metrics; Slice 2 redesigns RegisterCard on /cafe/pos to the Odoo-parity layout that consumes them, and renames the misleading soldToday/bankToday fields to sold/bank across the data layer. No migration.
soldToday → sold, bankToday → bank across all 3 summary types + 3 builders + the manager-live drawer (the names were misleading — the values were always session-scoped, never "today"). New closedAt field added to the landing types for the "Closed {date}" line.This mock mirrors the exact structure the test asserted against the react-dom/server output. Real Tailwind-styled screenshots come at Gate 2 on prod — /cafe/pos is an authed route that needs the full SSO stack to render locally, so per the established Cafe-UI workflow Gate 1 is typecheck + component-render assertions, Gate 2 is the visual pass.
✓ PosLanding renders via react-dom/server for all 3 states (no thrown error)
✓ Open card — 4-slot layout: Opening · Cash Balance · Bank Balance · Sold
✓ Open card — 'Open' state + 'Continue Selling' CTA
✓ Closed card — slot 1 flips to 'Closing' with the counted ending cash
✓ Closed card — 'Closed' state + 'Open Register' CTA
✓ No-session card — empty state, no metric grid, 'Open Register' CTA
✓ Card stays clickable — pos-register-{id} testid preserved (r1-2-landing depends on it)
The test renders directly with synthetic LandingConfig data
covering each state, then asserts the rendered HTML. (Raw rendered card
HTML for each state is saved alongside this page: 02-card-open.html /
03-card-closed.html / 04-card-none.html.)
nix-cafe:
app/(authed)/pos/pos-landing.tsx RegisterCard redesigned (4-slot adaptive
+ CTA); LandingConfig renamed + closedAt
app/(authed)/pos/loading.tsx skeleton updated to the 2x2 card shape
components/manager-live-control.tsx soldToday/bankToday → sold/bank
lib/db/pos_configs.ts MirrorPosConfigSummary rename + closedAt
lib/db/manager_live.ts cardFor rename + closedAt
lib/db/starter_landing.ts buildStarterLanding rename + closedAt
lib/odoo/queries.ts PosConfigSummary rename + closedAt
1 commit to nix-cafe (7 files, no migration) → push → CF deploy.
Prod test on get-coffee + lumiere-coffee:
• /cafe/pos renders the new 4-slot cards — Playwright screenshots of
both tenants for the visual pass
• get-coffee has 4 registers on a closed latest session — assert their
cards show the closed snapshot (Closing + Cash/Bank/Sold + "Closed
{date}" + Open Register CTA), and the 1 open register shows the live
layout + Continue Selling
• manager-live drawer still renders (rename consumer)
• 59/59 regression sweep — r1-2-landing + r7 are the in-blast-radius
suites
Note: the manager-live drawer card keeps its compact 3-cell design — it's
a different surface (R7), out of Slice 2's scope. It only took the field
rename. Reworking it (or un-muting closed-session stats now that they're
real) is a possible follow-up.