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:
42
src/db/schema/brigades.ts
Normal file
42
src/db/schema/brigades.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import {
|
||||
pgTable,
|
||||
uuid,
|
||||
text,
|
||||
boolean,
|
||||
doublePrecision,
|
||||
timestamp,
|
||||
index,
|
||||
} from "drizzle-orm/pg-core";
|
||||
|
||||
/**
|
||||
* Feuerwehren. `lat/lng` werden aus der Adresse geokodiert (Geo-Workstream).
|
||||
* `wehrfuehrer` bewusst ASCII (keine Umlaute in JS-Property/DB-Spalte).
|
||||
*/
|
||||
export const brigades = pgTable(
|
||||
"brigades",
|
||||
{
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
name: text("name").notNull(),
|
||||
art: text("art").notNull().default("FF"),
|
||||
strasse: text("strasse"),
|
||||
plz: text("plz"),
|
||||
ort: text("ort"),
|
||||
bundesland: text("bundesland").notNull().default("Niederösterreich"),
|
||||
lat: doublePrecision("lat"),
|
||||
lng: doublePrecision("lng"),
|
||||
geocodeQuery: text("geocode_query"),
|
||||
geocodedAt: timestamp("geocoded_at", { withTimezone: true }),
|
||||
geocodeStatus: text("geocode_status"),
|
||||
funkrufnameSchema: text("funkrufname_schema"),
|
||||
wehrfuehrer: text("wehrfuehrer"),
|
||||
telefon: text("telefon"),
|
||||
email: text("email"),
|
||||
aktiv: boolean("aktiv").notNull().default(true),
|
||||
erstelltAm: timestamp("erstellt_am", { withTimezone: true })
|
||||
.notNull()
|
||||
.defaultNow(),
|
||||
},
|
||||
(t) => ({
|
||||
latlngIdx: index("brigades_latlng_idx").on(t.lat, t.lng),
|
||||
}),
|
||||
);
|
||||
Reference in New Issue
Block a user