feat: checklist multi-type assignments, tab layouts for Fahrzeuge/Ausruestung, admin cleanup

- Migration 074: convert checklist vorlage single FK fields to junction tables
  (vorlage_fahrzeug_typen, vorlage_fahrzeuge, vorlage_ausruestung_typen, vorlage_ausruestungen)
- Backend checklist service: multi-type create/update/query with array fields
- Backend cleanup service: add checklist-history and reset-checklist-history targets
- Frontend types/service: singular FK fields replaced with arrays (fahrzeug_typ_ids, etc.)
- Frontend Checklisten.tsx: multi-select Autocomplete pickers for all assignment types
- Fahrzeuge.tsx/Ausruestung.tsx: add tab layout (Uebersicht + Einstellungen), inline type CRUD
- FahrzeugEinstellungen/AusruestungEinstellungen: replaced with redirects to tab URLs
- Sidebar: add Uebersicht sub-items, update Einstellungen paths to tab URLs
- DataManagementTab: add checklist-history cleanup and reset sections

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Matthias Hochmeister
2026-03-28 18:57:46 +01:00
parent 893fbe43a0
commit 4349de9bc9
14 changed files with 1078 additions and 1188 deletions

View File

@@ -0,0 +1,70 @@
-- Migration 074: Checklist multi-type assignment (junction tables)
-- Replaces single FK columns with M:N junction tables
-- 1. Create junction tables
CREATE TABLE IF NOT EXISTS checklist_vorlage_fahrzeug_typen (
vorlage_id INTEGER NOT NULL REFERENCES checklist_vorlagen(id) ON DELETE CASCADE,
fahrzeug_typ_id INTEGER NOT NULL REFERENCES fahrzeug_typen(id) ON DELETE CASCADE,
PRIMARY KEY (vorlage_id, fahrzeug_typ_id)
);
CREATE TABLE IF NOT EXISTS checklist_vorlage_fahrzeuge (
vorlage_id INTEGER NOT NULL REFERENCES checklist_vorlagen(id) ON DELETE CASCADE,
fahrzeug_id UUID NOT NULL REFERENCES fahrzeuge(id) ON DELETE CASCADE,
PRIMARY KEY (vorlage_id, fahrzeug_id)
);
CREATE TABLE IF NOT EXISTS checklist_vorlage_ausruestung_typen (
vorlage_id INTEGER NOT NULL REFERENCES checklist_vorlagen(id) ON DELETE CASCADE,
ausruestung_typ_id INTEGER NOT NULL REFERENCES ausruestung_typen(id) ON DELETE CASCADE,
PRIMARY KEY (vorlage_id, ausruestung_typ_id)
);
CREATE TABLE IF NOT EXISTS checklist_vorlage_ausruestung (
vorlage_id INTEGER NOT NULL REFERENCES checklist_vorlagen(id) ON DELETE CASCADE,
ausruestung_id UUID NOT NULL REFERENCES ausruestung(id) ON DELETE CASCADE,
PRIMARY KEY (vorlage_id, ausruestung_id)
);
-- 2. Migrate existing single-FK data into junction tables
-- (only if the old columns exist — safe with DO $$ blocks)
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='checklist_vorlagen' AND column_name='fahrzeug_typ_id') THEN
INSERT INTO checklist_vorlage_fahrzeug_typen (vorlage_id, fahrzeug_typ_id)
SELECT id, fahrzeug_typ_id FROM checklist_vorlagen WHERE fahrzeug_typ_id IS NOT NULL
ON CONFLICT DO NOTHING;
END IF;
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='checklist_vorlagen' AND column_name='fahrzeug_id') THEN
INSERT INTO checklist_vorlage_fahrzeuge (vorlage_id, fahrzeug_id)
SELECT id, fahrzeug_id FROM checklist_vorlagen WHERE fahrzeug_id IS NOT NULL
ON CONFLICT DO NOTHING;
END IF;
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='checklist_vorlagen' AND column_name='ausruestung_typ_id') THEN
INSERT INTO checklist_vorlage_ausruestung_typen (vorlage_id, ausruestung_typ_id)
SELECT id, ausruestung_typ_id FROM checklist_vorlagen WHERE ausruestung_typ_id IS NOT NULL
ON CONFLICT DO NOTHING;
END IF;
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='checklist_vorlagen' AND column_name='ausruestung_id') THEN
INSERT INTO checklist_vorlage_ausruestung (vorlage_id, ausruestung_id)
SELECT id, ausruestung_id FROM checklist_vorlagen WHERE ausruestung_id IS NOT NULL
ON CONFLICT DO NOTHING;
END IF;
END $$;
-- 3. Drop old FK columns (use DO $$ for safety)
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='checklist_vorlagen' AND column_name='fahrzeug_typ_id') THEN
ALTER TABLE checklist_vorlagen DROP COLUMN fahrzeug_typ_id;
END IF;
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='checklist_vorlagen' AND column_name='fahrzeug_id') THEN
ALTER TABLE checklist_vorlagen DROP COLUMN fahrzeug_id;
END IF;
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='checklist_vorlagen' AND column_name='ausruestung_typ_id') THEN
ALTER TABLE checklist_vorlagen DROP COLUMN ausruestung_typ_id;
END IF;
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='checklist_vorlagen' AND column_name='ausruestung_id') THEN
ALTER TABLE checklist_vorlagen DROP COLUMN ausruestung_id;
END IF;
END $$;