100 Commits
Author SHA1 Message Date
patrickandClaude Sonnet 5 c47fd022c6 fix(dashboard): Standard-Raster auf 16:9-Monitore ausgelegt
CI / backend-tests (push) Successful in 4m17s
CI / frontend-build (push) Successful in 30s
3 gleich breite Spalten (8/24) statt vorher 16+8-Split und 12-Restzeile -
Gesamthöhe von 23 auf 15 Zeilen reduziert, passt auf einem 16:9-Bildschirm
ohne vertikales Scrollen. Speicher-Key auf v4 angehoben, damit auch
bestehende Browser-Layouts das neue Standard-Raster bekommen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-10-13 14:43:56 +02:00
patrickandClaude Sonnet 5 9ea1271583 fix(scripts): seed_jahr.py weitere Namenskollisionen mit seed_monat.py (login, Objekt-Code)
CI / backend-tests (push) Successful in 4m10s
CI / frontend-build (push) Successful in 25s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-10-13 14:25:29 +02:00
patrickandClaude Sonnet 5 e5d8f86ccc fix(scripts): seed_jahr.py Standort-Namenskollision mit seed_monat.py behoben
CI / backend-tests (push) Successful in 4m19s
CI / frontend-build (push) Successful in 25s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-10-13 14:24:54 +02:00
patrickandClaude Sonnet 5 83bbf98b65 chore(scripts): seed_jahr.py - Jahr Fuhrpark-Nutzung mit km-/zeitbasierten Wartungsintervallen
CI / backend-tests (push) Successful in 4m35s
CI / frontend-build (push) Successful in 27s
Ergänzt seed_monat.py: Wartungsplan/Wartungsintervall statt nur Ad-hoc-
Wartungsaufträge, wachsender Kilometerstand je Fahrzeug über 365 Tage,
automatisch ausgelöste Inspektion (15.000 km) und HU/UVV (12 Monate).
Nur für die separate Test-Instanz, kein Produktionsbezug.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-10-13 14:24:33 +02:00
patrickandClaude Sonnet 5 ed88fa585f chore(scripts): seed_monat.py für simulierte Monatsnutzung (Testdaten, GUI-Review)
CI / backend-tests (push) Successful in 4m9s
CI / frontend-build (push) Successful in 27s
Legt synthetische Benutzer/Standorte/Objekte an und simuliert 30 Tage
Kontrollen/Mängel/Wartung/Verleih/Lagerbewegungen. Nur für die separate
Test-Instanz gedacht (eigene DB, kein Produktionsbezug).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-10-13 12:11:43 +02:00
patrickandClaude Sonnet 5 a4d4119d55 feat(auth): FOUND-016 API-Token für Entwicklungs-/Tooling-Zugriff
CI / backend-tests (push) Successful in 3m57s
CI / frontend-build (push) Successful in 24s
Rollenbasiertes, langlebiges Token neben dem normalen JWT-Login-Flow -
für automatisierte Zugriffe/Skripte. Admin wählt bei Erzeugung eine oder
mehrere Rollen, Klartext wird einmalig gezeigt (wie ein Passwort), Token
ist jederzeit deaktivierbar/reaktivierbar.

Architektur: jedes Token bekommt einen Begleit-"Dienstkonto"-Benutzer
(Benutzer.ist_dienstkonto=True, kein echter Login), der die Rollen über
die bestehende benutzer_rolle-Tabelle trägt - dadurch funktionieren
require_roles()/require_permission() und alle Audit-FKs unverändert,
keine bestehende Endpunkt-Dependency musste angepasst werden.
get_current_user() erkennt ein Token am Präfix mabea_pat_ und löst es
über den Hash (SHA-256, kein bcrypt - Token ist bereits hochentropisch)
auf den Begleit-Benutzer auf. Dienstkonten sind aus GET /benutzer
ausgeblendet, damit sie keine Auswahl-Dropdowns verunreinigen.

