Skip to content

Section I backend — audit trail + topology source - #32

Merged
patricznr1 merged 2 commits into
mainfrom
feat/i-audit-topology-backend
Jun 22, 2026
Merged

Section I backend — audit trail + topology source#32
patricznr1 merged 2 commits into
mainfrom
feat/i-audit-topology-backend

Conversation

@patricznr1

@patricznr1 patricznr1 commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Teil 1 von Sektion I (Plattform/Audit). Macht das nackte audit_logs-Skelett zu einem unveränderlichen, pseudonymen Audit-Trail (zugleich AI-Act-/Art.-50-Nachweis-Beleg) und leitet eine ehrliche Systemtopologie aus realen Quellen ab. §4I der Designstudie ist [VISION]; dieser PR baut die ehrlich abgeleitete Teilmenge — kein erfundener Knoten, kein erfundener Akteur.

Teil A — Audit-Trail

  • Migration 0010 (additiv): actor (HMAC-Token, nie Klartext), actor_role, action_type/origin (CHECK), target_kind/target_id/machine_id, detail (JSONB), occurred_at; Lese-Indizes; Append-Only-Trigger (PL/pgSQL, weist UPDATE/DELETE ab — Defense-in-Depth; bewusst kein TRUNCATE-Trigger, damit Test-/Reset-Pfade leeren können).
  • Writer mit zwei Wegen: record() in-session/atomar (HITL), emit_mcp_retrieval() best-effort auf eigener Session (MCP) — die MCP-Read-Only-Invariante bleibt intakt.
  • Zwei reale Schreibpfade: Drift-Quittier-Route (origin=dashboard, atomar) und der MCP-Tool-Wrapper _measured (origin=mcp, im finally nach geschlossener Read-Session).
  • GET /api/v1/audit — gefiltert (action_type/target_kind/target_id/actor/machine_id/since/until), paginiert, jüngste zuerst, nur Manager/Admin.

Teil B — Topologie-Quelle

  • Ehrlich abgeleitet: Eingänge aus data_points.source + jüngster readings-Aktivität (simulation als intern), Gedächtnis-Substrat (Live-Smoke-Probe, ?probe=false abschaltbar), F7-MCP-Grenze (Aktivität aus den neuen mcp_retrieval-Audit-Zeilen). Status nur wo messbar (sonst unbekannt, nie grün); benannte Drittsysteme nur in separater [VISION]-Liste.
  • GET /api/v1/topology — Manager voll · Schichtleiter nur Verbindungsstatus (kein Audit) · Werker/Techniker 403.

Ehrliche Abweichungen von der Prompt-Annahme (kein Fake)

  1. MCP-Akteur: mcp/auth.py hat keine Per-Client-Identität (nur ein geteilter Token) → actor = pseudonymisiertes Single-Consumer-Label; per-Client-Attribution bleibt [VISION].
  2. Quittier-Route liegt am Drift-Reasoner (alarms.py hat keine Ack-Route) — dort hängt der HITL-Write.
  3. audit_logs.user_id bleibt erhalten, aber ungenutzt; actor (HMAC) ist die pseudonyme Referenz. §8 nachgezogen.
  4. GROUND_TRUTH-Migrationsliste hing bei 0008 → 0009 + 0010 nachgetragen.

Verifikation

  • mypy strict 0, ruff clean + Format clean.
  • Migration 0010 up/down getestet; Trigger blockt UPDATE/DELETE nachgewiesen (eigene ephemere DB je Lauf).
  • MCP-Read-Only-Invariante nachgewiesen; Rollen-Guards (401/403); Topologie ehrlich; [VISION] markiert; Pseudonymität (actor nie Klartext).
  • Coverage ≥ 80 % auf audit//topology/ + neuen Routern. 607 Backend-Tests grün (lokal ohne F-PRED) + 31 neue Sektion-I-Tests.
  • GROUND_TRUTH (§4/§5/§8/§21.16/§22) + WALKTHROUGH im selben Commit. Hidden-Term-Scan sauber.

Nicht in diesem PR: Frontend §4I (Teil 2). Nicht selbst gemergt — bitte du.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Neuer Audit-Trail-Read-Endpunkt GET /api/v1/audit mit Filterung und Pagination (rollenbasiert, nur Manager).
    • Neue Systemtopologie-Ansicht GET /api/v1/topology mit Live-Status/Frischefenster und rollenbasierter Detailtiefe.
    • Automatisches Audit-Logging für Drift-Alarm-Bestätigungen sowie für Systemabfragen über die MCP-Schnittstelle (pseudonymisiert).
  • Bug Fixes

    • Erzwingt „Append-only“-Unveränderlichkeit des Audit-Trails auf Datenbankebene.
  • Documentation

    • Erweiterte Walkthrough-Dokumentation für Audit-Trail, Unveränderlichkeit und Topologie-Quelle.

Part 1 of Section I (platform/audit). Turns the bare `audit_logs`
skeleton into an immutable, pseudonymous audit trail and derives an
honest system topology from real sources.

Audit trail:
- Migration 0010: additive columns (actor HMAC token, action_type,
  target_kind/id, machine_id, origin, detail JSONB, occurred_at) +
  CHECK constraints + an append-only trigger (blocks UPDATE/DELETE,
  defense-in-depth; no TRUNCATE trigger so test/reset paths still work).
- Writer with two paths: in-session record() for the HITL acknowledge
  (atomic), best-effort emit() for MCP retrievals on its own session so
  the MCP read-only invariant stays intact.
- Two real writer paths: the drift acknowledge route (origin=dashboard)
  and the MCP tool wrapper _measured (origin=mcp). MCP actor is a
  pseudonymous single-consumer label (auth.py has no per-client id;
  per-client attribution stays [VISION]).
- GET /api/v1/audit, filtered + paginated, manager/admin only.

Topology source:
- Honestly derived nodes only: ingest sources (data_points.source +
  latest readings activity, simulation marked internal), memory
  substrate (best-effort live smoke probe), F7 MCP boundary (activity
  from the new mcp_retrieval audit rows). Status only where measurable
  (else unbekannt, never green). Named third systems stay in a separate
  [VISION] list.
- GET /api/v1/topology: manager full, shift_lead status-only, others 403.

actor is always an HMAC token, never cleartext (section 8); user_id
retained but unused. GROUND_TRUTH + WALKTHROUGH updated in the same commit.

Tested: mypy strict 0, ruff clean, migration 0010 up/down + trigger,
MCP read-only invariant, role guards, honest topology; coverage >=80%
on audit/ + topology/ + new routers. 607 backend tests green
(local, minus F-PRED) + 31 new Section-I tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 56201b4a-4c90-481d-85ea-6e60501506d9

📥 Commits

Reviewing files that changed from the base of the PR and between b6e1929 and 4c69620.

📒 Files selected for processing (5)
  • GROUND_TRUTH.md
  • src/foreman/api/routers/audit.py
  • src/foreman/api/routers/topology.py
  • src/foreman/audit/schemas.py
  • tests/migrations/test_migration_0010.py
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/foreman/api/routers/topology.py
  • src/foreman/audit/schemas.py
  • src/foreman/api/routers/audit.py
  • tests/migrations/test_migration_0010.py
  • GROUND_TRUTH.md

📝 Walkthrough

Walkthrough

PR führt ein vollständiges Audit-Trail-Subsystem (Schema-Migration mit Append-Only-Trigger, Pydantic-Schemas, Writer-Hilfsfunktionen, Read-Service und Router) sowie einen abgeleiteten Topologie-Read-Endpoint ein. Beide Router werden in FastAPI registriert. MCP-Tools und der Drift-Acknowledge-Endpoint schreiben Audit-Einträge. Migrations-Roundtrip-, API- und Topologie-Integrationstests sowie Dokumentationsaktualisierungen ergänzen die Änderungen.

Changes

