Replace Supabase auth with Clerk

✅ merged · #6 · zgbrenner/gary ← zgbrenner/gary · opened 7d ago by zgbrenner · merged 7d ago by zgbrenner · self · +739-1,056 across 28 files · ↗ on GitHub

From the PR description

Summary

Replaces Gary's built-in Supabase login/signup/auth flow with Clerk, so the app can run as a protected one-person web app on Vercel. The old login system is removed - there are no two competing auth systems left in the UI.

Scope is intentionally limited to authentication: no billing, organizations, RBAC, invitations, multi-tenant isolation, DB migrations, or new product features.

What changed

Clerk integration

  • Added @clerk/nextjs; bumped react/react-dom to ^19.2.3 (Clerk peer requirement). Both bun.lock and package-lock.json synced.
  • src/proxy.ts - Clerk middleware (Next.js 16 proxy.ts). Confirmed by next build as ƒ Proxy (Middleware).
  • Root layout wrapped in <ClerkProvider> inside <body>.
  • /login and /signup preserved as URLs, now catch-all routes rendering Clerk <SignIn> / <SignUp>.
  • useAuth() is now a thin Clerk-backed compatibility hook ({ user: {id,email}, isAuthenticated, authLoading, signOut }) so the ~15 consuming components needed no rewrite.
  • Sidebar account dropdown replaced with Clerk <UserButton> (with an "Account settings" link to /account).

Removed old auth

  • Deleted src/lib/supabase.ts, src/lib/auth.ts, src/app/login/page.tsx, src/app/signup/page.tsx, the AuthProvider, and the @supabase/* frontend deps.
  • All 8 backend-calling files (mikeApi.ts + 7 components/hooks) now attach the Clerk session token via a shared src/lib/apiToken.ts helper instead of supabase.auth.getSession().

Routes

  • Public: /login, /signup, static assets.
  • Protected: everything else - assistant, projects/matters, Review Tables, workflows (Saved Legal Tasks), account/settings, support.

Docs / env

  • frontend/.env.local.example, frontend/.env.vercel.example, docs/VERCEL_DEPLOYMENT.md, README.md updated with Clerk setup, env vars, and NEXT_PUBLIC_ vs secret warnings. Stale Supabase-auth wording removed.

Data scoping & backend - important

This PR is app-level protected only. Gary is effectively single-user; per-user data partitioning is not implemented here.

The separate Express backend still verifies Supabase JWTs and does not yet verify Clerk tokens. The frontend already sends the Clerk session token, so the documented follow-up is to swap the backend's requireAuth to verify Clerk JWTs. Until then, data-accessing features depend on that follow-up. This is called out in docs/VERCEL_DEPLOYMENT.md.

Env vars added

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, CLERK_SECRET_KEY, NEXT_PUBLIC_CLERK_SIGN_IN_URL, NEXT_PUBLIC_CLERK_SIGN_UP_URL, NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL, NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL.

Test plan

  • next build - passes (compiles + TypeScript clean); builds without Clerk keys (keys only needed at runtime).
  • New src/lib/clerkAuth.test.ts - 13 checks, all pass.
  • Existing test suites (branding, exportDraft, suggestedTask, matterReviewTable, builtinWorkflows) - still pass.
  • Lint - no new errors introduced (pre-existing repo lint failures unchanged).
  • Manual: sign up / sign in via Clerk, confirm protected routes redirect when signed out (requires real Clerk keys).

Recommended next PR

Update the backend requireAuth middleware to verify Clerk JWTs (via Clerk's JWKS) and map the Clerk user ID onto Gary's existing data model.

https://claude.ai/code/session_018GMAE164ehpBTxzBdsof9r


Generated by Claude Code

Our analysis

Replace Supabase auth with Clerk on Gary — read the full analysis →

Think the analysis missed something the PR description covers?

Commits in this PR (1)

SHA Subject Author Date
aa9602ce feat: replace Supabase auth with Clerk Claude 2026-05-20 ↗ GitHub
commit body
Swap Gary's built-in Supabase login/signup flow for Clerk so the app can
run as a protected one-person web app on Vercel.

- Add @clerk/nextjs; wrap the root layout in ClerkProvider
- Add Clerk middleware (proxy.ts) that protects every route except
  /login and /signup
- Render Clerk SignIn/SignUp at the existing /login and /signup URLs
- Back the useAuth() compatibility hook with Clerk instead of Supabase
- Replace the sidebar account dropdown with Clerk UserButton
- Send the Clerk session token on backend requests via a shared helper
- Remove the Supabase client, JWT helper, and @supabase/* frontend deps
- Document Clerk env vars and setup in the env examples and docs

The separate Express backend still verifies Supabase JWTs; swapping it to
verify Clerk tokens is a documented follow-up.

https://claude.ai/code/session_018GMAE164ehpBTxzBdsof9r

Capture this PR into my fork

Download a Markdown prompt that tells Claude how to port every commit in this PR into your working tree. Run it via claude -p < capture-pull-6.md from inside the repo you want the changes in.

⬇ Download capture-pull-6.md