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>
43 lines
1.2 KiB
TypeScript
43 lines
1.2 KiB
TypeScript
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),
|
|
}),
|
|
);
|