Board-Entscheidung: Backend-API zuerst, echtes Next.js-Frontend als separates Folgeticket - vermeidet Pseudo-Frontend-Protokoll. internal/retentionapi: 4 Endpunkte (anlegen/aendern, deaktivieren, liste, vorschau), Vorschau nutzt dieselbe ListExpiringObjects-Funktion wie RET-02s periodischer Job (keine Doppel-Implementierung). RequireRole ist AUSDRUECKLICH kein RBAC-02-Ersatz, sondern ein dokumentiertes Provisorium (Header-Check) - RBAC-02 ist reiner Core-interner Go-Code ohne HTTP-Schnittstelle fuer andere Module, derselbe Befund wie FDN-03/FDN-09. Provisorium real getestet inkl. Negativfall (403 ohne/mit falscher Rolle). retention_class_rules um active-Flag erweitert (deaktivieren ohne Historienverlust). Real auf 131 deployed und per curl end-to-end verifiziert.
4.9 KiB
RET-06-API – Prüfprotokoll: Aufbewahrungsfristen-Konfigurations-Backend
Voraussetzung RET-02 – erledigt, siehe eigenes Protokoll.
Scope-Entscheidung (Board-Rücksprache): RET-06 verlangt Next.js/ React-Frontend + Backend-API + RBAC. Statt eines einzigen Big-Scope-Tickets: Backend-API zuerst (dieses Protokoll), das echte Next.js-Frontend folgt als eigenes, separates Ticket. Diese Trennung wurde bewusst gewählt, damit das Prüfprotokoll nicht auf ein Pseudo-Frontend verweist.
Grundsatzentscheidung: provisorischer Rollen-Check, KEIN RBAC-02
Core RBAC-02 (internal/policy, Enforcer.Authorize) ist reiner
Go-Code innerhalb des Core-Moduls — keine HTTP-Schnittstelle, über die
Archive (physisch getrenntes Go-Modul) es aufrufen könnte. Derselbe
"gefunden, aber nicht modulübergreifend verdrahtet"-Befund wie bei Core
FDN-03/FDN-09 (siehe frühere Prüfprotokolle).
internal/retentionapi.RequireRole ist AUSDRÜCKLICH KEIN RBAC-02-
Ersatz, sondern ein Provisorium: prüft nur einen selbst gesetzten
Header (X-Admin-Roles), leicht zu fälschen von jedem, der den Header
setzen kann. Muss ersetzt werden, sobald ein Core-seitiger HTTP-Wrapper
um RBAC-02 existiert (Empfehlung: eigenes künftiges Core-Ticket,
z. B. RBAC-06, wiederverwendbar für alle Module statt je Modul einen
eigenen Provisorium-Check). Bis dahin real getestet inklusive
Negativfall (Pflichtprüfung, siehe unten) — ein UNGEPRÜFTER
Provisorium-Check wäre nur eine verschobene Schwachstelle.
Umsetzung
migrations/0005_retention_class_rules_active.up.sql/.down.sql—active-Flag statt DELETE (Klasse deaktivieren ohne Historienverlust).internal/retentionengine.DeactivateClassRule/ListClassRules— Erweiterung von RET-02s Paket,ComputeDueDate/ListExpiringObjectsberücksichtigen nur noch aktive Regeln.internal/retentionapi.RequireRole— provisorischer Header-Rollen-Check.internal/retentionapi.Mount— vier Endpunkte:POST /retention-classes(anlegen/ändern),POST /retention-classes/{class}/deactivate,GET /retention-classes(Liste),GET /retention-classes/preview(Vorschau, nutzt DIESELBEListExpiringObjects-Funktion wie RET-02s periodischer Job).cmd/retention-api— eigenständiger HTTP-Dienst.
Prüfungen
| # | Prüfung | Ergebnis |
|---|---|---|
| 1 | Änderung einer Frist wirkt sich nur auf künftige Berechnungen aus, nicht rückwirkend auf bereits protokollierte Vernichtungen | bestanden — TestConfigureClassRule_ChangeAppliesOnlyToFutureCalculations: bereits berechneter Stichtag bleibt unverändert (strukturell garantiert, keine Tabelle mit "bereits berechneten" Werten existiert, die rückwirkend verändert werden könnte), NEUE Berechnung übernimmt die neue Frist |
| 2 | Nicht berechtigte Rolle erhält keinen Zugriff auf die Konfiguration | bestanden — TestRequireRole_MissingRoleReturns403 (kein Header UND falsche Rolle, beide 403) UND TestRequireRole_CorrectRoleAllowsAccess (Gegentest); real auf 131: curl ohne Rollen-Header → 403 |
| 3 | Vorschauliste stimmt mit dem Ergebnis des periodischen Jobs überein | bestanden — TestPreviewHandler_MatchesPeriodicJobResult: HTTP-Vorschau UND direkter ListExpiringObjects-Aufruf liefern dasselbe Objekt (dieselbe Funktion, kein Doppel-Code) |
Zusätzlich: TestDeactivateClassRule_ExcludesFromFutureCalculations,
TestConfigureAndListHandler_RealHTTPRoundTrip,
TestDeactivateHandler_RealHTTPRoundTrip.
Echte Verdrahtung auf 192.168.1.131
retention-apigebaut nach/opt/nexarch-archive/bin//etc/nexarch/archive-retention-api.env(0600)nexarch-archive-retention-api.serviceinstalliert/aktiviert (dauerhaft,Restart=on-failure)- Realer End-zu-Ende-Test via
curl: POST ohne Rollen-Header → 403; POST mitX-Admin-Roles: archive_admin→ 200, Klasse angelegt;GET /retention-classeszeigt sie;GET /retention-classes/previewliefertnull(kein fälliges Objekt, korrekt leer) — Testdaten anschließend 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 -> 11/11 Pakete mit Tests ok, 0 Fehlschläge
Hinweis: Zwei Pakete (internal/retentionengine,
internal/retentionapi) gegen dieselbe reale Tenant-DB laufen zu lassen
erfordert -p 1 (sequentiell) — parallele Testläufe unterschiedlicher
Pakete gegen dieselbe echte Datenbank führen sonst zu
Cross-Test-Kontamination (TRUNCATE eines Pakets während ein anderes
noch liest/schreibt). make check/Makefile erzwingt das bereits.
Gesamtergebnis
Bestanden — Backend-Scope. Alle drei Pflichtprüfungen real erfüllt. Offen, bewusst nicht Teil dieses Protokolls: das Next.js/React- Frontend (separates Folgeticket) und der Ersatz des provisorischen Rollen-Checks durch einen echten RBAC-02-Aufruf, sobald Core einen HTTP-Wrapper dafür bereitstellt.