Rollen-differenzierte Verwaltungs-UI (Material-/Leitungsverantwortliche)
CI / backend-tests (push) Failing after 1m19s
CI / frontend-build (push) Successful in 23s

Bug: Frontend prüfte nur istAdmin, Materialverantwortliche und Leitungs-
verantwortliche sahen exakt dieselbe UI wie Mitarbeiter - obwohl das Backend
längst granular unterscheidet (require_roles je Endpunkt).

- AuthContext gibt volle Rollenliste + istVerantwortlich/istMaterial-
  verantwortlich/istLeitungsverantwortlich weiter.
- /admin-Route für alle drei Rollen offen, AdminPage filtert Tabs nach
  Rolle (Material/Leitung: Objekte-Pflege, Kontrollverantwortung,
  Änderungslog; nur Administration: Stammdaten/Benutzer/Eskalation/
  Zuständigkeit).
- ObjektSection blendet Anlegen/Duplizieren/Kopplung für Nicht-Admins aus
  (waren admin-only im Backend, hätten 403 geworfen).
- Promise.allSettled statt Promise.all beim Laden, damit ein admin-only
  Endpunkt (z.B. /benutzer) nicht die ganze Seite für niedrigere Rollen
  blockiert.
- Backend: GET /benutzer jetzt auch für Material-/Leitungsverantwortliche
  lesbar (für Kontrollverantwortung-Auswahl im Frontend nötig), Schreiben
  bleibt admin-only.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
This commit is contained in:
2026-09-04 22:25:32 +02:00
co-authored by Claude Sonnet 5
parent cf97b2e13d
commit 7f5bbb65d5
8 changed files with 180 additions and 51 deletions
+5 -2
View File
@@ -17,11 +17,14 @@ function GeschuetzteRoute({ children }: { children: ReactNode }) {
}
function AdminRoute({ children }: { children: ReactNode }) {
const { eingeloggt, istAdmin } = useAuth();
const { eingeloggt, istVerantwortlich } = useAuth();
if (!eingeloggt) {
return <Navigate to="/login" replace />;
}
if (!istAdmin) {
// Nicht mehr admin-exklusiv: Materialverantwortliche/Leitungsverantwortliche
// dürfen rein, sehen dort aber nur die für sie freigeschalteten Tabs
// (AdminPage filtert selbst nach Rolle, Backend erzwingt es ohnehin je Endpunkt).
if (!istVerantwortlich) {
return <Navigate to="/objekte" replace />;
}
return <AppShell>{children}</AppShell>;