feat: vehicle/equipment type system, equipment checklist support, and checklist overview redesign

This commit is contained in:
Matthias Hochmeister
2026-03-28 17:27:01 +01:00
parent 692093cc85
commit 6b46e97eb6
25 changed files with 2230 additions and 494 deletions

View File

@@ -0,0 +1,62 @@
-- Migration 070: Ausruestung-Typen (Equipment Types)
-- Dynamic equipment type table with many-to-many junction to ausruestung.
-- Mirrors the fahrzeug_typen pattern from migration 067.
-- Seeds initial types from existing ausruestung_kategorien values.
-- ═══════════════════════════════════════════════════════════════════════════
-- 1. Ausruestung-Typen
-- ═══════════════════════════════════════════════════════════════════════════
CREATE TABLE IF NOT EXISTS ausruestung_typen (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL UNIQUE,
beschreibung TEXT,
icon VARCHAR(50),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- ═══════════════════════════════════════════════════════════════════════════
-- 2. Junction table (many-to-many)
-- ═══════════════════════════════════════════════════════════════════════════
CREATE TABLE IF NOT EXISTS ausruestung_ausruestung_typen (
ausruestung_id UUID NOT NULL REFERENCES ausruestung(id) ON DELETE CASCADE,
ausruestung_typ_id INT NOT NULL REFERENCES ausruestung_typen(id) ON DELETE CASCADE,
PRIMARY KEY (ausruestung_id, ausruestung_typ_id)
);
CREATE INDEX IF NOT EXISTS idx_aat_ausruestung_id ON ausruestung_ausruestung_typen(ausruestung_id);
CREATE INDEX IF NOT EXISTS idx_aat_typ_id ON ausruestung_ausruestung_typen(ausruestung_typ_id);
-- ═══════════════════════════════════════════════════════════════════════════
-- 3. Seed types from existing ausruestung_kategorien
-- ═══════════════════════════════════════════════════════════════════════════
INSERT INTO ausruestung_typen (name, beschreibung)
SELECT name, kurzname
FROM ausruestung_kategorien
ON CONFLICT (name) DO NOTHING;
-- Populate junction table from existing kategorie_id assignments
INSERT INTO ausruestung_ausruestung_typen (ausruestung_id, ausruestung_typ_id)
SELECT a.id, at2.id
FROM ausruestung a
JOIN ausruestung_kategorien ak ON a.kategorie_id = ak.id
JOIN ausruestung_typen at2 ON at2.name = ak.name
WHERE a.kategorie_id IS NOT NULL
AND a.deleted_at IS NULL
ON CONFLICT DO NOTHING;
-- ═══════════════════════════════════════════════════════════════════════════
-- 4. Permission for managing equipment types
-- ═══════════════════════════════════════════════════════════════════════════
INSERT INTO permissions (id, feature_group_id, label, description, sort_order) VALUES
('ausruestung:manage_types', 'ausruestung', 'Typen verwalten', 'Ausruestung-Typen erstellen und bearbeiten', 10)
ON CONFLICT (id) DO NOTHING;
-- Grant to kommando and zeugmeister
INSERT INTO group_permissions (authentik_group, permission_id) VALUES
('dashboard_kommando', 'ausruestung:manage_types'),
('dashboard_zeugmeister', 'ausruestung:manage_types')
ON CONFLICT DO NOTHING;

View File

@@ -0,0 +1,82 @@
-- Migration 071: Checklisten Equipment Extensions
-- Extends the checklist system to support equipment (Ausruestung) alongside vehicles.
-- Depends on: 068_checklisten.sql, 070_ausruestung_typen.sql
-- ═══════════════════════════════════════════════════════════════════════════
-- 1. Extend checklist_vorlagen with direct assignment columns
-- ═══════════════════════════════════════════════════════════════════════════
ALTER TABLE checklist_vorlagen
ADD COLUMN IF NOT EXISTS fahrzeug_id UUID REFERENCES fahrzeuge(id) ON DELETE SET NULL;
ALTER TABLE checklist_vorlagen
ADD COLUMN IF NOT EXISTS ausruestung_id UUID REFERENCES ausruestung(id) ON DELETE SET NULL;
ALTER TABLE checklist_vorlagen
ADD COLUMN IF NOT EXISTS ausruestung_typ_id INT REFERENCES ausruestung_typen(id) ON DELETE SET NULL;
CREATE INDEX IF NOT EXISTS idx_cv_fahrzeug_id ON checklist_vorlagen(fahrzeug_id);
CREATE INDEX IF NOT EXISTS idx_cv_ausruestung_id ON checklist_vorlagen(ausruestung_id);
CREATE INDEX IF NOT EXISTS idx_cv_ausruestung_typ_id ON checklist_vorlagen(ausruestung_typ_id);
-- ═══════════════════════════════════════════════════════════════════════════
-- 2. Extend checklist_ausfuehrungen with ausruestung support
-- ═══════════════════════════════════════════════════════════════════════════
-- Make fahrzeug_id nullable (was NOT NULL; now either fahrzeug or ausruestung)
ALTER TABLE checklist_ausfuehrungen
ALTER COLUMN fahrzeug_id DROP NOT NULL;
ALTER TABLE checklist_ausfuehrungen
ADD COLUMN IF NOT EXISTS ausruestung_id UUID REFERENCES ausruestung(id) ON DELETE SET NULL;
CREATE INDEX IF NOT EXISTS idx_ca_ausruestung_id ON checklist_ausfuehrungen(ausruestung_id);
-- ═══════════════════════════════════════════════════════════════════════════
-- 3. Extend checklist_faelligkeit with ausruestung support
-- ═══════════════════════════════════════════════════════════════════════════
-- Make fahrzeug_id nullable (was part of composite PK)
ALTER TABLE checklist_faelligkeit
DROP CONSTRAINT IF EXISTS checklist_faelligkeit_pkey;
ALTER TABLE checklist_faelligkeit
ALTER COLUMN fahrzeug_id DROP NOT NULL;
ALTER TABLE checklist_faelligkeit
ADD COLUMN IF NOT EXISTS ausruestung_id UUID REFERENCES ausruestung(id) ON DELETE CASCADE;
-- Use partial unique indexes instead of UNIQUE NULLS NOT DISTINCT (compatible with PG < 15)
CREATE UNIQUE INDEX IF NOT EXISTS idx_cf_fahrzeug_vorlage
ON checklist_faelligkeit (vorlage_id, fahrzeug_id)
WHERE fahrzeug_id IS NOT NULL AND ausruestung_id IS NULL;
CREATE UNIQUE INDEX IF NOT EXISTS idx_cf_ausruestung_vorlage
ON checklist_faelligkeit (vorlage_id, ausruestung_id)
WHERE ausruestung_id IS NOT NULL AND fahrzeug_id IS NULL;
CREATE INDEX IF NOT EXISTS idx_cf_ausruestung_id ON checklist_faelligkeit(ausruestung_id);
-- ═══════════════════════════════════════════════════════════════════════════
-- 4. Ausruestung-spezifische Checklist Items
-- ═══════════════════════════════════════════════════════════════════════════
CREATE TABLE IF NOT EXISTS ausruestung_checklist_items (
id SERIAL PRIMARY KEY,
ausruestung_id UUID NOT NULL REFERENCES ausruestung(id) ON DELETE CASCADE,
bezeichnung VARCHAR(500) NOT NULL,
beschreibung TEXT,
pflicht BOOLEAN NOT NULL DEFAULT TRUE,
sort_order INT NOT NULL DEFAULT 0,
aktiv BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_aci_ausruestung_id ON ausruestung_checklist_items(ausruestung_id);
-- ═══════════════════════════════════════════════════════════════════════════
-- 5. Extend checklist_ausfuehrung_items to reference ausruestung items
-- ═══════════════════════════════════════════════════════════════════════════
ALTER TABLE checklist_ausfuehrung_items
ADD COLUMN IF NOT EXISTS ausruestung_item_id INT REFERENCES ausruestung_checklist_items(id) ON DELETE SET NULL;