feat: personal equipment tracking, order assignment, purge fix, widget consolidation
- Migration 084: new persoenliche_ausruestung table with catalog link, user assignment, soft delete; adds zuweisung_typ/ausruestung_id/persoenlich_id columns to ausruestung_anfrage_positionen; seeds feature group + 5 permissions - Fix user data purge: table was shop_anfragen, renamed to ausruestung_anfragen in mig 046 — caused full transaction rollback. Also keep mitglieder_profile row but NULL FDISK-synced fields (dienstgrad, geburtsdatum, etc.) instead of deleting the profile - Personal equipment CRUD: backend service/controller/routes at /api/persoenliche-ausruestung; frontend page with DataTable, user filter, catalog Autocomplete, FAB create dialog; widget in Status group; sidebar entry (Checkroom icon); card in MitgliedDetail Tab 0 - Ausruestungsanfrage item assignment: when a request reaches erledigt, auto-opens ItemAssignmentDialog listing all delivered positions; each item can be assigned as general equipment (vehicle/storage), personal item (user, prefilled with requester), or not tracked; POST /requests/:id/assign backend - StatCard refactored to use WidgetCard as outer shell for consistent header styling across all dashboard widget templates Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
-- Migration: 084_persoenliche_ausruestung
|
||||
-- Creates persoenliche_ausruestung table, adds assignment columns to
|
||||
-- ausruestung_anfrage_positionen, and seeds feature_group + permissions.
|
||||
|
||||
-- 1. Create persoenliche_ausruestung table
|
||||
CREATE TABLE IF NOT EXISTS persoenliche_ausruestung (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
bezeichnung TEXT NOT NULL,
|
||||
kategorie TEXT,
|
||||
artikel_id INT REFERENCES ausruestung_artikel(id) ON DELETE SET NULL,
|
||||
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
benutzer_name TEXT,
|
||||
groesse TEXT,
|
||||
seriennummer TEXT,
|
||||
inventarnummer TEXT,
|
||||
anschaffung_datum DATE,
|
||||
zustand TEXT DEFAULT 'gut' CHECK (zustand IN ('gut','beschaedigt','abgaengig','verloren')),
|
||||
notizen TEXT,
|
||||
anfrage_id INT REFERENCES ausruestung_anfragen(id) ON DELETE SET NULL,
|
||||
anfrage_position_id INT REFERENCES ausruestung_anfrage_positionen(id) ON DELETE SET NULL,
|
||||
erstellt_von UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
erstellt_am TIMESTAMPTZ DEFAULT NOW(),
|
||||
aktualisiert_am TIMESTAMPTZ DEFAULT NOW(),
|
||||
geloescht_am TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_persoenliche_ausruestung_user
|
||||
ON persoenliche_ausruestung(user_id) WHERE geloescht_am IS NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_persoenliche_ausruestung_artikel
|
||||
ON persoenliche_ausruestung(artikel_id);
|
||||
|
||||
-- Auto-update aktualisiert_am trigger (uses the aktualisiert_am variant from migration 018)
|
||||
CREATE TRIGGER trg_persoenliche_ausruestung_aktualisiert_am
|
||||
BEFORE UPDATE ON persoenliche_ausruestung
|
||||
FOR EACH ROW EXECUTE FUNCTION update_aktualisiert_am_column();
|
||||
|
||||
-- 2. Add assignment columns to ausruestung_anfrage_positionen
|
||||
ALTER TABLE ausruestung_anfrage_positionen
|
||||
ADD COLUMN IF NOT EXISTS zuweisung_typ TEXT CHECK (zuweisung_typ IN ('ausruestung','persoenlich','keine'));
|
||||
|
||||
ALTER TABLE ausruestung_anfrage_positionen
|
||||
ADD COLUMN IF NOT EXISTS zuweisung_ausruestung_id UUID REFERENCES ausruestung(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE ausruestung_anfrage_positionen
|
||||
ADD COLUMN IF NOT EXISTS zuweisung_persoenlich_id UUID REFERENCES persoenliche_ausruestung(id) ON DELETE SET NULL;
|
||||
|
||||
-- 3. Feature group + permissions
|
||||
INSERT INTO feature_groups (id, name, maintenance_mode)
|
||||
VALUES ('persoenliche_ausruestung', 'Persönliche Ausrüstung', false)
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO permissions (id, feature_group_id, description) VALUES
|
||||
('persoenliche_ausruestung:view', 'persoenliche_ausruestung', 'Eigene persönliche Ausrüstung anzeigen'),
|
||||
('persoenliche_ausruestung:view_all', 'persoenliche_ausruestung', 'Alle persönliche Ausrüstung anzeigen'),
|
||||
('persoenliche_ausruestung:create', 'persoenliche_ausruestung', 'Persönliche Ausrüstung erstellen'),
|
||||
('persoenliche_ausruestung:edit', 'persoenliche_ausruestung', 'Persönliche Ausrüstung bearbeiten'),
|
||||
('persoenliche_ausruestung:delete', 'persoenliche_ausruestung', 'Persönliche Ausrüstung löschen')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- Seed permissions for groups: admin, kommandant, gruppenkommandant, zeugmeister get all; others get view only
|
||||
INSERT INTO group_permissions (group_name, permission_id)
|
||||
SELECT g.name, p.id
|
||||
FROM (VALUES
|
||||
('dashboard_admin'),
|
||||
('dashboard_kommandant'),
|
||||
('dashboard_gruppenkommandant'),
|
||||
('dashboard_zeugmeister')
|
||||
) AS g(name)
|
||||
CROSS JOIN permissions p
|
||||
WHERE p.feature_group_id = 'persoenliche_ausruestung'
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- All other groups get view only
|
||||
INSERT INTO group_permissions (group_name, permission_id)
|
||||
SELECT g.name, 'persoenliche_ausruestung:view'
|
||||
FROM (VALUES
|
||||
('dashboard_feuerwehrmitglied'),
|
||||
('dashboard_atemschutztraeger'),
|
||||
('dashboard_fahrmeister'),
|
||||
('dashboard_jugend')
|
||||
) AS g(name)
|
||||
ON CONFLICT DO NOTHING;
|
||||
Reference in New Issue
Block a user