Files
nexarch/docs/VAL-04-PRUEFPROTOKOLL.md
patrickandClaude Sonnet 5 c3afbe8da2
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (pull_request) Canceled after 0s
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
Core-Pflichttest-Gate / pflichttest-gate (pull_request) Canceled after 0s
RBAC-Rollenhierarchie-Pflichtgate / rbac-policy-invariant (pull_request) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (pull_request) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (pull_request) Canceled after 0s
CI / Connect Security-Test-Gate (QA-01 AC4, Merge-Gate) (pull_request) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (pull_request) Canceled after 0s
CI / Connect Security-Test-Gate (QA-01 AC4, Merge-Gate) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
CI / Web (dms-browser) (pull_request) Canceled after 0s
CI / Web (pdf-viewer) (pull_request) Canceled after 0s
CI / Web (shl) (pull_request) Canceled after 0s
Core-Schnittstellen-Vertragstests / contract-tests (pull_request) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (pull_request) Canceled after 0s
Supply-Chain-Scan (npm) / npm-audit (pull_request) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (pull_request) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
VAL-04: audit-log-kontinuitaetspruefung
Pruefprotokoll mit Testergebnissen (real durchgefuehrt).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-14 21:54:48 +00:00

4.8 KiB
Raw Permalink Blame History

VAL-04 – Pruefprotokoll: Audit-Log-Kontinuitaetspruefung

Auftrag

Pruefung, dass aeltester und neuester Audit-Log-Eintrag je Tenant nach der Migration (COR-05, internal/migrationaudit) mit der Quelle (legacy_audit_log_staging) uebereinstimmt — keine Luecke, keine Zeitverschiebung.

Umsetzung

Neues Paket internal/migrationauditcontinuity:

  • continuity.go: AuditStats (Anzahl, aeltester/neuester Zeitstempel je Seite), StatsProvider-Interface, ContinuityReport mit Luecke(), Zeitverschiebung() und OffenerBefund() — jede der beiden Abweichungen gilt als blockierender Befund, es gibt (anders als bei VAL-01) keinen Erklaerungs-Mechanismus, da das Produkt-DNA-Prinzip fuer Audit-Logs keine Ausnahme vorsieht. Run() vergleicht Quelle gegen Ziel je Tenant.
  • postgres.go: PostgresSourceStatsProvider liest Anzahl/min/max aus legacy_audit_log_staging, ueber tenant_migration_map auf den Tenant-Slug aufgeloest (beide Altsysteme in einer Abfrage, je nach belegter archivmail_tenant_id/archivdms_tenant_id-Spalte). PostgresTargetStatsProvider liest dieselben Werte direkt aus audit_events (COR-05-Ziel).
  • render.go: RenderBericht() (deutschsprachige Markdown-Tabelle je Tenant, Berichtsmuster aus VAL-01 internal/migrationverify) und OffeneBefunde().
  • continuity_test.go: zwei Integrationstests gegen einen echten Postgres-Testcluster (Host 204).

Kein Eingriff in COR-05 (internal/migrationaudit) oder VAL-01 (internal/migrationverify) — reines, zusaetzliches Lese-/Pruefwerkzeug nach demselben Muster.

Pruefungen vor Abnahme — real durchgefuehrt

Testcluster: Host 204, TEST_ADMIN_DSN aus /etc/nexarch-dev/core-dev.env (Werte nie im Klartext ausgegeben, nur per set -a && source ... && set +a im selben Befehl eingespeist). Eigenes Test-Schema je Lauf (internal/testdb), automatisch aufgeraeumt.

Pruefung 1: Aeltester/neuester Eintrag fuer 3 Test-Tenants exakt mit Quelle abgeglichen

TestKontinuitaetspruefung_DreiTenantsMitEntferntemEintrag:

  • 3 synthetische Test-Tenants (mandant-a, mandant-b, mandant-c), je mit mehreren historischen legacy_audit_log_staging-Eintraegen (Zeitstempel 2018–2020, synthetische IPs/Metadaten).
  • Migration via migrationaudit.Migrator.MigrateAll (COR-05, unveraendert).
  • migrationauditcontinuity.Run gegen Quelle und Ziel.
  • Ergebnis: fuer mandant-a und mandant-b (ohne Manipulation) stimmen Anzahl, aeltester und neuester Zeitstempel exakt ueberein, OffenerBefund() ist false. Zielwert erreicht: PASS.

Pruefung 2: Absichtlich entfernter Testeintrag wird als Luecke erkannt

Selber Test, Tenant mandant-c: nach der Migration wird ein mittlerer Audit-Eintrag im Ziel (audit_events) real geloescht (Append-only-Trigger dafuer temporaer deaktiviert, wie es ein tatsaechlicher Datenverlust im Betrieb taete), die zugehoerige Staging-Referenz zuvor geloest, um die Fremdschluessel-Bindung sauber aufzuheben.

  • Ergebnis: Quelle=3, Ziel=2 Eintraege fuer mandant-c. ContinuityReport.Luecke() ist true, OffenerBefund() ist true. Der gerenderte Bericht enthaelt fuer diesen Tenant "OFFENER BEFUND", OffeneBefunde() liefert genau diesen einen Tenant. Zielwert erreicht: PASS.

Zusatzpruefung: Zeitverschiebung ohne Lueckenbildung

TestKontinuitaetspruefung_Zeitverschiebung (ueber die geforderten Pruefungen hinaus, deckt den zweiten in Akzeptanzkriterium 2 genannten Fall explizit ab): Zeitstempel eines migrierten Eintrags wird im Ziel um eine Stunde verschoben (Append-only-Update-Trigger temporaer deaktiviert). Anzahl bleibt identisch (Luecke() = false), aber Zeitverschiebung() = true, somit OffenerBefund() = true. Zielwert erreicht: PASS.

Testlauf

go test ./internal/migrationauditcontinuity/... -v
=== RUN   TestKontinuitaetspruefung_DreiTenantsMitEntferntemEintrag
--- PASS: TestKontinuitaetspruefung_DreiTenantsMitEntferntemEintrag (0.20s)
=== RUN   TestKontinuitaetspruefung_Zeitverschiebung
--- PASS: TestKontinuitaetspruefung_Zeitverschiebung (0.09s)
PASS
ok  	gitea.perlbach24.de/scripte/nexarch/internal/migrationauditcontinuity	0.297s

go build ./... und go vet ./... fuer das gesamte Repository: fehlerfrei.

Akzeptanzkriterien — Abgleich

  1. Fuer jeden Tenant liegt ein Kontinuitaetsbericht vor — Run() erzeugt je Tenant genau einen ContinuityReport, RenderBericht() stellt sie als Markdown-Tabelle dar. Erfuellt.
  2. Jede erkannte Luecke oder Zeitverschiebung ist ein blockierender Befund — OffenerBefund() kennt keine Erklaerungs-Ausnahme, beide Testfaelle (Luecke, Zeitverschiebung) zeigen den Befund. Erfuellt.

DSGVO

Alle Testdaten synthetisch (fiktive Tenant-/Nutzernamen, erfundene IPs/Metadaten), keine archivmail-/archivdms-Exporte verwendet. Keine Zugangsdaten im Code, Testverbindung ausschliesslich ueber TEST_ADMIN_DSN aus der Umgebung.