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
@@ -0,0 +1,26 @@
-- V8: Immutable Audit Log (KCanG §19 — 10-year retention)
CREATE TABLE IF NOT EXISTS audit_events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
event_type VARCHAR(50) NOT NULL,
entity_type VARCHAR(50) NOT NULL,
entity_id UUID,
actor_id UUID NOT NULL,
actor_name VARCHAR(255) NOT NULL,
actor_role VARCHAR(20) NOT NULL,
description TEXT NOT NULL,
metadata JSONB,
ip_address VARCHAR(45),
timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
tenant_id UUID NOT NULL
);
-- Indexes for efficient querying
CREATE INDEX idx_audit_timestamp ON audit_events(timestamp DESC);
CREATE INDEX idx_audit_entity ON audit_events(entity_type, entity_id);
CREATE INDEX idx_audit_actor ON audit_events(actor_id);
CREATE INDEX idx_audit_tenant ON audit_events(tenant_id);
CREATE INDEX idx_audit_type ON audit_events(event_type);
-- IMMUTABILITY: Revoke DELETE from application user
-- (In production, run as DBA: REVOKE DELETE ON audit_events FROM cannamanage_app;)
COMMENT ON TABLE audit_events IS 'Immutable audit log — 10-year retention (KCanG). Application role cannot DELETE.';