Files
Holzleitner---Backend--aktu…/migrations/0016_services.sql
Dennis Nemec 6a9b5872e1 Backend-Arbeitsstand: ERP-Sync, Lieferlebenszyklus, Reports + config.toml
Bringt das Backend vom initialen Skeleton auf den aktuellen Arbeitsstand
(Clean Architecture: domain → application → infrastructure → api).

Wesentliche Bereiche:
- ERP-Anbindung (MSSQL-Pull der Touren, Import-Scheduler, Rückschreiben)
- Lieferlebenszyklus: Scan/Hold/Cancel/Complete, Gutschriften, Notizen,
  Bild-Anhänge, Unterschriften, PDF-Lieferreport → DOCUframe
- Stammdaten: Kunden, Artikel, Lager, Zahlungsarten, Services
- Keycloak-JWT-Gate + Fahrer-Provisionierung via Admin-API
- Admin-API-Key-Gate (X-Admin-Api-Key) für Maschinen-Endpunkte

Jüngste Änderungen dieser Session:
- Belegspezifische Kontaktdaten: alle ERP-Adressen (Beleg-/Liefer-/
  Rechnungsadresse, Ansprechpartner, Kundenstamm) mit Telefon/Mobil/
  E-Mail werden gesynct (Migration 0029, MSSQL-Query, TourDetails)
- Konfiguration von .env (envy/dotenvy) auf config.toml (toml/serde)
  umgestellt; Vorlage config.example.toml, Pfad via HOLZLEITNER_CONFIG

Nicht im Repo (per .gitignore): config.toml (Secrets), data/ (Laufzeit-/
Kundendaten), demo.mp4, .claude/, variocontrol-ai/.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 17:52:58 +02:00

66 lines
3.2 KiB
SQL

-- 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);