Verwendung je Material einsehbar (Objektposition/Vorlagenposition/
Bestand/Kontrollposition/Fehlbestand/Ausgabe/Nachfüllung/
Materialbewegung), POST /materialien/{id}/ersetzen hängt alle
Referenzen auf ein Ziel-Material um und löscht die Quelle. Bricht bei
Konflikten ab (z.B. dasselbe Objekt hätte danach zwei Positionen für
dasselbe Material) statt Daten stillschweigend zu verlieren. Admin-UI:
"Zusammenführen" je Material zeigt Verwendung + Ziel-Auswahl.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Anlegen prüft jetzt case-insensitiv auf Duplikate (409 statt "Fach A"
neben "fach a"). Neuer Endpunkt GET /faecher/{id}/objekte zeigt, welche
Objekte ein Fach über ihre Vorlage tatsächlich nutzen. POST
/faecher/{id}/ersetzen benennt um und zieht alle Vorlagenpositionen
mit; landet der neue Name auf einem bereits bestehenden Fach, werden
beide zusammengeführt. Frontend: Fach anklicken öffnet Verwendung +
Ersetzen-Eingabe direkt in der Fächer-Verwaltung.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Bei 22 nachgetragenen Fächern über mehrere Objekttypen war die flache
Liste unübersichtlich. Nutzt das bereits vorhandene Objekttyp-Dropdown
(zum Anlegen) auch als Filter für die Liste darunter, statt ein
zusätzliches Element einzuführen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Vorlagenposition.fach ist Freitext ohne FK zur festen Fächer-Liste
(Fach-Tabelle) - beide liefen auseinander: ein Fach tauchte in der
Kontrolle auf ("Güdeltuben"), existierte aber nicht in der
Fächer-Verwaltung des Objekttyps. erstelle_vorlage/neue_version/
aktualisiere_positionen legen fehlende Fächer jetzt automatisch an.
Bestehende Lücken (22 Fächer über mehrere Objekttypen) direkt in
Produktion nachgetragen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Bevorstehende Ablaufdaten waren nur im Dashboard und als
Einsatzbereitschafts-Grund sichtbar, nicht direkt an der jeweiligen
Beladungsposition in der Akte. Neue Spalte "Ablauf", rot bei
überfälligem, gelb bei <30 Tagen verbleibender Zeit.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Bisher änderte eine Kontrolle Objektposition.istmenge nur indirekt
über eine anschließende Nachfüllung bei Abweichung. Zählte eine
Kontrolle Ist=Soll (kein Fehlbestand, keine Nachfüllung), blieb der
Wert dauerhaft auf 0 stehen - ein frisch angelegtes, aber vollständig
bestücktes Objekt zeigte in der Beladung nie den echten Bestand.
Kontrolle setzt istmenge jetzt immer auf den gezählten Wert.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Objektposition.istmenge bleibt bei materialtyp='geraet_sn' auf 0 -
die tatsächliche Ist-Menge ergibt sich aus der Anzahl einsatzbereiter
geraet_instanz-Zeilen (Karte 14). Die neue Beladung-Karte in der Akte
zeigte den rohen istmenge-Wert, also immer 0 statt z.B. 1 Defibrillator
oder 2 Sauerstoffflaschen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Beide Elemente trugen die Klasse akte-kopf und damit dasselbe
grid-area - das CSS-Grid platzierte sie übereinander statt
untereinander. Jetzt ein gemeinsamer Container mit einem grid-area.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Neues Wartungskonzept: Wartungsplan+Position+Intervall (zeit/km/
Betriebsstunden, kombinierbar - fällig sobald ein Kriterium erreicht
ist), Wartungsauftrag mit intern/externer Werkstatt, Status offen/
in_arbeit/erledigt, Kosten, Historie, Dokument-Anhang. Ad-hoc-Aufträge
ohne Plan möglich (z.B. kleinere Reparatur). Admin-Tab "Wartungspläne".
Objektakte-Redesign (Epic 21, Nutzer-Feedback "wirkt nicht modern"):
CSS-Grid statt Karten-Stapel, einspaltig mobil, zweispaltig ab 900px;
Fahrzeug-Objekte zeigen Wartung/Fahrzeugdaten prominent, Geräte/
Rucksäcke die Beladung. Dabei gefundene Lücke: Beladung (Soll/Ist je
Position) fehlte in der Akte komplett, nur über eine laufende
Kontrolle sichtbar - jetzt eigene Karte.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Dashboard-Listen "Nächste Prüftermine"/"Bevorstehende Ablaufdaten"
hatten keinen Link zum betroffenen Objekt - ein überfälliger Termin
war nicht erreichbar. Zusätzlich: "Prüfung heute durchgeführt"-Button
je Gerät auf der Akte (PATCH /geraete/{id}), bisher nur über die
Admin-Objektbearbeitung möglich.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
_synchronisiere_fehlbestand suchte nur nach Fehlbeständen der eigenen
Kontroll-Sitzung. Ein bereits offener Fehlbestand aus einer früheren
Kontrolle für dasselbe Objekt+Material wurde nicht wiedergefunden -
es entstand ein zweiter, paralleler Fehlbestand mit eigener (neuerer)
Sollmenge, der alte blieb mit veralteter Sollmenge offen liegen.
Lookup jetzt über objekt_id+material_id+status=offen statt
kontrolle_id; kontrolle_id am gefundenen Datensatz bleibt unverändert,
damit ein Abbruch der aktuellen Kontrolle ihn nicht fälschlich
mitlöscht. Löst sich die Abweichung über eine andere Kontrolle als
die erzeugende auf, wird der Fehlbestand jetzt sauber als erledigt
markiert (inkl. Mindermenge-Abschluss) statt stillschweigend gelöscht.
Nebenbei: Kommentare mit Kachel-/Datums-Referenzen ("Bug-Fund
2026-09-06", "UI-00X (Epic 20)") aus dem Code dieser Session entfernt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Karte "Letzte Aktivität" nutzt GET /historie (kein neuer Endpunkt),
statt Ereignisse nur pro Objekt in der Akte sehen zu können. Lesbare
Ereignis-Labels (EREIGNIS_LABEL) auch in AktePage statt rohem
ereignistyp-String. Angeregt durch Resgrid-Doku (Activity-Log-Panel).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
_kategorie_und_gruende() zählte "noch_nie_kontrolliert" bisher nur,
wenn es der EINZIGE Grund war - ein Objekt mit z.B. offenem
Fehlbestand UND nie kontrolliert verlor den Hinweis komplett, landete
nur unter "nicht einsatzbereit" ohne diesen Grund zu nennen. Jetzt
immer als Zusatzgrund angehängt. Neues Feld nie_kontrolliert_gesamt
liefert die tatsächliche Gesamtzahl über alle Kategorien hinweg,
Dashboard nutzt sie statt der (bewusst engeren) "unbekannt"-Kategorie.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
FehlbestandListePage, MangelListePage (Status + Prioritäts-Badge statt
Inline-Farbe) und admin/GeraeteInstanzenListe zeigten Status immer als
neutrales Badge statt farblich zu unterscheiden. Letzte hartkodierte
Hex-Fallbacks (NachfuellDialog, BeladungsplanerBoard) auf reine Tokens
umgestellt. Damit ist Epic 20 (UI-Redesign, UI-001..008) vollständig
durchlaufen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Kontrolle starten/Mangel melden direkt unter Status statt nur ein
Button am Seitenende - nach dem QR-Scan (MOBILE-002 landet auf der
Akte) sofort erreichbar. Mangel melden springt mit ?objekt_id=X in
MangelListePage und wählt das Objekt direkt vor.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
PositionCard bekommt eine farbige linke Randlinie je Zustand (grün
passt, gelb Abweichung/Fehlbestand, rot Übertragungsfehler) - eine
Abweichung war bisher nur während des kurz offenen Nachfüll-Dialogs
sichtbar, danach nicht mehr von einer normalen Bestätigung zu
unterscheiden. Fortschrittsanzeige existierte bereits. Nebenbei
hartkodierte Hex-Fallbackfarben durch Token-Referenzen ersetzt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Backend: objekt_readiness() in dashboard.py liefert Status+Gründe für
ein einzelnes Objekt, Fallunterscheidung aus einsatzbereitschaft()
extrahiert (_kategorie_und_gruende, keine Duplizierung). Neue Felder
an /akte/objekt/{id}. Frontend: ReadinessBadge + Gründeliste ersetzt
den rohen objekt.status-Badge (Objekt-Lebenszyklus-Status bleibt
separat sichtbar). Dokumente waren in der Akte bisher nur Text ohne
Interaktion - jetzt DokumentePanel eingebunden plus neuer "Ansehen"-
Klick (PDF/Bild im neuen Tab statt Zwangs-Download).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Bisher gab es keine reine Nutzer-Doku, nur technisches Backlog
(arbeitskacheln/) und Projekthistorie (GESAMTDOKUMENT.md). Deckt
Rollen, Command Palette (Strg/Cmd+K), Kernfunktionen je Bereich,
Dark Mode/Sync-Status/Statusfarben und Benachrichtigungen ab.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Root-Route "/" und Catch-all landeten bisher immer auf /objekte,
Login-Weiterleitung (Verantwortliche -> Dashboard) war der einzige
Pfad dorthin. Jetzt zentrale startseitenPfad()-Logik überall genutzt,
zusätzlich per Dropdown in der Sidebar einstellbar (automatisch/
Dashboard/Objekte), Präferenz in localStorage.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Neue Karte ganz oben fasst offene Fehlbestände, kritische Mängel,
überfällige Prüfungen, abgelaufene Chargen und nie kontrollierte
Objekte zusammen (bereits geladene Daten, keine neuen Endpunkte),
mit Direktlinks - "5-Sekunden-Antwort" auf "was muss ich jetzt tun".
Nebenbei: fehlende .text-success/.text-danger in global.css ergänzt
(waren in AktePage.tsx bereits referenziert, aber nie definiert).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
ReadinessBadge (ready/limited/not-ready/unknown, "unbekannt" nie wie
"einsatzbereit"), FristBadge als Basis für InspectionStatus/
InventoryStatus, SyncStatus neu in AppShell verdrahtet - Online/
Offline/Sync-Queue-Status war zuvor nirgends sichtbar, obwohl die
Offline-Infrastruktur seit Prompt 17 existiert. Dashboard nutzt die
neuen Komponenten statt Ad-hoc-Inline-Farben.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Personenbezogene Ausgabe ergänzt die reine Standort-/Lagerplatz-Sicht
um "wer hat das Ding gerade": neues Modell ausgabe (Material +
optional geraet_instanz_id), POST /ausgaben, GET /ausgaben (Filter
status/empfaenger), POST /ausgaben/{id}/rueckgabe mit Schutz vor
Doppel-Rueckgabe. Frontend als Admin-Tab "Ausgabe/Rückgabe" +
Command-Palette-Eintrag.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Globale Suche/Quick Actions per Strg/Cmd+K (CommandPalette): Objekt-
Suche nach Name/Code, Sprung zu QR-Scan/Material/Lager/Personal/
Verwaltung. AdminPage-Tab jetzt im URL-Query (?tab=...) statt nur
lokalem State, damit die Palette gezielt verlinken kann, ohne Routen
zu duplizieren. Bewusst keine neuen Sidebar-Punkte fuer Fahrzeuge/
Kontrollen/Pruefungen - dafuer gibt es keine eigenstaendigen Listen-
Seiten in MABEA.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Epic 20 (UI-Redesign) angelegt, Stufe 1: CSS-Variablen für Dark Mode
(System-Präferenz + manueller Schalter via ThemeToggle, localStorage-
persistiert) und eigene Farbtokens für Einsatzbereitschaft (ready/
limited/not-ready/unknown), Basis für ReadinessBadge in UI-003.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Scan-Ziel war noch auf den alten Kontroll-Direktsprung eingestellt,
obwohl die Akte (FILE-006) seit 2026-09-05 existiert. Kurzweg-Button
"Kontrolle starten" auf der Akte deckt den alten Ablauf weiter ab.
Frontend-Anzeigen-Audit über alle Epics ergab keine weiteren echten
Backend-fertig/Anzeige-fehlt-Lücken.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
4 parallele Review-Agenten (Reuse/Simplification/Efficiency/Altitude) gegen den
Diff dieser Session (c7dd47f...HEAD) laufen lassen, echte Funde angewendet:
- lager.py: 5x wiederholtes "db.get(...) or 404 raisen" durch _get_or_404()-
Helper ersetzt
- akte.py: zwei Queries für Geräte-Instanzen (erst Positions-IDs, dann Geräte)
zu einer Query mit Subquery zusammengefasst
- akte.py: manuelle Feld-für-Feld-Rekonstruktion von ObjektRead/HistorieRead
durch model_validate()+model_copy() ersetzt (HistorieRead.benutzer_name
bekommt dafür einen Default, harmlos für den bestehenden Endpunkt)
- vorlagen.py: doppelte "Positionen löschen + flush"-Logik (Vorlage-Löschen
und Positionen-Ersetzen) in loesche_alle_positionen() zusammengeführt
Bewusst nicht angewendet:
- Zentrale Session-Rollback-Vereinheitlichung für die drei Pre-Check-Stellen
(objekte.py Selbstbezug, geraet_instanz.py SN-Duplikat, lager.py Eltern-
Selbstbezug) - der Altitude-Review schlug das vor, aber get_db() rollt in
Produktion bei jeder Exception bereits korrekt zurück (jede Anfrage hat eine
eigene Session); das PendingRollbackError-Problem trat nur in der geteilten
Test-Session auf und wurde bereits gezielt per Pre-Check vermieden - eine
zusätzliche zentrale Rollback-Schicht würde nichts mehr reparieren, was
nicht schon repariert ist.
- Postgres-Cluster-Encoding (template1) auf beiden Hosts fixen, nicht nur in
CI/für die eine migrierte DB - echter Infra-Eingriff, braucht Rücksprache.
- LagerSection.tsx "inkonsistente" Formular-Resets - beim genaueren Hinsehen
gewolltes UX (Ort/Typ bleiben ausgewählt für mehrere Anlagen hintereinander).
140 Tests weiterhin grün.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Nutzer-Fund 2026-09-05: natives Drag&Drop funktionierte auf Desktop mit Maus
nicht zuverlässig und wäre auf Touch-Geräten ohnehin gar nicht nutzbar
(HTML5-DnD-API unterstützt keine Touch-Eingabe) - genau die Geräteklasse, die
dieses Projekt im Feld primär anspricht. Ersetzt durch Klick-zum-Zuordnen:
Material im Pool antippen (markiert es), dann Ziel-Fach antippen ordnet zu.
Funktioniert identisch auf Desktop und Touch.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Nutzer-Vorgabe: gute Inhalte aus Vergleichsprojekten übernehmen. Ersetzt die
Zeile-für-Zeile-Formular-Bearbeitung beim "Positionen bearbeiten" durch ein
Drag&Drop-Board: Material-Pool links, Fach-Spalten rechts (+ "Ohne Fach").
Material reinziehen ordnet zu, zwischen Spalten ziehen verschiebt das Fach,
"×" oder zurück in den Pool ziehen entfernt die Zuordnung. Sollmenge bleibt
inline editierbar. Nutzt weiterhin PUT /vorlagen/{id}/positionen, keine
Backend-Änderung nötig.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Meiste Punkte bereits erledigt (Vorlagen-Snapshot, Fahrzeug-Bug, CI-Fix, FLEET/
PERS-Kacheln), ein Widerspruch in der externen Roadmap markiert (Dispatch-Karte
vs. explizit ausgeschlossenes Dispatch/Alarmierung), zwei echte neue Punkte
protokolliert (Beladungsplanung Drag&Drop, Multi-Organisationen-Konzept).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Bisher wurde die Sollmenge einer Objektposition live aus der Vorlagenposition
gelesen (objekt.vorlage_id -> vorlagenposition.sollmenge), Bearbeiten der
Vorlage erzeugte deshalb zwingend eine neue Version - sonst hätte sich jede
Änderung rückwirkend auf alle Objekte ausgewirkt, die diese Vorlage nutzen.
- Neue Spalte objektposition.sollmenge_vorlage (Migration 0020): kopiert die
Sollmenge fest bei Anlage/Duplizieren statt live nachzuschlagen
- sollmenge_effektiv(position) liest jetzt nur noch override/sollmenge_vorlage,
kein DB-Lookup mehr nötig (sollmenge_map() entfernt)
- Neuer Endpoint PUT /vorlagen/{id}/positionen: ersetzt Positionen direkt,
ohne neue Version. Bestehende Objekte unbetroffen, nur neu angelegte nutzen
die aktualisierten Werte (Test: test_aktualisiere_positionen_wirkt_nicht_
rueckwirkend_auf_bestehendes_objekt)
- POST /vorlagen/{id}/neue-version bleibt zusätzlich bestehen (nicht entfernt)
- Frontend: "Neue Version speichern" -> "Positionen speichern" (PUT statt POST)
- 140 Tests grün
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Lagerort-Hierarchie (organisation/standort/gebaeude/raum/lager, self-referenzierend),
Lagerplätze mit eindeutigem Code, Bestand je Lagerplatz+Material, Ein-/Auslagerung
mit lückenlosem Materialbewegungsprotokoll (append-only, analog Lagerbewegung
auf Objekt-Ebene, hier aber Material-/Lagerplatz-fein).
- Migration 0019: 4 neue Tabellen (lagerort, lagerplatz, bestand, materialbewegung)
- Backend: CRUD Lagerort/Lagerplatz, Bestandsabfrage, Ein-/Auslagern-Endpunkte,
Negativbestand vorab abgefangen (kein DB-Constraint-Exception-Pfad, gleiches
Muster wie objekte.py-Fix vom 2026-09-05)
- Frontend: neuer Admin-Tab "Lager" (Lagerort/-platz-Verwaltung, Bestand+Buchung
je Lagerplatz)
- 2 neue Tests, 139 Tests weiterhin grün
WH-005 (Umlagerung) und WH-006 (Inventur) bewusst zurückgestellt - Kern zuerst,
laut Nutzer-Entscheidung.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
FILE-001..006 live (Akte-Aggregations-Endpunkt + Übersichtsseite), FILE-007
bewusst als eigene spätere QS-Kachel offen gelassen. MOBILE-002/004-Verweise
auf die vormals fehlende Akte korrigiert (Akte existiert jetzt, Scan-Ziel-
Umstellung ist nur noch kleiner Nachzug statt Neubau).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Größte Lücke aus arbeitskacheln/03_digital_file.md: alle Teilbereiche
(Stammdaten, Standort, Verantwortlichkeit, Historie, Dokumente, Geräte-
Prüfungen, Mängel) existierten einzeln, aber keine gebündelte Akte-Ansicht
je Objekt.
- GET /api/v1/akte/objekt/{id}: aggregiert alle Teilbereiche in einem Aufruf
(app/services/akte.py), 404 bei unbekanntem Objekt
- Zuständigkeits-Auflösung invertiert (wer ist für DIESES Objekt zuständig,
Standort-Vererbung + Objekt-Zeile als Vereinigung, Karte 04)
- Frontend: /akte/objekt/:objektId (AktePage.tsx), Link aus der Objektliste
- 2 neue Tests (test_akte.py), 137 Tests weiterhin grün
FILE-007 (Audit-Konsistenz-Check über alle Mutations-Endpunkte) bewusst
nicht Teil dieses Commits - eigene, spätere Qualitätssicherungs-Kachel.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Root Cause der "CI rot"-Meldung gefunden und behoben:
- CI legte Testdatenbank ohne explizites ENCODING an, erbte SQL_ASCII vom
Runner-Postgres-Template. Umlaute in JSONB (Historie-Einträge) brachen mit
UntranslatableCharacterError - betraf auch die Produktions-DB (separat
gemeldet, nicht Teil dieses Commits). CI legt jetzt explizit UTF8 an.
Drei echte Bugs beim Verifizieren gegen eine isolierte Testdatenbank gefunden:
- objekte.py PATCH /objekte/{id}: Selbstbezug-Check verließ sich auf den
DB-CHECK-Constraint statt vorab zu prüfen - ein Flush-Fehlschlag hinterlässt
die Session im Zustand DEACTIVE, jeder folgende Request in derselben Session
crasht mit PendingRollbackError (401 statt 404 im Test). Jetzt expliziter
Vorab-Check.
- geraet_instanz.py: gleiches Muster bei doppelter Seriennummer - jetzt
expliziter Vorab-Check statt UNIQUE-Constraint-Exception.
- test_lagerbewegung.py: Testbug, las objekt.standort_id NACH dem POST (durch
geteilte Session bereits auf den neuen Wert mutiert) statt vorher.
Nebenbei (Auftrag Priorität 4): "Mindermenge genehmigen"-Button direkt im
Nachfüll-Dialog der Kontroll-Erfassung (nur für materialverantwortlicher/
leitungsverantwortlicher/administration), nutzt den bereits bestehenden
POST /fehlbestaende/{id}/mindermenge Endpunkt.
Priorität 2 (Fahrzeug-Feldnamen-Mismatch) und Priorität 3 (nur Zugfahrzeuge
wählbar) waren bereits in früheren Commits erledigt (38b8ce1, 54fc296) -
Auftragsbeschreibung war auf altem Stand.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Inhalte bereits vollständig nach arbeitskacheln übernommen (siehe vorheriger Commit).
Alte Wiki-Links in ergebnisse/*.md, GESAMTDOKUMENT.md, prompts.md auf die gelöschten
Karten bleiben als historische Design-Doku unangetastet (kein Duplikat, eigener Aufwand).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
OPS-001..003 bewusst nur als Platzhalter spezifiziert (Ursprungs-Anforderung:
"noch nicht implementieren, aber architektonisch berücksichtigen") - kein
MABEA-Abgleich, da kein konkreter Bedarf vorliegt.
Damit sind alle 16 Epics des Backlogs mindestens einmal durchgegangen, 13
davon vollständig fachlich spezifiziert. Im Zuge der Detaillierung wurden
zwei echte Bugs in MABEA gefunden und noch am selben Tag live gefixt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
MOBILE-001/004/005 solide umgesetzt (Kontroll-UI gilt als Vorbild-Muster),
MOBILE-002 nur teilweise (Scan-Ziel ist Kontrolle statt vollständiger Akte,
hängt am Digital-File-Epic), MOBILE-003 (Offline) fehlt komplett, bewusst
P2/HIGH RISK.
Nutzer-Vorgabe: installierte Subagenten (postgres/sql/jwt/oauth-oidc/owasp/
docker/openapi/fastapi/python-expert) in die Kachel-Umsetzung einbeziehen -
zentrale Epic->Subagent-Zuordnungstabelle in 00_index.md statt Rework aller
11 Detail-Dateien.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Nutzer-Fund (Readiness-Backlog-Review): einsatzbereitschaft() zählte ein
Objekt ohne jede Kontrolle bisher als "einsatzbereit", weil keine Kriterien
verletzt waren - fachlich falsch, "nie geprüft" ist nicht dasselbe wie
"geprüft und in Ordnung".
Neuer vierter Zustand "unbekannt": Objekte ohne abgeschlossene Kontrolle UND
ohne sonstige Blocker fallen jetzt hierunter statt unter "einsatzbereit".
Objekte mit anderen Gründen (Fehlbestand/Mangel/Prüfung/...) bleiben davon
unberührt, die zählten schon vorher korrekt.
Tests angepasst: zwei bestehende Tests nutzten ungeprüfte Objekte und
erwarteten fälschlich "einsatzbereit" - jetzt entweder explizit kontrolliert
(Ist=Soll) oder auf "unbekannt" korrigiert, plus neuer Test für den Kernfall.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Funktional gut abgedeckt (einsatzbereitschaft() kombiniert schon mehr
Faktoren als ursprünglich spezifiziert). Zwei echte Lücken: keine
Konfigurierbarkeit (alles fest im Code, READY-001/005), und fachlich
wichtiger - fehlender UNKNOWN-Zustand: ein nie kontrolliertes Objekt gilt
aktuell fälschlich als einsatzbereit. Als neue Decision Required #5
aufgenommen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
PERS-003/005/006/007 vollständig in MABEA umgesetzt (Qualifikations-/
Berechtigungsprüfung sogar schon live getestet). PERS-001/002 (Person<->
Benutzer-Trennung) bleiben einziger echter offener Architekturentscheid im
gesamten Backlog - bewusst zurückgestellt bis konkreter Bedarf. PERS-004
(fachliche Funktion wie "Zugführer", getrennt von System-Rollen) fehlt
komplett.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Nutzer-Fund: funkkenner (z.B. OPTA-Nummer) fehlte in fahrzeugdetails komplett
- eigenes Feld, nicht dasselbe wie funkrufname (gesprochener Rufname vs.
formale Funk-Identifikationsnummer im Digitalfunknetz).
Migration 0018, Model/Schema/Frontend-Formular ergänzt. Auch im Kachel-
Backlog (arbeitskacheln/05_fleet.md, FLEET-002) nachgezogen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Fast vollständig in MABEA umgesetzt (Mangel-Modul deckt 4 von 5 Kacheln 1:1
ab). Kleinste Lücke aller bisher abgeglichenen Epics: DEFECT-003, eine aktive
Zuständigkeits-Zuweisung während der Mangel noch offen ist, fehlt (nur
erledigt_von nach Abschluss vorhanden).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Komplettes Epic fehlt in MABEA - kein Wartungskonzept vorhanden, nur Prüfung
(Inspections). Zusammen mit Warehouse und Digital File eines der drei Epics
mit größtem Umsetzungsaufwand, bewusst P2 (nicht MVP-kritisch).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Funktional großteils abgedeckt (Intervall-Berechnung, Fälligkeits-Ampel,
Prüftermin-Dashboard bereits produktiv), aber konzeptionell nicht generisch:
keine Prüfart-Stammdatentabelle, keine strukturierte Ergebnis-/Prüfer-
Erfassung, kein datumsunabhängiger FAILED-Zustand.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Am weitesten ausgereiftes Epic im Backlog - Beladungsvorlage/-versionierung,
Kontroll-Flow inkl. Sperre/Sofort-Nachfüllung/Signatur, letzte-Kontrolle-
Anzeige, Readiness-Kopplung sind in MABEA alle bereits produktiv. Keine
offenen Lücken.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Größter Abstand zwischen Backlog-Anspruch und MABEA-Ist-Stand bisher: Standort
ist flach (keine Hierarchie), kein Lagerplatz-Konzept, Lagerbewegung nur auf
Objekt-/Standort-Ebene statt Material-/Lagerplatz-Ebene, kein Inventur-Konzept.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
INV-005 (Ablaufdaten) und INV-006 (Fehlbestand/Mindermenge) decken sich
vollständig mit bereits ausgereiften MABEA-Modulen. INV-007 (Ausgabe/
Rückgabe) ist eine echte Lücke: MABEA kennt nur Standortzuordnung von
Objekten (Lagerbewegung), kein personenbezogenes Ausleih-Konzept für
Verbrauchsmaterial/Einzelteile.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Nutzer-Fund: FLEET-003 (Kilometerstand/Betriebsstunden) war fälschlich als
fahrzeug-gebundenes Datenmodell geplant, obwohl die Ursprungs-Anforderung
explizit auch Stromerzeuger/Pumpen mit betriebsstundenabhängiger Wartung
nennt (Modul 14). Neue generische Kachel ASSET-009 (Nutzungszähler)
eingeführt, FLEET-003 zur bloßen Fahrzeug-Anwendung davon reduziert.
MABEA-Abgleich korrigiert: echte Lücke ist jetzt doppelt - kein generischer
Zähler für Nicht-Fahrzeug-Geräte UND keine Rückwärtslauf-Validierung am
bestehenden Fahrzeug-Kilometerstand.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Fleet-Epic vollständig, Inventory-Epic begonnen (INV-005..007 folgen). Zwei
konkrete Funde beim MABEA-Abgleich: FLEET-003 (Kilometerstand) hat in MABEA
keine Rückwärtslauf-Validierung; INV-004 (Chargenverwaltung) wäre in MABEA
kein Nachzug sondern ein struktureller Umbau (Objektposition führt aktuell
nur eine Charge/Ablaufdatum, nicht mehrere gleichzeitig).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Digital-File-Epic damit vollständig (FILE-001..007), neues Assets-Epic
(04_assets.md) komplett detailliert. MABEA-Ist-Stand-Abgleich je Epic:
Digital File fehlt komplett (Aggregations-Akte existiert nirgends, obwohl
alle Einzelbausteine schon da sind), Assets ist bis auf AssetSet/Consumable
als eigenständige Konzepte bereits abgedeckt (Bereich/Kategorie/Objekttyp/
Objekt/Lagerbewegung).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Master-Prompt-Ergebnis vom 2026-09-05 (Epic-Übersicht, vollständige Kachel-
Liste, Abhängigkeitsgraph, MVP-Abgrenzung, Details zu den ersten 20 Kacheln)
aus dem Chat in Dateien überführt statt nur im Gespräch zu bleiben.
00_index.md: Decisions Required, Epic-Übersicht, vollständige Kachel-Tabelle,
Abhängigkeitsgraph, MVP-Abgrenzung.
01_foundation.md / 02_identity.md / 03_digital_file.md: Detailspezifikation
je Kachel (Ziel/Beschreibung/Datenmodell/Rechte/Akzeptanzkriterien/Tests/DoD),
jeweils mit Abgleich gegen den aktuellen MABEA-Ist-Stand.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Nutzer hat Screenshot von openfleet's Dashboard geschickt: linke Sidebar-Nav
statt Topbar, KPI-Kacheln mit Icon-Box/großer Zahl, sehr flach. Layout-Wechsel
komplett über CSS (.app-shell Reihe statt Spalte, .topbar wird zur
vertikalen 230px-Sidebar) - AppShell.tsx unverändert, kein JSX-Umbau nötig.
Unter 768px klappt es zurück auf die bisherige horizontale Topbar (Mobile-
Durchgang bleibt gültig, nur die Desktop-Optik ändert sich).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Nutzer-Vorgabe: Design in Richtung OpenFleet (schlicht) - Schatten auf none
gesetzt, Radius 12px->8px, ruhigere Palette. Da Schatten/Radius komplett über
CSS-Variablen liefen, genügt die Token-Änderung, kein Component-Code
angefasst.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
4 Admin-Sektionen (ObjektSection, MaterialSection, ZustaendigkeitSection,
ObjektPositionenPanel) hatten identisches fest-20rem/12rem-Sidebar-neben-
Liste-Layout ohne Umbruch - auf Mobile lagen beide Spalten nebeneinander
breiter als der Bildschirm. Neue global.css-Klassen .split-layout/
-sidebar/-sidebar-sm/-content lösen das inline-Style-Duplikat auf und
klappen unter 768px automatisch auf eine Spalte.
Zusätzlich: .page-wide/.topbar/.card-grid/.row bekommen eigene 768px-
Anpassungen (kleinere Paddings/Schrift, Kacheln volle Breite, automatischer
Zeilenumbruch). Tabellen (Historie/Lagerbewegungen) waren schon per
overflow-x:auto abgesichert, keine Änderung nötig dort.
Mitarbeiter-Mobilflow (ObjektListPage/KontrollPage, 640px-Spalte) unverändert
- war laut Nutzer-Feedback bereits gut.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Farbpalette/Radius/Schatten überarbeitet (global.css), alle bestehenden
Klassennamen bleiben unverändert - keine Seite muss angepasst werden. Neue
Klassen .card-grid/.stat-number für einheitliche KPI-Kacheln (Dashboard,
Mängel-Übersicht) - Muster aus allen drei Referenzprojekten (Resgrid/
OpenFleet/Emergency_Management_and_Coordination_System): Statistik-Karten
sind dort durchgängig das zentrale Dashboard-Element.
Dashboard/Mängel/Fehlbestände-Seiten von page (640px, für Mitarbeiter-
Mobilflow gedacht) auf page-wide umgestellt - das sind Verantwortliche-
Screens mit Karten/Listen, die auf Desktop-Breite gehören (Analog AdminPage).
Hartcodierte Statusfarben (#b00020/#b8860b) durch CSS-Variablen ersetzt.
Mobile/responsive Feinschliff folgt in einem eigenen Durchgang (Nutzer-
Entscheidung: erst Desktop normal bauen).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Nicht mitgezogen seit Migration 0012: personal, mangel, fahrzeugdetails,
lagerbewegung, dokument, permission. Live-Testlauf von scripts/create_admin.py
brach mit NoReferencedTableError ab (Benutzer.einheit_id -> einheit war nicht
registriert, da das Skript nur app.models.auth statt des vollständigen
Registry-Imports nutzt). App selbst lief nur zufällig fehlerfrei, weil
api.py alle Endpunkt-Module importiert und die dortigen Modell-Importe die
Lücke im Betrieb kaschiert haben.
Fix: __init__.py vervollständigt + create_admin.py/eskalation_pruefen.py
(täglicher Timer!) bekommen zusätzlich ein explizites "import app.models" als
Schutz, unabhängig davon ob die Registry künftig wieder unvollständig wird.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Additiv neben dem bestehenden 4-Rollen-System (mitarbeiter/material-
verantwortlicher/leitungsverantwortlicher/administration bleiben unverändert,
kein Breaking Change): Admin kann jetzt eigene Rollen (z.B. "Materialwart",
"Helfer" aus der Ursprungs-Anforderung) mit frei wählbaren Einzelrechten aus
einem Berechtigungs-Katalog anlegen und Benutzern zuweisen - auch Benutzern
ganz ohne feste RolleTyp-Zuordnung.
Neue Tabellen: berechtigung (Katalog), rolle (custom, admin-anlegbar),
rolle_berechtigung (M:N), benutzer_rolle_zuordnung (M:N, eigene Tabelle statt
Wiederverwendung des ENUM-basierten benutzer_rolle).
require_roles_or_permission() kombiniert beide Systeme: bestehende feste
Rollen ODER eine passende granulare Berechtigung. Auf die vom Nutzer genannten
Beispiel-Endpunkte angewendet: Material anlegen/bearbeiten, Lagerbewegung
durchführen, Mangel melden/lesen/bearbeiten, Prüfung durchführen - weitere
Endpunkte folgen bei Bedarf nach demselben Muster (require_permission()/
require_roles_or_permission() stehen jetzt als Bausteine bereit).
Neue Endpunkte: GET /berechtigungen, CRUD /rollen, PUT/DELETE
/rollen/{id}/berechtigungen/{id}, PUT/DELETE /benutzer/{id}/rollen/{id}.
Frontend: neuer Admin-Tab "Rollen & Rechte" (Rolle anlegen, Rechte togglen,
Benutzer zuweisen/entfernen).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Bisher waren nur Kontrolle/Fehlbestand/Nachfüllung/Mindermenge/Geräteinstanz
im append-only Audit-Log (historie.log() war seit Prompt 13 nie flächendeckend
verdrahtet, docstring sagte das bereits so). Drei neue Ereignisse ergänzt:
- mangel_gemeldet / mangel_status_geaendert (Mangel-Modul)
- qualifikation_erfasst (Personal-Modul, sicherheitsrelevant: "wer hat wem
wann eine Qualifikation bestätigt" hängt fachlich direkt an "wer darf
fahren")
- objekt_geaendert (Status-/Fahrzeug-Zuordnungsänderungen via PATCH /objekte)
Lagerbewegung bewusst NICHT zusätzlich in historie dupliziert - hat bereits
eigenes vollständiges Audit-Trail (Wer/Wann/Von/Nach/Grund in eigener
Tabelle).
Frontend: Änderungslog-Filter um geraet_instanz/mangel/benutzer_qualifikation/
objekt ergänzt (geraet_instanz fehlte dort zuvor ebenfalls).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Objekt bleibt der Materialträger (Rucksack/Gerät/Fahrzeug, Karte 11) -
"Material verschieben" heißt: das Objekt bekommt einen neuen Standort, jede
Bewegung wird append-only protokolliert (Wer/Wann/Von/Nach/Grund, Nutzer-
Vorgabe Modul 5).
POST /objekte/{id}/lagerbewegungen setzt Standort + protokolliert in einem
Zug, GET /lagerbewegungen (Filter objekt_id/standort_id) für die Historie.
Rollen wie beim Mangel-Modul: Materialverantwortliche+Leitung+Admin dürfen
verschieben, alle Eingeloggten dürfen lesen.
Frontend: "Verschieben"-Aktion in ObjektSection, neuer Admin-Tab
"Lagerbewegungen" (reine Anzeige, analog HistorieSection).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Kennzahlen: bestehender Endpoint /dashboard/kennzahlen war seit Prompt 12.1
nie im Frontend verdrahtet - jetzt eigene Kachel (offene Fehlbestände,
genehmigte Mindermengen, kürzlich erledigt, problematische Objekte, Objekte
gesamt).
Mängel: eigene Übersicht (offen/kritisch-Zahl + aufklappbare Liste) zusätzlich
zur bisherigen Erwähnung als Grund in Kachel 1 - nutzt bestehendes GET
/maengel, kein neuer Backend-Code.
Qualifikationsablauf: neuer Endpoint /dashboard/qualifikationsablaeufe
(bevorstehende_qualifikationsablaeufe(), 60 Tage Vorlauf) - analog
bevorstehende_prueftermine, aber für BenutzerQualifikation.gueltig_bis
(Nutzer-Vorgabe: "wer verliert bald Führerschein/Lehrgang-Gültigkeit").
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Neue Tabelle fahrzeugdetails (1:1 zu Objekt, additiv/optional): Kennzeichen,
Funkrufname, Baujahr, Kilometerstand, Betriebsstunden, nächste HU/UVV.
objekt_status um 'in_wartung' erweitert (Nutzer-Vorgabe: einsatzbereit/
eingeschränkt/nicht einsatzbereit/in Wartung/außer Dienst - die ersten drei
bleiben weiterhin rein rechnerisch über dashboard.einsatzbereitschaft(),
in_wartung/ausser_dienst sind die beiden manuell gesetzten Zustände).
dashboard.einsatzbereitschaft(): ausser_dienst-Objekte zählen nicht mehr mit,
in_wartung und überfällige HU/UVV sind neue Gründe für "nicht einsatzbereit".
dashboard.bevorstehende_prueftermine() (Kachel 2) zeigt jetzt Geräte- UND
Fahrzeugprüfungen (HU/UVV) in einer Liste (Nutzer-Vorgabe: ein Konzept für
"welche Prüfungen bald fällig sind") - Schema dafür verallgemeinert
(typ/bezeichnung/faelligkeitsdatum statt geräte-spezifischer Felder).
Frontend: Status-Dropdown + Fahrzeugdetails-Formular in ObjektSection
(nur für Objekttypen mit ist_zugfahrzeug=True), Dashboard-Kachel 2 zeigt
gemischte Liste.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Eigener Workflow für Schäden/Defekte, getrennt von Fehlbestand (Mengen-
Abweichung Soll/Ist). Status: neu → in_bearbeitung → ersatzteil_bestellt/
reparatur_geplant → erledigt. entitaet_typ/entitaet_id optional (Objektposition
oder Geräteinstanz), analog zum bestehenden historie.entitaet_typ-Muster,
objekt_id immer gesetzt für Dashboard-Abfragen.
Ein offener Mangel mit prioritaet=hoch macht das Objekt "nicht einsatzbereit"
(neuer Grund mangel_kritisch_offen in dashboard.einsatzbereitschaft) -
niedrige/normale Mängel blockieren nicht.
Melden/Lesen: alle Mitarbeiter+. Status ändern: Materialverantwortliche+.
Neue Seite /maengel für alle eingeloggten Nutzer (Nav-Link "Mängel").
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Neues Modul für die BOS-Ressourcenplattform-Erweiterung: Einheit (Zug/Gruppe,
self-referenzierend), Qualifikationstyp (Führerschein/Lehrgang/Berechtigung),
BenutzerQualifikation (mit Gültigkeit) und ObjekttypQualifikationsanforderung
(M:N) - beantwortet "wer darf dieses Fahrzeug fahren?" über
GET /objekte/{id}/berechtigung/{benutzer_id}.
Benutzer und Objekt bekommen optionale einheit_id (additiv, analog
fahrzeug_id-Muster). Nebenbei Bugfix: PATCH /benutzer konnte einheit_id nicht
auf null setzen (Feld-vorhanden-Check via model_fields_set statt is not None).
Frontend: neuer Admin-Tab "Personal" (Einheiten, Qualifikationstypen,
Benutzer-Qualifikationszuordnung), Einheit-Auswahl im Benutzer-Formular.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Bisher nirgends vermerkt/abrufbar, wann ein Objekt zuletzt komplett
kontrolliert wurde (nur roh in kontrolle.beendet_am ableitbar). Neues Feld
ObjektRead.letzte_kontrolle_am (jüngste Kontrolle mit status=abgeschlossen),
angezeigt in Objektliste und Admin-Objektsektion ("noch nie kontrolliert"
falls keine).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Materialverantwortlicher/Leitungsverantwortlicher/Administration werden nach
Login direkt zum neuen Leitungs-Dashboard geleitet statt zur Objektliste.
rollen im AuthContext laden asynchron nach - daher hier direkt /auth/me
abfragen statt auf den Context zu warten.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Objekttyp.ist_zugfahrzeug (Migration 0011) grenzt die Fahrzeug-Zuordnung
serverseitig auf tatsächliche Zugfahrzeuge ein (422 bei Verstoß), Frontend
filtert die Fahrzeug-Dropdowns entsprechend.
Neue Dashboard-Endpunkte /dashboard/einsatzbereitschaft und
/dashboard/prueftermine plus DashboardPage mit drei Kacheln
(Einsatzbereitschaft, Prüftermine, Ablaufdaten). Aktive
Mindermengen-Genehmigung zählt als "eingeschränkt einsatzbereit", nicht als
voll einsatzbereit (U2/Karte 08).
Neue FehlbestandListePage: Fehlbestände eigenständig nachfüllen/Mindermenge
genehmigen, ohne komplette Kontrolle des Objekts zu starten (Backend
existierte bereits, nur das Frontend fehlte).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
Beladungsvorlage/Vorlagenposition haben keine ORM-relationship() (nur rohe
FK-Spalten), SQLAlchemy kannte die Lösch-Reihenfolge nicht und schlug beim
echten Löschversuch mit FK-Verletzung fehl.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Vorlagen sind bewusst versioniert (Prompt 08) - normalerweise wird eine
Version durch eine neue ersetzt (status=veraltet), nie gelöscht. Echtes
Löschen jetzt möglich, aber nur wenn kein Objekt diese Version referenziert
(409 sonst) - für versehentlich angelegte/Test-Versionen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
89 "Blutdruckmanschette" <- 91 "Blutdruckmanschette ALT" zusammengelegt
(152 Materialien). Echter Konflikt an 7 Objekten geprüft und dokumentiert -
kein Datenverlust (Konfliktzeilen alle im Default-Zustand, einziger echter
Historie-Treffer korrekt umgehängt statt gelöscht).
ZustaendigkeitSection: gleiches zweispaltiges Layout mit Suche wie Material-/
Objektliste. screenshots/ ins .gitignore (lokale Debug-Bilder, nicht für
den Remote gedacht).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Anlegen-Formular links fix (20rem, nur Admin), Objektliste rechts mit
Suchfeld oben (Name/Code) - gleiches Muster wie MaterialSection, wächst
mit der Anzahl Objekte mit statt unsuchbare Liste zu werden.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Saß bisher als volle Bar über Sidebar+Kartenspalte (Screenshot-Fund) - jetzt
Teil der rechten Kartenspalte, direkt über der Positionsliste. Sidebar wird
nur noch gerendert, wenn Positionen existieren (Edge-Case: leeres Objekt
konnte bisher kein erstes Material bekommen, da der ganze Bereich hinter
positionen.length>0 hing).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
ObjektPositionenPanel: Fach-Sidebar (Vorlagen-Feature "feste Fächer-Liste")
links, damit die Bestückung übersichtlich bleibt und auch Dritte (Vertretung
ohne die Kontrollperson) sehen, wo welches Material im Rucksack hingehört.
Gruppierungslogik aus KontrollPage in gemeinsames Util (utils/fachGruppierung)
ausgelagert, da jetzt zweimal gebraucht.
.page-wide: margin:0 statt zentriert (Nutzer-Vorgabe: bei 1200px sonst viel
verschenkter Platz links/rechts auf breiten Monitoren).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
ObjektPositionenPanel zeigte bisher nur ablauf_charge/geraet_sn-Positionen
und konnte weder Sollmenge-Override noch Status noch neues Material ändern
- Backend-Endpunkte (PATCH/POST .../positionen) existierten schon, waren im
Frontend nicht angebunden.
Jetzt: alle Positionen sichtbar, Sollmenge-Override je Position, Entfernen/
Reaktivieren (ist_status), zusätzliches Material hinzufügen (Dropdown mit
noch nicht vorhandenen Materialien + Sollmenge).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
.page-wide (max-width 1200px statt 640px) für die AdminPage - Tabellen
(Änderungslog) und mehrspaltige Formulare brauchen am Desktop mehr Platz
als die mobile Kontroll-Ansicht der Mitarbeiter. Objektliste/Kontrolle/
Login bleiben bei .page (640px, mobile-optimiert).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Bug: Frontend prüfte nur istAdmin, Materialverantwortliche und Leitungs-
verantwortliche sahen exakt dieselbe UI wie Mitarbeiter - obwohl das Backend
längst granular unterscheidet (require_roles je Endpunkt).
- AuthContext gibt volle Rollenliste + istVerantwortlich/istMaterial-
verantwortlich/istLeitungsverantwortlich weiter.
- /admin-Route für alle drei Rollen offen, AdminPage filtert Tabs nach
Rolle (Material/Leitung: Objekte-Pflege, Kontrollverantwortung,
Änderungslog; nur Administration: Stammdaten/Benutzer/Eskalation/
Zuständigkeit).
- ObjektSection blendet Anlegen/Duplizieren/Kopplung für Nicht-Admins aus
(waren admin-only im Backend, hätten 403 geworfen).
- Promise.allSettled statt Promise.all beim Laden, damit ein admin-only
Endpunkt (z.B. /benutzer) nicht die ganze Seite für niedrigere Rollen
blockiert.
- Backend: GET /benutzer jetzt auch für Material-/Leitungsverantwortliche
lesbar (für Kontrollverantwortung-Auswahl im Frontend nötig), Schreiben
bleibt admin-only.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Excel-Kontext (Rettungsrucksack.xlsx Zeile 50, direkt nach "Beatmungsbeutel
Kind") + Nutzer-Bestätigung: "Beatmunsmaske" (102) war die S-Größe, andere
Rucksäcke führen Beatmungsmaske S/M/L bereits einzeln. Zusammengelegt mit
161 "Beatmungsmasken S" (154 Materialien).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Live-Datenbereinigung (172 -> 155 Materialien): Excel-Import-Tippfehler und
Leerzeichen-Varianten zusammengelegt, Material 148 "Manometer SN 1308409"
korrigiert (Name -> "Manometer", materialtyp -> geraet_sn, SN als erste
geraet_instanz-Zeile). Skript und Entscheidungsprotokoll (inkl. bewusst
unverändert gelassener Fälle) dokumentiert für Nachvollziehbarkeit.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Backend: geraet_instanz-CRUD (Liste/Anlegen/Status ändern inkl. optionalem
Fehlbestand pro Gerät/Löschen), pruefintervall_monate in Objektposition-
Schemas verdrahtet (Prüfdatum -> naechste_pruefung wird automatisch
berechnet, Monatsrechnung ohne neue Dependency).
Frontend: GeraeteInstanzenListe ersetzt das Einzel-SN-Feld im Admin-Portal
(ObjektPositionenPanel) durch eine Instanz-Liste mit Status/Prüfdatum/
Bemerkung je Exemplar - löst das Karte-14-Kernproblem (mehrere Geräte pro
Position). ObjektSection: Anhänger-Kopplung bei Anlage und nachträglich
änderbar.
Kontroll-Erfassung (PositionCard/KontrollPage) bleibt unverändert - die
komplett neue Erfassungs-UI für geraet_sn (Umsetzungsschritt 4, Karte 14)
ist bewusst nicht Teil dieses Commits.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
objektposition.seriennummer war ein Einzelfeld, konnte nur EIN Gerät pro
Materialtyp/Objekt abbilden (z.B. 2 Pulsoxymeter im selben Rucksack nicht
darstellbar). Neue Tabelle geraet_instanz erlaubt beliebig viele Exemplare
pro Position (Seriennummer, Prüfdatum, nächste Prüfung, Status). Zusätzlich
objektposition.pruefintervall_monate (individuell überschreibbar).
Bewusst additiv: seriennummer-Spalte bleibt vorerst stehen (Service/
Endpunkte/Frontend hängen noch daran), bestehende Werte werden per
INSERT...SELECT nach geraet_instanz kopiert. Drop + Umbau der abhängigen
Schichten folgt in Umsetzungsschritt 2 (siehe arbeitskarten/14_...).
Migration von postgres-expert gegengeprüft (ON CONFLICT DO NOTHING als
Sicherheitsnetz, DROP TYPE IF EXISTS ergänzt), Tests decken Mehrfach-
Instanzen, UNIQUE-Constraint je Position, gleiche SN an verschiedenen
Positionen und pruefintervall_monate ab.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Neuer Admin-Tab "Zuständigkeit": Benutzer materialverantwortlich für Standort
(vererbt sich auf alle Objekte dort) oder einzelnes Objekt zuordnen, Liste,
Entfernen. Backend-Endpunkte (inkl. DELETE) waren bereits vorhanden.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV