- API-ENDPOINTS.md: neue Sektion "Display-Steuerung" mit POST /api/v1/screens/{screenSlug}/display und POST /api/v1/screens/{screenSlug}/schedule
- SCHEMA.md: Hinweis zur vereinfachten screen_status-Tabelle (Migration 004) und neue Sektion screen_schedules (Migration 005)
- server/backend/README.md: scheduler-Package beschrieben, Migrationen 004+005 ergaenzt, Endpunkt-Tabelle aktualisiert
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Server gibt bei POST /api/v1/player/status jetzt mqtt-Block zurück (broker,
username, password) wenn MORZ_INFOBOARD_MQTT_BROKER gesetzt ist. Agents
parsen die Response und verbinden sich bei Config-Änderung automatisch neu
(applyMQTTConfig mit Reconnect-Logik, thread-safe via Mutex).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- GET /manage: neue Übersichtsseite mit Bulma-Karten für screen_user mit ≥2 Screens
- handleScreenUserRedirect leitet bei ≥2 Screens auf /manage statt auf ersten Screen
- On-Demand-Screenshot-Flow via MQTT:
- Backend publiziert signage/screen/{slug}/screenshot-request beim Seitenaufruf
- Player-Agent empfängt Topic, ruft TakeAndSendOnce() auf
- Player POST /api/v1/player/screenshot → Backend speichert in ScreenshotStore (RAM)
- GET /api/v1/screens/{screenId}/screenshot liefert gespeichertes Bild (authOnly)
- ScreenshotStore: In-Memory, thread-safe, kein Persistenz-Overhead
- JS-Retry nach 4s in Templates (Screenshot braucht 1-3s für MQTT-Roundtrip)
- manageTmpl zeigt Screenshot-Thumbnail beim Einzelscreen-Aufruf
- Doku: neue Endpoints, MQTT-Topics, Screenshot-Flow in SERVER-KONZEPT.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- HandleManageUI übergibt CSRFToken korrekt ans Template (leeres Hidden-Field
blockierte JS-Inject-Snippet)
- HandleTenantDashboard setzt CSRF-Cookie und befüllt CSRFToken in Template-Daten
- tenant/csrf_helpers.go: setCSRFCookie im tenant-Package (Import-Cycle-Isolation)
- Logout-Formular in tenantDashTmpl hat jetzt statisches CSRF-Hidden-Field
- Doku: POST /logout und POST /login mit CSRF-Anforderungen dokumentiert
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Neue Packages und Module:
- fileutil: Shared Upload-Logik mit Tenant-Isolation
- httpapi/csrf.go: Double-Submit-Cookie CSRF-Schutz
- httpapi/ratelimit.go: Rate-Limiting für /login
- httpapi/uploads.go: neuteredFileSystem (kein Directory-Listing)
- httpapi/manage/csrf_helpers.go: CSRF-Helpers für Templates
- player/agent/internal/screenshot/screenshot.go: Periodische Screenshot-Erfassung
Neue Umgebungsvariablen:
- MORZ_INFOBOARD_REGISTER_SECRET: Pre-Shared-Secret für Agent-Registrierung
- MORZ_INFOBOARD_SCREENSHOT_EVERY: Screenshot-Intervall im Player-Agent (Sekunden)
Dokumentation aktualisiert:
- server/backend/README.md: Neue Packages und Env-Variable REGISTER_SECRET
- DEVELOPMENT.md: Beide neuen Env-Variablen mit Erklärungen
- docs/API-ENDPOINTS.md: Screenshot-Endpoint als "In Vorbereitung" dokumentiert
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PDF-URLs bekommen #toolbar=0&navpanes=0&scrollbar=0&view=Fit&page=1
angehängt, damit Chromium den PDF-Viewer ohne Sidebar und Toolbar
im Vollbild rendert. PDF.js als Folgeschritt in TODO dokumentiert.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend published auf signage/screen/{slug}/playlist-changed nach
Playlist-Mutationen (2s Debounce). Agent subscribed und fetcht
Playlist sofort (3s Debounce). 60s-Polling bleibt als Fallback.
Neue Packages: mqttnotifier (Backend), mqttsubscriber (Agent)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
README, DEVELOPMENT und TODO spiegelten noch den Stand vor Ebene 1+2 wider.
Checkboxen in TODO von ~18 auf ~70 aktualisiert, drei neue API-Dokumentationsdateien ergänzt.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Drei eng zusammenhaengende Aenderungen in einem Commit, da sie dieselbe
Template-Infrastruktur teilen und gemeinsam die HTML-Diagnoseansicht
abrunden:
1. CSS-Extraktion (Verbesserung, kein Verhalten geaendert)
Das bisherige Inline-CSS wurde in die Konstante statusPageCSS
ausgelagert. statusPageCSSBlock injiziert es per String-Konkatenation
in alle Templates, sodass kein Template-Inheritance-Mechanismus
benoetigt wird und jede Seite eigenstaendig ausfuehrbar bleibt.
2. GET /status/{screenId} -- neue HTML-Detailseite
Zeigt den letzten bekannten Datensatz eines einzelnen Screens:
Derived State, Player-Status, Connectivity und Frische als
Summary-Cards; Timing- und Endpoints-Details in aufgeraeuemten
Key-Value-Tabellen. Verlinkung zurueck auf /status und auf den
bestehenden JSON-Endpunkt. Bei unbekanntem Screen: 404 mit HTML-
Fehlerseite und Rueck-Link.
Route: GET /status/{screenId}
3. HTML-Fehlerseite fuer /status bei ungueltigen Query-Parametern
Bisher lieferte handleStatusPage einen rohen JSON-Fehler, wenn
z.B. ?stale=banana uebergeben wurde -- inkongruent fuer einen
HTML-Endpunkt. writeStatusPageQueryError rendert jetzt dasselbe
statusPageErrorTemplate wie der Not-Found-Fall der Detailseite
und gibt text/html mit 400 zurueck.
Neue Tests (router_test.go):
- ScreenDetailPageRoute: prueft Inhalt, Links, Content-Type
- ScreenDetailPageNotFound: prueft 404 + HTML + Rueck-Link
- StatusPageRejectsInvalidQueryParams: prueft jetzt auch text/html
fuer alle Fehlerfaelle
Docs (PLAYER-STATUS-HTTP.md):
- Query-Parameter-Validierung mit erlaubten Werten und Fehlercodes
- Neue /status/{screenId}-Seite und HTML-Fehlerseiten dokumentiert
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>