80 lines
3 KiB
Markdown
80 lines
3 KiB
Markdown
# 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 `<select>`-Feld mit den Optionen:
|
|
- `screen_user` → "Vollzugriff" (default, bisheriges Verhalten)
|
|
- `restricted` → "Eingeschränkt (nur Medien/Playlist)"
|
|
|
|
Der gewählte Wert wird als `role`-Parameter an `CreateScreenUser()` übergeben.
|
|
|
|
Nachträgliches Ändern der Rolle ist nicht vorgesehen — wer die Rolle ändern möchte, legt den User neu an.
|
|
|
|
---
|
|
|
|
## Nicht im Scope
|
|
|
|
- Per-Screen-Rollenmischung (User X hat auf Screen A Vollzugriff, auf Screen B restricted) — nicht benötigt
|
|
- Nachträgliches Bearbeiten der Rolle eines bestehenden Users
|
|
- Anzeige der Rolle in der User-Liste (YAGNI)
|