Session 34: Design system Phase C — app shell, nav, routing, auth gate, footer, 404 (1818 tests)
VYNDR 2.0 conversion, Phase C (the frame every page sits inside). Frontend-only; zero backend changes. - Nav rewritten: new .wm Wordmark, mono uppercase links, More dropdown, search/ bell/read-meter/avatar, Ticker under the bar. layout main paddingTop 64 -> 96. - Routing: web/src/lib/routes.js (GATED/OPEN/HASH_ALIASES, isGatedRoute, resolveHashAlias). Client AuthGate bounces signed-out users off personal routes to /login?next=. HashRedirect maps #scan/#terminal to real routes. - Footer rewritten to system voice + Detroit signature; mounted globally in layout (removed per-page dup). - 404 converted to the north star (scanlines, crt-sweep, glitch wordmark, amber). - Stub pages for terminal/compare/invite/help/about/notifications via RouteStub. Honest reconciliations: auth gate is client-side (no auth-helpers pkg; session is client-side Supabase); GATED narrowed to protect the free-scan funnel; did not stub over existing real pages; redirect param is ?next= (what /login reads). 26 new tests. Backend 1792 -> 1818, 142 suites, zero regressions. Web build clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+90
-2
@@ -4,8 +4,96 @@
|
||||
2026-06-15
|
||||
|
||||
## Current Phase
|
||||
SHIP BUILD v33.0 — VYNDR 2.0 design system, Phase A+B: tokens + global CSS +
|
||||
fonts + glitch keyframes + shared components (Session 33)
|
||||
SHIP BUILD v34.0 — VYNDR 2.0 design system, Phase C: app shell — nav, routing,
|
||||
auth gate, footer, 404 (Session 34)
|
||||
|
||||
## Session 34 (2026-06-15) — SHIPPED
|
||||
|
||||
Phase C of the VYNDR 2.0 conversion: the app shell every page sits inside.
|
||||
Frontend-only; ZERO backend changes. Converted the nav/footer/404 to the design
|
||||
and added the routing + auth-gate frame. Backend 1792 → **1818 tests** (+26),
|
||||
142 suites, zero regressions. Web build clean (exit 0, 36 routes).
|
||||
|
||||
### Honest reconciliations (spec ↔ our reality — same discipline as the S32 NFL-key fix)
|
||||
- **Auth gate is CLIENT-side, not server middleware.** The prompt's example used
|
||||
`createMiddlewareClient` from `@supabase/auth-helpers-nextjs` — that package
|
||||
isn't installed, our auth is client-side Supabase (session in localStorage via
|
||||
`@supabase/supabase-js`), and the existing `middleware.ts` is locale-only. A
|
||||
server middleware physically can't read that session. So the gate runs in
|
||||
`<AuthGate>` (client) on top of the existing Supabase auth (rule 5 honored).
|
||||
Locale middleware left untouched.
|
||||
- **Narrowed the GATED set.** The prototype gated dashboard + scan; those are OUR
|
||||
free-scan acquisition funnel (anon/free get 5 reads), so gating them is a
|
||||
monetization regression. GATED = ledger/tracker/account/profile/settings/
|
||||
notifications/invite (genuinely personal surfaces). dashboard/scan stay OPEN.
|
||||
- **Did NOT stub over existing real pages.** The prompt's stub list assumed
|
||||
ledger/tracker/blog/game/responsible/offline didn't exist — they do, with real
|
||||
content. Stubs created ONLY for genuinely-missing routes.
|
||||
- **Redirect param is `?next=`,** not the prompt's `?redirect=` — that's the
|
||||
param our `/login` page already reads (`router.replace(next)`).
|
||||
|
||||
### C.1 — Traced the shell
|
||||
Nav used legacy `@/components/Wordmark` (`.wordmark`). Auth = `AuthContext`/
|
||||
`useAuth` (user/tier/scansRemaining/loading/signOut). `middleware.ts` = locale
|
||||
only. Footer existed but was mounted only on the landing page. 28 route pages.
|
||||
|
||||
### C.2 — Nav (`components/Nav.tsx` rewritten)
|
||||
- New `@/components/vyndr` Wordmark (size md, cursor, beta — `.wm` markup).
|
||||
- Primary links SLATE/TERMINAL/SCAN/LEDGER + a **More** dropdown (Compare,
|
||||
Tracker, The Report, Invite, Pricing, Settings). All nav chrome JetBrains Mono,
|
||||
uppercase, 11px, 0.08em; active = `--g-a`, hover `--text-0`, default `--text-1`.
|
||||
- Right cluster: `›` Query search trigger, NotificationBell (signed-in), read
|
||||
meter (`n/5 · MO`, free + scan/dashboard only) / `∞ TIER` plan badge, avatar
|
||||
menu (Account/Settings/Upgrade/Log out). Mobile toggle kept (full mobile shell
|
||||
is Session 37).
|
||||
- **Ticker** mounted under the bar (sample items; real feed = Session 38). Header
|
||||
is now a fixed wrapper = 60px nav + 32px ticker → `layout` main `paddingTop`
|
||||
64 → 96.
|
||||
|
||||
### C.3 — Routing + auth gate
|
||||
- `web/src/lib/routes.js` (CommonJS, unit-testable): `GATED_ROUTES`,
|
||||
`OPEN_ROUTES`, `HASH_ALIASES`, `isGatedRoute(path)`, `resolveHashAlias(hash)`.
|
||||
- `components/AuthGate.tsx` — waits for `loading`, then bounces signed-out users
|
||||
off gated routes to `/login?next=<path>`. Mounted around `<main>` in layout.
|
||||
- `components/vyndr/HashRedirect.tsx` — maps `#scan`/`#terminal`/… to real routes
|
||||
once on mount (keeps Next file-based routing; honors old share links). Mounted
|
||||
in layout.
|
||||
- Stub pages (design-system `RouteStub`, system language "ROUTE UNDER
|
||||
CONSTRUCTION · SESSION xx"): `/terminal`, `/compare`, `/invite`, `/help`,
|
||||
`/about`, `/notifications`.
|
||||
|
||||
### C.4 — Footer (`components/Footer.tsx` rewritten)
|
||||
System voice: Wordmark sm+beta, mono columns PRODUCT/COMPANY/LEGAL, legal/21+
|
||||
line with `--amber` 1-800-522-4700, and **BUILT BY KEVON BUTLER · DETROIT ·
|
||||
© 2026 VYNDR**. Now mounted GLOBALLY in the layout (removed the per-page import
|
||||
from the landing page to avoid a double footer).
|
||||
|
||||
### C.5 — 404 north star (`app/not-found.tsx` rewritten)
|
||||
Full-page `.scanlines`, `.crt-sweep` on load, glitch Wordmark (lg), amber-glow
|
||||
"TRANSMISSION INTERRUPTED", giant `--amber` 404 (`.wm` data-text), "This page
|
||||
doesn't exist. / The signal was lost.", VBtn CTAs (client `NotFoundActions`
|
||||
so the page stays a server component for metadata).
|
||||
|
||||
### Files created
|
||||
- `web/src/lib/routes.js`
|
||||
- `web/src/components/AuthGate.tsx`
|
||||
- `web/src/components/vyndr/{HashRedirect,NotFoundActions,RouteStub}.tsx`
|
||||
- `web/src/app/{terminal,compare,invite,help,about,notifications}/page.tsx`
|
||||
- `tests/unit/vyndrAppShell.test.js` (26 tests: routing logic, gate, nav/footer/
|
||||
404 contracts, layout wiring, stubs-don't-clobber-real-pages)
|
||||
|
||||
### Files modified
|
||||
- `web/src/components/Nav.tsx`, `web/src/components/Footer.tsx`
|
||||
- `web/src/app/layout.tsx` (mount HashRedirect + AuthGate + global Footer,
|
||||
paddingTop 96), `web/src/app/not-found.tsx`, `web/src/app/page.tsx` (drop dup
|
||||
footer)
|
||||
|
||||
### Deferred (Sessions 35+)
|
||||
- Real screens for the stubbed routes (D/E), mobile shell (F), living-layer
|
||||
ticker/heartbeat data + nav-string i18n (G). The Nav search `›` currently links
|
||||
to `/scan`; the ⌘K command palette is Phase G.
|
||||
|
||||
---
|
||||
|
||||
## Session 33 (2026-06-15) — SHIPPED
|
||||
|
||||
|
||||
Reference in New Issue
Block a user