# 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, Funktion `enable_tenant_rls`) Bestehende Datenbanken aus der Certvia-Zeit sind **nicht** migrierbar — lokal neu aufsetzen: ```bash 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: 1. **Migration**: nach dem `CREATE TABLE` im selben Migrationsfile ```sql SELECT enable_tenant_rls('customers'); ``` Die Funktion ist idempotent und setzt `ENABLE ROW LEVEL SECURITY`, die Policy `tenant_isolation` (`USING` **und** `WITH CHECK` auf `tenant_id = current_setting('app.tenant_id', true)`), `FORCE ROW LEVEL SECURITY` und die GRANTs für `craftvia_app`. 2. **`TENANT_MODELS` in `src/server/db.ts`** — aktiviert den Tenant-Guard (`dbForTenant` filtert/injiziert `tenantId`, prüft Ownership bei Mutationen). 3. **`TENANT_MODELS` in `src/server/backup/topology.ts`** — Backup/Restore/DSGVO-Export. Die Liste ist bewusst dupliziert; `scripts/test-backup-isolation.ts` bzw. `scripts/test-rls-enforcement.ts` prü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 ```bash # Schema ändern, dann: npx prisma migrate dev --name --create-only # migration.sql prüfen und ggf. `SELECT enable_tenant_rls('');` anhängen npx prisma migrate dev ``` ## RLS scharf testen (lokal) ```bash 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:@:5432/craftvia?schema=public`.