diff --git a/docs/superpowers/specs/2026-03-27-restricted-rolle-design.md b/docs/superpowers/specs/2026-03-27-restricted-rolle-design.md new file mode 100644 index 0000000..e1ee46f --- /dev/null +++ b/docs/superpowers/specs/2026-03-27-restricted-rolle-design.md @@ -0,0 +1,80 @@ +# Design: Restricted-Rolle für Screen-User + +**Datum:** 2026-03-27 +**Status:** Approved + +## Zusammenfassung + +Firmen, die einzelne Monitore mieten, erhalten einen User mit der Rolle `"restricted"`. Diese Nutzer dürfen Medien hochladen und die Playlist bearbeiten, aber keine Anzeige-Steuerung (An/Aus, Zeitplan, Override) vornehmen. + +--- + +## Datenmodell + +Kein Schema-Change erforderlich. `users.role` ist bereits ein freier String. `"restricted"` wird als dritter gültiger Rollenwert eingeführt (neben `"admin"` und `"screen_user"`). + +`CreateScreenUser()` erhält einen `role`-Parameter (aktuell immer `"screen_user"`), sodass der Admin-Handler beim Anlegen eines Users wahlweise `"screen_user"` oder `"restricted"` übergeben kann. + +Bestehende User behalten ihren bisherigen Wert — kein Migrationsbedarf. + +--- + +## Backend-Absicherung + +Neue Middleware `RequireNotRestricted` prüft `user.Role != "restricted"` und gibt andernfalls 403 zurück. + +Sie wird auf folgende Endpunkte in `router.go` gelegt (zusätzlich zur bestehenden `authScreen`-Middleware): + +| Methode | Pfad | Beschreibung | +|---------|------|--------------| +| `POST` | `/api/v1/screens/{screenSlug}/display` | An/Aus | +| `POST` | `/api/v1/screens/{screenSlug}/schedule` | Zeitplan | +| `POST` | `/api/v1/screens/{screenSlug}/override` | Per-Screen Override | +| `POST` | `/api/v1/global-override` | Globaler Override setzen | +| `DELETE` | `/api/v1/global-override` | Globaler Override löschen | + +**Erlaubt bleiben für `restricted`:** +- `POST /manage/{screenSlug}/upload` — Medien hochladen +- `POST /manage/{screenSlug}/items` — Playlist-Eintrag hinzufügen +- `POST /manage/{screenSlug}/reorder` — Playlist sortieren +- `DELETE /manage/{screenSlug}/items/{id}` — Playlist-Eintrag entfernen +- Alle lesenden Endpunkte + +--- + +## UI + +Der Handler übergibt die Rolle des eingeloggten Users als `UserRole string` im Template-Daten-Struct (`screenOverviewData` und `manageData`). + +Das Template blendet per `{{if ne .UserRole "restricted"}}` aus: + +**Übersicht (`/manage`):** +- Globaler Override-Banner (komplett) +- Bulk-Steuerleiste ("Alle an/aus") +- Pro Monitorkarte: An/Aus-Buttons, per-Screen-Override-Widget + +**Detailseite (`/manage/{slug}`):** +- Zeitplan-Box +- Override-Box ("Einschalten bis") + +Medien-Upload und Playlist bleiben unverändert sichtbar und bedienbar. + +--- + +## Admin-UI + +Beim Anlegen eines Screen-Users (`POST /admin/screens/{slug}/users`) gibt es ein neues `