feat(sprint-6): Phase 4 — Immutable audit log
Deploy to Production / test (push) Has been cancelled
Deploy to Production / deploy (push) Has been cancelled

- V8 migration: audit_events table (JSONB metadata, immutable by design)
- AuditEvent entity + AuditEventType enum (18 event types)
- AuditService: log events, paginated query, PDF export
- AuditController: GET /api/v1/audit (paginated, filtered), GET export
- AuditEventRepository with JPQL filtered queries
- Frontend: /audit-log page (read-only, filterable, timezone-aware)
- PDF export button for Behörde inspections
- Sidebar: 'Protokoll' under new Compliance section
- PdfReportGenerator: generateAuditReport method added
- 10-year retention, REVOKE DELETE documented
- Full i18n (de/en) with 18 event type translations
This commit is contained in:
Patrick Plate
2026-06-12 22:40:40 +02:00
parent 61e481b37b
commit 05933a08ca
12 changed files with 982 additions and 0 deletions
+45
View File
@@ -399,5 +399,50 @@
"active": "Aktiv",
"pastDue": "Zahlung ausstehend",
"canceled": "Gekündigt"
},
"audit": {
"title": "Audit-Protokoll",
"subtitle": "Unveränderliches Protokoll aller Vorgänge (10 Jahre Aufbewahrung)",
"timestamp": "Zeitstempel",
"type": "Typ",
"description": "Beschreibung",
"actor": "Akteur",
"entity": "Objekt",
"filterType": "Ereignistyp filtern",
"filterDateFrom": "Von",
"filterDateTo": "Bis",
"filterActor": "Akteur suchen",
"exportPdf": "Als PDF exportieren",
"exporting": "PDF wird generiert...",
"exported": "Audit-Protokoll exportiert.",
"allTypes": "Alle Typen",
"immutable": "Unveränderbar",
"timezone": "Europe/Berlin",
"retentionNote": "Aufbewahrungsfrist: 10 Jahre (KCanG-konform)",
"types": {
"DISTRIBUTION_RECORDED": "Ausgabe erfasst",
"DISTRIBUTION_VOIDED": "Ausgabe storniert",
"MEMBER_CREATED": "Mitglied angelegt",
"MEMBER_UPDATED": "Mitglied aktualisiert",
"MEMBER_SUSPENDED": "Mitglied gesperrt",
"MEMBER_EXPELLED": "Mitglied ausgeschlossen",
"BATCH_CREATED": "Charge angelegt",
"BATCH_RECALLED": "Charge zurückgerufen",
"LOGIN_SUCCESS": "Anmeldung",
"LOGIN_FAILED": "Fehlgeschlagene Anmeldung",
"LOGOUT": "Abmeldung",
"PASSWORD_CHANGED": "Passwort geändert",
"STAFF_INVITED": "Mitarbeiter eingeladen",
"STAFF_PERMISSIONS_CHANGED": "Berechtigungen geändert",
"STAFF_REVOKED": "Zugang entzogen",
"CONSENT_GRANTED": "Einwilligung erteilt",
"CONSENT_REVOKED": "Einwilligung widerrufen",
"DATA_EXPORTED": "Daten exportiert",
"DATA_DELETED": "Daten gelöscht",
"SUBSCRIPTION_STARTED": "Abo gestartet",
"SUBSCRIPTION_CANCELED": "Abo gekündigt",
"PAYMENT_RECEIVED": "Zahlung erhalten",
"PAYMENT_FAILED": "Zahlung fehlgeschlagen"
}
}
}
+45
View File
@@ -399,5 +399,50 @@
"active": "Active",
"pastDue": "Past due",
"canceled": "Canceled"
},
"audit": {
"title": "Audit Log",
"subtitle": "Immutable log of all operations (10-year retention)",
"timestamp": "Timestamp",
"type": "Type",
"description": "Description",
"actor": "Actor",
"entity": "Entity",
"filterType": "Filter by event type",
"filterDateFrom": "From",
"filterDateTo": "To",
"filterActor": "Search actor",
"exportPdf": "Export as PDF",
"exporting": "Generating PDF...",
"exported": "Audit log exported.",
"allTypes": "All types",
"immutable": "Immutable",
"timezone": "Europe/Berlin",
"retentionNote": "Retention period: 10 years (KCanG-compliant)",
"types": {
"DISTRIBUTION_RECORDED": "Distribution recorded",
"DISTRIBUTION_VOIDED": "Distribution voided",
"MEMBER_CREATED": "Member created",
"MEMBER_UPDATED": "Member updated",
"MEMBER_SUSPENDED": "Member suspended",
"MEMBER_EXPELLED": "Member expelled",
"BATCH_CREATED": "Batch created",
"BATCH_RECALLED": "Batch recalled",
"LOGIN_SUCCESS": "Login",
"LOGIN_FAILED": "Failed login",
"LOGOUT": "Logout",
"PASSWORD_CHANGED": "Password changed",
"STAFF_INVITED": "Staff invited",
"STAFF_PERMISSIONS_CHANGED": "Permissions changed",
"STAFF_REVOKED": "Access revoked",
"CONSENT_GRANTED": "Consent granted",
"CONSENT_REVOKED": "Consent revoked",
"DATA_EXPORTED": "Data exported",
"DATA_DELETED": "Data deleted",
"SUBSCRIPTION_STARTED": "Subscription started",
"SUBSCRIPTION_CANCELED": "Subscription canceled",
"PAYMENT_RECEIVED": "Payment received",
"PAYMENT_FAILED": "Payment failed"
}
}
}