diff --git a/docs/superpowers/specs/2026-03-28-user-spezifische-medien-design.md b/docs/superpowers/specs/2026-03-28-user-spezifische-medien-design.md index a8d4332..31721b9 100644 --- a/docs/superpowers/specs/2026-03-28-user-spezifische-medien-design.md +++ b/docs/superpowers/specs/2026-03-28-user-spezifische-medien-design.md @@ -13,6 +13,7 @@ Restricted Users können aktuell alle Medien des Tenants sehen und löschen. Sie - **Admins** sehen alle Medien des Tenants — inkl. solcher ohne Besitzer (Legacy-Medien) - **screen_users** sehen alle Medien des Tenants (unverändert) - Bestehende Medien (ohne Besitzer) bleiben erhalten und funktionieren weiter +- **Admins und screen_users** können Medien von Restricted Users ein-/ausblenden (Toggle). Default: **ausgeblendet** ## Ansatz: Filter im Store-Layer @@ -36,12 +37,15 @@ ALTER TABLE media_assets ## Go-Datenmodell -`MediaAsset`-Struct bekommt ein neues Feld: +`MediaAsset`-Struct bekommt zwei neue Felder: ```go -CreatedByUserID string // leer = kein Besitzer (legacy) +CreatedByUserID string // leer = kein Besitzer (legacy) +OwnerIsRestricted bool // true wenn Uploader Rolle "restricted" hat ``` +`OwnerIsRestricted` wird per `LEFT JOIN users` in der List-Query befüllt — kein separater Lookup nötig. + ## Store-Layer ### List @@ -50,8 +54,8 @@ CreatedByUserID string // leer = kein Besitzer (legacy) func (s *MediaStore) List(ctx context.Context, tenantID, ownerUserID string) ([]MediaAsset, error) ``` -- `ownerUserID == ""` → keine Einschränkung, alle Tenant-Medien (Admin, screen_user) -- `ownerUserID != ""` → `AND created_by_user_id = $2` (Restricted User) +- `ownerUserID == ""` → alle Tenant-Medien (Admin, screen_user); `OwnerIsRestricted` per LEFT JOIN befüllt +- `ownerUserID != ""` → `AND m.created_by_user_id = $2` (Restricted User); kein JOIN nötig ### Create @@ -85,25 +89,33 @@ Neu: ## UI -### Admin-Ansicht: Badge für Medien ohne Besitzer +### Admin- und screen_user-Ansicht -In der Medienliste zeigt der Admin bei Einträgen mit leerem `CreatedByUserID` ein Badge: +**Badge für Medien ohne Besitzer** (nur für Admins, da screen_users keine Legacy-Medien hochladen können): ```html Kein Besitzer ``` -Medien mit Besitzer erhalten kein Badge — der Benutzername wird nicht angezeigt. +Wird angezeigt wenn `CreatedByUserID == ""`. Kein Benutzername wird angezeigt. + +**Toggle: Restricted-Medien ein-/ausblenden** (Admin + screen_user): + +- Button in der Medienliste: `Restricted-Medien anzeigen` (Bulma `button is-small`) +- Jedes Medium von einem Restricted-User erhält `data-owner-restricted="true"` im HTML +- Default: diese Elemente sind per CSS ausgeblendet (`display: none`) +- Vanilla JS: Toggle-Button wechselt eine CSS-Klasse auf dem Container; Items mit `data-owner-restricted="true"` werden sichtbar/unsichtbar +- Kein Page-Reload, kein Server-Request — rein clientseitig ### Restricted-User-Ansicht -Keine strukturellen Änderungen. Die Liste ist serverseitig gefiltert — der User sieht einfach weniger Einträge. +Keine strukturellen Änderungen. Die Liste ist serverseitig gefiltert — der User sieht einfach nur eigene Einträge. Kein Toggle-Button sichtbar. ## Nicht im Scope - Anzeige des Besitzernamens bei Medien - Übertragung von Medien zwischen Usern -- Sichtbarkeit von Restricted-User-Medien für screen_users (sie sehen alles im Tenant) +- Persistierung der Toggle-Einstellung (wird nicht gespeichert, reset bei Seitenladen) ## Betroffene Dateien @@ -112,6 +124,6 @@ Keine strukturellen Änderungen. Die Liste ist serverseitig gefiltert — der Us | `server/backend/db/migrations/00X_media_owner.sql` | neue Spalte `created_by_user_id` | | `server/backend/internal/store/store.go` | `MediaAsset`-Struct, `List()`-Signatur, `Create()` | | `server/backend/internal/httpapi/manage/media.go` | Upload + Delete + List Handler | -| `manage/templates.go` | Badge für Medien ohne Besitzer | +| `manage/templates.go` | Badge für Medien ohne Besitzer; Toggle-Button + JS; `data-owner-restricted` Attribut | | `docs/SCHEMA.md` | neue Spalte dokumentieren | | `docs/API-ENDPOINTS.md` | ggf. List-Endpoint-Verhalten dokumentieren |