- SCHEMA.md: users-Tabelle korrigiert, sessions-Tabelle ergänzt - API-ENDPOINTS.md: Auth-Routen + Tenant-Dashboard-Routen ergänzt - SERVER-KONZEPT.md: Abschnitte Authentifizierung, Middleware-Kette, Tenant-Dashboard neu - backend/README.md: komplett neu auf Basis aktueller Implementierung - DEVELOPMENT.md: veraltete "nicht vorhanden"-Punkte bereinigt Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
9.1 KiB
Info-Board Neu - Server-Konzept
Ziel
Der Server ist die zentrale Steuer- und Verwaltungsinstanz der Plattform.
Er soll:
- Benutzer, Firmen und Screens verwalten
- Medien und Playlists bereitstellen
- globale Templates und Kampagnen steuern
- Provisionierung neuer Screens ausloesen
- Status, Screenshots und Heartbeats sammeln
- MQTT und HTTPS sauber trennen
Grundprinzip
Der Server ist die Quelle der fachlichen Wahrheit.
Der Player bleibt trotzdem lauffaehig, wenn der Server temporaer nicht erreichbar ist.
Das bedeutet:
- Server verwaltet Konfiguration und Inhalte zentral
- Player fuehrt lokal und robust aus
- Server sendet Steuerimpulse, Player synchronisiert aktiv nach
Hauptkomponenten
Reverse Proxy
Aufgaben:
- TLS-Terminierung
- Routing fuer API und Web-UIs
- optionale Auth-/Header-Regeln
Backend-API
Bevorzugte Sprache:
Go
Aufgaben:
- Authentifizierung und Autorisierung
- CRUD fuer Tenants, Users, Screens, Medien, Playlists
- Verwaltung globaler Templates und Kampagnen
- Player-Sync-Endpunkte
- Speicherung von Status und Screenshots
- Start von Provisionierungsjobs
Admin-UI
Aufgaben:
- Gesamtübersicht aller Screens
- Vorschau und Status
- Template-/Kampagnenverwaltung
- Kommandos und Provisionierung
Tenant-UI
Aufgaben:
- Uploads und Medienverwaltung pro Firma
- Pflege der monitorbezogenen Playlist
- Vorschau des eigenen Screens
Datenbank
Empfehlung:
- PostgreSQL
Aufgaben:
- Speicherung fachlicher Daten
- Status, Jobs, Revisionen, Zuordnungen
MQTT-Broker
Empfehlung:
- Mosquitto
Aufgaben:
- Heartbeats
- Statusmeldungen
- Events
- Kommandos und ACKs
Dateispeicher
Aufgaben:
- Uploads
- Screenshots
- ggf. serverseitig vorbereitete Medien
V1:
- Dateisystem ausreichend
Fachliche Bereiche
1. Mandanten und Benutzer
Der Server trennt:
- globale Admins
- tenantgebundene Nutzer
Regel:
- Firmen sehen nur ihren Bereich
- Admins sehen alles
2. Screen-Verwaltung
Der Server kennt jeden Screen mit:
- ID
- Name
- Klasse
- Orientierung
- Rotation
- Tenant-Zuordnung
- technischem Registrierungsstatus
3. Medienverwaltung
Der Server verwaltet:
- Uploads
- externe Medienreferenzen
- Metadaten
- tenant- oder screenspezifische Zuordnung
4. Playlist-Verwaltung
Der Server verwaltet tenantbezogene Inhalte pro Screen.
Wichtige Felder:
- Reihenfolge
- Dauer
valid_fromvalid_until- Fehlerstrategie
- Cache-Politik
5. Template- und Kampagnenverwaltung
Der Server stellt den globalen Orchestrierungsbereich bereit.
Funktionen:
- Templates erstellen
- Szenen pflegen
- Zielgruppen waehlen
- Kampagnen aktivieren/deaktivieren
- Zeitfenster setzen
- Uebersteuerung sichtbar machen
6. Provisionierung
Der Server startet Provisionierungsjobs fuer neue Screens.
Aufgaben:
- Eingaben aus Admin-UI entgegennehmen
- Job anlegen
- Secret-Handling absichern
- Worker oder Jobrunner starten
- Fortschritt speichern
- Fehler sauber rueckmelden
API-Bereiche
Die API soll mindestens diese Domänen haben:
authtenantsusersscreensmediaplayliststemplatescampaignsplayercommandsprovisioning
Revisionsmodell
Der Server arbeitet mit Revisionen, damit Player effizient synchronisieren koennen.
Mindestens:
config_revisionplaylist_revisionmedia_revisioncampaign_revision
Status- und Vorschaukonzept
Der Server speichert:
- letzten bekannten Heartbeat
- letzten Status
- letzten Screenshot
- aktuelle Inhaltsquelle pro Screen
Die Admin-UI soll damit erkennen:
- online/offline
- normaler tenantbezogener Betrieb
- globale Kampagnen-Uebersteuerung
- Fallback-Betrieb
- Fehlerzustand
Provisionierungsjobrunner
Die Provisionierung soll nicht direkt in Web-Requests laufen.
Stattdessen:
- API legt Job an
- dedizierter Worker/Jobrunnner arbeitet ihn ab
- Fortschritt wird in DB gespeichert
Zusaetzlich fuer v1 festzulegen:
- ACK-Timeout-Handling fuer
device_commandsueber Worker - Secret-Handling fuer Provisionierungs-Bootstrap ueber kurzlebige Secret-Referenzen
- physische Netzposition des Workers fuer SSH-Erreichbarkeit als Betriebsparameter
Docker-Compose-Zielbild
Sinnvolle Komponenten in compose/:
reverse-proxybackendpostgresmosquitto- optional
worker
Authentifizierung
Der Server verwendet einen Session-basierten Login-Flow mit bcrypt-Passwort-Hashing.
Login-Flow
GET /loginrendert das Login-Formular (Bulma-Card zentriert).POST /loginprueft Username und Passwort:AuthStore.GetUserByUsernamelaedt den User inkl. Tenant-Slug.bcrypt.CompareHashAndPasswordprueft das Passwort (Cost-Faktor 12).- Bei Erfolg legt
AuthStore.CreateSessioneine Session an (TTL 24 Stunden). - Das Session-Token wird als
morz_session-Cookie gesetzt (HttpOnly=true,Secure=true). - Im
DevMode(MORZ_INFOBOARD_DEV_MODE=true) wirdSecure=falsegesetzt fuer lokalen HTTP-Betrieb. - Weiterleitung je nach Rolle:
admin→/admin,tenant→/tenant/{slug}/dashboard.
POST /logoutloescht die Session in der DB und entfernt den Cookie.
Cookie-Lebensdauer
- Standard-TTL: 24 Stunden
- Der Cookie verfaellt automatisch; die DB wird stuendlich durch
CleanExpiredSessionsbereinigt.
Admin-User-Bootstrap
Beim Server-Start wird EnsureAdminUser aufgerufen, wenn MORZ_INFOBOARD_ADMIN_PASSWORD gesetzt ist.
Der Admin-User wird dem Tenant mit Slug MORZ_INFOBOARD_DEFAULT_TENANT (Standard: morz) zugeordnet.
Ist der User bereits vorhanden, passiert nichts. Fehler sind nicht fatal — der Server startet trotzdem.
Middleware-Kette
Alle geschuetzten Routen werden durch Middleware-Funktionen in internal/httpapi/middleware.go abgesichert.
Eingehende Anfrage
│
▼
RequireAuth Liest morz_session-Cookie, prueft Session via DB,
speichert *store.User im Request-Context.
→ Fehler: Redirect zu /login?next=<Pfad>
│
├─► RequireAdmin Prueft user.Role == "admin"
│ → Fehler: 403 Forbidden
│
└─► RequireTenant Prueft user.TenantSlug == {tenantSlug} aus dem URL-Pfad.
Access Admins duerfen immer durch.
→ Fehler: 403 Forbidden
Route-Gruppen im Router
| Gruppe | Middleware | Beispielrouten |
|---|---|---|
| Oeffentlich | keine | /healthz, /login, /api/v1/screens/register |
| Auth-only | RequireAuth | /manage/{screenSlug}/... |
| Admin-only | RequireAuth + RequireAdmin | /admin, /admin/screens/... |
| Tenant-scoped | RequireAuth + RequireTenantAccess | /tenant/{tenantSlug}/..., /api/v1/tenants/{tenantSlug}/... |
Der Hilfsfunktion chain(middlewares...) in router.go wrappet Handler von aussen nach innen.
Tenant-Dashboard
Das Tenant-Self-Service-Dashboard ist unter /tenant/{tenantSlug}/dashboard erreichbar.
URL-Schema
| Methode | Pfad | Beschreibung |
|---|---|---|
| GET | /tenant/{tenantSlug}/dashboard |
Dashboard rendern |
| POST | /tenant/{tenantSlug}/upload |
Medium hochladen |
| POST | /tenant/{tenantSlug}/media/{mediaId}/delete |
Medium loeschen |
Tabs
- Tab A – Meine Monitore: Zeigt Screen-Karten mit Live-Status. Der Status wird per JavaScript
aus
GET /api/v1/screens/statusgeladen und alle 30 Sekunden aktualisiert. Status-Badge:is-success(online),is-danger(offline),is-warning(unbekannt). - Tab B – Mediathek: Upload-Formular (Bild, Video, PDF oder Web-URL) und Dateiliste
mit Loeschen-Button. Nach Upload oder Loeschen Redirect mit
?tab=media&flash=uploaded/deleted.
Eigentuemer-Pruefung beim Loeschen
HandleTenantDeleteMedia prueft, dass asset.TenantID == tenant.ID, bevor es loescht.
Damit ist sichergestellt, dass ein Tenant keine Assets anderer Tenants loeschen kann,
selbst wenn er die mediaId erraten wuerde.
Sicherheitsgrundsaetze
- Root-Bootstrap-Geheimnisse nur kurzlebig oder referenziert speichern
- API- und MQTT-Zugaenge getrennt behandeln
- alle Admin-Kommandos auditieren
- Tenant-Trennung strikt serverseitig erzwingen
API-Fehlermodell
Vor Implementierungsbeginn gilt ein einheitlicher Fehlerumschlag.
Empfehlung:
{
"error": {
"code": "screen_not_found",
"message": "Screen existiert nicht",
"details": null
}
}
Zielstruktur im Repo
Empfohlene Unterstruktur fuer den Server:
server/backend/server/admin-ui/server/tenant-ui/server/worker/compose/
Testfaelle fuer den Server
- Tenant sieht nur eigene Daten
- Admin sieht alle Daten
- Kampagne ueberschreibt tenantbezogenen Content korrekt
- Screen-Provisionierung legt Job sauber an
- Player-Sync ueber Revisionen funktioniert
- MQTT-Kommandos werden protokolliert
- Screenshot-Upload erscheint im Admin-Dashboard