# 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`/`ListExpiringObjects` berü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 DIESELBE `ListExpiringObjects`-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-api` gebaut nach `/opt/nexarch-archive/bin/` - `/etc/nexarch/archive-retention-api.env` (0600) - `nexarch-archive-retention-api.service` installiert/aktiviert (dauerhaft, `Restart=on-failure`) - Realer End-zu-Ende-Test via `curl`: POST ohne Rollen-Header → 403; POST mit `X-Admin-Roles: archive_admin` → 200, Klasse angelegt; `GET /retention-classes` zeigt sie; `GET /retention-classes/preview` liefert `null` (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.