fix(historie): Audit-Lücke bei Mangel/Personal/Objekt-Änderungen geschlossen
CI / backend-tests (push) Failing after 1m47s
CI / frontend-build (push) Successful in 17s

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
This commit is contained in:
2026-09-05 13:50:48 +02:00
co-authored by Claude Sonnet 5
parent 417df2beb6
commit 11ad747136
9 changed files with 201 additions and 16 deletions
+24 -4
View File
@@ -4,6 +4,7 @@ from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.mangel import Mangel, MangelPrioritaet, MangelStatus
from app.services import historie as historie_service
OFFENE_MANGEL_STATI = (
MangelStatus.neu,
@@ -25,9 +26,28 @@ async def objekt_ids_mit_kritischem_offenem_mangel(db: AsyncSession) -> set[int]
return set(result.scalars().all())
async def erledige_mangel(db: AsyncSession, *, mangel: Mangel, benutzer_id: int) -> Mangel:
mangel.status = MangelStatus.erledigt
mangel.erledigt_von = benutzer_id
mangel.erledigt_am = datetime.now(timezone.utc)
async def aendere_status(
db: AsyncSession, *, mangel: Mangel, status: MangelStatus, benutzer_id: int, zustaendiger_server_id: int
) -> Mangel:
"""Historie-Lücke (Roadmap-Review): Status-Änderungen wurden bisher NICHT
protokolliert - Mangel hatte anders als Kontrolle/Fehlbestand/Geräteinstanz
kein Audit-Trail, obwohl "wer hat den Mangel auf erledigt gesetzt" fachlich
genauso relevant ist."""
alter_status = mangel.status
mangel.status = status
if status == MangelStatus.erledigt:
mangel.erledigt_von = benutzer_id
mangel.erledigt_am = datetime.now(timezone.utc)
await db.flush()
await historie_service.log(
db,
zustaendiger_server_id=zustaendiger_server_id,
benutzer_id=benutzer_id,
ereignistyp="mangel_status_geaendert",
entitaet_typ="mangel",
entitaet_id=mangel.id,
alter_wert={"status": alter_status.value},
neuer_wert={"status": status.value},
)
return mangel