Files
nexarch/archive/docs/RET-06-API-PRUEFPROTOKOLL.md
T
sysops 21278f1405 feat(archive): RET-06-API Aufbewahrungsfristen-Konfigurations-Backend
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.
2026-08-30 02:09:37 +02:00

92 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.