Found on ambrosio after the first real self-registration: GoTrue v2.158.1
persists OIDC-provisioned users with empty-string role and aud. PostgREST
then dies with `role "" does not exist` on every REST call because its
per-request `SET LOCAL role = $claim` can't resolve ''. Dev never caught
this because seed.sql hardcodes both columns.
- supabase/migrations/013_auth_users_role_default.sql: backfill existing
rows + BEFORE INSERT trigger on auth.users that fills empty/NULL role +
aud with 'authenticated'. Idempotent, preserves explicit values.
- supabase/tests/008_auth_user_role_default.sql: pgTAP coverage — function
+ trigger exist, backfill left nothing empty, empty-string and NULL
values get defaulted, explicit non-empty role is preserved.
- CLAUDE.md: status line updated to 255 tests (was 248), new gotcha #19
documenting the GoTrue quirk + that users in existing sessions must
re-login once for a fresh JWT after the fix lands on any given env.
Total: 41 pgTAP (was 34) + 140 integration + 15 unit + 58 Playwright + 1
gated rate-limit. Full `just test-all` green.