§10 review pass: address the architecture + product reviewers (todo §10); hide the gated Dashboard nav node from anonymous visitors in buildPluginChrome (a no-permission link to /dashboard only dead-ended them at /login) and dedup it into a shared DASHBOARD_NAV (admin-nav.ts, reused by chrome + adminNav). New chrome.signInHref bakes the current page in as return_to for the shell's anonymous Sign-in link (shell.ejs + reference overview.ejs), mirrored as optional ShellModel.signInHref so the typed builder is complete. ctx.chrome is now a lazy, memoized getter (context.ts chrome option = a factory) so a json/redirect handler or the public "/" with a standalone home never composes the global menu — app.ts passes the app-level memoized factory at every site. Default /dashboard prints a "Starter dashboard" note framing the mock-data home as a replaceable demo (signals its inert affordances); stale "until §4" comments fixed. RESERVED_PLUGIN_IDS drift-guard test derives the built-in segments from AUTH_FLOWS + ADMIN_*_BASE + host literals (home stays deliberately unreserved). Refreshed the stale plugin-contract status blurb and documented the chrome.*→partials/shell mapping. Reviewers: architecture + product APPROVE (no addressable findings remain), stability APPROVE (no Critical/High/Medium). typecheck + 356 units + visual(10) + full-flow(7) E2E green.

This commit is contained in:
2026-06-21 01:19:40 +02:00
parent 7bdeb24b7f
commit 58398481ca
17 changed files with 117 additions and 46 deletions

View File

@@ -164,7 +164,12 @@ test("the reference plugin: public Overview is open to all, the gated Shifts red
// The public overview is reachable with no session (200), not bounced to sign in.
const pub = await request.get("/scheduling", { maxRedirects: 0 });
expect(pub.status()).toBe(200);
expect(await pub.text()).toContain("Scheduling");
const body = await pub.text();
expect(body).toContain("Scheduling");
// Anonymous in the native shell (§10): the gated Dashboard link is hidden (it would only dead-end at
// /login), and the shell's Sign-in link carries the current page as return_to.
expect(body).not.toContain('href="/dashboard"');
expect(body).toContain('href="/login?return_to=%2Fscheduling"');
// The gated shifts list still bounces (don't follow — this Ory-free suite has no /login handler);
// assert the gate's 303 with the requested page preserved as return_to (§9).