Token storage
src/lib/auth.ts keeps tokens in localStorage:
| Key | Purpose |
|---|---|
trace_access_token | Short-lived JWT access token |
trace_refresh_token | Long-lived refresh token |
BACKEND_URL resolves to process.env.NEXT_PUBLIC_BACKEND_URL || "https://api.buildwithtrace.com".
Email + password login
The login page POSTs directly to the backend, then stores the returned tokens:GitHub OAuth
handleGitHubLogin() redirects to the backend, passing a callback that tells it which
site to return to:
Authenticated requests & auto-refresh
fetchWithAuth(url, options) attaches the bearer token and, on a 401, transparently
refreshes via POST /api/v1/auth/refresh and retries once:
clearTokens() is called and the user is signed out.
Which endpoints require auth
Browse, search, semantic search, suggestions, library detail, categories, thumbnails,
download, community list, comment reads, rating reads, health.
Generate, generate/save, contribute/submit, my-symbols / my-footprints (GET/PATCH/DELETE),
posting comments, posting ratings.
Plan gating
Generation is plan-restricted on the backend. Proxy routes surface this directly:| Status | Meaning |
|---|---|
401 | Missing/expired token — sign in again |
402 / 403 | Plan/quota does not include generation (upgrade required) |
502 / 504 | Backend error / generation timeout |
402/403 and links to pricing.