Audit-Trail & Topologie-Backend (Sektion I)

Layer / File(s) Zusammenfassung
AuditLog-Schemaerweiterung & Migration 0010
src/foreman/db/models.py, migrations/versions/0010_audit_trail_topology.py
AuditLog-ORM-Modell um typisierte Audit-Spalten (actor, actor_role, action_type, target_kind/id, machine_id, origin, detail, occurred_at), CheckConstraints und vier Indizes erweitert. Migration 0010 ergänzt dieselben Spalten/Constraints/Indizes und installiert den PL/pgSQL-Append-Only-Trigger (BEFORE UPDATE OR DELETE); downgrade() entfernt alles in umgekehrter Reihenfolge.
Audit-Pydantic-Schemas & Konstanten
src/foreman/audit/schemas.py, src/foreman/audit/__init__.py, src/foreman/audit/writer.py
AuditEntry (eingefrorenes Schreib-Contract mit frozen=True) und AuditEntryRead (Read-API-Sicht mit from_attributes=True) definiert. Action-/Origin-/MCP-Actor- und Label-Konstanten eingeführt.
Audit-Writer: build, record, emit
src/foreman/audit/writer.py
build_audit_log bildet AuditEntry auf AuditLog ab (inkl. Legacy-Spiegelung für action/target). hitl_acknowledge_entry und mcp_retrieval_entry erzeugen pseudonymisierte Entries. record schreibt atomar in eine übergebene Session (add+flush); emit_mcp_retrieval schreibt best-effort auf eigener Session mit Commit und schluckt alle Exceptions.
Audit-Service & Read-API-Router
src/foreman/audit/service.py, src/foreman/api/routers/audit.py
list_audit baut paginierte, gefilterte SQLAlchemy-Abfrage auf AuditLog mit Sortierung nach occurred_at DESC auf. Audit-Router exponiert GET /api/v1/audit mit Rollen-Check (nur ROLE_MANAGER → 403 sonst) und delegiert an list_audit.
HITL-Audit-Schreiben im Drift-Acknowledge
src/foreman/reasoners/drift/router.py
acknowledge_drift_alarm ruft await record(session, hitl_acknowledge_entry(...)) innerhalb desselben DB-Sessions wie die Quittierung auf und erfasst Operator-Rolle, pseudonymisierten user_id, alarm_id, machine_id und severity.
MCP-Tool-Wrapper mit Audit-Emission
src/foreman/mcp/tools.py
_measured-Kontext-Manager um optionale Zielparameter (target_kind, target_id, machine_id) erweitert; ruft emit_mcp_retrieval im finally-Block auf. Alle elf MCP-Tool-Handler (list_machines, get_machine, get_drift_status, get_alarms, list/get_failure_predictions, get_worker_recommendation, list/get_event_chains, search_notes, get_readings) übergeben semantische Zielmetadaten.
Topologie-Schemas & Service
src/foreman/topology/__init__.py, src/foreman/topology/schemas.py, src/foreman/topology/service.py
TopologyNode und TopologyView Pydantic-Modelle definiert. Status (verbunden/gestört/inaktiv/unbekannt) und Richtungs-Konstanten (liefert/liest/beides/keine) eingeführt. build_topology leitet Eingangsknoten aus DataPoint/Reading, Substrat-Knoten via Smoke-Probe und MCP-Grenze aus AuditLog-Zeilen ab.
Topologie-Read-API-Router & App-Verdrahtung
src/foreman/api/routers/topology.py, src/foreman/main.py
GET /api/v1/topology prüft Rolle (nur ROLE_MANAGER/ROLE_SHIFT_LEAD → 403 sonst), schaltet include_audit rollenbasiert um (Manager: Audit, Schichtleiter: kein Audit). audit.router und topology.router in _API_V1_ROUTERS für Mounten unter /api/v1 registriert.
Audit-Tests: Writer, API, MCP
tests/audit/test_writer.py, tests/audit/test_audit_api.py, tests/audit/test_mcp_audit.py
Unit-Tests für Writer-Feld-Mapping, Pseudonymisierung und Legacy-Spalten-Spiegelung. Integrationstests für HITL-Audit-Eintrag nach Drift-ACK, RBAC (401/403/200), Query-Filter (action_type, machine_id, Zeitfenster) und Service-Level-Filter. MCP-Audit-Zeilen-Struktur und read-only-Invariante.
Migrations-Roundtrip-Test 0010
tests/migrations/test_migration_0010.py
Erstellt isolierte Postgres-DB, prüft Upgrade auf head, verifiziert neue Spalten, Trigger-Blockierung (INSERT ok, UPDATE/DELETE abgewiesen), CHECK-Constraint-Verletzung, dass TRUNCATE erlaubt ist. Downgrade auf 0009 und Spaltenentfernung, erneutes Upgrade zur Idempotenz-Prüfung.
Topologie-Service- & HTTP-Tests
tests/topology/test_topology.py
Prüft Knotenstatus (verbunden/inaktiv/unbekannt), internal-Flag für Simulation-Sources, unkonfiguriertes Substrat, MCP-Knoten mit consumer_count, Vision-Markierung und HTTP-RBAC inkl. shift_lead-Audit-Detail-Unterdrückung. Best-effort Substrat-Smoke-Probe-Tests via Monkeypatching.
Dokumentations-Updates
GROUND_TRUTH.md, docs/WALKTHROUGH.md
GROUND_TRUTH.md um Audit-/Plattform-Routen-Spezifikation, vollständige audit_logs-Tabellendefinition, Migrations-Liste (0009/0010), Datenschutz-Klarstellung und Sektion-I-Narrativ erweitert. WALKTHROUGH.md erhält Sektion I mit Schema, Writer, Schreibpfaden, Read-Endpoints und dokumentierten Gates.

