feat(datenbank): Datenmodell mit Datenbankregeln und Seed (#003)

Alle Modelle fuer die fuenf Phasen in einer Migration, damit spaetere
Phasen keine Umbauten an Kerntabellen brauchen. Was auch an der
Service-Schicht vorbei gelten muss, steht als CHECK, partieller Index
oder Trigger in der Datenbank: Personen-Keys ohne Private Key, genau
ein Instanz-Deployment-Key, ein vertrauter Host-Key je Algorithmus,
shell-sichere Zielbenutzer und Pfade.

Das Protokoll ist append-only und per Hash-Kette verbunden; den Hash
berechnet ein Trigger, damit keine Zeile ohne Verkettung entstehen
kann (#005 baut darauf auf).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-12 09:12:06 +02:00
co-authored by Claude Opus 5.5
parent 224386106b
commit 03c7c45576
15 changed files with 1480 additions and 13 deletions
+19
View File
@@ -0,0 +1,19 @@
import { prisma } from "@/lib/db";
/**
* Leert alle Tabellen der Testdatenbank.
*
* Das Protokoll laesst sich nur leeren, weil die Sitzung `sshkv.test_modus` setzt – der
* Trigger verweigert TRUNCATE sonst (#005). Die Einstellung gilt nur fuer diese Transaktion.
*/
export async function datenbankLeeren(): Promise<void> {
const tabellen = await prisma.$queryRaw<{ tablename: string }[]>`
SELECT tablename FROM pg_tables
WHERE schemaname = 'public' AND tablename <> '_prisma_migrations'`;
if (tabellen.length === 0) return;
const liste = tabellen.map((t) => `"${t.tablename}"`).join(", ");
await prisma.$transaction([
prisma.$executeRawUnsafe(`SET LOCAL sshkv.test_modus = 'ja'`),
prisma.$executeRawUnsafe(`TRUNCATE ${liste} RESTART IDENTITY CASCADE`),
]);
}