- 67 Certvia-Migrationen zu prisma/migrations/0001_baseline gesquasht (prisma migrate diff --from-empty --to-schema) - RLS-Block: Rolle craftvia_app (NOLOGIN NOBYPASSRLS, idempotent), GRANTs + ALTER DEFAULT PRIVILEGES, wiederverwendbare Funktion enable_tenant_rls(tbl) (ENABLE + Policy tenant_isolation USING/WITH CHECK + FORCE + GRANT), angewendet auf alle Tenant-Tabellen (inkl. nullable tenant_id wie bisher) - docs/craftvia/MIGRATIONS.md: Pflichten für neue Tenant-Tabellen (enable_tenant_rls + beide TENANT_MODELS-Listen + PII-Felder) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2.7 KiB
Craftvia — Migrationen & Row Level Security
Ausgangslage
Die Certvia-Historie (67 Migrationen) wurde beim Rückbau zu einer Baseline gesquasht:
prisma/migrations/0001_baseline/migration.sql- DDL aus
npx prisma migrate diff --from-empty --to-schema prisma/schema.prisma --script - angehängter RLS-Block (Rolle
craftvia_app, GRANTs, Funktionenable_tenant_rls)
- DDL aus
Bestehende Datenbanken aus der Certvia-Zeit sind nicht migrierbar — lokal neu aufsetzen:
docker compose exec postgres psql -U craftvia -d postgres -c 'DROP DATABASE IF EXISTS craftvia WITH (FORCE);' -c 'CREATE DATABASE craftvia;'
npx prisma migrate deploy
npx prisma db seed
Mandantentrennung — drei Stellen, die immer zusammen gepflegt werden
Jede neue Tabelle mit tenant_id (z. B. customers, work_orders) braucht:
-
Migration: nach dem
CREATE TABLEim selben MigrationsfileSELECT enable_tenant_rls('customers');Die Funktion ist idempotent und setzt
ENABLE ROW LEVEL SECURITY, die Policytenant_isolation(USINGundWITH CHECKauftenant_id = current_setting('app.tenant_id', true)),FORCE ROW LEVEL SECURITYund die GRANTs fürcraftvia_app. -
TENANT_MODELSinsrc/server/db.ts— aktiviert den Tenant-Guard (dbForTenantfiltert/injizierttenantId, prüft Ownership bei Mutationen). -
TENANT_MODELSinsrc/server/backup/topology.ts— Backup/Restore/DSGVO-Export. Die Liste ist bewusst dupliziert;scripts/test-backup-isolation.tsbzw.scripts/test-rls-enforcement.tsprüfen Synchronität und RLS-Abdeckung gegen die DB.
Zusätzlich: Felder, die eine User.id referenzieren (Zuweisung, Freigabe, Ersteller),
in src/server/dsgvo/pii-fields.ts eintragen.
Globale Tabellen (Kataloge ohne tenant_id, z. B. künftige Materialstammdaten des
Plattformbetreibers) bekommen keine Policy und stehen in keiner TENANT_MODELS-Liste.
Nullable tenant_id
audit_logs, mail_logs und auth_tokens tragen eine nullable tenant_id
(Plattform-Ereignisse). Die Policy ist identisch; Zeilen mit NULL sind für
craftvia_app unsichtbar und werden ausschließlich über den Owner-Client geschrieben.
Neue Migration anlegen
# Schema ändern, dann:
npx prisma migrate dev --name <kurzname> --create-only
# migration.sql prüfen und ggf. `SELECT enable_tenant_rls('<tabelle>');` anhängen
npx prisma migrate dev
RLS scharf testen (lokal)
docker compose exec postgres psql -U craftvia -d craftvia \
-c "ALTER ROLE craftvia_app WITH LOGIN PASSWORD 'craftvia_app_local';"
npx tsx scripts/test-rls-enforcement.ts
Für den Betrieb mit scharfer RLS: RLS_ENFORCED=true und
RLS_DATABASE_URL=postgresql://craftvia_app:<pw>@<host>:5432/craftvia?schema=public.