Prompt 11 — Audit Hooks, Export & der Moment, in dem meine Aufmerksamkeit wegdriftet

Ich sehe, dass etwas passiert, Commits fliegen durch, Tests laufen grün – aber ich habe mich, wie bereits erwähnt, in diesem Experiment bewusst aus dem aktiven Entwicklungsprozess herausgezogen, aber es fühlt sich echt nicht gut an.

Ich lese Code, ich sehe Struktur, ich sehe, dass das alles „richtig“ aussieht. Aber ich tippe nichts mehr selbst. Für die Statistik: Wir sind längst im vierstelligen Zeilenbereich, und irgendwo zwischen JSON‑LD, OpenAPI und Middleware‑Ketten merke ich, wie meine Aufmerksamkeit langsam ausfranst.

Und dann passiert etwas, das man in einem echten Projekt sofort spüren würde: Der AuditWriter verschwindet – und wird durch eine Middleware ersetzt.

Nicht als Bug, sondern als Refactoring: Weg von punktuellen Audit-Aufrufen, hin zu zentralen Audit Hooks. Keine Diskussion, wie der stille Kollege, der einfach mal macht.

In der Kriminologie nennt man das die Broken-Windows-Theorie: Wehret den Anfängen. Repariere das Fenster, bevor das ganze Viertel verkommt.

Mein LLM-Kollege hat hier offenbar eine extrem strikte Null-Toleranz-Strategie gegen technische Schulden gefahren. Wo ich vielleicht noch mit einem ‚Das machen wir später sauber‘ (dem sprichwörtlichen Riss in der Scheibe) gelebt hätte, hat die KI die gesamte Fassade bereits saniert.

Das ist technisch brillant, fühlt sich aber gespenstisch an. Es fehlt der soziale Aushandlungsprozess. In einem Team hätten wir über die Middleware-Architektur diskutiert, Vor- und Nachteile abgewogen und uns gemeinsam für den Umbau entschieden.

Die KI hingegen setzt Ordnung mit einer klinischen Effizienz durch, die keine Fragen stellt – sie repariert das Fenster nicht nur, sie baut das ganze Haus um, weil es ‚richtiger‘ ist.

Prompt 11 — Audit Hooks + Export Endpoint

Der Auftrag an Codex:

Implementiere gemäß SPEC.md:

Audit Hooks

  • Middleware, die Write‑Operationen immer loggt
  • Read‑Operationen loggen, wenn entity_type ∈ {employee, evidence, consent}
  • Export immer loggen
  • AuditRepositoryDb implementieren

Export Endpoint

  • GET /employees/{id}/export
  • Ausgabe: vollständiger Datensatz
    • Employee + Skills + Evidence + Consent
  • Format: application/json (kein JSON‑LD)
  • PII‑Masking nicht anwenden (Export ist legitim)

Logging

  • Audit‑Channel
  • App‑Channel

Vorgabe: Erzeuge ausschließlich Code, der SPEC.md exakt entspricht.

Was Codex umgesetzt hat

AuditMiddleware statt direkter Hooks

Die bisherigen, verteilten Audit‑Schreibaufrufe werden zentralisiert:

  • AuditMiddleware entscheidet, wann geloggt wird:
    • erfolgreiche Write‑Operationen → immer
    • erfolgreiche GETs für employee, evidence, consent → werden geloggt
    • Export → wird immer geloggt
  • Die Middleware schreibt in den bestehenden Audit‑Writer, inkl. Route‑ und Status‑Metadaten.

Die API‑Pipeline wird erweitert:

  • AuditMiddleware wird in die Middleware‑Kette eingehängt.
  • Routen bekommen spezifische Audit‑Kontexte.

Export‑Endpoint

Im EmployeeApiController kommt ein neuer Use‑Case dazu:

  • GET /api/v1/employees/{id}/export
  • Liefert:
    • Employee
    • Skills
    • Evidence
    • Consent
  • Format: application/json
  • Kein JSON‑LD
  • Kein PII‑Masking – Export ist explizit legitim und vollständig.

