|
| 1 | +# PR_26179_OWNER_035-dev-auth-user-key-db-authority |
| 2 | + |
| 3 | +## Summary |
| 4 | + |
| 5 | +This PR makes DEV account session resolution treat the database `users` row as authoritative. |
| 6 | + |
| 7 | +Runtime sign-in now resolves a session only when the Supabase Auth user id matches `users.authProviderUserId`. Matching by email alone is not accepted for login/session resolution. Email remains valid only for the approved DEV identity sync step that locates the existing database `users` row before writing the real Supabase Auth id back to `users.authProviderUserId`. |
| 8 | + |
| 9 | +## Branch Status |
| 10 | + |
| 11 | +- Source branch: `PR_26179_OWNER_035-dev-auth-user-key-db-authority` |
| 12 | +- Base branch: `main` |
| 13 | +- Rebased onto main HEAD: `13cbe98955c1bcc014bff07480b7d3399386e72f` |
| 14 | +- Main still excludes this fix until PR merge: yes |
| 15 | + |
| 16 | +## Diagnostic Findings |
| 17 | + |
| 18 | +### Where `users.key` comes from |
| 19 | + |
| 20 | +- DEV seed setup still defines static fixture keys in `src/dev-runtime/seed/seed-db-keys.mjs` for seed/bootstrap data. |
| 21 | +- Before this PR, DEV Supabase identity sync used those seed constants as the authoritative app user keys. |
| 22 | +- After this PR, DEV sync locates existing database `users` rows by email and reads `users.key` from the database row. Missing or duplicate database rows are explicit setup errors. |
| 23 | + |
| 24 | +### Where `authProviderUserId` is populated |
| 25 | + |
| 26 | +- Account provisioning continues to write `authProviderUserId` in `src/dev-runtime/server/local-api-router.mjs` through the API/server path. |
| 27 | +- DEV identity sync reads Supabase Auth `auth.users.id`, reads the existing product `users.key` from the database row found by email, then writes the real Auth id to `users.authProviderUserId`. |
| 28 | + |
| 29 | +### Runtime resolution |
| 30 | + |
| 31 | +- Supabase sign-in/session resolution now requires an active product `users` row whose `authProviderUserId` equals the Supabase Auth user id. |
| 32 | +- If Auth succeeds but the product row is not linked, the API returns a controlled setup message directing the operator to run the approved DEV identity sync. |
| 33 | +- Runtime login no longer hardcodes DavidQ/user keys and no longer uses display name as an identity key. |
| 34 | + |
| 35 | +## Exact Fix |
| 36 | + |
| 37 | +- Removed email fallback from Supabase sign-in session resolution. |
| 38 | +- Added a Creator-safe setup failure when Auth succeeds but the matching email row has not been linked to the Auth id. |
| 39 | +- Added a narrow server-side Postgres client injection hook for tests, with default runtime behavior unchanged. |
| 40 | +- Refactored DEV creator identity sync so canonical identity definitions are email-based and database `users.key` is read from existing rows. |
| 41 | +- Changed role assignment and cleanup repair logic to derive canonical user keys from database rows. |
| 42 | +- Removed the Alfa toolbox tag/design/configuration helper behavior that upserted seed `users` rows over DEV account keys. |
| 43 | +- Changed the DEV identity sync default so existing Supabase Auth users are updated without sending a password. Password updates now require explicit `--update-passwords`. |
| 44 | +- Added regression tests for auth id matching, stale authProviderUserId handling, existing database key preservation, missing database rows, Tags API seeding not modifying `users`, and password-safe sync defaults. |
| 45 | + |
| 46 | +## Current DEV Data Note |
| 47 | + |
| 48 | +Read-only verification before packaging found: |
| 49 | + |
| 50 | +- `qbytes.dq@gmail.com` exists in Supabase Auth. |
| 51 | +- `qbytes.dq@gmail.com` is currently missing from the product `users` table. |
| 52 | +- Therefore `users.authProviderUserId` is not synced for that account yet. |
| 53 | + |
| 54 | +The mutating DEV identity sync was not run during this package/push step. Next action after this PR is merged: run the approved DEV identity sync against the current DEV database, then re-test sign-in. |
| 55 | + |
| 56 | +## Files Changed |
| 57 | + |
| 58 | +- `src/dev-runtime/server/local-api-router.mjs` - updated |
| 59 | +- `src/dev-runtime/testing/supabase-dev-creator-identity-seed-sync.mjs` - updated |
| 60 | +- `src/dev-runtime/toolbox-api/alfa-tool-services.mjs` - updated |
| 61 | +- `dev/scripts/sync-supabase-dev-creator-identities.mjs` - updated |
| 62 | +- `dev/tests/dev-runtime/SupabaseProviderContractStub.test.mjs` - updated |
| 63 | +- `dev/tests/dev-runtime/SupabaseDevCreatorIdentitySeedSync.test.mjs` - updated |
| 64 | +- `dev/tests/dev-runtime/TagsApiService.test.mjs` - updated |
| 65 | + |
| 66 | +## Validation |
| 67 | + |
| 68 | +PASS: |
| 69 | + |
| 70 | +- `git diff --check` |
| 71 | +- `npm run validate:canonical-structure` |
| 72 | +- `node --check src/dev-runtime/server/local-api-router.mjs` |
| 73 | +- `node --check src/dev-runtime/testing/supabase-dev-creator-identity-seed-sync.mjs` |
| 74 | +- `node --check src/dev-runtime/toolbox-api/alfa-tool-services.mjs` |
| 75 | +- `node --check dev/scripts/sync-supabase-dev-creator-identities.mjs` |
| 76 | +- `node --check dev/tests/dev-runtime/SupabaseProviderContractStub.test.mjs` |
| 77 | +- `node --check dev/tests/dev-runtime/SupabaseDevCreatorIdentitySeedSync.test.mjs` |
| 78 | +- `node --check dev/tests/dev-runtime/TagsApiService.test.mjs` |
| 79 | +- `node --test dev/tests/dev-runtime/SupabaseDevCreatorIdentitySeedSync.test.mjs` |
| 80 | +- `node --test --test-name-pattern "Supabase sign-in resolves|Supabase sign-in does not" dev/tests/dev-runtime/SupabaseProviderContractStub.test.mjs` |
| 81 | +- `node --test dev/tests/dev-runtime/TagsApiService.test.mjs` |
0 commit comments