Workstream 2: Datenbankschema & Migrationen (Phase 1)

Vollständiges Drizzle-Schema (alle Tabellen/Enums/Indizes aus Spec §6):
brigades, users, merkmale(+optionen), vehicle_templates(+merkmale,+aliasse),
equipment_categories(+merkmale), vehicles, equipment, merkmal_values (EAV mit
typisierten Spalten + 4 Indizes), login_attempts, audit_log. Einzige initiale
Migration 0000 (idempotent: enum-DO-Blöcke, IF NOT EXISTS), scripts/migrate.ts,
db:* npm-Scripts.

Verifiziert (offline): tsc --noEmit OK; drizzle-kit check 'Everything's fine';
Migration 7 CREATE TYPE / 14 CREATE TABLE / 17 CREATE INDEX / 32 IF NOT EXISTS.
DEFERRED (kein Postgres im Sandbox — Ursache des vorherigen Stalls): live
db:migrate und DB-abhängige Schema-Tests; laufen in CI/Deploy mit Postgres.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude
2026-06-09 08:58:56 +02:00
parent d7c74aa041
commit a9666ff96c
23 changed files with 3291 additions and 30 deletions

33
scripts/migrate.ts Normal file
View File

@@ -0,0 +1,33 @@
import { drizzle } from "drizzle-orm/node-postgres";
import { migrate } from "drizzle-orm/node-postgres/migrator";
import { Pool } from "pg";
/**
* Programmatischer Migrations-Runner.
*
* Verwendet `drizzle-orm/node-postgres/migrator` mit dem Drizzle-Journal,
* sodass mehrfaches Ausführen idempotent ist (bereits angewandte Migrationen
* werden übersprungen). Liest `DATABASE_URL` direkt aus der Umgebung, um nicht
* von der Next.js-Env-Validierung abhängig zu sein.
*/
async function main(): Promise<void> {
const connectionString = process.env.DATABASE_URL;
if (!connectionString) {
throw new Error("DATABASE_URL ist nicht gesetzt.");
}
const pool = new Pool({ connectionString, max: 1 });
const db = drizzle(pool);
try {
await migrate(db, { migrationsFolder: "./drizzle" });
console.log("Migrationen erfolgreich angewandt.");
} finally {
await pool.end();
}
}
main().catch((err: unknown) => {
console.error("Migration fehlgeschlagen:", err);
process.exit(1);
});