-- 0016_services.sql -- -- Services (früher „Lieferoptionen") — admin-konfigurierbare Stammdaten plus -- Pro-Lieferung-Werte. -- -- Im alten ERPframe-Stand kamen die Optionen datengetrieben pro Lieferung -- (key/display/numerical/value). Neu: der Administrator pflegt die Definitionen -- frei (anlegen/ändern/löschen, Muster wie payment_methods), der Fahrer wählt -- sie in Phase 4 pro Lieferung aus (Checkbox bzw. Zahl mit min/max). CREATE TABLE services ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Stabiler Programm-Identifier (z. B. "podium_setup"). Eindeutig. key TEXT NOT NULL UNIQUE, -- Anzeige-Name in der UI (z. B. "Podest aufgestellt"). Frei änderbar. name TEXT NOT NULL, -- 'boolean' → Checkbox, 'numeric' → Zahlenfeld mit min/max. kind TEXT NOT NULL CHECK (kind IN ('boolean', 'numeric')), -- Nur für numeric relevant; bei boolean NULL. min_value INT, max_value INT, -- Soft-Delete: deaktivierte Services bleiben für historische Lieferungen -- referenzierbar, tauchen aber im Default-Listing nicht auf. active BOOLEAN NOT NULL DEFAULT TRUE, -- Anzeige-Reihenfolge in Phase 4. sort_order INT NOT NULL DEFAULT 0, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), -- boolean trägt keine Grenzen; numeric darf welche haben. CONSTRAINT services_bounds_kind CHECK ( (kind = 'boolean' AND min_value IS NULL AND max_value IS NULL) OR kind = 'numeric' ), -- Falls beide gesetzt: min ≤ max. CONSTRAINT services_min_le_max CHECK ( min_value IS NULL OR max_value IS NULL OR min_value <= max_value ) ); -- Initialer Stamm (deterministische UUIDs für stabile Seeds/Tests). Der -- Administrator kann sie jederzeit ändern/deaktivieren/ergänzen. INSERT INTO services (id, key, name, kind, min_value, max_value, sort_order) VALUES ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa01', 'podium_setup', 'Podest aufgestellt', 'boolean', NULL, NULL, 1), ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa02', 'old_appliance_taken', 'Altgerät mitgenommen', 'boolean', NULL, NULL, 2), ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa03', 'commissioning', 'Inbetriebnahme', 'boolean', NULL, NULL, 3), ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa04', 'floor', 'Stockwerk', 'numeric', 0, 20, 4); -- Pro-Lieferung gewählter Wert eines Service. Genau eine Zeile je -- (Lieferung, Service) — Upsert. `bool_value` für boolean, `numeric_value` -- für numeric (Use Case stellt sicher, dass nur das passende Feld gesetzt ist). CREATE TABLE delivery_services ( delivery_id UUID NOT NULL REFERENCES deliveries(id) ON DELETE CASCADE, -- RESTRICT: ein referenzierter Service darf nicht hart gelöscht werden -- (sonst verlöre die Lieferung ihren Wert) — stattdessen deaktivieren. service_id UUID NOT NULL REFERENCES services(id) ON DELETE RESTRICT, bool_value BOOLEAN, numeric_value INT, author_personalnummer BIGINT, author_car_id UUID, updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), PRIMARY KEY (delivery_id, service_id) ); CREATE INDEX delivery_services_delivery ON delivery_services (delivery_id);