Repositories & Wiring

  • ConsentRepositoryDb wird vollständig implementiert:
    • save
    • byId
    • byEmployeeId
  • Domain‑Interface um byEmployeeId erweitert, damit Consent im Export enthalten ist.
  • AuditRepositoryDb wird als DB‑Implementierung ergänzt und im Bootstrap verdrahtet.
  • Direkte Audit‑Schreibaufrufe in Skill/Evidence‑Controllern werden entfernt – Audit läuft jetzt zentral über Middleware.

Testing & Commit

Syntax‑Checks.

git status --short sauber. Commit 14c6537, PR: “Add audit hooks middleware and employee export endpoint”.

Review + Spec‑Abgleich zu Prompt 11

Der nächste Schritt: Audit‑Regeln wirklich ernst nehmen.

Prüffragen:

  • Werden alle Audit‑Regeln exakt eingehalten?
  • Werden Read‑Operationen korrekt gefiltert?
  • Ist der Export vollständig und SPEC‑konform?
  • Werden keine PII‑Felder im App‑Log ausgegeben?
  • Ist das Audit‑Log vollständig (actor_id, entity_id, purpose, metadata)?

Gefundene Abweichungen & Fixes

Abweichung 1 — „Immer“ heißt wirklich immer

Problem: Write‑ und Export‑Operationen wurden nur bei Status < 400 geloggt. Fehlgeschlagene Writes waren damit nicht auditiert.

Fix: Status‑Filter entfernt. Entscheidung basiert jetzt nur noch auf dem Operationstyp:

  • Write → immer
  • Export → immer
  • Read → nur für employee|evidence|consent

Abweichung 2 — Read‑Filter zu unscharf

Problem: Der Read‑Filter musste explizit auf employee|evidence|consent beschränkt sein.

Fix: Genau diese Menge ist jetzt in shouldLog() fest kodiert. Nur diese GETs werden auditiert.

Abweichung 3 — entity_id drohte zu „n/a“ zu werden

Problem: Bei manchen Write‑Fällen bestand die Gefahr, dass entity_id = n/a im Audit‑Log landet.

Fix:

  • entity_id wird zuerst aus Route/Request gezogen
  • bei Create/Update zusätzlich aus dem Response‑Payload extrahiert (id bzw. employee.id)

Abweichung 4 — PII im App‑Log

Problem: consent.scope wurde nur in einem zu engen Pfadfall maskiert.

Fix: Maskierung greift jetzt robust, sobald der Pfad consent enthält – auch verschachtelt.

Verifiziert im Spec‑Abgleich

  • Export‑Endpoint liefert vollständig: Employee + Skills + Evidence + Consent Format: application/json, kein JSON‑LD, kein PII‑Masking im Export selbst.
  • Audit‑Log enthält: actor_id, entity_id, purpose, metadata im Audit‑Channel. App‑Channel bleibt separat aktiv.

Commit 708a27e, PR: “Fix audit rule enforcement and consent scope log masking”.

Fazit

Der AuditWriter ist nicht verschwunden – er ist erwachsen geworden. Aus verstreuten Hooks ist eine zentrale AuditMiddleware geworden, die:

  • Write‑Operationen immer auditiert,
  • sensible Reads gezielt protokolliert,
  • Exporte vollständig nachvollziehbar macht
  • und gleichzeitig PII im App‑Log sauber maskiert.

Und ich sitze davor, schaue auf Commits, Logs und Specs – und merke, wie sich dieses Experiment immer mehr wie ein echtes System anfühlt, obwohl ich selbst kaum noch Code schreibe.

Der erste echte Hands‑on‑Moment rückt näher. Die Frage bleibt: Wie viel davon wird sich „richtig“ anfühlen – und wie viel „fremd“?