morz-infoboard/DEVELOPMENT.md
Jesko Anschütz aff12a4d81 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>
2026-03-23 09:55:36 +01:00

362 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Info-Board Neu - Entwicklung
## Ziel
Dieses Dokument soll den Einstieg auf einem anderen Entwicklungsrechner moeglichst reibungsfrei machen.
Es beschreibt:
- minimale Voraussetzungen
- wichtige Verzeichnisse
- Build- und Run-Kommandos
- aktuelle Annahmen fuer den lokalen Entwicklungsbetrieb
## Repository
- Remote: `git.az-it.net:az/morz-infoboard.git`
- Standard-Branch: `main`
Projektwurzel:
- `/srv/docker/info-board-neu`
## Wichtige Verzeichnisse
- `docs/` fuer Architektur- und Fachkonzepte
- `server/backend/` fuer das zentrale Go-Backend
- `player/agent/` fuer den Go-basierten Player-Agent
- `ansible/` fuer Deployment und Provisionierung
- `compose/` spaeter fuer den zentralen Server-Stack
## Aktueller Entwicklungsstand
Bereits vorhanden:
- fachliche Architektur- und Betriebskonzepte
- relationaler Schema-Entwurf in `docs/SCHEMA.md`
- 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:
- admin-seitige Benutzerautentifizierung und Zugriffskontrolle
- Multi-Tenancy-Isolation auf API-Ebene
- produktives SSL/TLS-Handling fuer Deployment
## Voraussetzungen auf dem Entwicklungsrechner
Mindestens empfohlen:
- `git`
- `go` in Version `1.24.x`
- `make`
Spaeter zusaetzlich sinnvoll:
- `docker` und `docker compose`
- `postgresql-client`
- `mosquitto-clients`
- `golangci-lint`
Fuer Container-Builds liegen erste Dockerfiles in:
- `server/backend/Dockerfile`
- `player/agent/Dockerfile`
## Schnellstart
Repository klonen:
```bash
git clone git.az-it.net:az/morz-infoboard.git
cd morz-infoboard
```
Dokumentationsbasis lesen:
1. `README.md`
2. `PLAN.md`
3. `TECH-STACK.md`
4. `docs/SCHEMA.md`
5. `docs/OFFENE-ARCHITEKTURFRAGEN.md`
6. `docs/LAYOUT-JSON.md`
## Build-Kommandos
### Backend bauen
```bash
cd server/backend
go build ./...
```
### Agent bauen
```bash
cd player/agent
go build ./...
```
### Alternativ ueber Makefile
```bash
make build
```
Aktuell bedeutet das:
- `make build` baut Backend und Agent
- `make build-backend` baut nur `server/backend`
- `make build-agent` baut nur `player/agent`
- `make run-backend` startet das Backend
- `make run-agent` startet den Agenten
- `make fmt` formatiert beide Go-Module
- `make lint` prueft beide Go-Module mit `golangci-lint`
Hinweis:
- auf dem aktuellen System dieser Session sind `make` und `go` nicht installiert; die Befehle sind fuer den Entwicklungsrechner vorbereitet
## Lokaler Start
### Backend lokal starten
```bash
cd server/backend
go run ./cmd/api
```
Standard:
- HTTP-Adresse: `:8080`
- Health-Endpunkt: `GET /healthz`
- Basis-Endpunkt: `GET /api/v1`
Konfigurierbar ueber:
- `MORZ_INFOBOARD_HTTP_ADDR` HTTP-Adresse (Standard: `:8080`)
- `MORZ_INFOBOARD_STATUS_STORE_PATH` Pfad zur JSON-Datei fuer persistenten Status-Store; leer lassen fuer reinen In-Memory-Betrieb
Beispiele:
```bash
MORZ_INFOBOARD_HTTP_ADDR=:18080 go run ./cmd/api
```
```bash
MORZ_INFOBOARD_HTTP_ADDR=:8080 \
MORZ_INFOBOARD_STATUS_STORE_PATH=/tmp/screen-status.json \
go run ./cmd/api
```
### Agent lokal starten
```bash
cd player/agent
go run ./cmd/agent
```
Standardwerte:
- `MORZ_INFOBOARD_SCREEN_ID=unset-screen`
- `MORZ_INFOBOARD_SERVER_URL=http://127.0.0.1:8080`
- `MORZ_INFOBOARD_MQTT_BROKER=` (leer = MQTT wird uebersprungen)
- `MORZ_INFOBOARD_PLAYER_ADDR=127.0.0.1:8090`
- `MORZ_INFOBOARD_PLAYER_CONTENT_URL=` (leer = kein Inhalt eingebettet)
Optional:
- `MORZ_INFOBOARD_MQTT_USERNAME` MQTT-Benutzername
- `MORZ_INFOBOARD_MQTT_PASSWORD` MQTT-Passwort
- `MORZ_INFOBOARD_CONFIG=/etc/signage/config.json` dateibasierte Konfiguration
Eine Beispielkonfiguration liegt in `player/config/config.example.json`.
Der Agent stellt unter `http://127.0.0.1:8090/player` eine lokale Kiosk-Seite bereit.
Beispiel ohne MQTT:
```bash
MORZ_INFOBOARD_SCREEN_ID=info01-dev \
MORZ_INFOBOARD_SERVER_URL=http://127.0.0.1:8080 \
go run ./cmd/agent
```
Beispiel mit MQTT:
```bash
MORZ_INFOBOARD_SCREEN_ID=info01-dev \
MORZ_INFOBOARD_SERVER_URL=http://127.0.0.1:8080 \
MORZ_INFOBOARD_MQTT_BROKER=tcp://127.0.0.1:1883 \
MORZ_INFOBOARD_MQTT_USERNAME=user \
MORZ_INFOBOARD_MQTT_PASSWORD=pass \
go run ./cmd/agent
```
## Ansible-Deployment auf einen Zielrechner
Der `ansible/`-Ordner enthaelt ein vollstaendiges Playbook fuer das Deployment auf einen Pi oder ein Debian-System.
### Voraussetzungen
- Ansible auf dem Entwicklungsrechner
- SSH-Key fuer den Zielrechner hinterlegt
- Ansible Vault fuer MQTT-Zugangsdaten
### Inventory und Konfiguration
- `ansible/inventory.yml` Hosts und Gruppen
- `ansible/host_vars/<host>/vars.yml` host-spezifische Variablen (`screen_id`, `ansible_host`, `ansible_user`)
- `ansible/group_vars/signage_players/vars.yml` globale Defaults
- `ansible/group_vars/signage_players/vault.yml` verschluesselte Zugangsdaten (gitignored)
Vault-Datei anlegen:
```bash
ansible-vault create ansible/group_vars/signage_players/vault.yml
```
Inhalt:
```yaml
vault_mqtt_username: "benutzername"
vault_mqtt_password: "passwort"
```
In `vars.yml` referenzieren:
```yaml
morz_mqtt_username: "{{ vault_mqtt_username }}"
morz_mqtt_password: "{{ vault_mqtt_password }}"
```
### Deployment ausfuehren
```bash
cd ansible
ansible-playbook site.yml -i inventory.yml --ask-vault-pass
```
Das Playbook erledigt:
1. Agent-Binary cross-kompilieren (lokal, `GOOS=linux GOARCH=arm64`)
2. Binary und Konfiguration auf den Zielrechner uebertragen
3. systemd-Unit fuer den Agent anlegen und starten
4. journald auf RAM-Speicherung konfigurieren (SD-Karte schonen)
5. X11-Paketstack und Chromium installieren
6. Kiosk-Startskript und systemd-Unit fuer die Anzeige anlegen
### Rollen
- `signage_player` Agent, Konfiguration, systemd-Unit, journald
- `signage_display` X11, Chromium, Kiosk-Service
## Aktuelle Architekturentscheidungen mit direkter Auswirkung auf Entwicklung
- `message_wall` wird serverseitig in konkrete Screen-Szenen aufgeloest
- Kampagnengruppen werden serverseitig in konkrete Screen-Assignments expandiert
- `playlist_items` haben im finalen Implementierungsschema keinen direkten `screen_id`-Fremdschluessel
- Provisionierung wird worker-/jumphost-faehig geplant
- API-Fehler sollen einen einheitlichen Fehlerumschlag nutzen
## Empfohlene naechste Implementierungsschritte
1. Backend: einheitliches Fehlerformat und Routing-Grundstruktur anlegen
2. Backend: Konfigurations- und App-Lifecycle stabilisieren
3. Agent und Backend: den HTTP-Statuspfad als Grundlage fuer Identitaet, Persistenz und spaetere Admin-Vorschau erweitern
4. Agent: danach MQTT-spezifische Reachability und feinere Connectivity-Schwellenlogik aufsetzen
5. Danach die Netzwerk-, Sync- und Kommandopfade schrittweise produktionsnah ausbauen
## End-to-End-Entwicklungstest (Backend + Agent)
Backend und Agent koennen lokal gegeneinander laufen. Reihenfolge:
1. Backend starten (Terminal 1):
```bash
cd server/backend
MORZ_INFOBOARD_STATUS_STORE_PATH=/tmp/screen-status.json go run ./cmd/api
```
2. Agent starten (Terminal 2):
```bash
cd player/agent
MORZ_INFOBOARD_SCREEN_ID=info01-dev \
MORZ_INFOBOARD_SERVER_URL=http://127.0.0.1:8080 \
go run ./cmd/agent
```
3. Status pruefen:
```bash
# JSON-Uebersicht
curl http://127.0.0.1:8080/api/v1/screens/status
# HTML-Diagnoseseite
open http://127.0.0.1:8080/status
# Einzelner Screen
curl http://127.0.0.1:8080/api/v1/screens/info01-dev/status
# Screen loeschen
curl -X DELETE http://127.0.0.1:8080/api/v1/screens/info01-dev/status
```
Die Datei `/tmp/screen-status.json` enthaelt nach dem ersten Heartbeat den persistierten Status-Store.
## Ergaenzt seit dem ersten Geruest:
**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
- `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
- 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 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
Empfohlen:
- kleine, klar umrissene Commits
- zuerst Konzepte anpassen, dann Code
- Schema und API-Vertrag synchron halten
- neue Fachentscheidungen immer in `docs/` dokumentieren
## Hinweise fuer einen zweiten Entwicklungsrechner
- vor Arbeitsbeginn `git pull --rebase` oder gleichwertig den aktuellen Stand holen
- bei paralleler Arbeit zuerst in den Dokumenten pruefen, ob neue Architekturentscheidungen getroffen wurden
- falls lokale Tools abweichen, mindestens `go version` und `make --version` pruefen