Sequence Diagram(s)

sequenceDiagram
  participant Client as API-Client
  participant AuditRouter as GET /api/v1/audit
  participant TopologyRouter as GET /api/v1/topology
  participant AuditService as list_audit()
  participant TopologyService as build_topology()
  participant DB as PostgreSQL

  Client->>AuditRouter: GET /api/v1/audit?action_type=...&machine_id=...
  AuditRouter->>AuditRouter: Rollen-Check (nur manager → sonst 403)
  AuditRouter->>AuditService: list_audit(session, filter-params, limit, offset)
  AuditService->>DB: SELECT * FROM audit_logs WHERE ... ORDER BY occurred_at DESC
  DB-->>AuditService: Sequence[AuditLog]
  AuditService-->>AuditRouter: Sequence[AuditLog]
  AuditRouter-->>Client: list[AuditEntryRead]

  Client->>TopologyRouter: GET /api/v1/topology?probe=true&fresh_within_minutes=60
  TopologyRouter->>TopologyRouter: Rollen-Check (manager/shift_lead → sonst 403)
  TopologyRouter->>TopologyService: build_topology(session, include_audit=True/False, ...)
  TopologyService->>DB: SELECT source, max(time) FROM readings GROUP BY source
  TopologyService->>DB: SELECT actor, max(occurred_at) FROM audit_logs WHERE action_type=mcp_retrieval
  TopologyService-->>TopologyRouter: TopologyView
  TopologyRouter-->>Client: TopologyView (nodes + vision + generated_at)
