Skip to content

Commit 5eee9bd

Browse files
authored
Merge pull request #10 from parva3105/chore/sync-memory-pre-m3
chore: sync memory logs — pre-M3 fixes
2 parents c905bbd + 0ec4782 commit 5eee9bd

4 files changed

Lines changed: 92 additions & 5 deletions

File tree

.claude/memory/decisions.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ The following were evaluated and explicitly excluded from MVP. Do not reopen wit
161161

162162
---
163163

164+
## 2026-03-19 — jsdom version pinned to v24 for Node 20.11.1 compatibility ⚠️ SUPERSEDED
164165
## 2026-03-19 — Landing page auth redirect (server-side)
165166
**Decision**: auth() + redirect() in the Server Component at app/page.tsx.
166167
**Reason**: Keeps proxy.ts free of per-page logic. Server Component redirect is instant — no client-side flash.
@@ -183,3 +184,36 @@ The following were evaluated and explicitly excluded from MVP. Do not reopen wit
183184
**Decision**: Downgraded jsdom from v29 (installed by default) to v24 in devDependencies.
184185
**Reason**: jsdom v29 requires Node >=20.19.0; the project runs on Node 20.11.1. v24 is compatible and supports all required testing features.
185186
**Alternatives considered**: Upgrade Node (blocked — system constraint); skip component tests in jsdom (violates TDD mandate).
187+
**SUPERSEDED BY**: "happy-dom for all vitest environments" decision below — jsdom was later abandoned entirely in favour of happy-dom due to a transitive ESM conflict.
188+
189+
---
190+
191+
## 2026-03-19 — happy-dom for all vitest environments
192+
**Decision**: All vitest `environmentMatchGlobs` entries use `"happy-dom"` instead of `"jsdom"`.
193+
**Reason**: `jsdom@29` (installed as transitive dep despite the v24 pin) pulls in `html-encoding-sniffer@6` which does a synchronous `require()` of `@exodus/bytes` (pure-ESM only). This crashes the jsdom environment with an unhandled error that exits vitest with code 1 even when all tests pass — failing CI. `happy-dom` (already installed) has no such transitive dependency and is fully compatible with all existing tests.
194+
**Effect**: Both `components/__tests__/**/*.test.tsx` and `app/**/*.test.tsx` use `happy-dom`. 100/100 tests pass, zero unhandled errors.
195+
196+
---
197+
198+
## 2026-03-19 — Proxy loop guard for stale JWT
199+
**Decision**: In `proxy.ts`, before redirecting to `/signup/complete` when `role` is missing, check `req.nextUrl.pathname === "/signup/complete"` and return early if true.
200+
**Reason**: When the Clerk session token claim (`{{ user.public_metadata }}`) is not configured in the Clerk dashboard, or when a JWT was issued before a role was assigned, `sessionClaims.metadata.role` is undefined. Without the guard, the proxy redirects to `/signup/complete` even when the user is already there — causing a visible redirect loop. The `/signup/complete` page handles staleness client-side via `session.reload()`.
201+
**Constraint**: Never call external APIs from `proxy.ts` (it is Next.js middleware running on the edge). The guard is a pure pathname check with no I/O.
202+
203+
---
204+
205+
## 2026-03-19 — Landing page auth redirect (server-side)
206+
**Decision**: Authenticated user redirect on `/` handled via `auth()` + `redirect()` inside the Server Component (`app/page.tsx`), not in `proxy.ts`.
207+
**Reason**: Keeps proxy.ts free of per-page redirect logic. Server Component redirect is synchronous and instant — no client-side flash. Role read from `(sessionClaims?.metadata as { role?: string })?.role`.
208+
209+
---
210+
211+
## 2026-03-19 — /signup hash detection for Clerk SSO compatibility
212+
**Decision**: `/signup/page.tsx` reads `window.location.hash` on mount to decide between showing the role picker (direct visit) or `<SignUp>` (Clerk SSO multi-step flow).
213+
**Reason**: Clerk SSO flows (Google, phone verification) redirect back to `/signup` with a hash fragment (`#/continue`, `#/factor-one`). Detecting the hash on one route preserves SSO compatibility without adding a new route. Direct visits (no hash) show the pre-auth role picker.
214+
215+
---
216+
217+
## 2026-03-19 — Button asChild not available; use Link + buttonVariants()
218+
**Decision**: For anchor-styled buttons (links that look like buttons), use `Link` from `next/link` with `buttonVariants()` class applied directly — not `<Button asChild>`.
219+
**Reason**: The project's `components/ui/button.tsx` wraps `@base-ui/react/button`, which does not expose a Radix-style `asChild` prop. Applying `buttonVariants()` to a `Link` achieves the same visual result without the prop.

