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.
3.4 KiB
RET-01 – Prüfprotokoll: Generisches Retention-Objektmodell
Keine Vorbedingungen (Welle 1 des RET-Epics).
Grundsatzentscheidung: Adapter-Muster, keine Fremdschlüssel auf Modul-Tabellen
retention_objects.object_type/object_reference sind reine
Textfelder — Archive importiert weder DMS- noch Mail-Code (eigene
Go-Module, physisch getrennte Verantwortung, dieselbe Disziplin wie
BAK-05s reconcile-Paket gegenüber file_revisions). Ein neues Modul
kann retention-pflichtige Objekte einbinden, ohne dieses Paket zu
ändern — nur RegisterObject(objectType, objectReference) aufrufen.
Aufbewahrungsklassen-Zuordnung ist historisiert: AssignClass fügt
IMMER eine neue Zeile hinzu, ändert nie eine bestehende — die "aktuelle"
Klasse ist die mit dem jüngsten assigned_at. Damit bleibt
nachvollziehbar, wann und wie oft sich die Klasse eines Objekts
geändert hat, ohne eigene Audit-Tabelle.
Umsetzung
migrations/0002_retention.up.sql/.down.sql—retention_objects,retention_class_assignments.internal/retention.RegisterObject— idempotent (ON CONFLICT).internal/retention.AssignClass/CurrentClass/ClassHistory.
Prüfungen
| # | Prüfung | Ergebnis |
|---|---|---|
| 1 | Migration vorwärts und rückwärts getestet | bestanden — TestMigration_ForwardAndBackward: real gegen die tatsächlichen Migrationsdateien (nicht nachgebaut), vorwärts→Tabellen vorhanden, rückwärts→Tabellen weg, erneut vorwärts→sauber (kein Rest blockiert erneuten Lauf) |
| 2 | Testobjekt aus fiktivem DMS- und Mail-Adapter beide korrekt abgebildet | bestanden — TestRegisterObject_MapsDMSAndMailAdapterObjectsIdentically: dms_document/mail_message beide ohne modulspezifische Spalten abgebildet, zusätzlich Idempotenz bewiesen (erneute Registrierung liefert dieselbe ID) |
| 3 | Tenant-Isolation der Kern-Tabellen durch Negativtest belegt | bestanden — TestTenantIsolation_Negativtest: reales zweites Tenant-DB (ret01_tenant_test_b), Objekt aus Tenant A über Verbindung zu Tenant B abgefragt, count=0 — technisch nicht sichtbar, keine gemeinsame Tabelle mit tenant_id-Filter (Modell C, TEN-01) |
Zusätzlich: TestAssignClass_IsHistoricized — zwei Klassen-Zuordnungen,
CurrentClass liefert die jüngste, ClassHistory beide chronologisch.
Echte Verdrahtung auf 192.168.1.131
- Migration real gegen
dms_tenant_testangewendet (psql -f migrations/0002_retention.up.sql) —retention_objects,retention_class_assignmentsbestätigt vorhanden (\dt retention*) - Kein systemd-Dienst/Timer nötig — RET-01 ist reines Datenmodell + Bibliothek, kein eigenständiger Prozess (Verbraucher sind spätere RET-Tickets, allen voran RET-05 als Adapter-Interface)
- Zweites Tenant-DB (
ret01_tenant_test_b) nur für den Isolationstest angelegt, danach entfernt
Build/Test-Ergebnis (192.168.1.131, make check)
go build ./... -> clean
go vet ./... -> clean
golangci-lint run ./... -> 0 issues
go test ./... -p 1 -count=1 -> 8/8 Pakete mit Tests ok (backup, objectbackup, reconcile, restore, restoretest, retention, scrub, tenantbackup), 0 Fehlschläge
Gesamtergebnis
Bestanden. Alle drei Akzeptanzkriterien und alle drei
Pflichtprüfungen real erfüllt — Migration gegen die tatsächlichen
.sql-Dateien (nicht nachgebaut) getestet, Mandantentrennung gegen ein
echtes zweites Tenant-DB bewiesen. Grundlage für RET-05 (Adapter-
Interface, als Nächstes) und RET-02 gelegt.