Commit Graph
5 Commits
Author SHA1 Message Date
sysopsandClaude Sonnet 5 3376cf99dc AUD-05: audit-log-registrierung bei archive-retention-engine
internal/audit/retention.go: RegisterWithArchive meldet audit_log_entry als
Objekttyp bei Archives Retention-Engine an (Default-Frist 10 Jahre, GoBD-
Buchungsbeleg-Frist, tenant-ueberschreibbar). RetentionRegistrar ist der
RET-05-Modul-Adapter-Vertrag, wie Core ihn konsumiert — die eigentliche
Implementierung lebt im Archive-Modul.

WICHTIGER HINWEIS: Archive (RET-01 Retention-Objektmodell, RET-02 Fristen-
Engine, RET-05 Modul-Adapter) existiert zum Zeitpunkt dieser Kachel NICHT
als Code — nur als Planung in archive-kanban/. Diese Kachel implementiert
ausschliesslich die Core-Seite (Registrierungsaufruf gegen die Schnittstelle)
und testet sie gegen einen lokalen Fake, der den RET-05-Vertrag simuliert.
Das ist KEIN Ersatz fuer eine echte Integrationspruefung gegen Archive.

Core implementiert bewusst keine eigene Loeschlogik fuer Audit-Eintraege
(Akzeptanzkriterium 3) — es gibt in diesem Paket keinen Delete-Codepfad
ausser dem durch AUD-02 technisch unterbundenen.

Pruefungen:
1. Registrierung bei Archive erfolgreich getestet, Objekttyp taucht in
   Archives Retention-Konfiguration auf — NICHT durchfuehrbar, da Archive
   nicht existiert. Stattdessen TestRegisterWithArchive_UsesCorrectObjectTypeAndRetention
   gegen Fake: bestaetigt korrekten Aufruf mit objectType=audit_log_entry,
   10 Jahre, tenantOverridable=true. Ausgefuehrt, PASS — aber die eigentliche
   Pruefung bleibt OFFEN bis Archive RET-05 existiert.
2. Audit-Eintrag mit abgelaufener Frist wird von Archive korrekt als
   loeschfaellig markiert, Core greift nicht ein — NICHT durchfuehrbar ohne
   Archive RET-02. Offen.
3. Legal Hold aus Archive verhindert Loeschung trotz abgelaufener Frist —
   NICHT durchfuehrbar ohne Archive RET-01/02. Offen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 20:56:48 +02:00
sysopsandClaude Sonnet 5 b12d53f469 AUD-01: zentrales-audit-log-modell
internal/audit: eigenes, strukturiertes Audit-Datenmodell (Akteur, Aktion,
Zielobjekt, Zeitpunkt, Tenant) in der Registry-DB, getrennt von jedem
allgemeinen Anwendungs-Log (eigenes Paket, eigene Tabelle audit_events,
kein Logging-Framework). Log.Record ist der EINE zentrale Schreibpfad —
es gibt keine zweite Schreibmoeglichkeit, ueber die ein Handler die
Validierung umgehen koennte.

Fehlender Tenant-Bezug wird zweifach verhindert (Akzeptanzkriterium 2):
Log.Record weist leeren TenantSlug direkt ab (ErrMissingTenant), zusaetzlich
erzwingt eine CHECK-Constraint in der Migration dasselbe auf Datenbankebene,
selbst wenn Log.Record umgangen wuerde. Mandantenuebergreifende Ereignisse
(z.B. Superadmin-Aktionen) nutzen den reservierten Wert audit.SystemTenant
statt NULL oder leerem String — es gibt keinen Weg, ganz ohne Tenant-Bezug
zu schreiben.

Pruefungen (ausgefuehrt auf root@192.168.1.131, go build/vet/test PASS):
1. Automatisierter Test belegt genau einen Audit-Eintrag pro
   sicherheitsrelevantem Vorgang — TestRecord_PersistsExactlyOneEventPerSecurityIncident
   (simulierter fehlgeschlagener Login), Feldinhalte verifiziert. PASS.
2. Fehlender Tenant-Bezug durch Constraint/Test verhindert —
   TestRecord_RejectsMissingTenant (App-Ebene) UND
   TestConstraint_RejectsMissingTenantAtDatabaseLevel (direkter INSERT unter
   Umgehung von Log.Record, durch CHECK-Constraint abgewiesen). PASS.
3. Datenmodell von zweiter Person gegen Dokumentation geprueft — NICHT
   durchgefuehrt (keine zweite Person in dieser Session verfuegbar). Offen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 19:22:50 +02:00
sysopsandClaude Sonnet 5 8da9c67d08 TEN-01: tenant-registry-datenbank-provisioning
Registry-DB (nur Tenant-Metadaten), Provisioning-Routine legt pro Mandant
eine physisch isolierte Postgres-DB an und registriert sie transaktional
(Rollback der DB bei fehlgeschlagener Registrierung). Schlanker HTTP-Handler
als Schnittstellen-Vorbereitung fuer API-01/TEN-02, kein eigenes REST-Grundgerüst.

Pruefungen:
1. Migration up/down geschrieben (0001_tenant_registry.{up,down}.sql) — nicht
   gegen echte DB ausgefuehrt, da auf dieser Maschine kein Go/Postgres-Test-
   Setup verfuegbar ist. Offen zur Ausfuehrung.
2. Integrationstest TestProvision_CreatesIsolatedDatabases geschrieben (zwei
   Mandanten, prueft unterschiedliche db_name und current_database()) —
   ebenfalls nicht ausgefuehrt, guarded per TEST_ADMIN_DSN env var. Offen.
3. Slug-Validierung (unit test TestValidateSlug) deckt SQL-Injection-Versuch
   im Datenbanknamen ab — ebenfalls nicht lokal ausgefuehrt, da kein Go
   Compiler auf dieser Maschine vorhanden ist. Offen.

Alle drei Pruefungen sind vorbereitet, aber NICHT durchgefuehrt worden —
zaehlen laut Vorgabe als offen bis auf einer Maschine mit Go+Postgres verifiziert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 17:40:35 +02:00
sysops c895a67c4b core: initial Go module skeleton (config, db pool, tenant registry migration) 2026-08-27 17:27:59 +02:00
sysops 72261cc69f first commit 2026-08-27 17:20:02 +02:00