- fix(auth): guard extractNames() against Authentik sending full name in
given_name field (e.g. "Matthias Hochmeister" + family_name "Hochmeister");
detect by checking given_name ends with family_name suffix, fall through
to name-splitting so Vorname/Nachname display correctly in Profile
- fix(db): add migration 018 to repair broken BEFORE UPDATE triggers on
veranstaltungen and veranstaltung_kategorien; old triggers called
update_updated_at_column() which references NEW.updated_at, but both
tables use aktualisiert_am, causing every category/event edit to fail
- feat(booking): open vehicle booking creation to all authenticated users;
only dashboard_admin / dashboard_moderator can change the Buchungsart
(type select disabled for regular members); edit and cancel still
restricted to WRITE_GROUPS
- feat(vehicles): VehicleDashboardCard now fetches equipment warnings via
equipmentApi.getVehicleWarnings() in parallel and shows an alert when
any vehicle equipment is not einsatzbereit
- fix(ui): add MuiTextField defaultProps (InputLabelProps.shrink=true) and
MuiOutlinedInput notch legend font-size override to theme to eliminate
floating-label / border conflict on click
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add VehicleDashboardCard: self-contained widget modelled after
AtemschutzDashboardCard, shows einsatzbereit ratio and inspection
warnings inline; replaces StatsCard + InspectionAlerts in Dashboard
- Add EquipmentDashboardCard: consolidated equipment status widget
showing only aggregated counts (no per-item listing); replaces
EquipmentAlerts component in Dashboard
- Fix auth race condition: add authInitialized flag to api.ts so 401
responses during initial token validation no longer trigger a
spurious redirect to /login; save intended destination before login
redirect and restore it after successful auth callback
- Fix profile firstname/lastname: add extractNames() helper to
auth.controller.ts that falls back to splitting userinfo.name when
Authentik does not provide separate given_name/family_name fields;
applied on both create and update paths
- Dynamic groups endpoint: replace hardcoded KNOWN_GROUPS array in
events.controller.ts with a DB query (SELECT DISTINCT unnest
(authentik_groups) FROM users); known slugs get German labels via
lookup map, unknown slugs are humanized automatically
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>