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
AuditRepositoryDbimplementieren
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:
AuditMiddlewareentscheidet, 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:
AuditMiddlewarewird 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
ConsentRepositoryDbwird vollständig implementiert:savebyIdbyEmployeeId
- Domain‑Interface um
byEmployeeIderweitert, damit Consent im Export enthalten ist. AuditRepositoryDbwird 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_idwird zuerst aus Route/Request gezogen- bei Create/Update zusätzlich aus dem Response‑Payload extrahiert (
idbzw.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,metadataim 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“?