internal/retention: object_type/object_reference als reine Textfelder (Adapter-Muster, keine Fremdschluessel auf DMS-/Mail-Tabellen). Aufbewahrungsklassen-Zuordnung historisiert (jede Zuordnung eigene, unveraenderliche Zeile). Migration real vorwaerts+rueckwaerts gegen die tatsaechlichen .sql-Dateien getestet, Mandantentrennung gegen echtes zweites Tenant-DB bewiesen. Grundlage fuer RET-05 (Adapter- Interface) und RET-02.
27 lines
1.4 KiB
SQL
27 lines
1.4 KiB
SQL
-- RET-01: generisches Retention-Objektmodell. Modulübergreifend über
|
|
-- Adapter (object_type/object_reference als reine Textfelder, KEINE
|
|
-- Fremdschlüssel auf DMS-/Mail-Tabellen) — Archive kennt die
|
|
-- Fachobjekte anderer Module nicht, nur deren Typ+Referenz.
|
|
CREATE TABLE IF NOT EXISTS retention_objects (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
object_type TEXT NOT NULL,
|
|
object_reference TEXT NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'expired', 'deleted')),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
UNIQUE (object_type, object_reference)
|
|
);
|
|
|
|
-- Historisiert: JEDE Zuordnung ist eine eigene, unveränderliche Zeile
|
|
-- (nie UPDATE) — "aktuelle" Aufbewahrungsklasse ist die mit dem
|
|
-- jüngsten assigned_at je retention_object_id. So bleibt nachvollziehbar,
|
|
-- wann sich die Klasse eines Objekts geändert hat (Akzeptanzkriterium 2).
|
|
CREATE TABLE IF NOT EXISTS retention_class_assignments (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
retention_object_id UUID NOT NULL REFERENCES retention_objects(id) ON DELETE CASCADE,
|
|
retention_class TEXT NOT NULL,
|
|
assigned_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_retention_class_assignments_object
|
|
ON retention_class_assignments (retention_object_id, assigned_at DESC);
|