Neuer Admin-Tab "API-Tokens" (Gruppe System, nur Administration).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-17 01:23:21 +02:00
patrickandClaude Sonnet 5 dabe0dbe0c fix(lager): fehlenden Import standort_fuer_lagerort ergänzt
CI / backend-tests (push) Successful in 3m42s
CI / frontend-build (push) Successful in 20s
CI-Fund: NameError beim Testlauf - standort_fuer_lagerort() wird in
liste_lagerorte() (Runde 7) verwendet, war aber nicht importiert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-15 00:40:25 +02:00
patrickandClaude Sonnet 5 260e0f6133 fix(zustaendigkeit): ZUST-004 Runde 7 - Lagerort-Lücken aus Runde 5 geschlossen
CI / backend-tests (push) Failing after 3m47s
CI / frontend-build (push) Failing after 1m2s
GET /lagerorte war entgegen /lagerplaetze nicht standortgefiltert - Nutzer-
Review deckte das auf. Zusätzlich: standort_id konnte bisher an jedem
Lagerort-Typ gesetzt werden, nur dokumentiert als "nur bei typ=standort
sinnvoll". Jetzt harte 409-Validierung bei POST und PATCH (PATCH prüft die
resultierende Typ/standort_id-Kombination, nicht nur einzeln übergebene
Felder).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-15 00:33:10 +02:00
patrickandClaude Sonnet 5 b68314a06d feat(zustaendigkeit): ZUST-004 Runde 6 - kennzahlen/ablaufdaten/wartungen
CI / frontend-build (push) Successful in 22s
CI / backend-tests (push) Successful in 3m44s
Letzte dashboard-nahen Objekt-bezogenen Endpunkte ohne Standort-Filter
geschlossen: kennzahlen() (vier Fehlbestand-Zählungen + Objekte-Gesamtzahl),
bevorstehende_ablaufdaten(), alle_faelligen_wartungen() bekommen optionales
sichtbare_standort_ids. Hintergrund-Job wartung_benachrichtigung.py ruft
weiterhin ohne Filter auf. bevorstehende_qualifikationsablaeufe() bleibt
bewusst unangetastet - rein Personal-bezogen, kein Objekt-/Standort-Konzept.
Damit ist ZUST-004 für alle Objekt-bezogenen Endpunkte durchgezogen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-14 23:56:56 +02:00
patrickandClaude Sonnet 5 9084e6c9d7 feat(zustaendigkeit): ZUST-004 Runde 5 - Lagerort mit echtem Standort verknüpft
CI / frontend-build (push) Successful in 22s
CI / backend-tests (push) Successful in 3m42s
Lagerort.standort_id (Migration 0060, nullable, nur an typ=standort-Knoten
fachlich sinnvoll) löst die bisherige Blockade auf: standort_fuer_lagerort()/
standort_fuer_lagerplatz() laufen die parent_id-Kette hoch bis zum nächsten
Standort-Treffer. Damit jetzt eingeschränkt: GET /lagerplaetze(+bestand),
POST einlagern/auslagern/umlagern (Umlagern prüft Quelle UND Ziel). Admin-UI
zeigt Standort-Auswahl nur bei typ=standort. Lagerbewegung (Objekt-Ebene,
WH-007) bleibt unberührt - anderes Modell, war nie Teil der Blockade.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-14 23:36:48 +02:00
patrickandClaude Sonnet 5 6f116edd51 fix(tests): test_historie_standort_eingeschraenkt falsche Rolle
CI / backend-tests (push) Successful in 3m40s
CI / frontend-build (push) Successful in 22s
CI-Fund: Test nutzte mitarbeiter_user, aber /historie war schon vor
ZUST-004 auf _verantwortliche (Administration/Materialverantwortliche/
Leitung) beschränkt - reiner Mitarbeiter bekam korrekt 403, unabhängig von
der neuen Standort-Prüfung. Kein Code-Bug, nur falsche Testannahme.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-14 23:15:48 +02:00
patrickandClaude Sonnet 5 6c05d4514d feat(zustaendigkeit): ZUST-004 Runde 4 - Historie und Dashboard-Aggregate
CI / backend-tests (push) Failing after 3m39s
CI / frontend-build (push) Successful in 21s
GET /historie prüft Standort-Sichtbarkeit, wenn entitaet_typ+entitaet_id
gesetzt sind (globale Liste ohne Filter bleibt unrestricted). Nutzer-
Entscheidung: Dashboard-Aggregate (Einsatzbereitschaft, Prüftermine)
berücksichtigen jetzt ebenfalls sichtbare Standorte - bewusste Erweiterung
der ursprünglich dokumentierten "V1 zeigt globale Zahlen"-Festlegung.
readiness_snapshot.py bleibt unrestricted (kein Nutzer-Konzept im
Hintergrund-Job). kennzahlen/ablaufdaten/wartungen/qualifikationsablaeufe
bewusst nicht angefasst, eigene Folge-Runde bei Bedarf.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-14 23:07:28 +02:00
patrickandClaude Sonnet 5 1fd5649282 feat(admin): Akte-Anzeige-Felder visuell gruppiert + Hinweistext
CI / backend-tests (push) Successful in 3m57s
CI / frontend-build (push) Successful in 22s
Objekttyp-Art/Zugfahrzeug/Ressourcenbuchung/Wartung/Zählerstand standen
bisher lose in derselben Reihe wie die Pflichtfelder (Bereich/Kategorie/
Name) - eigener umrandeter Block "Akte-Anzeige" mit Hinweis, dass die
Einstellung für alle Objekte dieses Typs gilt, nicht nur eins.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-14 22:59:46 +02:00
patrickandClaude Sonnet 5 20d4903d9c feat(admin): Objekttyp-Presets beim Anlegen statt drei Einzel-Regler
CI / backend-tests (push) Successful in 3m39s
CI / frontend-build (push) Successful in 24s
Dropdown "Objekttyp-Art" (Verbrauchsmaterial/Gerät mit Wartungspflicht/
Fahrzeug/Benutzerdefiniert) setzt Zugfahrzeug/Ressourcenbuchung/Wartung/
Zählerstand mit sinnvollen Defaults vor - einzelne Felder bleiben danach
frei änderbar (kein Locking), manuelle Änderung schaltet automatisch auf
"Benutzerdefiniert" um. Reines Frontend, keine Schema-/API-Änderung.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-14 11:56:16 +02:00
patrickandClaude Sonnet 5 d661354d69 fix(maintenance): MAINT-003 Wartung als Opt-in je Objekttyp
CI / backend-tests (push) Successful in 3m41s
CI / frontend-build (push) Successful in 23s
Nutzer-Fund: Wartungsauftrag war für JEDES Objekt anlegbar/sichtbar, auch
reine Bestandsobjekte (Rettungsrucksack), die nur Inventur/Kontrolle
brauchen. Neues Feld Objekttyp.wartung_aktiv (Migration 0059, bestehende
Objekttypen mit Wartungsplan oder ist_zugfahrzeug automatisch aktiviert)
steuert jetzt, ob WartungSection in der Akte überhaupt erscheint - gleiches
Opt-in-Muster wie ressourcenbuchung_aktiv/zaehler_typ.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-14 09:40:26 +02:00
patrickandClaude Sonnet 5 29b334578f fix(assets): ASSET-009 Zählerstand-Panel als Opt-in je Objekttyp
CI / backend-tests (push) Successful in 3m36s
CI / frontend-build (push) Successful in 22s
Nutzer-Fund: Panel war ungeachtet des Objekttyps in jeder Akte sichtbar,
auch bei einem Rettungsrucksack ohne Kilometerstand/Betriebsstunden. Neues
Feld Objekttyp.zaehler_typ (keiner/kilometer/betriebsstunden/beide, Migration
0058, bestehende Fahrzeug-Objekttypen automatisch auf "beide" migriert)
steuert jetzt Sichtbarkeit UND welche Felder das Panel zeigt - gleiches
Opt-in-Muster wie ressourcenbuchung_aktiv (ASSET-012). Admin-UI in
ObjekttypSection.tsx ergänzt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-13 23:19:26 +02:00
patrickandClaude Sonnet 5 e5bb213cca fix(akte): Grid-Overlap bei Nicht-Fahrzeug-Objekten auf Desktop-Breite
CI / backend-tests (push) Successful in 3m37s
CI / frontend-build (push) Successful in 21s
Nutzer-Screenshot-Fund: Notizen/Bereitschaftshistorie/Ressourcenbuchung
werden für JEDES Objekt gerendert, das Desktop-Grid-Template (≥900px) für
Nicht-Fahrzeuge listete diese Grid-Areas aber gar nicht - Kinder ohne
gültige Area landeten im Implicit-Grid und überlappten sich (z.B.
"Hinzufügen"-Button über Bereitschaftshistorie-Text). Zusätzlich: neues
ZaehlerstandPanel (ASSET-009) hatte gar keine Grid-Area zugewiesen, dadurch
zu schmal gerendert (Platzhaltertext abgeschnitten, Zahlen-Spinner
überlappte Text). Beide Templates jetzt vollständig, ZaehlerstandPanel
bekommt eigene Area + Felder untereinander statt in einer Reihe.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-13 23:08:41 +02:00
patrickandClaude Sonnet 5 f3cf7d98dd docs(backlog): MAINT-008 stale DECISION-REQUIRED-Rest bereinigt
CI / backend-tests (push) Successful in 3m35s
CI / frontend-build (push) Successful in 20s
War bereits am 2026-09-10 entschieden/umgesetzt (siehe DoD), Formulierung
im Beschreibungstext stand noch als offen da.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-13 22:55:43 +02:00
patrickandClaude Sonnet 5 b8ab97b659 feat(zustaendigkeit): ZUST-004 Runde 3 - Wartung/Verleih/Zählerstand
CI / backend-tests (push) Successful in 3m33s
CI / frontend-build (push) Successful in 21s
GET /wartungsauftraege, GET /verleihe(+uebergabeliste), PATCH /objekte/{id}/
zaehlerstand und GET /objekte/{id}/uebergabeliste (Aussonderung) bekommen
dieselbe Standort-Sichtbarkeitsprüfung. Lagerbewegungen/Lagerplätze bleiben
bewusst blockiert - Lagerort hat keine FK auf die echte Standort-Tabelle
(eigene, unabhängige Hierarchie), braucht erst eine eigene Entscheidung
bevor ZUST-004 dort anwendbar ist.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-13 22:47:58 +02:00
patrickandClaude Sonnet 5 56fae09a6c feat(zustaendigkeit): ZUST-004 Runde 2 - Kontrollen und Mängel eingeschränkt
CI / backend-tests (push) Successful in 3m34s
CI / frontend-build (push) Successful in 21s
GET /maengel filtert jetzt nach sichtbaren Standorten (Join auf Objekt),
GET /kontrollen/{id} prüft den Standort des zugehörigen Objekts. Gleiches
additives Muster wie Runde 1 (Objekte/Dokumente) - kein Eintrag in
benutzer_standort_zugriff bleibt weiterhin unrestricted.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-13 22:44:06 +02:00
patrickandClaude Sonnet 5 346d119054 docs(backlog): PERS-008/LOAD-007 DECISION-REQUIRED-Reste bereinigt
CI / backend-tests (push) Successful in 3m32s
CI / frontend-build (push) Successful in 21s
Beide waren bereits umgesetzt (2026-09-10) - stale DECISION-REQUIRED-Text
stand noch mitten in der Kachel-Beschreibung, obwohl die DoD am Ende längst
die getroffene Entscheidung dokumentierte. Gleicher Fall wie zuvor bei
WH-006/PERS-004/MAINT-008 in dieser Session. Keine Code-Änderung, nur
Backlog-Korrektur.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-13 22:33:42 +02:00
patrickandClaude Sonnet 5 e5f490170a feat(zustaendigkeit): ZUST-004 Standort-weite Leseeinschränkung (schließt DOC-006)
CI / backend-tests (push) Successful in 3m30s
CI / frontend-build (push) Successful in 22s
Korrektur des ursprünglichen Threat-Model-Funds DOC-006: Standort war im
gesamten System nie eine Sicherheitsgrenze für Lesezugriffe (GET /objekte
hatte keinerlei Standort-Prüfung, ZUST-003 gilt nur für granulare
Custom-Rollen-Schreibrechte). Nutzer-Entscheidung: echte Sichtbarkeitsgrenze
einführen statt nur Dokumente zu flicken - neue Tabelle
benutzer_standort_zugriff (M:N, kein Eintrag = weiterhin alles sichtbar,
Rückwärtskompatibilität), OHNE Rollen-Bypass (auch Administration wird bei
Zuordnung eingeschränkt, anders als ZUST-003).