.claude/memory/iterations.md

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,40 @@ _Append only. One entry per session or PR. Never delete._
217217

218218
---
219219

220-
## 2026-03-19 — fix/pre-m3-proxy-loop
221-
- Added /signup/complete loop guard to proxy.ts to prevent redirect loop on stale JWT
222-
- When authenticated user has no role claim in JWT and is already on /signup/complete, proxy now returns immediately instead of redirecting again
220+
## 2026-03-19 — fix/pre-m3-proxy-loop (PR #8)
221+
**Type**: Bug fix
222+
**Branch**: fix/pre-m3-proxy-loop
223+
**What changed**:
224+
- `proxy.ts` — added one-line loop guard: when an authenticated user has no role claim in their JWT and is already on `/signup/complete`, proxy returns immediately instead of redirecting again
225+
- Prevents the infinite redirect loop that occurs when the Clerk JWT is stale (role claim not yet in token)
226+
- JWT staleness is handled client-side by `session.reload()` in `/signup/complete` — proxy just stays out of the way
227+
- `npm run typecheck` → zero errors ✅
228+
- `npm run lint` → zero errors ✅
229+
**PR**: https://github.com/parva3105/projectAlpha/pull/8
230+
231+
---
232+
233+
## 2026-03-19 — fix/pre-m3-landing-auth (PR #9)
234+
**Type**: Feature + Bug fix
235+
**Branch**: fix/pre-m3-landing-auth
236+
**What changed**:
237+
- `app/page.tsx` — replaced Next.js scaffold with branded landing page (Server Component); server-side auth redirect via `auth()` + `redirect()`; hero + 3 benefit blocks + 3 role cards; dark surface, Geist Sans, shadcn/ui Card + buttonVariants
238+
- `app/(public)/signup/page.tsx` — replaced bare `<SignUp>` with `'use client'` role picker + Clerk SSO fallback; detects Clerk SSO flows via `window.location.hash` on mount (hash present = Clerk driving; no hash = role picker)
239+
- `components/auth/signup-role-picker.tsx` — pre-auth role selection (Agency / Creator / Brand) with shadcn/ui Cards and correct hrefs; Server Component
240+
- `components/auth/auth-layout.tsx` — shared two-panel auth layout Server Component (branded left panel hidden on mobile via `hidden md:flex`, Clerk right panel)
241+
- `app/(public)/login/[[...rest]]/page.tsx` — wrapped in AuthLayout; forceRedirectUrl unchanged
242+
- `app/(public)/signup/agency/[[...rest]]/page.tsx` — wrapped in AuthLayout; forceRedirectUrl unchanged
243+
- `app/(public)/signup/creator/[[...rest]]/page.tsx` — wrapped in AuthLayout; forceRedirectUrl unchanged
244+
- `app/(public)/signup/brand/[[...rest]]/page.tsx` — wrapped in AuthLayout; forceRedirectUrl unchanged
245+
- `app/page.test.tsx` — 9 vitest tests for landing page
246+
- `components/__tests__/auth-layout.test.tsx` — 3 vitest tests for AuthLayout
247+
- `components/__tests__/signup-role-picker.test.tsx` — 3 vitest tests for SignupRolePicker
248+
- `vitest.config.ts` — switched `app/**/*.test.tsx` and `components/__tests__/**/*.test.tsx` to `happy-dom` (from `jsdom`) to resolve CJS/ESM crash from `html-encoding-sniffer` v6 in jsdom v29
249+
- All 100 tests pass ✅ (zero unhandled errors)
250+
- `npm run typecheck` → zero errors ✅
251+
- `npm run lint` → zero errors ✅
252+
- `npm run build` → success ✅
253+
**PR**: https://github.com/parva3105/projectAlpha/pull/9
223254

