← All tests

POS Section Rework — Slice 2 (local)

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.

7/7 local component-render test PASS. nix-cafe typechecks clean. No migration. 7 files touched.

Card states — structure rendered by the Gate 1 test

Open Reg
Open
Started May 14 · 9:02 AM
Opening
$100
Cash Balance
$287.50
Bank Balance
$137.50
Sold
$287.50
Continue Selling
Closed Reg
Closed
Closed May 10
Closing
$312.25
Cash Balance
$308.50
Bank Balance
$20
Sold
$64.25
Open Register
Fresh Reg
No sessions yet
 
No sessions yet — open the register to start one.
Open Register
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.

Local component-render test — 7/7

✓ 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.)

Files touched — 7, no migration

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

Gate 2 plan

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.