- migrations/0010_deletion_requests: speichert nur den Token-Hash, nie das Token selbst - archive/internal/deletionapproval: RequestDeletion (einmaliges Klartext-Token), ConfirmAndExecute (FOR UPDATE-Lock, andere Person als requester, zeitkonstanter Tokenvergleich via subtle.ConstantTimeCompare, ruft danach genau einmal deletionworkflow.Destroy (RET-03) auf) - 4 Tests real bestanden, inkl. echtem Nebenlaeufigkeits-Test (zwei echte Goroutinen, genau 1 Erfolg + 1 ErrAlreadyExecuted, genau ein destruction_log-Eintrag) - Migration real auf dms_tenant_test angewendet Pruefungen siehe archive/docs/CMP-06-PRUEFPROTOKOLL.md
18 lines
935 B
SQL
18 lines
935 B
SQL
-- CMP-06: Vier-Augen-Freigabe fuer Loeschungen. Eine Loeschanfrage muss
|
|
-- von einer ANDEREN Person bestaetigt werden als der, die sie gestellt
|
|
-- hat, bevor RET-03s Destroy() tatsaechlich ausgefuehrt wird. Nur der
|
|
-- Hash des Bestaetigungs-Tokens wird gespeichert (Akzeptanzkriterium 3),
|
|
-- niemals das Token selbst.
|
|
CREATE TABLE IF NOT EXISTS deletion_requests (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
retention_object_id UUID NOT NULL REFERENCES retention_objects(id) ON DELETE CASCADE,
|
|
requested_by TEXT NOT NULL,
|
|
requested_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
confirmation_token_hash BYTEA NOT NULL,
|
|
token_expires_at TIMESTAMPTZ NOT NULL,
|
|
confirmed_by TEXT,
|
|
confirmed_at TIMESTAMPTZ,
|
|
executed_at TIMESTAMPTZ
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_deletion_requests_object ON deletion_requests (retention_object_id);
|