/cafe/login placeholder PROD · GATE 2
Bug diagnosed live from a user screen-recording (2026-05-22). After an idle
period — or after our regression sweep rotated tenant_users.active_session_token
via R8.2 — clicking NIX Cafe on the Commerce launchpad bounced through
/cafe/login and landed back on the launchpad with the original
destination lost. Root cause was identified, fixed, and verified end-to-end
on prod by forcing the exact failure mode via SQL.
eec1a56. 6 files · ~25 LOC · no migration.
Middleware now injects x-nix-pathname on every passed-through
request; new loginRedirectUrl() helper in lib/auth.ts
reads it; 5 server-side callsites swapped from
redirect("/login") → redirect(await loginRedirectUrl()).
Prod test reproduces the full chain: SSO-login → SQL-rotate
active_session_token → GET /cafe/dashboard with
stale-sid cookie → assert 307 to /cafe/login?redirect=%2Fcafe%2Fdashboard
(the fix) → follow chain to Commerce login form → submit → land back on
/cafe/dashboard (full recovery).
owner@lumiere-coffee.com → mints fresh nix_session cookieUPDATE tenant_users SET active_session_token = gen_random_uuid() WHERE id = … → user's cookie sid is now stale (R8.2 invalidation simulated)GET /cafe/dashboard with stale-sid cookie → 307 to /cafe/login?redirect=%2Fcafe%2Fdashboard ← the fix; pre-fix would be bare /cafe/login with no ?redirect=/cafe/login?redirect=%2Fcafe%2Fdashboard → placeholder's useEffect forwards to /auth/login with the path preserved/auth/login?redirect=/cafe/dashboard renders the login form (H5.8 guard works given preserved path — pre-fix this is where the user got dropped on launchpad)/cafe/dashboard (full recovery — exactly where the user intended)active_session_token — no explicit DB cleanup needed (sid rotation cycles itself)| test-phase1-prod.mjs | 11/11 |
| test-phase2-sso-outdoor-prod.mjs | 6/6 |
| test-phase2-cafe-multishop-prod.mjs | 6/6 * |
| test-m1-prod.mjs | 10/10 |
| test-r7-prod.mjs | 14/14 |
| test-r8-prod.mjs | 4/4 |
* phase2-cafe-multishop first run as parallel-with-narongix-sweep failed 5/6 with "Got bounced to login" on the POS picker check — a race against whatever transient state the in-flight narongix logins were rotating. Solo re-run was 6/6 green. Not a regression from this slice — the change is server-side redirect URL plumbing only, doesn't touch any auth check that could newly reject a different tenant's session.


loginRedirectUrl() helper preserves ?redirect=%2Fcafe%2Fdashboard. The useEffect then forwards to Commerce with the same path.
?redirect=/cafe/dashboard is a sibling-product path and falls through — login form actually shows up instead of auto-bouncing to launchpad. This is the key behavior change visible to the user.
Test artifacts: result.json · login-state.json (captured user id + pre-test sid for reference)
The "click Cafe → login flash → launchpad" UX failure after R8.2 sid rotation or 30-min idle TTL is resolved. Specifically:
/cafe/login → /auth/login → form-submit chain?redirect= value — combination of the two fixes covers the full failure modeUnderlying root causes NOT addressed in this slice (deliberate — different scope):
Both are improvements for another day. The recovery UX is what users see, and it's now correct.