Erste Runde (bewusst nicht alle Endpunkte auf einmal, wie ZUST-003 selbst
vorschreibt): GET /objekte(+code/{id}), GET /dokumente(+download/versionen).
Kontrollen/Mängel/Historie/Dashboard/Wartung/Lager folgen bei Bedarf nach
demselben Muster.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-13 22:23:38 +02:00
patrickandClaude Sonnet 5 25c0a9ea92 chore: DEVLOG aktualisieren
CI / backend-tests (push) Successful in 3m26s
CI / frontend-build (push) Successful in 21s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-13 20:39:52 +02:00
patrickandClaude Sonnet 5 c440ccd05e feat(mobile): MOBILE-003 Scope-Erweiterung - drei weitere Offline-Queues
CI / backend-tests (push) Successful in 3m23s
CI / frontend-build (push) Successful in 21s
Nutzer-Entscheidung revidiert bisherige Scope-Begrenzung (2026-09-10) auf
Kontrolle/Mangel. Neu: Gerätestatus, Wartungsauftrag, Lagerbewegung laufen
jetzt über eigene Offline-Queues statt bei Verbindungsverlust sofort zu
scheitern. Weiterhin kein genereller Endpunkt-Layer (bleibt abgelehnt) -
fünf eigenständige Queues teilen sich nur die Sync-Mechanik
(offline/draftQueue.ts). Lagerbuchungen bewusst anders: Bestandskonflikte
(4xx) werden weiterhin sofort angezeigt statt erst beim Sync-Versuch,
nur echte Netzwerkfehler landen in der Queue.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-13 10:47:55 +02:00
patrickandClaude Sonnet 5 f4e8a83097 feat(assets): ASSET-013 Aussonderungs-Teil - ObjektStatus.ausgesondert
CI / backend-tests (push) Successful in 3m27s
CI / frontend-build (push) Successful in 23s
Neuer Status per Migration (ALTER TYPE ADD VALUE), gesetzt über den
bestehenden generischen PATCH /objekte/{id}-Endpunkt (Historie-Logging kam
damit automatisch mit). Dashboard blendet ausgesondert wie ausser_dienst
aus. Neuer GET /objekte/{id}/uebergabeliste nutzt denselben PDF-Mechanismus
wie der Verleih-Teil, ohne Verleih-/Externe-Stelle-Bezug. Damit ist
ASSET-013 komplett (Verleih-Teil war bereits 2026-09-12 fertig).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-13 10:13:06 +02:00
patrickandClaude Sonnet 5 69f66c6d1c feat(assets): ASSET-009 generischer Nutzungszähler (km/Betriebsstunden)
CI / backend-tests (push) Successful in 3m25s
CI / frontend-build (push) Successful in 21s
Fahrzeugdetails war nie technisch auf Fahrzeuge beschränkt, aber es gab
keinen Weg, den Zählerstand überhaupt zu setzen (nur Formular-Ersatz-PUT
ohne Validierung, keine Frontend-Anbindung). Neuer PATCH-Endpunkt mit
Monoton-Validierung (Rückwärtslauf nur Administrator), neues
ZaehlerstandPanel in der Akte - bewusst ohne Fahrzeug-Gate, damit
Stromerzeuger/Pumpen denselben Mechanismus nutzen können.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-12 23:35:57 +02:00
patrickandClaude Sonnet 5 e03696642f feat(personal): PERS-004-Lücke - Einheit/Funktion auch für Person ohne Login
CI / backend-tests (push) Successful in 3m20s
CI / frontend-build (push) Successful in 21s
Einsatzfunktion/Einheit gab es bisher nur an Benutzer - eine Person ohne
Systemzugang (Jugendgruppe, externe Helfer) konnte keiner Einheit/Funktion
zugeordnet werden. Migration 0055 ergänzt beide Felder an Person, Admin-Tab
"Personen" bekommt dieselben zwei Auswahlfelder wie "Benutzer". Außerdem
PERS-004-DoD korrigiert (war fälschlich als "komplett neu/fehlt" markiert,
Einsatzfunktion-Konzept existierte bereits für Benutzer).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-12 23:20:14 +02:00
patrickandClaude Sonnet 5 c0c484cf8a feat(pruefung): INSP-002 Phase 3 - Objekttyp-Intervall als Fallback
CI / backend-tests (push) Successful in 3m18s
CI / frontend-build (push) Successful in 21s
Prüftermine sind sicherheits-/haftungsrelevant (Nutzer-Vorgabe) - Änderung
bewusst additiv statt Ersetzung: Objektposition.pruefintervall_monate bleibt
Override wie bisher, NUR bei fehlendem Override greift jetzt der
Objekttyp-Standard (objekttyp_pruefart) statt naechste_pruefung leer zu
lassen. Kein Migrations-/Schema-Change, Regressionstest für bestehenden
Pfad ergänzt. Außerdem: WH-006-Ist-Stand-Notiz korrigiert (war als "fehlt
komplett" markiert, ist laut eigenem DoD seit 2026-09-10 fertig).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-12 23:04:38 +02:00
patrickandClaude Sonnet 5 4a0d0fd5f1 feat(verleih): Übergabeliste zum Unterschreiben (ASSET-013 Verleih-Teil)
CI / backend-tests (push) Successful in 3m18s
CI / frontend-build (push) Successful in 22s
Reines Druck-PDF (reportlab, kein digitaler Signatur-Workflow) mit
Objektpositionen (Soll/Ist), nach Fach gruppiert wo vorhanden, plus
Unterschriftsfelder für Übergeber/Übernehmer. Aussonderungs-Teil von
ASSET-013 bleibt offen (braucht erst neuen ObjektStatus).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-12 22:47:49 +02:00
patrickandClaude Sonnet 5 5ce9430816 docs(backlog): ASSET-013 Übergabeliste bei Verleih/Aussonderung geplant
CI / backend-tests (push) Successful in 3m18s
CI / frontend-build (push) Successful in 22s
Nutzer-Anforderung: signierbare Materialliste, sobald ein Objekt dauerhaft
den Standort verlässt (Verleih oder Aussonderung). Nur Planung, keine
Umsetzung - Entscheidungen getroffen: neuer ObjektStatus.ausgesondert,
weasyprint für PDF-Erzeugung, Verleih+Aussonderung zusammen in einer Kachel.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-12 22:43:40 +02:00
patrickandClaude Sonnet 5 9312d6a17c fix(frontend): Session-Timeout ausgeloggt statt in kaputtem Zustand stecken
CI / backend-tests (push) Successful in 3m18s
CI / frontend-build (push) Successful in 22s
401 bei abgelaufenem Token wurde nirgends erkannt - "eingeloggt" blieb true,
Hard-Reload half nicht, da der abgelaufene Token weiter in localStorage lag
und /auth/me erneut mit 401 scheiterte (gleicher Zustand auf derselben URL).
apiRequest ruft jetzt bei echtem Session-Timeout einen von AuthProvider
registrierten Handler auf, der korrekt auf logout() setzt - Router-Guard
leitet danach automatisch zu /login um.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-12 22:33:20 +02:00
patrickandClaude Sonnet 5 c8d9480cf9 perf(mangel): Foto-Kompression vor Upload in beiden Clients ergänzt
CI / backend-tests (push) Successful in 3m17s
CI / frontend-build (push) Successful in 22s
PWA lud Mangel-Fotos bislang komplett unkomprimiert hoch (rohes File aus
capture-Input) - Canvas-basierte Verkleinerung/Neukodierung (max. 1600px,
JPEG q0.7) vor dem Enqueue ergänzt. Flutter-Client nutzte nur imageQuality
(reine JPEG-Kompression ohne Auflösungs-Downscale) - maxWidth/maxHeight
ergänzt. Beides zahlt sich bei schlechter Feld-Verbindung aus.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-12 22:23:31 +02:00
patrickandClaude Sonnet 5 ecca012197 fix(flutter): Sync-Abbruch-Bug in Offline-Queues behoben, API-URL konfigurierbar
CI / backend-tests (push) Successful in 3m16s
CI / frontend-build (push) Successful in 21s
flutter analyze/test/build erstmals verifiziert (Build-Host 192.168.1.236,
Flutter 3.47.3). Dabei Bug gefunden: synchronisiere() brach in beiden
Offline-Queues (Kontrolle + Mangel) bei JEDEM unerwarteten Fehler die
komplette Restqueue ab statt nur bei echtem Netzwerkfehler - ein kaputter
Eintrag hätte alle nachfolgenden dauerhaft blockiert. Jetzt nur noch bei
SocketException. Zusätzlich kApiBaseUrl auf --dart-define umgestellt statt
Code-Änderung pro Build, und Test für die neue Mangel-Queue ergänzt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-12 22:10:56 +02:00
patrickandClaude Sonnet 5 230237ac94 feat(flutter): Mangelmeldung-Offline-Queue + Threat-Model-Fund als Kachel
CI / backend-tests (push) Successful in 3m16s
CI / frontend-build (push) Successful in 20s
Android-Client zieht die Draft-first-Offline-Queue für Mangelmeldung nach
(bisher nur Kontrolle abgedeckt), inkl. Foto-Upload per Multipart und
eigenem Melde-Screen. Zusätzlich Backend-Threat-Model erstellt und daraus
DOC-006 (IDOR bei Dokument-Download) als Kachel im Backlog angelegt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
2026-09-12 21:42:44 +02:00
patrickandClaude Sonnet 5 d6786396d1 fix(admin): Gruppen-Sidebar-Kontrast/Abstände verbessert
CI / backend-tests (push) Successful in 3m31s
CI / frontend-build (push) Successful in 24s
.card + Tailwind-p-2 kollidierten (Tailwind-Layer gewann, Card-Padding
faktisch wirkungslos) - eigener Rahmen statt .card-Klasse. Gruppen jetzt
per Trennlinie abgesetzt statt nur Abstand, aktiver Tab mit linkem
Akzentbalken statt nur schwachem Soft-Hintergrund.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012BmsfwPHiAjwtJetgykazx
2026-09-11 15:44:59 +02:00
patrickandClaude Sonnet 5 46b203dc44 feat(admin): Objekte-Liste als Tabelle mit Filterleiste statt statischer Liste
CI / backend-tests (push) Successful in 3m35s
CI / frontend-build (push) Successful in 28s
Desktop: sortierte Spalten-Tabelle (Code/Name/Standort/Fahrzeug/Status-Badge/
Kontrolle), Filter nach Standort und Status zusätzlich zur Suche. Mobile
bleibt Kartenliste (useIsDesktop, wie ObjektListPage). Verschieben/Fahrzeug/
Duplizieren-Formulare in ObjektAktionenFormulare.tsx ausgelagert, von Zeile
und Karte gemeinsam genutzt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012BmsfwPHiAjwtJetgykazx
2026-09-11 15:41:29 +02:00
patrickandClaude Sonnet 5 71aa07dd52 refactor(frontend): Menü auf eigenes Sidebar-Primitive umgebaut
CI / backend-tests (push) Successful in 3m38s
CI / frontend-build (push) Successful in 23s
Hauptnav (AppShell) und Admin-Gruppennav nutzen jetzt dasselbe
collapsible Sidebar-Muster (Icons, Gruppen, Mobile-Sheet, Strg/⌘+B)
statt Topbar + separater Button-Liste. Tote .app-shell/.topbar-CSS
entfernt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012BmsfwPHiAjwtJetgykazx
2026-09-11 15:28:59 +02:00
patrickandClaude Sonnet 5 ffc9559ac3 fix(admin): Sidebar-Breite auf 20rem, Buttons brachen um
CI / backend-tests (push) Successful in 3m29s
CI / frontend-build (push) Successful in 23s
split-layout-sidebar-sm (12rem) war zu schmal für die Tab-Labels.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 23:13:18 +02:00
patrickandClaude Sonnet 5 6e9c131cbc refactor(admin): Menüstruktur in thematische Gruppen umgebaut
CI / backend-tests (push) Successful in 3m18s
CI / frontend-build (push) Successful in 21s
Admin-Tabs (25 Stück) waren eine flache Liste. Jetzt gruppiert nach
Stammdaten, Personal & Rechte, Betrieb, Wartung & Prüfung, Einsätze &
Meldungen, System. Mobile-Sonderfall (Sheet/istDesktop) entfernt,
bestehende split-layout-CSS übernimmt das responsive Verhalten.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 23:02:16 +02:00
patrickandClaude Sonnet 5 e39d704de8 docs(flutter): Server-Adresse einstellbar (mabea-scan v0.9.0, mabea-doku v0.4.0)
CI / backend-tests (push) Successful in 3m17s
CI / frontend-build (push) Successful in 21s
Zahnrad-Icon auf dem Login-Screen beider Apps öffnet Dialog zum
Ändern der Server-URL (flutter_secure_storage, Zurücksetzen auf
Standard), greift sofort ohne Neubau der App.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 22:46:28 +02:00
patrickandClaude Sonnet 5 3a19c1f273 docs(flutter): mabea-doku v0.3.0 - INTERNET-Permission-Fix
CI / backend-tests (push) Successful in 3m18s
CI / frontend-build (push) Successful in 23s
android.permission.INTERNET fehlte in AndroidManifest.xml (Standard-
flutter-create-Template setzt sie nicht automatisch) - App konnte
dadurch gar keine Netzwerkverbindung aufbauen ("keine Verbindung zum
Server"), unabhängig vom Backend-Status. mabea-scan hatte die
Permission bereits korrekt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 22:30:37 +02:00
patrickandClaude Sonnet 5 97498abe57 fix(tests): CI-Fix - verstümmelte Assertions in test_akte.py behoben
CI / backend-tests (push) Successful in 3m29s
CI / frontend-build (push) Successful in 23s
Vorheriger Edit hatte Zeilen der ursprünglichen
test_akte_buendelt_teilbereiche-Assertions versehentlich in die neue
Testfunktion verschoben (NameError: 'body' nicht definiert). Zeilen
zurück an den richtigen Test gehängt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 21:54:18 +02:00
patrickandClaude Sonnet 5 ce99aa6fbb feat: mabea-doku Zwei-Apps-Support + Ressourcenbuchung Opt-in
CI / backend-tests (push) Failing after 3m31s
CI / frontend-build (push) Successful in 23s
Backend/Frontend-Seite: /app-download/info und /app-download/qr.png
bekommen app-Query-Parameter (scan/doku), Download-Seite /app?app=...
mit Umschalter für die beiden eigenständigen Flutter-Apps.

ASSET-012 Nutzer-Feedback: Ressourcenbuchung war in jeder Akte
sichtbar, unabhängig vom Objekttyp - jetzt Opt-in je Objekttyp
(Objekttyp.ressourcenbuchung_aktiv, Migration 0054, Default false),
Admin-Checkbox in ObjekttypSection.tsx, AktePage.tsx zeigt das Panel
nur noch wenn aktiviert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 21:49:34 +02:00
patrickandClaude Sonnet 5 3d560738de docs(flutter): FLUT-001 v0.7.0 - Akte-Details, Taschenlampe, Geräte-Code
CI / backend-tests (push) Successful in 3m33s
CI / frontend-build (push) Successful in 23s
Objekt-Scan zeigt jetzt Einsatzbereitschafts-Ampel + Gründe, letzte
Kontrolle, offene Mängel (via GET /akte/objekt/{id}, Ladefehler nicht
fatal). Taschenlampe-Toggle im Scan-Screen. Geräte-Exemplar-Code als
Fallback, wenn kein Objekt-Code passt (Geräte-Etiketten waren bisher
gar nicht scanbar).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 21:20:47 +02:00
patrickandClaude Sonnet 5 6f3589f4e0 docs(backlog): FOUND-ID-Kollision behoben, FOUND-008 won't-do
CI / backend-tests (push) Successful in 3m16s
CI / frontend-build (push) Successful in 21s
Zwei Kacheln waren fälschlich unter denselben IDs geführt wie bereits
vergebene aus der ursprünglichen Master-Prompt-Liste: CSV/XLS-Import
FOUND-007 -> FOUND-014, Fristen-Dienst FOUND-008 -> FOUND-015. Alle
Code-Kommentare/Kachel-Querverweise mitgezogen.

FOUND-008 (Docker/Compose-Setup) als won't-do geschlossen -
widerspricht der bare-metal-Policy für MABEA selbst (CLAUDE.md).
GlitchTip (FOUND-013) nutzt Docker als externe Fremdsoftware auf
einem separaten, optionalen Host - kein Widerspruch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 21:09:30 +02:00
patrickandClaude Sonnet 5 f93798e3f3 fix(qr): reportlab renderPM-Backend fehlte auf CI-Runner
CI / backend-tests (push) Successful in 3m17s
CI / frontend-build (push) Successful in 20s
Erster echter Test für services/qr_png.py (bisher nie getestet, auch
nicht in ASSET-010) deckte auf: reportlab.graphics.renderPM braucht
einen nativen Rendering-Backend, der auf Python 3.13 nicht lauffähig
installiert war. Hätte auch die ASSET-010-QR-Anzeige im Ausgabe-
Dialog treffen können, war nur nie bemerkt worden. Auf qrcode[pil]
(reiner Python-Encoder, kein natives Backend nötig) umgestellt.
label.py (PDF-Vektor-Labels) ist unverändert, nicht betroffen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 20:57:56 +02:00
patrickandClaude Sonnet 5 777bf5eaa5 feat(flutter): öffentliche Download-Seite für Scan-App-Feldtest
CI / backend-tests (push) Failing after 3m17s
CI / frontend-build (push) Successful in 21s
/app zeigt QR-Code + Download-Button + Installationsanleitung ohne
Login (Henne-Ei: die App ist der Login-Client). Backend liefert
GET /app-download/info und /app-download/qr.png (bewusst ohne Auth),
liest version.json vom lokalen downloads_dir, QR über bestehenden
services/qr_png.py. Admin-Hinweis verlinkt jetzt auf /app statt
Version/URL zu duplizieren.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 20:51:52 +02:00
patrickandClaude Sonnet 5 973bf35514 fix(admin): Scan-App-Download-Link liest Version aus version.json
CI / backend-tests (push) Successful in 3m16s
CI / frontend-build (push) Successful in 22s
Portal-Link war fest auf v0.5.apk verlinkt, dadurch nach dem
v0.6.0-Build stale. Liest jetzt zur Laufzeit /downloads/version.json
(dieselbe Quelle wie der In-App-Update-Check) statt einer fest
hinterlegten Versionsnummer im Link - bleibt bei jedem künftigen
APK-Build automatisch aktuell.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 20:39:32 +02:00
patrickandClaude Sonnet 5 d53c9a57d1 docs(flutter): FLUT-001 v0.6.0 Zugangsdaten-Persistenz + Server-Umzug
CI / backend-tests (push) Successful in 3m17s
CI / frontend-build (push) Successful in 20s
Korrigiert vorherige fehlerhafte Notiz (flutter_app/ im Repo ist ein
getrenntes, ungenutztes Scaffold - nicht der echte Prototyp). Echter
FLUT-001-Code lebt weiterhin nur auf dem Build-Server
(mabea_scan_prototyp), dokumentiert v0.6.0 (flutter_secure_storage
für Token+optionale Zugangsdaten, Auto-Relogin bei 401, Logout) und
den Umzug von /opt/flutter-projects nach /mnt/projekte/flutter
(Symlink) auf 192.168.1.236.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 20:36:02 +02:00
patrickandClaude Sonnet 5 11e2e5e399 feat(flutter): sicherer Zugangsdaten-Speicher + Auto-Relogin
CI / backend-tests (push) Successful in 3m15s
CI / frontend-build (push) Successful in 21s
Token-Speicherung von SharedPreferences (Klartext) auf
flutter_secure_storage (Android Keystore/iOS Keychain) umgestellt.
Optional werden Benutzername/Passwort mitgespeichert (Checkbox auf
dem Login-Screen, Default an, abwählbar - löscht dabei auch
vorhandene gespeicherte Zugangsdaten), damit die App nach Ablauf des
8h-Tokens automatisch neu einloggt statt den Nutzer zurück auf den
Login-Screen zu werfen (ApiClient.versucheAutoRelogin(), greift bei
401 in request()).

Tests auf FakeSecureStorage (In-Memory-Testdouble) statt
SharedPreferences.setMockInitialValues umgestellt.

Kein lokales Flutter-SDK in dieser Umgebung - Änderungen per
manuellem Code-Review statt flutter analyze/test verifiziert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 20:24:33 +02:00
patrickandClaude Sonnet 5 78b07d671f feat(mobile): MOBILE-003 Draft-first-Muster auf Mangelmeldung ausgeweitet
CI / backend-tests (push) Successful in 3m18s
CI / frontend-build (push) Successful in 21s
Gleiches Offline-Queue-Muster wie bei der Kontroll-Erfassung
(offline/queue.ts) jetzt auch für Mangelmeldung: sofort lokal
speichern statt auf Server-Antwort zu warten, Foto wird mit
gequeued und nach erfolgreicher Mangel-Erstellung separat
hochgeladen. useOnlineStatus/SyncStatus decken jetzt beide Queues ab.

Bewusst begrenzter Scope (Nutzer-Entscheidung): kein genereller
Offline-Layer für alle Schreib-Endpunkte, nur Kontrolle + Mangel.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 20:14:39 +02:00
patrickandClaude Sonnet 5 aceef65418 fix(identity): Label-Design vergrößert (QR + Name)
CI / backend-tests (push) Successful in 3m14s
CI / frontend-build (push) Successful in 20s
Nutzer-Feedback: QR-Code (25mm) und Klartext-Name (9pt) auf gedruckten
Etiketten waren zu klein. QR-Zielgröße auf 38mm, Klartext-Zeile auf
13pt fett angehoben - gilt für Code128- und QR-Label gleichermaßen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 20:02:46 +02:00
patrickandClaude Sonnet 5 536b2edc4d feat(inspections): INSP Phase 2 - Admin-UI + Dashboard-Lesepfad-Ergänzung
CI / backend-tests (push) Successful in 3m16s
CI / frontend-build (push) Successful in 20s
Prüfarten-Verwaltung + Objekttyp-Zuordnung im Admin-Frontend
(PruefartenSection.tsx, neue Endpunkte GET/PUT/DELETE
/objekttypen/{id}/pruefarten), Prüfhistorie + FAILED-Ampel-Badge je
Geräte-Exemplar (GeraeteInstanzenListe.tsx).

Dashboard-Lesepfad ergänzt (nicht ersetzt): bevorstehende_prueftermine()
zeigt ein Gerät mit fehlgeschlagener Prüfung jetzt auch dann, wenn
naechste_pruefung datumsbasiert noch als "gueltig" gelten würde.

Bewusst NICHT umgestellt: naechste_pruefung-Berechnung bleibt auf
Objektposition.pruefintervall_monate (nicht objekttyp_pruefart),
Fristen-Dienst/ASSET-010 bleiben unverändert - siehe Kachel-DoD.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 19:53:38 +02:00
patrickandClaude Sonnet 5 e5dc80c3a6 feat(foundation): FOUND-013 optionales Error-Tracking (GlitchTip)
CI / backend-tests (push) Successful in 3m14s
CI / frontend-build (push) Successful in 21s
Zielserver-Entscheidung durch optionales Install-Script aufgelöst statt
festgeschrieben: deploy/glitchtip-install.sh installiert GlitchTip per
Docker Compose auf einem beliebigen, selbst gewählten Host - nichts
automatisch/ungefragt.

DSN wird zur Laufzeit über eine neue Admin-GUI-Seite ein-/ausschaltbar
(Systemeinstellung-Singleton, GET/PATCH /einstellungen/sentry), statt
nur per .env - kein Redeploy zum Umschalten nötig. Frontend lädt
@sentry/react nur dynamisch nach, wenn tatsächlich aktiv.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 19:35:47 +02:00
patrickandClaude Sonnet 5 11e6ed4332 feat(warehouse): WH-006 Inventur & Bestandskorrektur
CI / backend-tests (push) Successful in 3m8s
CI / frontend-build (push) Successful in 19s
Inventurlauf je Lagerort (inkl. Unter-Lagerorte), Sollmenge wird beim
Start aus Bestand gesnapshotted, Abweichung erzeugt beim Abschluss
automatisch Korrekturbuchung + Audit-Log statt stiller Anpassung.
Teil-Inventur erlaubt (ungezählte Positionen blockieren nicht).
Backend-Grundgerüst von fastapi-expert-Subagent, Review/Frontend/
Tests-Ergänzung/Doku durch Hauptagent.

Außerdem: 00_index.md Status-Abgleich (FLEET-006, ASSET-011/012,
PERS-008, INSP-001..004 waren bereits umgesetzt, aber im Index noch
als offen markiert).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 18:39:46 +02:00
patrickandClaude Sonnet 5 bc1542a5e9 feat(loadout): LOAD-007 Gemeinsame Sollmenge über mehrere Standorte
CI / backend-tests (push) Successful in 3m3s
CI / frontend-build (push) Successful in 18s
Objektposition kann optional einer sollmengen_gruppe zugeordnet werden;
Fehlbestand-Prüfung erfolgt dann gegen die Gruppen-Summe statt die
eigene Sollmenge. Fehlbestand bleibt an der Position verankert, die
die Unterdeckung real festgestellt hat (kein Standort-Raten), wird
aber gruppenweit gesucht/aufgelöst, damit Deckung durch eine andere
Position im Verbund den Fehlbestand korrekt schließt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 18:15:22 +02:00
patrickandClaude Sonnet 5 c18e4481b6 feat(maint): MAINT-008 Lieferanten-/Dienstleister-Verzeichnis
CI / backend-tests (push) Successful in 3m2s
CI / frontend-build (push) Successful in 18s
ExterneStelle (ASSET-011) um Kategorie erweitert statt zweites
Adressbuch anzulegen; Wartungsauftrag optional mit dienstleister_id
verknuepfbar, Freitext werkstatt_name bleibt als Fallback bestehen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 17:43:42 +02:00
patrickandClaude Sonnet 5 3d596ab456 feat(assets): ASSET-012 Ressourcen-Buchungskalender (Verfügbarkeitsprüfung)
CI / backend-tests (push) Successful in 2m59s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 16:51:17 +02:00
patrickandClaude Sonnet 5 1ad693073e feat(assets): ASSET-011 externer Verleih mit Rückgabe-Tracking
CI / backend-tests (push) Successful in 2m59s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 16:16:14 +02:00
patrickandClaude Sonnet 5 63ac9ecf2c fix(tests): admin-Token für Geräteinstanz-Anlage in PERS-008-Tests nutzen (CI-Fix)
CI / backend-tests (push) Successful in 2m57s
CI / frontend-build (push) Successful in 19s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 15:46:06 +02:00
patrickandClaude Sonnet 5 163c881b82 feat(personal): PERS-008 Einweisungspflicht-Warnung bei Geräteausgabe
CI / backend-tests (push) Failing after 2m53s
CI / frontend-build (push) Successful in 21s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 15:41:58 +02:00
patrickandClaude Sonnet 5 80bd79ad4d docs(arbeitskacheln): 5 neue Kacheln aus vertieftem HiOrg-Server-Vergleich (PERS-008, ASSET-011/012, MAINT-008, LOAD-007)
CI / backend-tests (push) Successful in 2m54s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 15:35:16 +02:00
patrickandClaude Sonnet 5 52bf7d9ec9 feat(assets): ASSET-007 Material-Sets (Kits), ASSET-008 Consumable-Doku korrigiert
CI / frontend-build (push) Successful in 19s
CI / backend-tests (push) Successful in 2m55s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 15:22:02 +02:00
patrickandClaude Sonnet 5 0aa5d6d249 feat(fleet): FLEET-006 Fahrzeug-Einsatzhistorie über OPS-002
CI / backend-tests (push) Successful in 2m51s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 15:11:17 +02:00
patrickandClaude Sonnet 5 7219762a4c docs(arbeitskacheln): FLEET-004 Index-Status korrigiert (war bereits vollständig umgesetzt)
CI / backend-tests (push) Successful in 2m52s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 15:08:34 +02:00
patrickandClaude Sonnet 5 ad4483e18c fix(inspections): pruefung.geraet_instanz_id FK mit ON DELETE CASCADE (CI-Fix, DELETE /geraete/{id} war blockiert)
CI / backend-tests (push) Successful in 2m50s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 15:02:10 +02:00
patrickandClaude Sonnet 5 25437ec070 feat(inspections): INSP-001..004 Phase 1 generisches Pruefart-System additiv (Dual-Write, FAILED-Ampel)
CI / backend-tests (push) Failing after 2m53s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 14:57:30 +02:00
patrickandClaude Sonnet 5 8e4c2608e3 feat(foundation): FOUND-006 strukturiertes Logging, FOUND-010 DB-Backup-Timer, IDENT-010 GTIN-Materialabgleich
CI / backend-tests (push) Successful in 2m50s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 14:07:22 +02:00
patrickandClaude Sonnet 5 fdeae8b5e3 docs(arbeitskacheln): FOUND-013 Error-Tracking (GlitchTip) geplant, Index-Statuszeilen auf Ist-Stand nachgezogen
CI / backend-tests (push) Successful in 2m50s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 13:33:01 +02:00
patrickandClaude Sonnet 5 ddd1b446a2 feat(einsatz): Epic 16 Einsatz-Nachdokumentation (OPS-001/002/003 kombiniert)
CI / backend-tests (push) Successful in 2m48s
CI / frontend-build (push) Successful in 19s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 13:07:47 +02:00
patrickandClaude Sonnet 5 46a65ba6ff feat(readiness): READY-001 an/abschaltbare Bereitschafts-Kriterien (abgespeckte Regel-Engine)
CI / backend-tests (push) Successful in 2m48s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 12:51:02 +02:00
patrickandClaude Sonnet 5 d41d04c26c feat(ui): UI2-002/003/004/005 Sheet-Navigation, FormField-Einsatz, Skeleton, Table-Wrapper
CI / backend-tests (push) Successful in 2m45s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 12:37:16 +02:00
patrickandClaude Sonnet 5 91cfb1087f feat(notif): NOTIF-003 proaktive Wartungsfälligkeits-Benachrichtigung
CI / backend-tests (push) Successful in 2m46s
CI / frontend-build (push) Successful in 17s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 12:17:57 +02:00
patrickandClaude Sonnet 5 d095db4172 docs(arbeitskacheln): FLUT-001 auf Ist-Stand nachgezogen (v0.1.0-v0.5.0), FLUT-002 als offene Frage dokumentiert
CI / frontend-build (push) Successful in 17s
CI / backend-tests (push) Successful in 2m44s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 12:06:42 +02:00
patrickandClaude Sonnet 5 1457496763 fix(tests): admin-Token für Geräteinstanz-Anlage nutzen statt mitarbeiter (CI-Fix ASSET-010)
CI / backend-tests (push) Successful in 2m43s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 11:56:43 +02:00
patrickandClaude Sonnet 5 24db5a056f feat(custody): ASSET-010 Gerät-Ausgabe/Rücknahme mit optionalem QR-Signier-Flow
CI / backend-tests (push) Failing after 2m42s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 11:52:07 +02:00
patrickandClaude Sonnet 5 1147ec0872 feat(ui): UI2-001/006/007/009/010 Design-Tokens, Toast, AlertDialog, Formular-a11y
CI / backend-tests (push) Successful in 2m38s
CI / frontend-build (push) Successful in 17s
chore(agents): Flutter/iOS/Swift-Subagenten aus claude-subagents-Repo übernommen

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 11:36:42 +02:00
patrickandClaude Sonnet 5 eeb87d889d feat(permission): ZUST-003 Standort-Scoping für granulare Rollen-Berechtigungen
CI / backend-tests (push) Successful in 2m38s
CI / frontend-build (push) Successful in 17s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 11:22:34 +02:00
patrickandClaude Sonnet 5 e7e6c4c8af fix(tests): hash-Feld bei direkter Historie()-Konstruktion ergänzen, Erwartungswert korrigiert (CI-Fix FILE-008)
CI / backend-tests (push) Successful in 2m33s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 11:12:10 +02:00
patrickandClaude Sonnet 5 429ece3c65 feat(historie): FILE-008 manipulationssicheres Audit-Journal (Hash-Kette je Ressource)
CI / backend-tests (push) Failing after 2m34s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 11:08:07 +02:00
patrickandClaude Sonnet 5 a1ad2d6cef feat(readiness): READY-006 täglicher Bereitschafts-Snapshot mit Trend-Dashboard und Akte-Historie
CI / backend-tests (push) Successful in 2m32s
CI / frontend-build (push) Successful in 19s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 10:54:08 +02:00
patrickandClaude Sonnet 5 bb0c601b2f feat(foundation): FOUND-008 gemeinsame Fristen-Normalisierung (Dringlichkeits-Ampel)
CI / backend-tests (push) Successful in 2m28s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 10:42:06 +02:00
patrickandClaude Sonnet 5 04a255429d feat(wartung): MAINT-007 Tankbuch/Kraftstoffverbrauch je Fahrzeug
CI / backend-tests (push) Successful in 2m30s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 10:32:10 +02:00
patrickandClaude Sonnet 5 96499d655f fix(api): import_export-Router vor objekte/geraet_instanz registriert (Routenkonflikt /objekte/export, CI-Fix)
CI / backend-tests (push) Successful in 2m28s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 10:13:56 +02:00
patrickandClaude Sonnet 5 76a984ad56 fix(tests): login als Helper-Funktion statt Fixture importieren (CI-Fix FOUND-007)
CI / backend-tests (push) Failing after 2m26s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 10:09:15 +02:00
patrickandClaude Sonnet 5 807c818405 feat(foundation): FOUND-007 CSV-Import/Export für Objekte und Geräteinstanzen
CI / backend-tests (push) Failing after 2m28s
CI / frontend-build (push) Successful in 18s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 10:04:56 +02:00
patrickandClaude Sonnet 5 eaafeeb89c fix(admin): Download-Link auf aktuelle APK-Version v0.5 korrigiert
CI / backend-tests (push) Successful in 2m28s
CI / frontend-build (push) Successful in 17s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 08:38:50 +02:00
patrickandClaude Sonnet 5 15bbab258b feat(admin): Download-Link für FLUT-001 Scan-Prototyp im Portal
CI / backend-tests (push) Successful in 2m52s
CI / frontend-build (push) Successful in 48s
Admin-only Hinweis mit Link auf die APK unter /downloads/ - reine Sondierung,
kein Produktivstand.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 01:06:45 +02:00
patrickandClaude Sonnet 5 1e8d66f636 feat(akte): FILE-009 Freitext-Notizen an beliebiger Ressource
CI / backend-tests (push) Successful in 2m39s
CI / frontend-build (push) Successful in 20s
Polymorphes akte_notiz-Modell (gleiches entitaet_typ/entitaet_id-Muster wie
Dokument/Historie/Mangel), CRUD-Endpunkte, NotizenPanel im Akte-Grid. Löschen
nur durch Autor oder Administrator.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 00:49:47 +02:00
patrickandClaude Sonnet 5 9c6426190e docs(arbeitskacheln): Open-Source-/HiOrg-Vergleich ausgewertet, 14 neue Kacheln ausgearbeitet
Vergleich mit InvenTree, Snipe-IT, Grocy, Shelf.nu, Resgrid, KP Front, FleetMS,
HiOrg-Server ergibt neue Kacheln (ASSET-010 Custody, FILE-008 Hash-Audit-Journal,
FILE-009 Notizen, NOTIF-003, MAINT-007 Tankbuch, ZUST-003 Standort-Scoping,
FOUND-007 Import/Export, FOUND-008 Fristen-Dienst, READY-006 Statistik-Dashboard,
UI2-006..010) sowie Referenz-Ergänzungen bei bestehenden Lücken. Alle Design-
Entscheidungen (Datenmodell, Sicherheitsanforderungen bei ASSET-010) geklärt.

Neues Epic 23 (Flutter-Begleit-App, Sondierungs-Prototyp FLUT-001) inkl. geklärtem
TLS-Blocker (Domain mabea.perlbach-edv.de mit Let's-Encrypt-Zertifikat statt
selbstsigniertem Server-Zertifikat).

Alle Kacheln bleiben offen/ungeplant, nur ausgearbeitet, keine Implementierung.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 00:49:32 +02:00
patrickandClaude Sonnet 5 3e39c3b7fd fix(frontend): @vitejs/plugin-react auf v6 für Vite-8-Kompatibilität
CI / backend-tests (push) Successful in 2m26s
CI / frontend-build (push) Successful in 24s
CI schlug fehl (ERESOLVE): @vitejs/plugin-react@4.7.0 kennt nur Vite
bis v7 als Peer-Dependency, lief lokal nur weil node_modules bereits
force-aufgelöst war. v6.1.1 unterstützt Vite 8 nativ, sauberes
npm install ohne --force jetzt möglich, 0 vulnerabilities.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-08 22:46:50 +02:00
patrickandClaude Sonnet 5 e10123fae7 chore(frontend): Vite-Major-Upgrade auf v8 (npm audit fix)
CI / backend-tests (push) Successful in 2m27s
CI / frontend-build (push) Failing after 3s
Schließt alle 6 gemeldeten Schwachstellen (esbuild-Dev-Server-CVE,
GHSA-67mh-4wv8-2f99), betraf nur den lokalen Dev-Server, kein
Produktions-Impact. Vite 5->8, vitest 2->5, vite-plugin-pwa 0.20->1.3.
tsc/build/vitest lokal geprüft, 0 vulnerabilities.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-08 22:41:48 +02:00
patrickandClaude Sonnet 5 7dc6446a56 feat(personal): PERS-001/002 Person fachlich von Benutzer getrennt
CI / backend-tests (push) Successful in 2m29s
CI / frontend-build (push) Successful in 28s
Neue Tabelle person (Migration 0034, Backfill bestehender Benutzer 1:1
per Zeilennummer, keine Datenverluste). Benutzer.person_id optional -
Login kann bestehende Person verknüpfen oder legt automatisch eine neue
an (Rückwärtskompatibilität zum bisherigen Anlegen-Flow). /personen-CRUD
(admin-only), neue PersonSection.tsx im Personal-Tab, BenutzerSection
um Personen-Auswahl erweitert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-08 22:31:46 +02:00
patrickandClaude Sonnet 5 847c303a97 feat(wartung): MAINT-005 Ersatzteile/Kosten je Wartungsauftrag
CI / backend-tests (push) Successful in 2m22s
CI / frontend-build (push) Successful in 25s
Neue Tabelle wartungsauftrag_teil (Migration 0033), CRUD-Endpunkte
/wartungsauftraege/{id}/teile, UI-Panel in WartungSection.tsx mit
Summenanzeige. Backlog Epic 22 (UI-Redesign Runde 2, Kacheln UI2-001..005)
als geplant ergänzt, Umsetzung folgt separat.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-08 22:06:02 +02:00
patrickandClaude Sonnet 5 3b5cf8feab feat(identity): IDENT-003 konfigurierbare Nummernschemata je Objekttyp
CI / backend-tests (push) Successful in 2m24s
CI / frontend-build (push) Successful in 27s
Neue Stammdaten-Tabelle nummernschema (Migration 0032): Präfix + Stellenzahl
einmal je Objekttyp festlegen statt bei jeder Objekt-Anlage manuell
einzutippen (Fehlerquelle - Tippfehler, uneinheitliche Schreibweise,
falsches Präfix für den Typ). GET /objekte/naechster-code akzeptiert jetzt
objekttyp_id als Alternative zu praefix; ohne konfiguriertes Schema bleibt
der bisherige manuelle Präfix-Weg nutzbar (Rückwärtskompatibilität).

Admin-UI: Nummernschema-Pflege direkt in der Objekttyp-Verwaltung
(ObjekttypSection). ObjektAnlegenFormular versucht zuerst das Schema des
gewählten Objekttyps, fällt bei 404 auf manuelles Präfix zurück.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-08 20:23:14 +02:00
patrickandClaude Sonnet 5 15f783fb5e feat(personal): PERS-004 Einsatzfunktionen (Gruppenführer/Melder/...)
CI / backend-tests (push) Successful in 2m17s
CI / frontend-build (push) Successful in 26s
Neue Stammdaten-Tabelle einsatzfunktion (Migration 0031), benutzer bekommt
optionales einsatzfunktion_id-Feld - analog zu einheit_id modelliert, eine
Person hat im Regelfall genau eine primäre Einsatzfunktion. Bewusst
getrennt von den technischen App-Rollen (RolleTyp), die nur steuern, was
jemand in MABEA tun darf, nicht welche Funktion er im Einsatz hat.

CRUD-Endpunkt /einsatzfunktionen nach Kategorie-Muster, Duplikat-Prüfung
vorab (Projekt-Konvention). Admin-UI: Auswahl + Inline-Neuanlage in der
Benutzerverwaltung (BenutzerSection).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-08 20:07:16 +02:00
patrickandClaude Sonnet 5 b7d9581b90 feat(identity): IDENT-009 QR-/Code-Neuvergabe mit Historie
CI / backend-tests (push) Successful in 2m20s
CI / frontend-build (push) Successful in 27s
POST /objekte/{id}/code-neu-vergeben und /objektpositionen/{id}/code-neu-
vergeben (admin-only) - z.B. bei beschädigtem/verlorenem Etikett. Alter
Code bleibt über die bestehende Audit-Infrastruktur (Historie-Tabelle,
Prompt 13) nachvollziehbar statt eine eigene Versions-Tabelle zu brauchen:
GET /historie?entitaet_typ=objekt&entitaet_id=... zeigt alter_wert/
neuer_wert des Codes. Duplikat-Prüfung explizit vorab (Projekt-Konvention,
siehe geraet_instanz.py::erstelle).

Frontend: "Code neu vergeben"-Aktion in der Objektakte (nur Admin), inline
statt window.prompt (Accessibility-Vorgabe aus dieser Session).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-08 18:13:53 +02:00
patrickandClaude Sonnet 5 08ce8efe55 fix(backend): Hersteller/Modell-Duplikatprüfung vorab statt über UNIQUE-Constraint
CI / backend-tests (push) Successful in 2m17s
CI / frontend-build (push) Successful in 27s
Testsuite-get_db-Override macht kein Rollback bei Exceptions (dokumentierter
Fund 2026-09-05) - ein Flush-Fehlschlag über IntegrityError hinterlässt die
geteilte Test-Session im PendingRollbackError-Zustand für jeden folgenden
Request im selben Test. Projekt-Konvention laut geraet_instanz.py::erstelle
ist deshalb explizites Vorab-Prüfen statt Verlassen auf den DB-Constraint -
hier nachgezogen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-08 14:56:05 +02:00
patrickandClaude Sonnet 5 2dd7e574e6 feat(identity): IDENT-005 Hersteller/Modell-Stammdaten
CI / backend-tests (push) Failing after 2m16s
CI / frontend-build (push) Successful in 26s
Neue Tabellen hersteller/modell (Migration 0030), CRUD-Endpunkte
(/hersteller, /modelle) nach bestehendem Kategorie-Muster, inkl. 409 bei
Duplikaten (IntegrityError abgefangen wie in personal.py). geraet_instanz
bekommt optionales modell_id-Feld - verknüpft eine konkrete Geräteinstanz
(mit Seriennummer, IDENT-004) mit ihrem Hersteller/Modell.

Ergänzt Material.hersteller (bleibt unverändert als Freitext) um eine
normalisierte Variante gezielt für Geräte mit Seriennummer - keine
Datenmigration bestehender Freitext-Werte (Scope dieser Kachel).

Bewusst kein neues Admin-UI-Screen für die Pflege (Scope-Grenze der
Kachel) - Hersteller/Modell aktuell nur über die API verwaltbar.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-08 14:51:15 +02:00
patrickandClaude Sonnet 5 ae09433c11 feat(dokumente): DOC-004 Original-vs-Kopie-Kennzeichnung
CI / backend-tests (push) Successful in 2m16s
CI / frontend-build (push) Successful in 27s
Neues Feld ist_original (Boolean, Migration 0029) - explizit beim Upload
und beim Ersetzen (DOC-003) setzbar, kein Default in eine Richtung erraten.
Wird beim Ersetzen bewusst NICHT vom Vorgänger übernommen (neue Version
könnte ein nachgereichtes Original sein, das eine bisherige Kopie ersetzt,
oder umgekehrt). Frontend: Checkbox "Original (nicht nur Kopie/Scan)" im
Upload-Formular, "Original"-Badge in der Dokumentenliste.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-08 12:16:25 +02:00