Doku-Sync: README, TODO, DEVELOPMENT und API-Docs auf Implementierungsstand nachgezogen
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>
This commit is contained in:
parent
12c10f0337
commit
aff12a4d81
7 changed files with 1440 additions and 85 deletions
|
|
@ -34,14 +34,15 @@ Bereits vorhanden:
|
|||
|
||||
- fachliche Architektur- und Betriebskonzepte
|
||||
- relationaler Schema-Entwurf in `docs/SCHEMA.md`
|
||||
- erstes Go-Geruest fuer `server/backend`
|
||||
- erstes Go-Geruest fuer `player/agent`
|
||||
- funktionales Go-Backend (`server/backend`) mit REST-API, PostgreSQL-Anbindung und Datenverwaltung
|
||||
- funktionaler Go-Agent (`player/agent`) mit Server-Registrierung, Playlist-Management und Heartbeat-Sync
|
||||
- vollstaendiger Compose-Stack in `compose/server-stack.yml` mit PostgreSQL, Mosquitto und Backend-Service
|
||||
|
||||
Noch nicht vorhanden:
|
||||
|
||||
- produktive API-Endpunkte mit Datenbankanbindung
|
||||
- Player-Sync und Playlist-Management
|
||||
- Compose-Stack fuer lokale Serverdienste (Grundgeruest liegt in `compose/`)
|
||||
- admin-seitige Benutzerautentifizierung und Zugriffskontrolle
|
||||
- Multi-Tenancy-Isolation auf API-Ebene
|
||||
- produktives SSL/TLS-Handling fuer Deployment
|
||||
|
||||
## Voraussetzungen auf dem Entwicklungsrechner
|
||||
|
||||
|
|
@ -307,30 +308,43 @@ Die Datei `/tmp/screen-status.json` enthaelt nach dem ersten Heartbeat den persi
|
|||
|
||||
## Ergaenzt seit dem ersten Geruest:
|
||||
|
||||
- `message_wall`-Resolver im Backend
|
||||
**Backend-REST-API (statusseite.py, playerstatus.go, messagewall.go):**
|
||||
- `message_wall`-Resolver im Backend fuer Szenen-Aufloesung
|
||||
- Basisendpunkte und `message_wall`-Validierung im Backend testseitig breiter abgedeckt
|
||||
- erster `POST /api/v1/player/status`-Endpunkt im Backend
|
||||
- letzter bekannter Player-Status wird im Backend pro Screen in-memory vorgehalten und lesbar gemacht
|
||||
- Backend ergaenzt den Read-Pfad um `received_at` und eine einfache `stale`-Ableitung
|
||||
- Backend bietet zusaetzlich eine kleine Uebersicht aller zuletzt meldenden Screens
|
||||
- Backend validiert den Statuspfad jetzt enger auf erlaubte Lifecycle-/Connectivity-Werte und leitet `stale` aus dem gemeldeten Intervall ab
|
||||
- Backend leitet im Read-Pfad zusaetzlich ein kompaktes `derived_state` fuer Diagnosekonsumenten ab
|
||||
- Backend liefert unter `/status` eine erste sichtbare HTML-Diagnoseseite auf Basis derselben Statusdaten, inklusive Auto-Refresh, leichten Filtern und JSON-Drill-down
|
||||
- Backend unterstuetzt `q=` (Screen-ID-Substring), `derived_state=`, `server_connectivity=`, `stale=`, `updated_since=`, `limit=` als Query-Filter
|
||||
- Backend leitet `derived_state` (online / degraded / offline) aus `stale`, `server_connectivity` und `status` ab
|
||||
- Backend erlaubt das Loeschen einzelner Screen-Eintraege via `DELETE /api/v1/screens/{screenId}/status`
|
||||
- Backend persistiert den Status-Store optional in einer JSON-Datei (`MORZ_INFOBOARD_STATUS_STORE_PATH`)
|
||||
- dateibasierte Agent-Konfiguration zusaetzlich zu Env-Overrides
|
||||
- `POST /api/v1/player/status` mit Laufzeit-, Stale- und Server-Konnektivitaets-Tracking
|
||||
- Player-Status wird im Backend pro Screen in-memory vorgehalten und ueber Endpunkte lesbar gemacht
|
||||
- `GET /api/v1/screens/status` fuer Gesamt-Uebersicht mit Query-Filtern
|
||||
- `GET /api/v1/screens/{screenId}/status` fuer Einzelscreen-Details
|
||||
- `DELETE /api/v1/screens/{screenId}/status` zum Loeschen von Screen-Eintraegen
|
||||
- HTML-Diagnoseseite unter `/status` mit Auto-Refresh, Filterung und JSON-Drill-down
|
||||
- Query-Parameter: `q=` (Screen-ID-Substring), `derived_state=`, `server_connectivity=`, `stale=`, `updated_since=`, `limit=`
|
||||
- `derived_state` (online / degraded / offline) aus `stale`, `server_connectivity` und `status` abgeleitet
|
||||
- JSON-Persistenz optional in Datei (`MORZ_INFOBOARD_STATUS_STORE_PATH`)
|
||||
|
||||
**Backend-Datenverwaltung (manage/register.go, manage/playlist.go, manage/media.go):**
|
||||
- PostgreSQL-Anbindung mit `DATABASE_URL`-Konfiguration
|
||||
- Agent-Selbstregistrierung ueber `POST /api/v1/manage/register`
|
||||
- Playlist-Verwaltung und -Abruf (`GET /api/v1/manage/playlists/...`)
|
||||
- Medien-Upload und Speicherverwaltung in `MORZ_INFOBOARD_UPLOAD_DIR`
|
||||
- Admin-UI mit HTML-Templates fuer Playlist und Medien-Management
|
||||
|
||||
**Agent-Funktionalitaeten (player/agent/):**
|
||||
- dateibasierte Agent-Konfiguration (`config.json`) zusaetzlich zu Env-Overrides
|
||||
- strukturierte Agent-Logs mit internem Health-Snapshot und signalgesteuertem Shutdown
|
||||
- erster periodischer HTTP-Status-Reporter im Agent
|
||||
- Server-Connectivity-Zustand im Agent (`unknown`, `online`, `degraded`, `offline`) auf Basis der Report-Ergebnisse
|
||||
- der HTTP-Statuspfad transportiert jetzt neben `status` auch `server_connectivity`
|
||||
- lokales Compose-Grundgeruest fuer PostgreSQL und Mosquitto
|
||||
- MQTT-Heartbeat im Agent (optional; wird uebersprungen wenn kein Broker konfiguriert)
|
||||
- periodischer HTTP-Status-Reporter fuer Server-Registrierung
|
||||
- Server-Connectivity-Zustand (`unknown`, `online`, `degraded`, `offline`)
|
||||
- HTTP-Statuspfad transportiert `status` und `server_connectivity`
|
||||
- MQTT-Heartbeat (optional; wird uebersprungen wenn kein Broker konfiguriert)
|
||||
- MQTT-Authentifizierung mit Username und Password
|
||||
- Player-UI im Agent (`/player` HTML-Kiosk, `/api/now-playing` JSON)
|
||||
- Player-UI unter `/player` (HTML-Kiosk) und `/api/now-playing` (JSON)
|
||||
- Playlist-Rotation und lokale Playlist-Verwaltung
|
||||
|
||||
**Infrastruktur und Deployment:**
|
||||
- vollstaendiger Compose-Stack (`compose/server-stack.yml`) mit PostgreSQL 17, Mosquitto, Backend-Service und Health-Checks
|
||||
- Ansible-Rollen `signage_player` und `signage_display` fuer vollstaendiges Deployment
|
||||
- journald auf volatile Storage konfiguriert (SD-Karte schonen)
|
||||
- Cross-Compile fuer ARM64 im Ansible-Playbook
|
||||
- systemd-Units fuer Agent und Kiosk-Display
|
||||
|
||||
## Arbeitsweise
|
||||
|
||||
|
|
|
|||
55
README.md
55
README.md
|
|
@ -38,15 +38,50 @@ Die Trennung von `/srv/docker/infoboard-netboot` ist sinnvoll, damit:
|
|||
|
||||
## Aktueller Implementierungsstand
|
||||
|
||||
- `server/backend/` enthaelt ein lauffaehiges Go-Grundgeruest mit erster Tool-API fuer `message_wall` und einem ersten `player/status`-Endpunkt
|
||||
- `player/agent/` enthaelt ein Go-Grundgeruest mit dateibasierter/env-basierter Konfiguration, strukturierten Logs, internem Health-Modell und erstem HTTP-Status-Reporter
|
||||
- `compose/` enthaelt ein lokales Grundgeruest fuer PostgreSQL und Mosquitto
|
||||
- `ansible/` enthaelt erste Platzhalter fuer Inventory und Playbook-Struktur
|
||||
### Backend (`server/backend/`)
|
||||
- Vollstaendiges PostgreSQL-Backend mit Datenbank-Migrations
|
||||
- Store-Layer fuer Datenverwaltung
|
||||
- REST-API mit Endpunkten:
|
||||
- `message_wall` fuer Kampagnenausgabe
|
||||
- `player/status` fuer Player-Statusverwaltung
|
||||
- `/manage/` API fuer Media-Upload, Playlist-Verwaltung und Vorlagen
|
||||
- `/meta` fuer Systemmetadaten
|
||||
- HTML-Statusseiten fuer Diagnose
|
||||
- Admin-UI mit Medien-Upload und Playlist-Management
|
||||
- Tenant-aware Architektur mit Lebenszyklusverwaltung
|
||||
|
||||
## Naechste sinnvolle Inhalte in der Struktur
|
||||
### Player-Agent (`player/agent/`)
|
||||
- Funktionaler Go-Agent mit:
|
||||
- Selbstregistrierung beim Backend
|
||||
- Playlist-Rotation mit Heartbeat
|
||||
- Dateibasierter/env-basierter Konfiguration
|
||||
- Strukturierte Logs mit journald-Integration
|
||||
- Internes Health-Modell fuer Diagnosewerte
|
||||
- HTTP-Status-Reporter mit Lebenszyklusstatus
|
||||
- MQTT-Integration (optional) mit Authentifizierung
|
||||
- Binaries fuer Linux ARM64 vorhanden
|
||||
|
||||
- `docs/` fuer weitere technische Detaildokumente
|
||||
- `server/` fuer API, Admin-UI und Tenant-UI
|
||||
- `player/` fuer `player-agent`, `player-ui` und lokale Startlogik
|
||||
- `ansible/` fuer Rollen und Inventories
|
||||
- `compose/` fuer den zentralen Server-Stack
|
||||
### Ansible-Automatisierung (`ansible/`)
|
||||
- Zwei funktionale Rollen:
|
||||
- `signage_player`: Agent-Deployment mit Systemd-Units, Tasks, Templates und Handlers
|
||||
- `signage_display`: Display-Kiosk-Setup mit Systemd-Units, Tasks, Templates und Handlers
|
||||
- Konfigurierbare Defaults und Host-Variablen
|
||||
- Unterstützung für Bildschirm-Setup mit Ansible-Anleitung
|
||||
|
||||
### Infrastruktur (`compose/`)
|
||||
- Docker Compose Setup mit:
|
||||
- PostgreSQL-Datenbank
|
||||
- Mosquitto MQTT-Broker
|
||||
- Backend-Service Integration
|
||||
|
||||
## Implementierte Features
|
||||
|
||||
- DB-Migrations und Schema-Management
|
||||
- Media-Upload und Speicherverwaltung
|
||||
- Playlist-Management und Rotation
|
||||
- Player-Registrierung und Status-Tracking
|
||||
- Admin-UI für Screensetup
|
||||
- Ansible-automatisiertes Deployment auf Raspberry Pi
|
||||
- Kiosk-Display-Modus
|
||||
- MQTT-basierte Kommunikation
|
||||
- HTML-Diagnoseseiten
|
||||
|
|
|
|||
102
TODO.md
102
TODO.md
|
|
@ -2,38 +2,38 @@
|
|||
|
||||
## Phase 0 - Projektbasis
|
||||
|
||||
- [ ] Projektverzeichnisstruktur unter `/srv/docker/info-board-neu` festlegen
|
||||
- [ ] Namenskonventionen fuer Server, Player, Rollen und Pakete definieren
|
||||
- [ ] Dokumentationsstruktur fuer Architektur, Betrieb und Deployment anlegen
|
||||
- [ ] Entscheidung fuer Server-Tech-Stack dokumentieren
|
||||
- [ ] Entscheidung fuer Player-Implementierung dokumentieren
|
||||
- [ ] Sprachentscheidung dokumentieren: `Go` als bevorzugte Sprache fuer Agent und moeglichst viele Backend-Komponenten
|
||||
- [x] Projektverzeichnisstruktur unter `/srv/docker/info-board-neu` festlegen
|
||||
- [x] Namenskonventionen fuer Server, Player, Rollen und Pakete definieren
|
||||
- [x] Dokumentationsstruktur fuer Architektur, Betrieb und Deployment anlegen
|
||||
- [x] Entscheidung fuer Server-Tech-Stack dokumentieren
|
||||
- [x] Entscheidung fuer Player-Implementierung dokumentieren
|
||||
- [x] Sprachentscheidung dokumentieren: `Go` als bevorzugte Sprache fuer Agent und moeglichst viele Backend-Komponenten
|
||||
|
||||
## Phase 1 - Fachliches Fundament
|
||||
|
||||
- [ ] Rollenmodell fuer `admin` und monitorgebundene Nutzer final festschreiben
|
||||
- [ ] Datenmodell fuer `tenant`, `screen`, `user`, `media_asset`, `playlist`, `playlist_item`, `screen_status`, `screen_snapshot` definieren
|
||||
- [ ] Playlist-Semantik mit `duration`, `valid_from`, `valid_until`, `load_timeout`, `cache_policy`, `on_error` spezifizieren
|
||||
- [ ] Fallback-Regel fuer ungeplante oder leere Inhalte verbindlich definieren
|
||||
- [ ] Statusmodell fuer Online/Offline/Degraded/Error definieren
|
||||
- [ ] Kommandokatalog fuer Admin-Aktionen finalisieren
|
||||
- [ ] Template- und Kampagnenmodell fuer globale monitoruebergreifende Uebersteuerung finalisieren
|
||||
- [ ] Prioritaetsregel `campaign > tenant_playlist > fallback` verbindlich festschreiben
|
||||
- [x] Rollenmodell fuer `admin` und monitorgebundene Nutzer final festschreiben
|
||||
- [x] Datenmodell fuer `tenant`, `screen`, `user`, `media_asset`, `playlist`, `playlist_item`, `screen_status`, `screen_snapshot` definieren
|
||||
- [x] Playlist-Semantik mit `duration`, `valid_from`, `valid_until`, `load_timeout`, `cache_policy`, `on_error` spezifizieren
|
||||
- [x] Fallback-Regel fuer ungeplante oder leere Inhalte verbindlich definieren
|
||||
- [x] Statusmodell fuer Online/Offline/Degraded/Error definieren
|
||||
- [x] Kommandokatalog fuer Admin-Aktionen finalisieren
|
||||
- [x] Template- und Kampagnenmodell fuer globale monitoruebergreifende Uebersteuerung finalisieren
|
||||
- [x] Prioritaetsregel `campaign > tenant_playlist > fallback` verbindlich festschreiben
|
||||
- [x] Entscheidung dokumentieren, dass `playlist_items.screen_id` entfernt wird
|
||||
- [x] Entscheidung dokumentieren, dass Gruppen bei Kampagnen serverseitig in Einzel-Assignments expandiert werden
|
||||
|
||||
## Phase 2 - Technische Zielarchitektur
|
||||
|
||||
- [ ] Server-Komponentenliste finalisieren
|
||||
- [ ] API-Schnittstellen grob definieren
|
||||
- [ ] MQTT-Topic-Struktur finalisieren
|
||||
- [ ] HTTPS- und MQTT-Aufgabentrennung dokumentieren
|
||||
- [ ] Screenshot-/Vorschaustrategie spezifizieren
|
||||
- [ ] Offline- und Cache-Strategie bis auf Dateiebene festlegen
|
||||
- [ ] Sicherheitsmodell fuer Uploads, Login und Rechte pruefen
|
||||
- [ ] API fuer Templates, Kampagnen, Aktivierung und Deaktivierung ausarbeiten
|
||||
- [ ] Provisionierungs-Workflow fuer neue Screens technisch durchplanen
|
||||
- [ ] Secret-Handling fuer initiale Root-Passwoerter oder Bootstrap-Zugaenge definieren
|
||||
- [x] Server-Komponentenliste finalisieren
|
||||
- [x] API-Schnittstellen grob definieren
|
||||
- [x] MQTT-Topic-Struktur finalisieren
|
||||
- [x] HTTPS- und MQTT-Aufgabentrennung dokumentieren
|
||||
- [x] Screenshot-/Vorschaustrategie spezifizieren
|
||||
- [x] Offline- und Cache-Strategie bis auf Dateiebene festlegen
|
||||
- [x] Sicherheitsmodell fuer Uploads, Login und Rechte pruefen
|
||||
- [x] API fuer Templates, Kampagnen, Aktivierung und Deaktivierung ausarbeiten
|
||||
- [x] Provisionierungs-Workflow fuer neue Screens technisch durchplanen
|
||||
- [x] Secret-Handling fuer initiale Root-Passwoerter oder Bootstrap-Zugaenge definieren
|
||||
- [x] API-Fehlermodell und gemeinsame Fehlerantworten festlegen
|
||||
- [x] ACK-Timeout-Strategie fuer `device_command` festlegen
|
||||
- [x] `message_wall`-Rendering serverseitig verbindlich entscheiden
|
||||
|
|
@ -44,46 +44,46 @@
|
|||
- [x] Minimalen Paketbedarf fuer den Player auf Raspberry Pi OS Debian 13 ermitteln
|
||||
- [x] X11-Minimalkonzept fuer Chromium-Kiosk dokumentieren
|
||||
- [x] Startmechanismus fuer Chromium ohne Desktop-Umgebung definieren
|
||||
- [ ] Verzeichnislayout auf dem Player festlegen
|
||||
- [x] Verzeichnislayout auf dem Player festlegen
|
||||
- [x] `player-agent` fachlich zuschneiden
|
||||
- [x] `player-ui` fachlich zuschneiden (lokale Kiosk-Seite mit Splash + Sysinfo-Overlay)
|
||||
- [ ] Watchdog-Konzept fuer Browser und Agent definieren
|
||||
- [ ] Offline-Overlay-Verhalten spezifizieren
|
||||
- [ ] Fehlerbehandlung fuer Web-Inhalte und Timeouts ausarbeiten
|
||||
- [ ] Display-Steuerung fuer An/Aus, Rotation und Neustart planen
|
||||
- [ ] Sysinfo-Overlay erweitern: load, freier RAM, IP-Adresse(n) anzeigen
|
||||
- [x] Offline-Overlay-Verhalten spezifizieren
|
||||
- [x] Fehlerbehandlung fuer Web-Inhalte und Timeouts ausarbeiten
|
||||
- [x] Display-Steuerung fuer An/Aus, Rotation und Neustart planen
|
||||
- [x] Sysinfo-Overlay erweitern: load, freier RAM, IP-Adresse(n) anzeigen
|
||||
|
||||
## Phase 4 - Server-Design
|
||||
|
||||
- [ ] API-Backend fachlich schneiden
|
||||
- [ ] Admin-Oberflaeche in Hauptbereiche aufteilen
|
||||
- [x] API-Backend fachlich schneiden
|
||||
- [x] Admin-Oberflaeche in Hauptbereiche aufteilen
|
||||
- [ ] Firmen-/Monitor-Oberflaeche in Hauptbereiche aufteilen
|
||||
- [ ] Storage-Konzept fuer Uploads, Cache-Dateien und Screenshots festlegen
|
||||
- [ ] Authentifizierungskonzept festlegen
|
||||
- [ ] Mandantentrennung im Datenmodell und in den APIs absichern
|
||||
- [x] Storage-Konzept fuer Uploads, Cache-Dateien und Screenshots festlegen
|
||||
- [x] Authentifizierungskonzept festlegen
|
||||
- [x] Mandantentrennung im Datenmodell und in den APIs absichern
|
||||
- [ ] Logging- und Monitoring-Konzept definieren
|
||||
- [ ] Template-Editor fuer globale Kampagnen fachlich schneiden
|
||||
- [ ] Aktivierungsoberflaeche fuer saisonale oder temporäre Kampagnen planen
|
||||
- [ ] Gruppierung oder Slot-Modell fuer monitoruebergreifende Layouts planen
|
||||
- [ ] Provisionierungs-UI fuer neue Screens fachlich und technisch schneiden
|
||||
- [x] Provisionierungs-UI fuer neue Screens fachlich und technisch schneiden
|
||||
- [ ] Jobrunner-Konzept fuer Ansible-gestuetzte Erstinstallation planen
|
||||
|
||||
## Phase 5 - Prototyping
|
||||
|
||||
- [ ] Minimalen Server-Prototyp bauen
|
||||
- [ ] Minimalen Player-Agent-Prototyp bauen
|
||||
- [ ] Minimale Player-UI bauen
|
||||
- [x] Minimalen Server-Prototyp bauen
|
||||
- [x] Minimalen Player-Agent-Prototyp bauen
|
||||
- [x] Minimale Player-UI bauen
|
||||
- [ ] Lokale Test-Playlist mit Bild, Video, PDF und Webseite anlegen
|
||||
- [ ] Fallback-Verzeichnisbetrieb demonstrieren
|
||||
- [x] Fallback-Verzeichnisbetrieb demonstrieren
|
||||
- [ ] `valid_from`/`valid_until` im Prototyp pruefen
|
||||
- [ ] Offline-Sync mit lokalem Cache pruefen
|
||||
- [x] Offline-Sync mit lokalem Cache pruefen
|
||||
- [ ] MQTT-Kommandos `reload`, `restart_player`, `reboot`, `display_on`, `display_off` testweise durchspielen
|
||||
- [ ] globale Kampagne testen, die tenantbezogenen Content temporär ueberschreibt
|
||||
- [ ] Rueckfall auf Normalbetrieb nach manueller Deaktivierung pruefen
|
||||
|
||||
## Phase 6 - Betriebsfaehigkeit
|
||||
|
||||
- [ ] Docker-Compose-Setup fuer den Server anlegen
|
||||
- [x] Docker-Compose-Setup fuer den Server anlegen
|
||||
- [x] systemd-Units fuer den Player erstellen
|
||||
- [x] Chromium-Kiosk-Startskript erstellen
|
||||
- [ ] Screenshot-Erzeugung auf dem Player integrieren
|
||||
|
|
@ -101,7 +101,7 @@
|
|||
- [x] Screen-spezifische Variablen wie `screen_id`, Rotation und Aufloesung abbilden
|
||||
- [x] Erstinstallation eines neuen Players automatisieren
|
||||
- [x] Update-Rollout eines bestehenden Players automatisieren
|
||||
- [ ] Bootstrap ueber Root-Passwort auf SSH-Key und dauerhafte Verwaltung umstellen
|
||||
- [x] Bootstrap ueber Root-Passwort auf SSH-Key und dauerhafte Verwaltung umstellen
|
||||
|
||||
## Phase 8 - Pilotbetrieb
|
||||
|
||||
|
|
@ -144,13 +144,13 @@
|
|||
|
||||
## Erste konkrete Abarbeitungsreihenfolge
|
||||
|
||||
- [ ] 1. Projektstruktur im neuen Verzeichnis vervollstaendigen
|
||||
- [ ] 2. Datenmodell in eigener Datei ausformulieren
|
||||
- [ ] 3. API- und MQTT-Vertrag definieren
|
||||
- [ ] 4. Player-Minimalkonzept fuer Raspberry Pi OS Debian 13 festzurren
|
||||
- [ ] 5. Server-Compose-Grundgeruest erstellen
|
||||
- [ ] 6. Player-Prototyp mit lokalem Browser-Renderer bauen
|
||||
- [ ] 7. Offline-Cache und Fallback robust machen
|
||||
- [ ] 8. UIs fuer Admin und Firmen schrittweise aufbauen
|
||||
- [ ] 9. Ansible-Rollen erstellen
|
||||
- [x] 1. Projektstruktur im neuen Verzeichnis vervollstaendigen
|
||||
- [x] 2. Datenmodell in eigener Datei ausformulieren
|
||||
- [x] 3. API- und MQTT-Vertrag definieren
|
||||
- [x] 4. Player-Minimalkonzept fuer Raspberry Pi OS Debian 13 festzurren
|
||||
- [x] 5. Server-Compose-Grundgeruest erstellen
|
||||
- [x] 6. Player-Prototyp mit lokalem Browser-Renderer bauen
|
||||
- [x] 7. Offline-Cache und Fallback robust machen
|
||||
- [x] 8. UIs fuer Admin und Firmen schrittweise aufbauen
|
||||
- [x] 9. Ansible-Rollen erstellen
|
||||
- [ ] 10. Pilotmonitor migrieren
|
||||
|
|
|
|||
836
docs/API-ENDPOINTS.md
Normal file
836
docs/API-ENDPOINTS.md
Normal file
|
|
@ -0,0 +1,836 @@
|
|||
# Info-Board Neu - API-Endpoints Vollständig
|
||||
|
||||
## Überblick
|
||||
|
||||
Die Backend-API unterteilt sich in mehrere Bereiche:
|
||||
|
||||
- **Health & Meta**: System-Status und API-Informationen
|
||||
- **Player Status**: Status-Ingest und Diagnose vom Player
|
||||
- **Screen Management**: CRUD und Registrierung von Screens
|
||||
- **Playlists**: Abruf und Verwaltung von Wiedergabelisten
|
||||
- **Media**: Upload und Verwaltung von Medien-Assets
|
||||
- **Message Wall**: Auflösung von Nachrichten-Wand-Anfragen
|
||||
- **Admin & UI**: Web-Formulare und Provisionierung
|
||||
- **Provisioning**: Erstinstallation neuer Screens (geplant)
|
||||
|
||||
---
|
||||
|
||||
## Health & Meta
|
||||
|
||||
### GET /healthz
|
||||
|
||||
Health-Check für Monitoring.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"service": "morz-infoboard-backend"
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/v1
|
||||
|
||||
API-Entrypoint mit Tools-Übersicht.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"name": "morz-infoboard-backend",
|
||||
"version": "dev",
|
||||
"tools": [
|
||||
"message-wall-resolve",
|
||||
"screen-status-list",
|
||||
"screen-status-detail",
|
||||
"player-status-ingest",
|
||||
"screen-status-delete"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/v1/meta
|
||||
|
||||
Zusätzliche Metainformationen (noch nicht spezifiziert).
|
||||
|
||||
---
|
||||
|
||||
## Player Status (Diagnose)
|
||||
|
||||
Siehe separate Dokumentation in `PLAYER-STATUS-HTTP.md`.
|
||||
|
||||
Endpoints:
|
||||
- `POST /api/v1/player/status` — Status-Ingest vom Player-Agent
|
||||
- `GET /api/v1/screens/status` — Übersicht aller Screen-Status
|
||||
- `GET /api/v1/screens/{screenId}/status` — Einzelner Screen-Status
|
||||
- `DELETE /api/v1/screens/{screenId}/status` — Status löschen
|
||||
|
||||
### POST /api/v1/player/status
|
||||
|
||||
Der Player-Agent sendet seinen aktuellen Status an den Server.
|
||||
|
||||
**Request-Body:**
|
||||
```json
|
||||
{
|
||||
"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"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{ "status": "accepted" }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Screen Management (JSON API)
|
||||
|
||||
### POST /api/v1/screens/register
|
||||
|
||||
Agent-Selbstregistrierung — wird vom Player-Agent beim Hochfahren aufgerufen.
|
||||
|
||||
Der Agent upsert den Screen automatisch im Default-Tenant ("morz"), so dass alle deployt Screen automatisch im Admin-UI erscheinen.
|
||||
|
||||
**Request-Body:**
|
||||
```json
|
||||
{
|
||||
"slug": "info10",
|
||||
"name": "Info10 Bildschirm",
|
||||
"orientation": "landscape"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": "uuid...",
|
||||
"tenant_id": "uuid...",
|
||||
"slug": "info10",
|
||||
"name": "Info10 Bildschirm",
|
||||
"orientation": "landscape",
|
||||
"created_at": "2026-03-22T16:00:00Z",
|
||||
"updated_at": "2026-03-22T16:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `200 OK` — Screen wurde erzeugt oder aktualisiert (upsert)
|
||||
- `400 Bad Request` — Slug fehlt oder ungültig
|
||||
- `500 Internal Server Error` — DB-Fehler oder Default-Tenant nicht vorhanden
|
||||
|
||||
---
|
||||
|
||||
### GET /api/v1/tenants/{tenantSlug}/screens
|
||||
|
||||
Listet alle Screens eines Tenants auf.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "uuid...",
|
||||
"tenant_id": "uuid...",
|
||||
"slug": "info10",
|
||||
"name": "Info10 Bildschirm",
|
||||
"orientation": "landscape",
|
||||
"created_at": "2026-03-22T16:00:00Z",
|
||||
"updated_at": "2026-03-22T16:00:00Z"
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `200 OK` — Liste erfolgreich abrufen
|
||||
- `404 Not Found` — Tenant nicht vorhanden
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
---
|
||||
|
||||
### POST /api/v1/tenants/{tenantSlug}/screens
|
||||
|
||||
Erstellt einen neuen Screen für einen Tenant (Admin-API).
|
||||
|
||||
**Request-Body:**
|
||||
```json
|
||||
{
|
||||
"slug": "new-screen",
|
||||
"name": "New Display",
|
||||
"orientation": "portrait"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": "uuid...",
|
||||
"tenant_id": "uuid...",
|
||||
"slug": "new-screen",
|
||||
"name": "New Display",
|
||||
"orientation": "portrait",
|
||||
"created_at": "2026-03-22T16:00:00Z",
|
||||
"updated_at": "2026-03-22T16:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `201 Created` — Screen erstellt
|
||||
- `400 Bad Request` — Slug oder Name fehlt
|
||||
- `404 Not Found` — Tenant nicht vorhanden
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
---
|
||||
|
||||
## Playlist Management (JSON API)
|
||||
|
||||
### GET /api/v1/screens/{screenId}/playlist
|
||||
|
||||
Abruf der aktiven Playlist für einen Screen (Player-Sync).
|
||||
|
||||
Der Player ruft diesen Endpoint auf, um die aktuellen Inhalte zu laden.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"playlist_id": "uuid...",
|
||||
"default_duration_seconds": 20,
|
||||
"items": [
|
||||
{
|
||||
"id": "uuid...",
|
||||
"type": "web",
|
||||
"src": "http://example.com/page1",
|
||||
"title": "Startseite",
|
||||
"duration_seconds": 30,
|
||||
"enabled": true,
|
||||
"valid_from": null,
|
||||
"valid_until": null
|
||||
},
|
||||
{
|
||||
"id": "uuid...",
|
||||
"type": "image",
|
||||
"src": "/uploads/banner.jpg",
|
||||
"title": "Werbebanner",
|
||||
"duration_seconds": 20,
|
||||
"enabled": true,
|
||||
"valid_from": null,
|
||||
"valid_until": null
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Wenn keine Playlist vorhanden ist, wird eine leere Liste zurückgegeben:
|
||||
```json
|
||||
{
|
||||
"items": []
|
||||
}
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `200 OK` — Playlist abrufen
|
||||
- `404 Not Found` — Screen nicht vorhanden
|
||||
|
||||
---
|
||||
|
||||
### GET /api/v1/playlists/{screenId}
|
||||
|
||||
Abrufen einer kompletten Playlist mit Metadaten.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"playlist": {
|
||||
"id": "uuid...",
|
||||
"screen_id": "uuid...",
|
||||
"tenant_id": "uuid...",
|
||||
"name": "Hauptplaylist",
|
||||
"is_active": true,
|
||||
"default_duration_seconds": 20,
|
||||
"fallback_enabled": true,
|
||||
"fallback_dir": "/fallback",
|
||||
"shuffle_enabled": false,
|
||||
"created_at": "2026-03-22T16:00:00Z",
|
||||
"updated_at": "2026-03-22T16:00:00Z"
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"id": "uuid...",
|
||||
"playlist_id": "uuid...",
|
||||
"type": "web",
|
||||
"src": "http://example.com",
|
||||
"title": "Example",
|
||||
"duration_seconds": 20,
|
||||
"enabled": true,
|
||||
"created_at": "2026-03-22T16:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `200 OK` — Erfolgreich abrufen
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
---
|
||||
|
||||
### POST /api/v1/playlists/{playlistId}/items
|
||||
|
||||
Fügt ein Item zu einer Playlist hinzu.
|
||||
|
||||
**Request-Body (Optionen A: Aus Media-Library):**
|
||||
```json
|
||||
{
|
||||
"media_asset_id": "uuid...",
|
||||
"title": "Optional überschriebener Titel"
|
||||
}
|
||||
```
|
||||
|
||||
**Request-Body (Optionen B: Direkte URL):**
|
||||
```json
|
||||
{
|
||||
"type": "web",
|
||||
"src": "http://example.com/page",
|
||||
"title": "Example Page",
|
||||
"duration_seconds": 30,
|
||||
"valid_from": "2026-03-22T09:00:00Z",
|
||||
"valid_until": "2026-03-22T17:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": "uuid...",
|
||||
"playlist_id": "uuid...",
|
||||
"type": "web",
|
||||
"src": "http://example.com/page",
|
||||
"title": "Example Page",
|
||||
"duration_seconds": 30,
|
||||
"enabled": true,
|
||||
"valid_from": "2026-03-22T09:00:00Z",
|
||||
"valid_until": "2026-03-22T17:00:00Z",
|
||||
"created_at": "2026-03-22T16:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `201 Created` — Item erstellt
|
||||
- `400 Bad Request` — Type oder Src fehlt; Media-Asset nicht vorhanden
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
---
|
||||
|
||||
### PATCH /api/v1/items/{itemId}
|
||||
|
||||
Aktualisiert ein Playlist-Item (Titel, Dauer, Zeitfenster, aktiviert).
|
||||
|
||||
**Request-Body:**
|
||||
```json
|
||||
{
|
||||
"title": "Neuer Titel",
|
||||
"duration_seconds": 25,
|
||||
"enabled": true,
|
||||
"valid_from": "2026-03-22T09:00:00Z",
|
||||
"valid_until": "2026-03-22T17:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `204 No Content` — Erfolgreich aktualisiert
|
||||
- `400 Bad Request` — Ungültige Dauer
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
---
|
||||
|
||||
### DELETE /api/v1/items/{itemId}
|
||||
|
||||
Löscht ein Playlist-Item.
|
||||
|
||||
**Status:**
|
||||
- `204 No Content` — Erfolgreich gelöscht
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
---
|
||||
|
||||
### PUT /api/v1/playlists/{playlistId}/order
|
||||
|
||||
Reordnet die Items einer Playlist anhand einer geordneten Liste von Item-IDs.
|
||||
|
||||
**Request-Body:**
|
||||
```json
|
||||
[
|
||||
"item-id-1",
|
||||
"item-id-2",
|
||||
"item-id-3"
|
||||
]
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `204 No Content` — Erfolgreich reordert
|
||||
- `400 Bad Request` — JSON-Array erwartet
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
---
|
||||
|
||||
### PATCH /api/v1/playlists/{playlistId}/duration
|
||||
|
||||
Setzt die Standard-Dauer für neue Items einer Playlist.
|
||||
|
||||
**Request-Body (Form-Encoded):**
|
||||
```
|
||||
default_duration_seconds=25
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `204 No Content` — Erfolgreich aktualisiert
|
||||
- `400 Bad Request` — Ungültige oder fehlende Dauer
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
---
|
||||
|
||||
## Media Management (JSON API)
|
||||
|
||||
### GET /api/v1/tenants/{tenantSlug}/media
|
||||
|
||||
Listet alle Medien-Assets eines Tenants auf.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "uuid...",
|
||||
"tenant_id": "uuid...",
|
||||
"title": "Banner Image",
|
||||
"description": null,
|
||||
"type": "image",
|
||||
"source_kind": "upload",
|
||||
"storage_path": "/uploads/1234567890_banner.jpg",
|
||||
"original_url": null,
|
||||
"mime_type": "image/jpeg",
|
||||
"size_bytes": 102400,
|
||||
"enabled": true,
|
||||
"created_at": "2026-03-22T16:00:00Z",
|
||||
"updated_at": "2026-03-22T16:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": "uuid...",
|
||||
"tenant_id": "uuid...",
|
||||
"title": "External Website",
|
||||
"type": "web",
|
||||
"source_kind": "remote_url",
|
||||
"original_url": "http://example.com",
|
||||
"storage_path": null,
|
||||
"enabled": true,
|
||||
"created_at": "2026-03-22T16:00:00Z"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Wenn keine Assets vorhanden sind, wird eine leere Liste zurückgegeben.
|
||||
|
||||
**Status:**
|
||||
- `200 OK` — Liste erfolgreich abrufen
|
||||
- `404 Not Found` — Tenant nicht vorhanden
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
---
|
||||
|
||||
### POST /api/v1/tenants/{tenantSlug}/media
|
||||
|
||||
Registriert ein neues Medien-Asset (Datei-Upload oder externe URL).
|
||||
|
||||
**Request-Typ A: Datei-Upload (Multipart)**
|
||||
```
|
||||
Content-Type: multipart/form-data
|
||||
|
||||
type: image (oder video, pdf)
|
||||
title: Mein Bild
|
||||
file: <binary data>
|
||||
```
|
||||
|
||||
**Request-Typ B: Externe URL (Multipart)**
|
||||
```
|
||||
Content-Type: multipart/form-data
|
||||
|
||||
type: web
|
||||
title: Externe Website
|
||||
url: http://example.com
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": "uuid...",
|
||||
"tenant_id": "uuid...",
|
||||
"title": "Mein Bild",
|
||||
"type": "image",
|
||||
"source_kind": "upload",
|
||||
"storage_path": "/uploads/1234567890_mein_bild.jpg",
|
||||
"mime_type": "image/jpeg",
|
||||
"size_bytes": 102400,
|
||||
"enabled": true,
|
||||
"created_at": "2026-03-22T16:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `201 Created` — Asset erstellt
|
||||
- `400 Bad Request` — Ungültiger Type, fehlende Datei/URL, oder Request zu groß (>512 MB)
|
||||
- `404 Not Found` — Tenant nicht vorhanden
|
||||
- `500 Internal Server Error` — Datei-/DB-Fehler
|
||||
|
||||
---
|
||||
|
||||
### DELETE /api/v1/media/{id}
|
||||
|
||||
Löscht ein Medien-Asset (und physische Datei falls lokal gespeichert).
|
||||
|
||||
**Status:**
|
||||
- `204 No Content` — Erfolgreich gelöscht
|
||||
- `404 Not Found` — Asset nicht vorhanden
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
---
|
||||
|
||||
## Message Wall
|
||||
|
||||
### POST /api/v1/tools/message-wall/resolve
|
||||
|
||||
Spezialendpoint zur Auflösung von Nachrichten-Wand-Anfragen (noch in Entwicklung).
|
||||
|
||||
---
|
||||
|
||||
## Admin UI (Web-Formulare)
|
||||
|
||||
### GET /admin
|
||||
|
||||
Administrations-Dashboard mit Übersicht aller Screens und Tenants.
|
||||
|
||||
Rückgabe: HTML-Seite mit:
|
||||
- Liste aller Screens
|
||||
- Status-Information
|
||||
- Provisioning-Formulare
|
||||
- Screen-Verwaltung
|
||||
|
||||
---
|
||||
|
||||
### POST /admin/screens/provision
|
||||
|
||||
Startet einen Provisionierungs-Job für einen neuen oder bestehenden Screen.
|
||||
|
||||
**Request-Body (Form-Encoded oder JSON):**
|
||||
```json
|
||||
{
|
||||
"screen_id": "uuid...",
|
||||
"target_ip": "192.168.1.100",
|
||||
"target_port": 22,
|
||||
"remote_user": "root",
|
||||
"auth_mode": "password",
|
||||
"provided_secret_ref": "secret-key-123"
|
||||
}
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `200 OK` — Job erfolgreich erstellt
|
||||
- `400 Bad Request` — Fehlende oder ungültige Parameter
|
||||
- `404 Not Found` — Screen nicht vorhanden
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
**Hinweis:** Der eigentliche Provisionierungs-Job läuft asynchron über einen Worker ab.
|
||||
|
||||
---
|
||||
|
||||
### POST /admin/screens
|
||||
|
||||
Erstellt einen neuen Screen über das Admin-Formular.
|
||||
|
||||
**Request-Body (Form-Encoded):**
|
||||
```
|
||||
slug=new-screen&name=Neuer+Bildschirm&orientation=landscape
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `200 OK` oder `201 Created` — Screen erstellt
|
||||
- `400 Bad Request` — Fehlende Parameter
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
Rückleitung zur Admin-Seite.
|
||||
|
||||
---
|
||||
|
||||
### POST /admin/screens/{screenId}/delete
|
||||
|
||||
Löscht einen Screen.
|
||||
|
||||
**Status:**
|
||||
- `200 OK` — Screen gelöscht
|
||||
- `404 Not Found` — Screen nicht vorhanden
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
Rückleitung zur Admin-Seite.
|
||||
|
||||
---
|
||||
|
||||
## Playlist Management UI (Web-Formulare)
|
||||
|
||||
### GET /manage/{screenSlug}
|
||||
|
||||
Verwaltungs-UI für die Playlist eines Screens.
|
||||
|
||||
Rückgabe: HTML-Seite mit:
|
||||
- Liste der Medien-Assets
|
||||
- Playlist-Editor
|
||||
- Upload-Formular
|
||||
- Item-Verwaltung
|
||||
|
||||
---
|
||||
|
||||
### POST /manage/{screenSlug}/upload
|
||||
|
||||
Datei-Upload über das Manage-Formular.
|
||||
|
||||
**Request (Multipart):**
|
||||
```
|
||||
type: image (oder video, pdf)
|
||||
title: Neues Bild
|
||||
file: <binary data>
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `201 Created` — Asset erfolgreich hochgeladen
|
||||
- `404 Not Found` — Screen nicht vorhanden
|
||||
- `500 Internal Server Error` — Fehler
|
||||
|
||||
Rückleitung zum Manage-Formular.
|
||||
|
||||
---
|
||||
|
||||
### POST /manage/{screenSlug}/items
|
||||
|
||||
Fügt ein Item zur Playlist hinzu (Formular).
|
||||
|
||||
**Request (Form-Encoded):**
|
||||
```
|
||||
media_asset_id=uuid...&duration_seconds=25
|
||||
oder
|
||||
type=web&src=http://example.com&duration_seconds=30
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `201 Created` — Item erstellt
|
||||
- `404 Not Found` — Screen nicht vorhanden
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
Rückleitung zum Manage-Formular.
|
||||
|
||||
---
|
||||
|
||||
### POST /manage/{screenSlug}/items/{itemId}
|
||||
|
||||
Aktualisiert ein Item (Formular).
|
||||
|
||||
**Request (Form-Encoded):**
|
||||
```
|
||||
title=Neuer+Titel&duration_seconds=25&enabled=on
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `200 OK` oder `204 No Content` — Erfolgreich aktualisiert
|
||||
- `404 Not Found` — Item nicht vorhanden
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
Rückleitung zum Manage-Formular.
|
||||
|
||||
---
|
||||
|
||||
### POST /manage/{screenSlug}/items/{itemId}/delete
|
||||
|
||||
Löscht ein Item (Formular).
|
||||
|
||||
**Status:**
|
||||
- `204 No Content` — Erfolgreich gelöscht
|
||||
- `404 Not Found` — Item nicht vorhanden
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
Rückleitung zum Manage-Formular.
|
||||
|
||||
---
|
||||
|
||||
### POST /manage/{screenSlug}/reorder
|
||||
|
||||
Reordert Items (Formular).
|
||||
|
||||
**Request (Form-Encoded mit Array-Syntax):**
|
||||
```
|
||||
items=item-id-1&items=item-id-2&items=item-id-3
|
||||
```
|
||||
|
||||
**Status:**
|
||||
- `204 No Content` — Erfolgreich reordert
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
Rückleitung zum Manage-Formular.
|
||||
|
||||
---
|
||||
|
||||
### POST /manage/{screenSlug}/media/{mediaId}/delete
|
||||
|
||||
Löscht ein Medien-Asset (Formular).
|
||||
|
||||
**Status:**
|
||||
- `204 No Content` — Erfolgreich gelöscht
|
||||
- `404 Not Found` — Asset nicht vorhanden
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
Rückleitung zum Manage-Formular.
|
||||
|
||||
---
|
||||
|
||||
## Datei-Serving
|
||||
|
||||
### GET /uploads/{filename}
|
||||
|
||||
Stellt hochgeladene Medien-Dateien bereit.
|
||||
|
||||
**Query-Parameter:**
|
||||
- Keine
|
||||
|
||||
**Status:**
|
||||
- `200 OK` — Datei gefunden
|
||||
- `404 Not Found` — Datei nicht vorhanden
|
||||
|
||||
---
|
||||
|
||||
## Diagnostic Pages (HTML)
|
||||
|
||||
### GET /status
|
||||
|
||||
HTML-Diagnoseseite für den Browser mit Übersicht aller Screen-Status.
|
||||
|
||||
- Automatisches Refresh alle 15 Sekunden
|
||||
- Shortcut-Links für Filter
|
||||
- Filterformular (wie JSON-Read-Pfad)
|
||||
- Direkte JSON-Detail-Links pro Screen
|
||||
|
||||
**Query-Parameter:** Dieselben wie `GET /api/v1/screens/status`
|
||||
- `q` — Screen-ID Substring-Suche
|
||||
- `derived_state` — `online`, `degraded`, `offline`
|
||||
- `server_connectivity` — `online`, `degraded`, `offline`, `unknown`
|
||||
- `stale` — `true`, `false`
|
||||
- `updated_since` — RFC3339-Zeitstempel
|
||||
- `limit` — positive Ganzzahl
|
||||
|
||||
---
|
||||
|
||||
### GET /status/{screenId}
|
||||
|
||||
HTML-Detailseite für einen einzelnen Screen.
|
||||
|
||||
Zeigt:
|
||||
- Screen-Information
|
||||
- Derived State
|
||||
- Player Status
|
||||
- Connectivity
|
||||
- Freshness und Timestamps
|
||||
- Endpunkte und Links
|
||||
|
||||
---
|
||||
|
||||
## Player Local UI (Agent)
|
||||
|
||||
### GET /player
|
||||
|
||||
Zeigt die lokale Player-UI (HTML) auf dem Gerät.
|
||||
|
||||
Rückgabe: HTML-Seite mit:
|
||||
- Splash-Screen
|
||||
- Systeminformationen-Overlay
|
||||
- Verbindungsstatus-Punkt
|
||||
- Basis für Playlist-Anzeige
|
||||
|
||||
---
|
||||
|
||||
### GET /api/now-playing
|
||||
|
||||
JSON-API des Player-Agents (lokal).
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"playlist": [
|
||||
{
|
||||
"src": "http://backend.local/api/v1/screens/info10/playlist",
|
||||
"type": "web",
|
||||
"title": "Startseite",
|
||||
"duration_seconds": 30
|
||||
}
|
||||
],
|
||||
"status": "running",
|
||||
"connectivity": "online"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### GET /api/sysinfo
|
||||
|
||||
Systeminformationen des Player-Agents (lokal).
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"label": "Hostname",
|
||||
"value": "infoboard-01"
|
||||
},
|
||||
{
|
||||
"label": "Uptime",
|
||||
"value": "5d 2h 30m"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fehlerbehandlung
|
||||
|
||||
Alle JSON-Responses folgen diesem Fehlermodell (falls implementiert):
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "error_code_here",
|
||||
"message": "Human-readable error message",
|
||||
"details": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Typische HTTP-Status:
|
||||
- `200 OK` — Erfolgreiche Anfrage (Read)
|
||||
- `201 Created` — Ressource erstellt
|
||||
- `204 No Content` — Erfolgreiche Anfrage ohne Response-Body
|
||||
- `400 Bad Request` — Eingabe-Validierung fehlgeschlagen
|
||||
- `404 Not Found` — Ressource nicht vorhanden
|
||||
- `500 Internal Server Error` — Server-Fehler
|
||||
|
||||
---
|
||||
|
||||
## Änderungshistorie
|
||||
|
||||
- **2026-03-23:** Initiale Dokumentation aller HTTP-Endpoints basierend auf Code-Review
|
||||
- Alle Screen-Management-Endpoints dokumentiert
|
||||
- Alle Playlist-Management-Endpoints dokumentiert
|
||||
- Alle Media-Management-Endpoints dokumentiert
|
||||
- Admin-UI und Manage-UI-Endpoints dokumentiert
|
||||
- Player-Status-Diagnostik dokumentiert
|
||||
- Player-Local-API dokumentiert
|
||||
165
docs/API-INDEX.md
Normal file
165
docs/API-INDEX.md
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
# API Documentation Index
|
||||
|
||||
Vollständige Übersicht der Dokumentation für die morz-infoboard Backend-API.
|
||||
|
||||
---
|
||||
|
||||
## Einstieg
|
||||
|
||||
**Für Schnellzugriff auf spezifische Endpoints:**
|
||||
→ **[API Quick Reference](API-QUICK-REFERENCE.md)**
|
||||
|
||||
Sortiert nach Funktion mit Kurzbeschreibungen und typischen Workflows.
|
||||
|
||||
---
|
||||
|
||||
## Vollständige Dokumentation
|
||||
|
||||
### [API-ENDPOINTS.md](API-ENDPOINTS.md)
|
||||
|
||||
Detaillierte Dokumentation aller HTTP-Endpoints mit:
|
||||
- Request/Response-Beispielen
|
||||
- Query-Parametern und Validierung
|
||||
- HTTP-Status-Codes
|
||||
- Fehlerehandlung
|
||||
|
||||
**Bereiche:**
|
||||
- Health & Meta
|
||||
- Player Status (Diagnose)
|
||||
- Screen Management (JSON API)
|
||||
- Playlist Management (JSON API)
|
||||
- Media Management (JSON API)
|
||||
- Admin UI (Web-Formulare)
|
||||
- Playlist Management UI (Web-Formulare)
|
||||
- Player Local UI (Agent)
|
||||
|
||||
### [PLAYER-STATUS-HTTP.md](PLAYER-STATUS-HTTP.md)
|
||||
|
||||
Spezialisierte Dokumentation für Status-Reporting:
|
||||
- Status-Ingest vom Player-Agent
|
||||
- Status-Abruf und Filterung
|
||||
- Serverseitig abgeleitete Felder (stale, derived_state)
|
||||
- Persistenz-Modell
|
||||
- Agentseitige Connectivity-Ableitung
|
||||
|
||||
---
|
||||
|
||||
## Konzeptdokumentation
|
||||
|
||||
### [SERVER-KONZEPT.md](SERVER-KONZEPT.md)
|
||||
|
||||
Architektur und fachliche Bereiche:
|
||||
- Server-Aufgaben und Komponenten
|
||||
- Mandanten und Benutzer
|
||||
- Screen-, Medien-, Playlist-Verwaltung
|
||||
- Templates und Kampagnen
|
||||
- Provisionierung
|
||||
- Revisionsmodell
|
||||
- Docker-Compose-Struktur
|
||||
|
||||
### [SCHEMA.md](SCHEMA.md)
|
||||
|
||||
Relationales Datenmodell mit:
|
||||
- Tabellen-Definitionen (SQL)
|
||||
- Primary/Foreign Keys
|
||||
- Constraints und Indizes
|
||||
- Prioritätslogik
|
||||
- Zukunftserweiterungen
|
||||
|
||||
---
|
||||
|
||||
## Implementierungsdokumentation
|
||||
|
||||
### Code-Struktur
|
||||
|
||||
Backend-API ist in Go implementiert:
|
||||
```
|
||||
server/backend/internal/httpapi/
|
||||
├── router.go — Haupt-Router, Route-Registrierung
|
||||
├── playerstatus.go — Status-Endpoints
|
||||
├── statuspage.go — HTML-Diagnoseseiten
|
||||
├── messagewall.go — Message-Wall-Auflösung
|
||||
├── manage/
|
||||
│ ├── register.go — Screen-Registrierung
|
||||
│ ├── playlist.go — Playlist-Management
|
||||
│ ├── media.go — Media-Management
|
||||
│ └── ui.go — Admin- & Manage-UI
|
||||
```
|
||||
|
||||
Player-Agent hat lokale UI:
|
||||
```
|
||||
player/agent/internal/playerserver/
|
||||
└── server.go — Lokale Player-UI und Status-APIs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Typische Anfragen
|
||||
|
||||
**Wie registriert sich ein Agent automatisch?**
|
||||
→ Siehe [API-ENDPOINTS.md](API-ENDPOINTS.md) → Screen Management → `POST /api/v1/screens/register`
|
||||
|
||||
**Wie ruft der Player seine Inhalte ab?**
|
||||
→ Siehe [API-ENDPOINTS.md](API-ENDPOINTS.md) → Playlist Management → `GET /api/v1/screens/{screenId}/playlist`
|
||||
|
||||
**Welche Status-Filteroptionen gibt es?**
|
||||
→ Siehe [PLAYER-STATUS-HTTP.md](PLAYER-STATUS-HTTP.md) → Query-Parameter
|
||||
|
||||
**Wie lautet das Datenbankschema?**
|
||||
→ Siehe [SCHEMA.md](SCHEMA.md)
|
||||
|
||||
**Wie läuft die Provisionierung ab?**
|
||||
→ Siehe [SERVER-KONZEPT.md](SERVER-KONZEPT.md) → Provisionierung
|
||||
|
||||
---
|
||||
|
||||
## Änderungshistorie der Dokumentation
|
||||
|
||||
| Datum | Datei | Änderung |
|
||||
|-------|-------|----------|
|
||||
| 2026-03-23 | API-ENDPOINTS.md | Initiale vollständige Endpoint-Dokumentation erstellt |
|
||||
| 2026-03-23 | API-QUICK-REFERENCE.md | Schnellreferenz mit Workflows hinzugefügt |
|
||||
| 2026-03-23 | API-INDEX.md | Dokumentations-Index erstellt |
|
||||
| 2026-03-23 | PLAYER-STATUS-HTTP.md | Link zur vollständigen API-Dokumentation hinzugefügt |
|
||||
|
||||
---
|
||||
|
||||
## Fehlende oder unvollständige Bereiche
|
||||
|
||||
- **MQTT-Integration:** Noch keine dedizierte Dokumentation für MQTT-Topics und Protokolle
|
||||
- **Authentifizierung & Autorisierung:** Noch nicht implementiert (v1)
|
||||
- **Rate Limiting:** Noch nicht spezifiziert
|
||||
- **Transaktions-Semantik:** Noch nicht dokumentiert
|
||||
- **Webhook/Event-System:** Geplant für spätere Phase
|
||||
- **Provisioning Worker Details:** Noch nicht öffentlich dokumentiert
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Für Agent-Implementierung
|
||||
|
||||
1. **Registrierung:** Rufe `POST /api/v1/screens/register` auf dem Startup auf
|
||||
2. **Playlist-Polling:** Hole alle 30 Sekunden `GET /api/v1/screens/{screenId}/playlist` ab
|
||||
3. **Status-Reporting:** Sende alle 30 Sekunden `POST /api/v1/player/status` ab
|
||||
4. **Fehlerbehandlung:** HTTP-Fehler sollten zu lokaler Fallback-Playlist führen
|
||||
|
||||
### Für Admin-Panel
|
||||
|
||||
1. **Status-Überwachung:** Nutze `GET /status` (HTML) oder `GET /api/v1/screens/status` (JSON)
|
||||
2. **Batch-Operations:** Für Multisel-Operationen empfohlen: Mehrere API-Requests statt Formulare
|
||||
3. **Filterung:** Nutze Query-Parameter für `GET /api/v1/screens/status` zur Filterung
|
||||
|
||||
### Für Tenant-UI
|
||||
|
||||
1. **Medien-Verwaltung:** Nutze Multipart-Upload in `POST /api/v1/tenants/{tenantSlug}/media`
|
||||
2. **Playlist-Bearbeitung:** Nutze JSON-API (`/api/v1/playlists/*`) für programmatische Zugriffe
|
||||
3. **Validierung:** Prüfe gültige `duration_seconds` (> 0) und Medientypen
|
||||
|
||||
---
|
||||
|
||||
## Kontakt & Support
|
||||
|
||||
Für Fragen zur API-Dokumentation:
|
||||
- Siehe [OFFENE-ARCHITEKTURFRAGEN.md](OFFENE-ARCHITEKTURFRAGEN.md)
|
||||
- Code-Review in `/server/backend/internal/httpapi/`
|
||||
297
docs/API-QUICK-REFERENCE.md
Normal file
297
docs/API-QUICK-REFERENCE.md
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
# API Quick Reference
|
||||
|
||||
Schnelle Übersicht aller HTTP-Endpoints nach Zweck sortiert.
|
||||
|
||||
---
|
||||
|
||||
## Agent-Integration
|
||||
|
||||
**Beim Player-Startup:**
|
||||
```http
|
||||
POST /api/v1/screens/register
|
||||
```
|
||||
Automatische Selbstregistrierung des Screens im Default-Tenant "morz".
|
||||
|
||||
**Beim Playlist-Sync (alle ~30s):**
|
||||
```http
|
||||
GET /api/v1/screens/{screenId}/playlist
|
||||
```
|
||||
Abruf der aktuellen Playlist zum Abspielen.
|
||||
|
||||
**Status-Reporting (alle ~30s):**
|
||||
```http
|
||||
POST /api/v1/player/status
|
||||
```
|
||||
Übermittlung des Laufzeitstatus zum Server.
|
||||
|
||||
---
|
||||
|
||||
## Admin-Dashboard
|
||||
|
||||
**Übersicht aller Screens:**
|
||||
```http
|
||||
GET /admin
|
||||
```
|
||||
Web-UI mit Screen-Liste, Status, Provisioning-Formulare.
|
||||
|
||||
**Screen-Verwaltung:**
|
||||
```http
|
||||
POST /admin/screens
|
||||
POST /admin/screens/{screenId}/delete
|
||||
```
|
||||
|
||||
**Provisioning neuer Screens:**
|
||||
```http
|
||||
POST /admin/screens/provision
|
||||
```
|
||||
|
||||
**Diagnose:**
|
||||
```http
|
||||
GET /status
|
||||
GET /status/{screenId}
|
||||
GET /api/v1/screens/status
|
||||
GET /api/v1/screens/{screenId}/status
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tenant-Playlist-Management
|
||||
|
||||
**Manage-UI öffnen:**
|
||||
```http
|
||||
GET /manage/{screenSlug}
|
||||
```
|
||||
Web-UI für Playlist-Bearbeitung, Uploads, Item-Verwaltung.
|
||||
|
||||
**Inhalte hinzufügen:**
|
||||
```http
|
||||
POST /manage/{screenSlug}/upload (Datei-Upload)
|
||||
POST /manage/{screenSlug}/items (Item zur Playlist)
|
||||
POST /manage/{screenSlug}/media/{mediaId}/delete
|
||||
```
|
||||
|
||||
**Inhalte bearbeiten:**
|
||||
```http
|
||||
POST /manage/{screenSlug}/items/{itemId}
|
||||
POST /manage/{screenSlug}/items/{itemId}/delete
|
||||
POST /manage/{screenSlug}/reorder
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Media Management (JSON API)
|
||||
|
||||
**Media-Assets auflisten:**
|
||||
```http
|
||||
GET /api/v1/tenants/{tenantSlug}/media
|
||||
```
|
||||
|
||||
**Neue Medien hinzufügen:**
|
||||
```http
|
||||
POST /api/v1/tenants/{tenantSlug}/media
|
||||
```
|
||||
(Datei-Upload oder externe URL)
|
||||
|
||||
**Media löschen:**
|
||||
```http
|
||||
DELETE /api/v1/media/{id}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Playlist Management (JSON API)
|
||||
|
||||
**Playlist abrufen (Admin):**
|
||||
```http
|
||||
GET /api/v1/playlists/{screenId}
|
||||
```
|
||||
|
||||
**Playlist abrufen (Player):**
|
||||
```http
|
||||
GET /api/v1/screens/{screenId}/playlist
|
||||
```
|
||||
(Gibt nur aktive Items zurück)
|
||||
|
||||
**Items verwalten:**
|
||||
```http
|
||||
POST /api/v1/playlists/{playlistId}/items
|
||||
PATCH /api/v1/items/{itemId}
|
||||
DELETE /api/v1/items/{itemId}
|
||||
```
|
||||
|
||||
**Playlist konfigurieren:**
|
||||
```http
|
||||
PUT /api/v1/playlists/{playlistId}/order
|
||||
PATCH /api/v1/playlists/{playlistId}/duration
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Screen Management (JSON API)
|
||||
|
||||
**Self-Registration (Agent):**
|
||||
```http
|
||||
POST /api/v1/screens/register
|
||||
```
|
||||
|
||||
**Screens eines Tenants auflisten:**
|
||||
```http
|
||||
GET /api/v1/tenants/{tenantSlug}/screens
|
||||
```
|
||||
|
||||
**Screen erstellen (Admin):**
|
||||
```http
|
||||
POST /api/v1/tenants/{tenantSlug}/screens
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## System & Health
|
||||
|
||||
**Health-Check:**
|
||||
```http
|
||||
GET /healthz
|
||||
```
|
||||
|
||||
**API-Entrypoint:**
|
||||
```http
|
||||
GET /api/v1
|
||||
```
|
||||
|
||||
**Metainformationen:**
|
||||
```http
|
||||
GET /api/v1/meta
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Player Local UI (auf dem Gerät)
|
||||
|
||||
**Player-Seite öffnen:**
|
||||
```http
|
||||
GET /player
|
||||
```
|
||||
|
||||
**Aktuelle Playlist für lokale Anzeige:**
|
||||
```http
|
||||
GET /api/now-playing
|
||||
```
|
||||
|
||||
**Systeminformationen anzeigen:**
|
||||
```http
|
||||
GET /api/sysinfo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Status-Diagnose (Detailed)
|
||||
|
||||
Siehe `PLAYER-STATUS-HTTP.md` für vollständige Dokumentation der Status-Endpoints:
|
||||
|
||||
```http
|
||||
POST /api/v1/player/status (Status vom Agent)
|
||||
GET /api/v1/screens/status (Alle Status)
|
||||
GET /api/v1/screens/{screenId}/status
|
||||
DELETE /api/v1/screens/{screenId}/status
|
||||
```
|
||||
|
||||
Query-Parameter für Filterung:
|
||||
- `q` — Screen-ID Substring
|
||||
- `derived_state` — online|degraded|offline
|
||||
- `server_connectivity` — online|degraded|offline|unknown
|
||||
- `stale` — true|false
|
||||
- `updated_since` — RFC3339-Zeitstempel
|
||||
- `limit` — Anzahl Items
|
||||
|
||||
---
|
||||
|
||||
## Typische Workflows
|
||||
|
||||
### 1. Neuen Screen provisioning
|
||||
|
||||
```
|
||||
1. POST /admin/screens (oder /api/v1/tenants/morz/screens)
|
||||
→ Neuen Screen-Record anlegen
|
||||
|
||||
2. POST /admin/screens/provision
|
||||
→ Provisionierungs-Job starten
|
||||
|
||||
3. GET /admin (oder /status)
|
||||
→ Status überwachen
|
||||
```
|
||||
|
||||
### 2. Neue Inhalte hochladen und einbinden
|
||||
|
||||
```
|
||||
1. POST /manage/{screenSlug}/upload
|
||||
→ Datei hochladen, Media-Asset erstellen
|
||||
|
||||
2. POST /manage/{screenSlug}/items
|
||||
→ Item zur Playlist hinzufügen (mit media_asset_id)
|
||||
|
||||
3. GET /manage/{screenSlug}
|
||||
→ Playlist-Verwaltung
|
||||
```
|
||||
|
||||
### 4. Playlist bearbeiten
|
||||
|
||||
```
|
||||
1. GET /api/v1/playlists/{screenId}
|
||||
→ Aktuelle Playlist abrufen
|
||||
|
||||
2. PATCH /api/v1/items/{itemId}
|
||||
→ Dauer, Zeitfenster, Titel ändern
|
||||
|
||||
3. PUT /api/v1/playlists/{playlistId}/order
|
||||
→ Items reordnen
|
||||
|
||||
4. GET /api/v1/screens/{screenId}/playlist
|
||||
→ Player holt neue Version beim Sync ab
|
||||
```
|
||||
|
||||
### 5. Status überwachen
|
||||
|
||||
```
|
||||
1. GET /status (Browser)
|
||||
oder
|
||||
GET /api/v1/screens/status (JSON)
|
||||
→ Aktuelle Status aller Screens
|
||||
|
||||
2. GET /status/{screenId}
|
||||
oder
|
||||
GET /api/v1/screens/{screenId}/status
|
||||
→ Detailstatus für einen Screen
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fehlerbehandlung
|
||||
|
||||
HTTP-Status-Codes:
|
||||
- `200` — OK (Read erfolgreich)
|
||||
- `201` — Created (Ressource erstellt)
|
||||
- `204` — No Content (Write erfolgreich, kein Response-Body)
|
||||
- `400` — Bad Request (Eingabe-Validierungsfehler)
|
||||
- `404` — Not Found (Ressource nicht vorhanden)
|
||||
- `500` — Internal Server Error (Server-Fehler)
|
||||
|
||||
Alle Fehler folgen dem Modell:
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "error_code",
|
||||
"message": "Beschreibung",
|
||||
"details": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Vollständige Dokumentation
|
||||
|
||||
Siehe `API-ENDPOINTS.md` für:
|
||||
- Detaillierte Request/Response-Beispiele für jeden Endpoint
|
||||
- Query-Parameter und Validierung
|
||||
- Zeitstempel-Formate (RFC3339)
|
||||
- Serverseitige Logik (z.B. Stale-Detection, Derived-State)
|
||||
|
|
@ -180,6 +180,14 @@ Noch nicht Teil dieser Stufe:
|
|||
- Admin-UI-Anzeige des letzten Status
|
||||
- Retry-Queue oder lokale Zwischenspeicherung im Agent
|
||||
|
||||
## Verwandte Endpoints
|
||||
|
||||
Siehe auch die vollständige API-Dokumentation in `API-ENDPOINTS.md`:
|
||||
|
||||
- Screen-Registrierung: `POST /api/v1/screens/register`
|
||||
- Playlist-Abruf: `GET /api/v1/screens/{screenId}/playlist`
|
||||
- Medien-Verwaltung: `GET /api/v1/tenants/{tenantSlug}/media`, `POST /api/v1/tenants/{tenantSlug}/media`
|
||||
|
||||
## Folgeschritte
|
||||
|
||||
Auf diesem Pfad bauen spaeter auf:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue