morz-infoboard/docs/PLAYER-STATUS-HTTP.md
Jesko Anschütz cfab277dc4 Fuege HTML-Detailseite und HTML-Fehlerseite fuer den Status-UI-Pfad hinzu
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>
2026-03-22 20:03:24 +01:00

6.7 KiB
Raw Blame History

Info-Board Neu - Erster HTTP-Statuspfad fuer den Player-Agent

Ziel

Dieses Dokument beschreibt den ersten bewusst kleinen Statuspfad zwischen player/agent und server/backend.

Er ist fuer die aktuelle Entwicklungsstufe gedacht und noch kein finales Persistenz-, Authentifizierungs- oder MQTT-Modell.

V1-Dev-Entscheidung

  • der Agent sendet zunaechst Statusdaten per HTTP an das Backend
  • das Backend validiert und bestaetigt den Request und haelt den letzten bekannten Status pro Screen in-memory vor
  • der Pfad dient als erste echte Backend-Agent-Integration vor Registration, Sync und MQTT

Endpoint

  • POST /api/v1/player/status

Request-Felder

Mindestens enthalten:

  • screen_id
  • ts
  • status

Fuer die aktuelle Entwicklungsstufe sind zulaessig:

  • status: starting, running, stopped
  • server_connectivity: unknown, online, degraded, offline
  • heartbeat_every_seconds: positive Ganzzahl

Aktuell zusaetzlich enthalten:

  • server_connectivity
  • server_url
  • mqtt_broker
  • heartbeat_every_seconds
  • started_at
  • last_heartbeat_at

Beispiel

{
  "screen_id": "info01-dev",
  "ts": "2026-03-22T16:00:00Z",
  "status": "running",
  "server_connectivity": "online",
  "server_url": "http://127.0.0.1:8080",
  "mqtt_broker": "tcp://127.0.0.1:1883",
  "heartbeat_every_seconds": 30,
  "started_at": "2026-03-22T15:59:30Z",
  "last_heartbeat_at": "2026-03-22T16:00:00Z"
}

Antwort

Bei gueltigem Request liefert das Backend aktuell:

{
  "status": "accepted"
}

Bei ungueltigen Requests wird wie bei den anderen API-Endpunkten der gemeinsame Fehlerumschlag verwendet.

Aktueller Read-Pfad

Zusätzlich zur Write-Route gibt es in dieser Stufe:

  • GET /status
  • GET /api/v1/screens/status
  • GET /api/v1/screens/{screenId}/status

GET /status liefert eine kleine serverseitig gerenderte HTML-Statusseite fuer den Browser. Sie nutzt dieselbe in-memory Statusuebersicht wie die JSON-Endpunkte und ist als erste sichtbare Diagnoseoberflaeche gedacht.

Die Seite bietet aktuell bewusst nur leichte Diagnosehilfen auf Basis des bestehenden Read-Pfads:

  • automatisches Refresh alle 15 Sekunden
  • Shortcut-Links fuer Connectivity- und Freshness-Filter wie server_connectivity=offline|degraded sowie stale=true|false
  • ein kleines Filterformular fuer dieselben Uebersichtsparameter wie im JSON-Read-Pfad
  • direkte JSON-Detail-Links pro Screen auf GET /api/v1/screens/{screenId}/status
  • einen Link zur aktuell gefilterten JSON-Uebersicht auf GET /api/v1/screens/status

GET /api/v1/screens/status liefert eine kleine Uebersicht aller bisher berichtenden Screens mit ihrem jeweils letzten bekannten Datensatz. Die Rueckgabe wird aktuell fuer Diagnosezwecke priorisiert sortiert: zuerst offline, dann degraded, dann online, innerhalb derselben Gruppe nach screen_id. Zusaetzlich enthaelt die Antwort eine summary mit kompakten Counts fuer total, online, degraded, offline und stale.

