TeamVis Self-Host-Bundle v0.31.0
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
-- DSGVO Art. 17 (Recht auf Vergessenwerden) fuer Empfangs-Audit-Daten.
|
||||
-- ====================================================================
|
||||
-- Problem: reception_visit_audit ist per Trigger append-only (GoBD).
|
||||
-- Bei einem Loeschanspruch nach DSGVO muessen aber personenbezogene
|
||||
-- Daten aus dem `payload`-JSON entfernt werden — die strukturelle
|
||||
-- Zeile (id, occurred_at, event_kind, actor_kind, actor_id, lead_id)
|
||||
-- bleibt fuer den Audit-Trail erhalten.
|
||||
--
|
||||
-- Loesung:
|
||||
-- 1. Spalte `redacted_at` markiert anonymisierte Eintraege.
|
||||
-- 2. UPDATE-Trigger erlaubt EINEN spezifischen UPDATE-Pfad: das
|
||||
-- Setzen von `redacted_at` UND gleichzeitiges Nullen / Redacten
|
||||
-- der payload-PII. Alle anderen UPDATEs werden weiterhin geblockt.
|
||||
-- 3. card_leads bekommt auch `redacted_at` — Anonymisierung sowohl
|
||||
-- im Hauptdatensatz als auch im Audit-Log.
|
||||
|
||||
alter table public.reception_visit_audit
|
||||
add column if not exists redacted_at timestamptz;
|
||||
|
||||
alter table public.card_leads
|
||||
add column if not exists redacted_at timestamptz;
|
||||
|
||||
-- Trigger neu definieren: erlaubt UPDATEs die NUR redacted_at + payload
|
||||
-- ändern (Anonymisierungs-Pfad). Aenderungen anderer Spalten bleiben
|
||||
-- blockiert.
|
||||
create or replace function public.reject_reception_audit_modify()
|
||||
returns trigger as $$
|
||||
begin
|
||||
if tg_op = 'DELETE' then
|
||||
raise exception 'reception_visit_audit ist append-only — DELETE nicht erlaubt';
|
||||
end if;
|
||||
-- UPDATE: nur erlauben wenn redacted_at von NULL auf NOT NULL gesetzt
|
||||
-- wird UND keine anderen identitaetsrelevanten Felder geaendert werden.
|
||||
if tg_op = 'UPDATE' then
|
||||
if old.redacted_at is not null then
|
||||
raise exception 'Eintrag wurde bereits anonymisiert — keine weiteren UPDATEs';
|
||||
end if;
|
||||
if new.redacted_at is null then
|
||||
raise exception 'reception_visit_audit-UPDATE nur fuer DSGVO-Anonymisierung erlaubt (redacted_at muss gesetzt werden)';
|
||||
end if;
|
||||
if new.id <> old.id
|
||||
or new.lead_id is distinct from old.lead_id
|
||||
or new.occurred_at <> old.occurred_at
|
||||
or new.event_kind <> old.event_kind
|
||||
or new.actor_kind <> old.actor_kind
|
||||
or new.actor_id is distinct from old.actor_id
|
||||
then
|
||||
raise exception 'reception_visit_audit-Anonymisierung darf nur payload + redacted_at aendern';
|
||||
end if;
|
||||
return new;
|
||||
end if;
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- Index fuer schnelle Filterung "noch nicht anonymisiert".
|
||||
create index if not exists reception_visit_audit_active_idx
|
||||
on public.reception_visit_audit (occurred_at desc)
|
||||
where redacted_at is null;
|
||||
Reference in New Issue
Block a user