Record Fase 1 design decisions before implementation

- JWT strategy: Option B (GoTrue as OIDC proxy, not direct Keycloak JWT)
- Self-registration enabled in Keycloak realm
- Multiple collectives per user with sidebar switcher
- Invitations are link-only (no email/Resend integration)
- Avatar upload uses in-browser crop (cropperjs) at 1:1 ratio
- Removed Edge Functions from plan; invitation logic handled in SvelteKit server actions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-12 14:39:11 +02:00
parent 973f9e413c
commit f197a81a42
3 changed files with 31 additions and 31 deletions

View File

@@ -97,13 +97,17 @@ The central organizing unit is the **Collective** (household group), not the ind
- Trash retains deleted items/notes for 7 days before permanent deletion.
- If the sole admin deletes their account, the system auto-promotes the oldest member before allowing deletion.
## Auth Architecture (Keycloak → Supabase)
## Auth Architecture (Keycloak → GoTrue → Supabase)
Auth flows through Keycloak as the OIDC IdP. Supabase validates Keycloak-issued JWTs. Supabase RLS uses `auth.uid()` which reads the `sub` claim from the JWT (must be a UUID v4 — Keycloak default).
**Strategy: Option B — GoTrue as OIDC proxy.**
The app authenticates with Keycloak (PKCE), then exchanges the Keycloak token with GoTrue for a Supabase JWT. Supabase RLS uses `auth.uid()` which resolves to the GoTrue user UUID (mapped from Keycloak `sub`). GoTrue maintains `auth.users`.
The Keycloak RS256 public key must be set as `JWT_SECRET` in Supabase. **Rotating Keycloak signing keys requires updating Supabase `JWT_SECRET` simultaneously.**
Key decisions:
- **Self-registration enabled** in Keycloak — users can create accounts on the Keycloak login screen.
- **Invitations are link-only** — no email sent. Admin generates a link and shares it manually.
- **Multiple collectives per user** — a user can belong to several collectives and switch between them in the sidebar.
Logout must invalidate both sides: call `keycloak.logout()` (invalidates Keycloak session) AND clear the Supabase client locally.
Logout must invalidate both sides: call `keycloak.logout()` (invalidates Keycloak session) AND clear the Supabase client session locally.
## Sync Strategy