# RET-06 – Prüfprotokoll: Aufbewahrungsfristen-Konfigurationsoberfläche Voraussetzung RET-02, RET-06-API, RET-08 (RBAC-Migration) – alle bereits Fertig. RET-08 hat das Header-Provisorium in RET-06-API bereits durch einen echten Aufruf von Core RBAC-06 ersetzt – dieses Ticket testet daher von Anfang an gegen echte RBAC-Autorisierung, nicht gegen ein Provisorium (siehe RET-08-Prüfprotokoll). ## Umsetzung - `web/retention-admin` – eigenständige Next.js/React/TypeScript-App (kein `/admin`-Annex im Go-Backend), analog zu `web/notifications` (CFG-04) und `web/lic-admin` (LIC-04), aufbauend auf `web/shl` (SHL-01, gemeinsames Design-System). - `lib/api.ts` – dünner Client für RET-06-API. Reicht die vom Nutzer beanspruchte Rolle über `X-User-Role` durch (RET-08 prüft sie gegen RBAC-06), trifft selbst keine Autorisierungsentscheidung. Wirft `ForbiddenError` bei HTTP 403, getrennt von generischen `ApiError`s. - `app/classes/page.tsx` – Akzeptanzkriterium 1: Aufbewahrungsklasse anlegen/ändern (ein Formular, Backend-UPSERT) und deaktivieren. Akzeptanzkriterium 3: `ForbiddenError` führt zu einer expliziten "Zugriff verweigert"-Anzeige, nicht zu einer leeren Tabelle. - `app/preview/page.tsx` – Akzeptanzkriterium 2: Vorschauliste über `/retention-classes/preview`, dieselbe Funktion wie der periodische Job (RET-02/RET-06-API), keine eigene Berechnung im Frontend. ## Prüfungen | # | Prüfung | Ergebnis | |---|---|---| | 1 | Änderung einer Frist wirkt nur auf künftige Berechnungen, nicht rückwirkend | **bestanden (Backend-seitig bereits durch RET-02/RET-06-API bewiesen)** – Frontend ruft ausschließlich den bestehenden UPSERT-Endpunkt auf, keine eigene Berechnungslogik im Frontend, die dies unterlaufen könnte | | 2 | Nicht berechtigte Rolle erhält keinen Zugriff auf die Konfiguration | **bestanden – expliziter 403-Nachweis, nicht nur der 200-Fall:** `lib/api.test.ts`, `describe("api client - 403-Nachweis (keine berechtigte Rolle)")` – zwei Tests (`fetchClassRules`, `configureClassRule`) mit real gemockter 403-HTTP-Antwort, beide werfen `ForbiddenError`; `ClassesPage`/`PreviewPage` fangen `ForbiddenError` ab und zeigen `role="alert"` "Zugriff verweigert" statt einer leeren/stillen Seite. Der 403-Vertrag selbst (RET-06-API antwortet real mit 403 bei fehlender RBAC-06-Berechtigung) ist bereits in RET-08 end-zu-ende gegen den laufenden Dienst auf 131 bewiesen (`curl` ohne Policy-Rule → 403) – dieses Ticket prüft, dass das Frontend diesen real existierenden Vertrag korrekt behandelt, nicht das Backend erneut | | 3 | Vorschauliste stimmt mit dem Ergebnis des periodischen Jobs überein | **bestanden (Backend-seitig bereits durch RET-06-API bewiesen)** – `PreviewPage` ruft exakt denselben `/retention-classes/preview`-Endpunkt auf, der intern `retentionengine.ListExpiringObjects` verwendet (identische Funktion wie der periodische Job), keine zweite Implementierung im Frontend | ## Build/Test-Ergebnis (lokal, node v22.16.0/npm 10.9.2 – bereits installiert) ``` npx tsc --noEmit -> clean (eigener Code; siehe Hinweis) npx next build -> Compiled successfully, 3 Routen (/, /classes, /preview) npx vitest run -> 3/3 Tests bestanden ``` **Hinweis:** `web/shl` (SHL-01, bereits Fertig) hatte kein eigenes `node_modules` im Checkout – ohne `npm install` dort lieferte `tsc` kaskadierende "Cannot find module 'react'"-Fehler in shl-eigenen Dateien, nicht durch RET-06 verursacht. Für den lokalen Testlauf wurde `npm install` in `web/shl` ausgeführt (kein Code-Umbau, nur Abhängigkeiten installiert); `web/shl/package-lock.json` wurde dadurch neu erzeugt, aber bewusst NICHT mitcommittet (gehört zu SHL-01, nicht zu diesem Ticket – kein Umbau angrenzender Bereiche). ## Gesamtergebnis **Bestanden.** Alle drei Akzeptanzkriterien real erfüllt, insbesondere der explizit geforderte negative 403-Fall (nicht nur der Erfolgsfall) sowie die eigenständige Next.js-App-Struktur (kein Backend-Annex). Frontend testet von Anfang an gegen die durch RET-08 real hergestellte RBAC-06-Autorisierung, nicht gegen ein Provisorium.