Aktuell unterstuetzte Query-Parameter fuer die Uebersicht:

  • server_connectivity=<value> zum Filtern nach Reachability-Zustand; erlaubte Werte: online, offline, degraded, unknown; ungueltige Werte liefern 400 (invalid_server_connectivity)
  • stale=true|false zum Filtern nach serverseitiger Veraltet-Einschaetzung; ungueltige Werte liefern 400 (invalid_stale)
  • updated_since=<RFC3339> zum Filtern nach received_at; ungueltige Zeitstempel liefern 400 (invalid_updated_since)
  • limit=<positive integer> zum Begrenzen der Anzahl zurueckgelieferter Screens; nicht-positive Werte liefern 400 (invalid_limit)

Die Query-Parameter beeinflussen die Liste in screens; die summary beschreibt weiterhin den gesamten aktuell bekannten Statusbestand. Dieselben Parameter koennen aktuell sowohl an GET /api/v1/screens/status als auch an GET /status verwendet werden, damit Browser-Ansicht und JSON-Uebersicht dieselbe Diagnose-Sicht teilen.

GET /status/{screenId} liefert eine HTML-Detailseite fuer einen einzelnen Screen. Sie zeigt denselben Datensatz wie der JSON-Endpunkt Derived State, Player-Status, Connectivity, Frische, Timestamps und Endpoints in derselben visuellen Sprache wie die Uebersichtsseite. Bei unbekanntem Screen liefert sie 404 mit einer erklaerenden HTML-Fehlermeldung und einem Rueck-Link auf /status.

Fehlerfall bei ungueltigem Query-Parameter auf /status (z.B. ?stale=banana): statt rohem JSON liefert der Endpunkt jetzt eine HTML-Fehlerseite mit erklaerenden Hinweisen und einem Rueck-Link.

GET /api/v1/screens/{screenId}/status liefert den zuletzt akzeptierten Status fuer einen einzelnen Screen zurueck. Wenn fuer den Screen noch kein Status vorliegt, liefert das Backend 404 mit dem gemeinsamen Fehlerumschlag.

Der aktuell zurueckgelieferte Datensatz enthaelt damit sowohl den Lifecycle-Status (status) als auch den vom Agenten lokal abgeleiteten Reachability-Zustand (server_connectivity).

Zusaetzlich fuegt das Backend im Read-Pfad derzeit hinzu:

  • received_at als serverseitigen Annahmezeitpunkt des letzten gueltigen Reports
  • stale als einfache serverseitige Einordnung, ob der letzte Report bereits veraltet wirkt
  • derived_state als zusammengefasste Diagnoseeinschaetzung fuer Konsumenten des Read-Pfads

stale ist aktuell bewusst nur eine kleine Diagnosehilfe fuer die Entwicklungsstufe und noch kein vollstaendiges Online-/Offline-Modell fuer spaetere Admin-Oberflaechen. Die Schwelle wird derzeit einfach aus dem gemeldeten heartbeat_every_seconds abgeleitet: mehr als zwei Intervalle ohne neuen Report gelten als veraltet.

derived_state wird aktuell bewusst einfach abgeleitet:

  • offline bei stale = true oder server_connectivity = offline
  • degraded bei server_connectivity = degraded|unknown oder wenn status nicht running ist
  • online in den verbleibenden Faellen

Abgrenzung

Noch nicht Teil dieser Stufe:

  • dauerhafte Speicherung in Datenbank oder State-Store
  • Screen-Authentifizierung
  • MQTT-Heartbeat oder MQTT-Status
  • Admin-UI-Anzeige des letzten Status
  • Retry-Queue oder lokale Zwischenspeicherung im Agent

Agent-seitig wird die Server-Erreichbarkeit aktuell lokal als unknown, online, degraded oder offline aus dem Erfolg der HTTP-Reports abgeleitet.

Fuer den transportierten Wert im erfolgreichen HTTP-Report gilt aktuell bewusst einfach:

  • wenn ein Report vom Backend akzeptiert wurde, wird dieser Report selbst als server_connectivity = online gespeichert
  • anhaltende Ausfaelle werden primaer ueber lokale Agent-Zustaende und serverseitige stale-Ableitung sichtbar

Folgeschritte

Auf diesem Pfad bauen spaeter auf:

  • Screen-Identitaet und Authentifizierung
  • persistierter letzter Heartbeat und letzter Status auf dem Server
  • Trennung zwischen HTTP-Snapshot und MQTT-Heartbeat
  • Admin-Vorschau fuer Online-/Offline- und Degraded-Zustaende