From c5f222cad870fcacb2696a89a0e321df571c41ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesko=20Ansch=C3=BCtz?= Date: Fri, 27 Mar 2026 21:19:50 +0100 Subject: [PATCH] =?UTF-8?q?docs:=20Design-Spec=20f=C3=BCr=20restricted-Rol?= =?UTF-8?q?le?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- .../2026-03-27-restricted-rolle-design.md | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 docs/superpowers/specs/2026-03-27-restricted-rolle-design.md 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 `