@real-life/supabase-connector
v0.3.2
Published
Connector for a central Supabase backend (auth, rows, realtime).
Readme
@real-life/supabase-connector
Nativer Supabase-Connector: PostgREST für Queries/Writes, Supabase Realtime
(postgres_changes) für live observe() — dieselbe Reaktivität wie beim
WoT-Connector. Claim-Modus authoritative (Spec 08): das trusted-Verdikt
stützt sich auf die serverseitigen RLS-Policies in
supabase/migrations/0001_rls_schema.sql (INSERT bindet created_by an
auth.uid(), ein Trigger macht Identitätsfelder unveränderlich), nicht auf
Client-Code.
Lokal starten
Voraussetzung: Docker.
# Im Repo-Root — startet Postgres, PostgREST, GoTrue, Realtime, Studio
npx supabase startsupabase start gibt API URL, anon key und service_role key aus.
Migrationen aus supabase/migrations/ werden automatisch angewendet.
Reference-App dagegen fahren
cd apps/reference
VITE_SUPABASE_URL=http://127.0.0.1:54321 \
VITE_SUPABASE_ANON_KEY=<anon key> \
VITE_DEFAULT_CONNECTOR=supabase \
pnpm devAlternativ per URL-Param: http://localhost:5173/?connector=supabase&dev.
Die App zeigt den Anmeldebildschirm des Toolkits (E-Mail, Registrierung,
anonym); supabase-js hält die Session über Reloads.
Für einen Server: deploy/supabase/README.md. Die Einordnung, auch der
Anmeldung, steht im Handbuch unter „Ein Supabase-Backend betreiben“ und
„Identität und Anmeldung“.
Tests
- Unit-Tests (
pnpm test): laufen überall — der echte Connector gegen einen In-Memory-Fake des supabase-js-Subsets. Der Fake ist NICHT der Schiedsrichter für PostgREST-Semantik, sondern prüft Wiring: Autor-Bindung, Mapping, Realtime-Refresh, Relation-Store, Gruppen-Scoping. - Live-Contract-Suite (
tests/data-interface-contract.live.test.ts): die geteilte DataInterface-Contract-Suite plus RLS-Grenztests gegen eine echte Instanz. Ohne Env-Variablen skippt sie.
SUPABASE_URL=http://127.0.0.1:54321 \
SUPABASE_ANON_KEY=<anon key> \
SUPABASE_SERVICE_ROLE_KEY=<service_role key> \
pnpm --filter @real-life/supabase-connector testVertragsgrenzen (dokumentierte Abweichungen)
hasFieldnutztNOT data->key IS NULL: ein Feld mit explizitem JSON-nullzählt hier als abwesend, währendmatchesFilter(key in data) es als vorhanden zählt. Feldnamen sind auf[A-Za-z0-9_-]beschränkt (alles andere wirft — fail closed statt Query-Injection).getAuthMethods:anonymous,email(signInWithPassword),email-signup(signUp, optionaldisplayName).- Fixture-Pfad (
allowFixtureAuthors: true, für Tests/Tooling mit service_role-Key): behält fremde Autoren und VERLIERT dafürverifyRecordClaim— wie bei Local/Mock.