224255
---
225256

@@ -236,3 +267,13 @@ _Append only. One entry per session or PR. Never delete._
236267
- Fix applied to all branches: postinstall: "prisma generate" for Vercel build compatibility
237268
- Total: 76 tests across 4 PRs, all passing
238269
- All 13 M2 tasks delivered
270+
271+
---
272+
273+
## 2026-03-19 — CI fixes: test regex + vitest env (PR #9 follow-up)
274+
**Type**: Bug fix
275+
**Branch**: fix/pre-m3-landing-auth (commits 467669f, e579c71)
276+
**What changed**:
277+
- `app/page.test.tsx` line 70: tightened regex from `/get started/i` to `/^get started$/i` — the broad regex matched all 4 "Get started" links on the landing page causing `getByRole` to throw "Found multiple elements"
278+
- `vitest.config.ts`: switched `components/__tests__/**/*.test.tsx` from `jsdom` to `happy-dom` to eliminate 5 unhandled errors from `html-encoding-sniffer` v6's synchronous `require()` of `@exodus/bytes` (pure-ESM); both globs now use `happy-dom`
279+
- All 100 tests pass, zero unhandled errors, CI green

.claude/memory/memory.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22
_Last updated: 2026-03-19_
33

44
## Current state
5-
- Status: **M2 COMPLETE** ✅ — Ready to begin M3
6-
- Active milestone: M3 — Creator Portal + Content Approval (next)
5+
- Status: **M2 COMPLETE** ✅ — Pre-M3 fixes in progress (2 PRs open)
6+
- Active milestone: Pre-M3 fixes → then M3 — Creator Portal + Content Approval
7+
8+
## Pre-M3 fixes in progress — 2 PRs open
9+
- **PR #8** `fix/pre-m3-proxy-loop` — proxy.ts redirect loop guard (stale JWT)
10+
- **PR #9** `fix/pre-m3-landing-auth` — landing page + /signup role picker + branded auth layouts
11+
- ⚠️ Both PRs must be merged AND the Clerk dashboard step completed before M3 begins
712
- Production URL: https://project-alpha-rho.vercel.app (deployed, all env vars baked in)
813
- Vercel Root Directory: blank (repo root) — confirmed correct
914
- GitHub repo: https://github.com/parva3105/projectAlpha

.claude/memory/roadmap.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ M8 (Polish) ← depends on all milestones complete
3535

3636
---
3737

38+
## Pre-M3 — Regression fixes (2026-03-19)
39+
- [🔄 PR Open] **PR #8** `fix/pre-m3-proxy-loop` — proxy.ts redirect loop guard for stale JWT
40+
- [🔄 PR Open] **PR #9** `fix/pre-m3-landing-auth` — landing page, /signup role picker, branded auth layouts
41+
- ⚠️ REQUIRED MANUAL STEP: Clerk dashboard → Configure → Sessions → Customize session token → add `{ "metadata": "{{user.public_metadata}}" }` → Save
42+
43+
---
44+
3845
## Pre-M1 — Completed refactors
3946
- Completed pre-M2 refactor: app lifted to repo root (refactor/lift-to-root PR)
4047

0 commit comments

Comments
 (0)