Loading
sequenceDiagram
  participant Operator as Operator (HITL)
  participant DriftRouter as PATCH /drift/alarms/:id/acknowledge
  participant Writer as audit/writer.py
  participant DB as PostgreSQL

  Operator->>DriftRouter: PATCH acknowledge (Bearer token)
  DriftRouter->>DriftRouter: Setzt acknowledged_at + acknowledged_by
  DriftRouter->>Writer: hitl_acknowledge_entry(pseudo, user_id, role, alarm_id, machine_id, ...)
  Writer-->>DriftRouter: AuditEntry (pseudonymisierter actor)
  DriftRouter->>Writer: record(session, entry)
  Writer->>DB: INSERT INTO audit_logs ... (add + flush, kein Commit)
  DriftRouter->>DB: COMMIT (atomar mit Alarm-Update)
  DB-->>DriftRouter: OK
  DriftRouter-->>Operator: 200 OK
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • patricznr1/foreman#4: Das vorliegende PR erweitert den Drift-Reasoner-Acknowledge-Endpunkt in src/foreman/reasoners/drift/router.py um HITL-Audit-Schreiben, das direkt auf dem Drift-Acknowledge-Endpunkt aufbaut.
  • patricznr1/foreman#16: Das vorliegende PR ergänzt src/foreman/mcp/tools.py um Audit-Emission und Zielmetadaten-Weitergabe, das denselben MCP-Tools-Stack betrifft, der in diesem PR ausgebaut wurde.
  • patricznr1/foreman#31: Das vorliegende PR enthält die gleiche Migration 0009_event_chain_snapshot wie das abgerufene PR, die reasoner_explanations.chain_snapshot und siblings_snapshot einführt.

Poem

🐇 Ein Hase tippt fleißig im Datenbankland,
schreibt Audit-Logs mit pseudonymisierter Hand.
BEFORE UPDATE — nein, das lasse ich nicht!
Append-only, klar, das ist meine Pflicht. 🔒
Topologie blüht, der MCP-Knoten glänzt,
weil dieser PR alles zusammen ergänzt. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 39.51% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Der PR-Titel bezieht sich direkt auf die Hauptänderungen: Implementation von Audit-Trail und Topologie-Quelle (Section I Backend Part 1), was die core Objetktive des PRs widerspiegelt.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/i-audit-topology-backend

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/foreman/api/routers/audit.py (1)

20-20: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Ungenutzter Import.

AuditLog wird in diesem Modul nicht direkt verwendet – list_audit gibt Sequence[AuditLog] zurück, aber FastAPI serialisiert über response_model=list[AuditEntryRead]. Der Import kann entfernt werden.

♻️ Vorgeschlagene Bereinigung
 from foreman.audit.schemas import AuditEntryRead
 from foreman.audit.service import list_audit
-from foreman.db.models import AuditLog
 from foreman.realtime.authz import ROLE_MANAGER
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/foreman/api/routers/audit.py` at line 20, The import statement for
`AuditLog` from `foreman.db.models` is unused in this module. Although
`AuditLog` may appear in type hints, FastAPI handles serialization via the
`response_model=list[AuditEntryRead]` parameter, making this import unnecessary.
Remove the `from foreman.db.models import AuditLog` line from the file.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@GROUND_TRUTH.md`:
- Around line 127-129: The role naming terminology is inconsistent across the
document. In the endpoints documented for the GET /api/v1/audit and GET
/api/v1/topology sections, the terms "Manager/Admin" are used, but the actual
role model defined in §5 only defines the roles: worker, shift_lead, technician,
and manager. Standardize all role references in these sections to match the
authoritative role model from §5 by replacing "Manager/Admin" with either just
"manager" or by explicitly adding "admin" as an official role throughout the
document if that role is actually supported by the system, ensuring consistency
across all affected sections (the GET /api/v1/audit description, GET
/api/v1/topology description, and any other similar references).

In `@tests/migrations/test_migration_0010.py`:
- Around line 119-140: The test for the append-only trigger behavior is
incomplete. After the DELETE test block and before the CHECK constraint test
(after line 140), add a new test case that verifies TRUNCATE operations are
permitted on the audit_logs table despite the append-only trigger being active.
Unlike the UPDATE and DELETE operations which should raise
asyncpg.exceptions.RaiseError with the "append-only" message, the TRUNCATE
operation should execute successfully without raising an exception. This
verifies that the append-only trigger permits TRUNCATE for test and reset
operations as documented in the PR objectives.

---

