← back to index

Item #3l — POS lockdown (middleware redirect + manager-PIN override + sidebar filter)PROD

Test-Run #3 doc sub-item 3l (yellow-flagged "deal with it later"). PIN-unlocked cashier could previously escape the POS by typing /cafe/dashboard in the URL bar or clicking sidebar links — the middleware only signature-checked the JWT, never the active-cashier cookie. Now: the cashier is hard-locked to the POS surfaces (Register, Picker, Orders). Owner-operators step into the backend via a 30-min manager-PIN override (reuses tenant_users.pos_pin_hash via verifyPosPinForUser) — designed for Cambodian SME cafes where the owner routinely works the register and needs quick stock checks without closing shift. Decisions locked without Narong per his original "deal with it later" tag.

Summary

Status
16/16 prod · 51/51 regression = 67/67 · shipped
Commits
nix-cafe 007b135 + 2da5394 (basePath fix)
Files
10 modified + 4 new · ~790 LOC · no migration · reuses existing PIN infra
Architecture
Middleware redirect (Edge runtime, signature-only) + manager-override JWT cookie (30 min TTL) + nav-model lockdown filter + persistent amber banner with countdown

What ships

16/16 prod checks

Pre-flight: lumiere owner has POS PIN (seeded "1234" since absent)
SSO login on lumiere
Baseline: /cafe/dashboard renders normally before unlock (no active-cashier cookie → no lockdown)
Resolve active register's pos_config int id (1000000024 Test 1 / Lumière BKK1)
PIN-unlock as Manager via lock screen → active-cashier cookie set (actorKind="user")
Lockdown URL-bar test: page.goto(/cafe/dashboard) → middleware 302s back to /cafe/pos/register/1000000024 ← THE load-bearing test
Lockdown: /cafe/settings URL bar → same bounce
Sidebar on /cafe/pos shows POS-only items (admin labels Dashboard / Settings / Products / Customers / Inventory / Team / Reports / Finance / Configurations / Telegram / Subscription all absent)
Open ⋮ menu → Manager Mode dialog opens (testid manager-override-dialog + PIN input visible)
Wrong PIN ("0000") → error surface displays "Invalid PIN" + cookie NOT set
Correct PIN ("1234") → redirects to /cafe/dashboard → page renders → amber banner present with countdown (29-30 min left)
Override active: /cafe/settings loads normally + banner still visible
Return to POS → cookie cleared → redirected to register → banner gone
After Return to POS, lockdown is back: /cafe/dashboard bounces to register again
Close shift via SQL (cleanup) — test session marked closed
No 5xx during the suite

Screenshots (click to enlarge)

Mid-Gate-2 finds

Regression sweep — 51/51

16/16 + 51/51 = 67/67 prod tests green on the karouna-dev branch.
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

phase2-cafe-multishop ran solo (the bash parallel sub-shell dropped the backgrounded job on this run) — first-attempt green. 19th validation of feedback_phase2_cafe_multishop_solo_retry.