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:
187
drizzle/0000_opposite_santa_claus.sql
Normal file
187
drizzle/0000_opposite_santa_claus.sql
Normal file
@@ -0,0 +1,187 @@
|
||||
DO $$ BEGIN CREATE TYPE "public"."asset_status" AS ENUM('einsatzbereit', 'wartung', 'ausser_dienst'); EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN CREATE TYPE "public"."auth_typ" AS ENUM('authentik', 'local'); EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN CREATE TYPE "public"."entity_typ" AS ENUM('vehicle', 'equipment'); EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN CREATE TYPE "public"."geltungsbereich" AS ENUM('vehicle', 'equipment', 'both'); EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN CREATE TYPE "public"."merkmal_status" AS ENUM('active', 'proposed'); EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN CREATE TYPE "public"."merkmal_typ" AS ENUM('number', 'enum', 'boolean', 'text'); EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN CREATE TYPE "public"."role" AS ENUM('platform_admin', 'wehr_admin', 'wehr_read'); EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "brigades" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"art" text DEFAULT 'FF' NOT NULL,
|
||||
"strasse" text,
|
||||
"plz" text,
|
||||
"ort" text,
|
||||
"bundesland" text DEFAULT 'Niederösterreich' NOT NULL,
|
||||
"lat" double precision,
|
||||
"lng" double precision,
|
||||
"geocode_query" text,
|
||||
"geocoded_at" timestamp with time zone,
|
||||
"geocode_status" text,
|
||||
"funkrufname_schema" text,
|
||||
"wehrfuehrer" text,
|
||||
"telefon" text,
|
||||
"email" text,
|
||||
"aktiv" boolean DEFAULT true NOT NULL,
|
||||
"erstellt_am" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "users" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"brigade_id" uuid,
|
||||
"rolle" "role" NOT NULL,
|
||||
"auth_typ" "auth_typ" NOT NULL,
|
||||
"email" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"passwort_hash" text,
|
||||
"aktiv" boolean DEFAULT true NOT NULL,
|
||||
"erstellt_von" uuid,
|
||||
"erstellt_am" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
CONSTRAINT "users_email_uq" UNIQUE("email")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "merkmal_optionen" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"merkmal_id" uuid NOT NULL,
|
||||
"wert" text NOT NULL,
|
||||
"label" text NOT NULL,
|
||||
"reihenfolge" integer DEFAULT 0 NOT NULL,
|
||||
CONSTRAINT "merkmal_optionen_uq" UNIQUE("merkmal_id","wert")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "merkmale" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"slug" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"typ" "merkmal_typ" NOT NULL,
|
||||
"einheit" text,
|
||||
"geltungsbereich" "geltungsbereich" NOT NULL,
|
||||
"status" "merkmal_status" DEFAULT 'proposed' NOT NULL,
|
||||
"vorgeschlagen_von_brigade_id" uuid,
|
||||
"erstellt_am" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
CONSTRAINT "merkmale_slug_uq" UNIQUE("slug")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "vehicle_template_aliasse" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"template_id" uuid NOT NULL,
|
||||
"alias" text NOT NULL,
|
||||
"bestaetigt" boolean DEFAULT false NOT NULL,
|
||||
CONSTRAINT "vehicle_template_aliasse_uq" UNIQUE("template_id","alias")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "vehicle_template_merkmale" (
|
||||
"template_id" uuid NOT NULL,
|
||||
"merkmal_id" uuid NOT NULL,
|
||||
"vorgabewert_num" double precision,
|
||||
"vorgabewert_text" text,
|
||||
"vorgabewert_bool" boolean,
|
||||
"pflicht" boolean DEFAULT false NOT NULL,
|
||||
"reihenfolge" integer DEFAULT 0 NOT NULL,
|
||||
CONSTRAINT "vehicle_template_merkmale_template_id_merkmal_id_pk" PRIMARY KEY("template_id","merkmal_id")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "vehicle_templates" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"code" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"beschreibung" text,
|
||||
"reihenfolge" integer DEFAULT 0 NOT NULL,
|
||||
CONSTRAINT "vehicle_templates_code_uq" UNIQUE("code")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "equipment_categories" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"reihenfolge" integer DEFAULT 0 NOT NULL,
|
||||
CONSTRAINT "equipment_categories_name_uq" UNIQUE("name")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "equipment_category_merkmale" (
|
||||
"category_id" uuid NOT NULL,
|
||||
"merkmal_id" uuid NOT NULL,
|
||||
"reihenfolge" integer DEFAULT 0 NOT NULL,
|
||||
CONSTRAINT "equipment_category_merkmale_category_id_merkmal_id_pk" PRIMARY KEY("category_id","merkmal_id")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "equipment" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"brigade_id" uuid NOT NULL,
|
||||
"category_id" uuid NOT NULL,
|
||||
"vehicle_id" uuid,
|
||||
"name" text NOT NULL,
|
||||
"status" "asset_status" DEFAULT 'einsatzbereit' NOT NULL,
|
||||
"erstellt_am" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "vehicles" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"brigade_id" uuid NOT NULL,
|
||||
"template_id" uuid,
|
||||
"name" text NOT NULL,
|
||||
"funkrufname" text,
|
||||
"status" "asset_status" DEFAULT 'einsatzbereit' NOT NULL,
|
||||
"notiz" text,
|
||||
"erstellt_am" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "merkmal_values" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"merkmal_id" uuid NOT NULL,
|
||||
"entity_typ" "entity_typ" NOT NULL,
|
||||
"entity_id" uuid NOT NULL,
|
||||
"value_num" double precision,
|
||||
"value_text" text,
|
||||
"value_bool" boolean
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "login_attempts" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"key" text NOT NULL,
|
||||
"erfolg" boolean NOT NULL,
|
||||
"zeitpunkt" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "audit_log" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"actor_user_id" uuid,
|
||||
"aktion" text NOT NULL,
|
||||
"ziel_typ" text,
|
||||
"ziel_id" uuid,
|
||||
"details" jsonb,
|
||||
"zeitpunkt" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN ALTER TABLE "users" ADD CONSTRAINT "users_brigade_id_brigades_id_fk" FOREIGN KEY ("brigade_id") REFERENCES "public"."brigades"("id") ON DELETE restrict ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN ALTER TABLE "merkmal_optionen" ADD CONSTRAINT "merkmal_optionen_merkmal_id_merkmale_id_fk" FOREIGN KEY ("merkmal_id") REFERENCES "public"."merkmale"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN ALTER TABLE "merkmale" ADD CONSTRAINT "merkmale_vorgeschlagen_von_brigade_id_brigades_id_fk" FOREIGN KEY ("vorgeschlagen_von_brigade_id") REFERENCES "public"."brigades"("id") ON DELETE set null ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN ALTER TABLE "vehicle_template_aliasse" ADD CONSTRAINT "vehicle_template_aliasse_template_id_vehicle_templates_id_fk" FOREIGN KEY ("template_id") REFERENCES "public"."vehicle_templates"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN ALTER TABLE "vehicle_template_merkmale" ADD CONSTRAINT "vehicle_template_merkmale_template_id_vehicle_templates_id_fk" FOREIGN KEY ("template_id") REFERENCES "public"."vehicle_templates"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN ALTER TABLE "vehicle_template_merkmale" ADD CONSTRAINT "vehicle_template_merkmale_merkmal_id_merkmale_id_fk" FOREIGN KEY ("merkmal_id") REFERENCES "public"."merkmale"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN ALTER TABLE "equipment_category_merkmale" ADD CONSTRAINT "equipment_category_merkmale_category_id_equipment_categories_id_fk" FOREIGN KEY ("category_id") REFERENCES "public"."equipment_categories"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN ALTER TABLE "equipment_category_merkmale" ADD CONSTRAINT "equipment_category_merkmale_merkmal_id_merkmale_id_fk" FOREIGN KEY ("merkmal_id") REFERENCES "public"."merkmale"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN ALTER TABLE "equipment" ADD CONSTRAINT "equipment_brigade_id_brigades_id_fk" FOREIGN KEY ("brigade_id") REFERENCES "public"."brigades"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN ALTER TABLE "equipment" ADD CONSTRAINT "equipment_category_id_equipment_categories_id_fk" FOREIGN KEY ("category_id") REFERENCES "public"."equipment_categories"("id") ON DELETE restrict ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN ALTER TABLE "equipment" ADD CONSTRAINT "equipment_vehicle_id_vehicles_id_fk" FOREIGN KEY ("vehicle_id") REFERENCES "public"."vehicles"("id") ON DELETE set null ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN ALTER TABLE "vehicles" ADD CONSTRAINT "vehicles_brigade_id_brigades_id_fk" FOREIGN KEY ("brigade_id") REFERENCES "public"."brigades"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN ALTER TABLE "vehicles" ADD CONSTRAINT "vehicles_template_id_vehicle_templates_id_fk" FOREIGN KEY ("template_id") REFERENCES "public"."vehicle_templates"("id") ON DELETE set null ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN ALTER TABLE "merkmal_values" ADD CONSTRAINT "merkmal_values_merkmal_id_merkmale_id_fk" FOREIGN KEY ("merkmal_id") REFERENCES "public"."merkmale"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
DO $$ BEGIN ALTER TABLE "audit_log" ADD CONSTRAINT "audit_log_actor_user_id_users_id_fk" FOREIGN KEY ("actor_user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$;--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "brigades_latlng_idx" ON "brigades" USING btree ("lat","lng");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "merkmal_optionen_merkmal_idx" ON "merkmal_optionen" USING btree ("merkmal_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "merkmale_status_idx" ON "merkmale" USING btree ("status");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "merkmale_active_name_uq" ON "merkmale" USING btree ("name") WHERE "merkmale"."status" = 'active';--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "vtm_merkmal_idx" ON "vehicle_template_merkmale" USING btree ("merkmal_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "ecm_merkmal_idx" ON "equipment_category_merkmale" USING btree ("merkmal_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "equipment_brigade_idx" ON "equipment" USING btree ("brigade_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "equipment_category_idx" ON "equipment" USING btree ("category_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "equipment_vehicle_idx" ON "equipment" USING btree ("vehicle_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "vehicles_brigade_idx" ON "vehicles" USING btree ("brigade_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "vehicles_template_idx" ON "vehicles" USING btree ("template_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "mv_merkmal_num_idx" ON "merkmal_values" USING btree ("merkmal_id","value_num");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "mv_merkmal_bool_idx" ON "merkmal_values" USING btree ("merkmal_id","value_bool");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "mv_merkmal_text_idx" ON "merkmal_values" USING btree ("merkmal_id","value_text");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "mv_entity_idx" ON "merkmal_values" USING btree ("entity_typ","entity_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "login_attempts_key_zeit_idx" ON "login_attempts" USING btree ("key","zeitpunkt");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "audit_log_zeitpunkt_idx" ON "audit_log" USING btree ("zeitpunkt");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "audit_log_aktion_idx" ON "audit_log" USING btree ("aktion");
|
||||
1474
drizzle/meta/0000_snapshot.json
Normal file
1474
drizzle/meta/0000_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
13
drizzle/meta/_journal.json
Normal file
13
drizzle/meta/_journal.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"entries": [
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "7",
|
||||
"when": 1780936243787,
|
||||
"tag": "0000_opposite_santa_claus",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user