Nitpick comments:
In `@src/foreman/api/routers/audit.py`:
- Line 20: The import statement for `AuditLog` from `foreman.db.models` is
unused in this module. Although `AuditLog` may appear in type hints, FastAPI
handles serialization via the `response_model=list[AuditEntryRead]` parameter,
making this import unnecessary. Remove the `from foreman.db.models import
AuditLog` line from the file.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2b2fe210-3961-46a6-965f-0a1cfda43650

📥 Commits

Reviewing files that changed from the base of the PR and between 938472b and b6e1929.

📒 Files selected for processing (21)
  • GROUND_TRUTH.md
  • docs/WALKTHROUGH.md
  • migrations/versions/0010_audit_trail_topology.py
  • src/foreman/api/routers/audit.py
  • src/foreman/api/routers/topology.py
  • src/foreman/audit/__init__.py
  • src/foreman/audit/schemas.py
  • src/foreman/audit/service.py
  • src/foreman/audit/writer.py
  • src/foreman/db/models.py
  • src/foreman/main.py
  • src/foreman/mcp/tools.py
  • src/foreman/reasoners/drift/router.py
  • src/foreman/topology/__init__.py
  • src/foreman/topology/schemas.py
  • src/foreman/topology/service.py
  • tests/audit/test_audit_api.py
  • tests/audit/test_mcp_audit.py
  • tests/audit/test_writer.py
  • tests/migrations/test_migration_0010.py
  • tests/topology/test_topology.py

Comment thread GROUND_TRUTH.md
Comment thread tests/migrations/test_migration_0010.py
- Role consistency: replace "Manager/Admin" with "Manager" in the
  GROUND_TRUTH contract + router docs/comments — the role vocabulary
  (section 5) has no `admin` role; the platform/audit view is enforced
  for `manager`. Add a study-mapping note (Designstudie §4I says
  "Manager/Admin" → maps to manager; future admin role would be
  additive in _AUDIT_ROLES/_FULL_ROLES).
- Migration 0010 test: assert TRUNCATE is still permitted (the
  deliberate "no TRUNCATE trigger" choice so test/reset paths can
  clear the table) — append-only covers UPDATE/DELETE, not "never
  emptyable".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@patricznr1

Copy link
Copy Markdown
Owner Author

CodeRabbit-Feedback adressiert (Commit 4c69620):

  • Rollen-Konsistenz („Manager/Admin" → „Manager"): das Rollen-Vokabular (§5) kennt keine separate admin-Rolle; die Plattform-/Audit-Sicht ist für manager durchgesetzt. GROUND_TRUTH + Router-Doku vereinheitlicht, plus ein Mapping-Hinweis (Designstudie §4I nennt „Manager/Admin" → bildet auf manager ab; eine künftige echte admin-Rolle käme additiv in _AUDIT_ROLES/_FULL_ROLES). Die Designstudie selbst bleibt unverändert (Vision-Quelle).
  • TRUNCATE-Verifikation im Migrationstest ergänzt: prüft jetzt explizit, dass TRUNCATE trotz Append-Only-Trigger erlaubt bleibt (die bewusste „kein TRUNCATE-Trigger"-Entscheidung — Test-/Reset-Pfade müssen leeren können). Append-only meint UPDATE/DELETE.
  • ↩️ Nitpick AuditLog-Import (audit.py): bewusst belassen — der Import wird im Return-Typ Sequence[AuditLog] des Handlers verwendet (der die ORM-Objekte zurückgibt, FastAPI serialisiert über response_model=list[AuditEntryRead]). Entfernen bräche mypy --strict und ruff (F821 in der Annotation). Kein False-Negative beim Lint-Gate, daher kein Change.

Gates lokal grün nach den Fixes: mypy strict 0, ruff clean + Format clean, Migrationstest (inkl. TRUNCATE) grün.

@patricznr1
patricznr1 merged commit c3e7690 into main Jun 22, 2026
3 checks passed
@patricznr1
patricznr1 deleted the feat/i-audit-topology-backend branch June 22, 2026 12:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant