- dev auth flow (side-step OAuth) - db event processing integration tests - dev scripts (eg Makefile) - db / test db migration setup scripts.
3.7 KiB
Work Summary — 2026-08-03 23:42
Task
Add a dev-only auth bypass so local testing doesn't require a real Auth0 login round-trip, per the dev-iteration plan from the previous session (see work-summary-Claude-2026-08-03-2009.md).
Context
The only way to get an authenticated session locally was to log into the real Auth0 tenant in a browser and copy the resulting access_token JWT cookie into curl commands by hand — evidenced by several one-off curl-with-pasted-cookie entries in .claude/settings.local.json. Auth is driven entirely by DB state: Identify middleware (server/auth/auth.go) looks up access_token in oauth_tokens, joined to oauth_users and accounts — there's no in-process session logic to fake, just rows to write.
Also discovered along the way: the database_migrations/ .sql files are stale relative to the live schema — migration 000016 (still on disk) references a claims JSONB NOT NULL column and a TEXT-typed id_token_custom_claims_updated_at, but the live oauth_tokens table has no claims column at all and that column is actually timestamptz. Something changed the schema by hand at some point without updating the migration files. Didn't touch this — just noted it and built against the real live schema (confirmed via psql \d oauth_tokens).
Changes
config/config.go: added optionalDevAuthEnabled bool, parsed fromDEV_AUTH_ENABLED(strconv.ParseBool; unset = false; invalid value = fail fast).domains/authentication/dev.go(new):Authenticator.DevLogin(ctx, userID, name)generates a randomdev_-prefixed token and writes realoauth_users/oauth_tokensrows (expiry set 1 year out, specifically to stay clear of the near-expiry auto-refresh path inserver/auth, since a dev token has no real Auth0 refresh token behind it). Reuses the exact same tables real login writes to, so every downstream code path (identity lookup, account linking/creation, cookie handling) treats it identically to a real session — no special-cased "is this dev" branches anywhere else in the app.server/api/auth/router.go:Routestakes a newdevAuthEnabled bool. When true, logs a loud startup warning and registersGET /api/auth/dev-login?user_id=...&name=...&target=...(all params optional; differentuser_idvalues let you test multiple accounts side by side).- Threaded
devAuthEnabledthroughserver/api/apis.go→server/server.go(NewRouter) →main.go(runServer), sourced fromcfg.DevAuthEnabled. .env/.env.example: addedDEV_AUTH_ENABLED(true in local.env, documented in.env.example).
Verification
go build ./...clean.- Full manual end-to-end run against the real local Postgres: hit
/api/auth/dev-login?user_id=dev-smoke-test&target=/ui, confirmedSet-Cookieon the response, followed up with/uiusing that cookie and got a 200 with account-appropriate content (the "no account yet" state, matching what a real first-time login produces). Verifiedoauth_users/oauth_tokensrows landed correctly viapsql, then deleted the test rows. go vet ./...shows only two pre-existing unreachable-code warnings unrelated to this change (domains/accounts/accounts.go:1472,server/sse/publisher.go:141).
Follow-ups / not done here
database_migrations/*.sqlare out of sync with the live DB schema (see Context above) — worth reconciling at some point (either a migration that documents the drift, or regenerating migrations from the live schema) sogo:generate'd diagrams and any fresh-DB setup aren't misleading.- Next planned step per the dev-iteration plan: a dev script/Makefile to bring up Postgres, run migrations, build Tailwind, and start the server in one command.