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>
11 KiB
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 Fachkonzepteserver/backend/fuer das zentrale Go-Backendplayer/agent/fuer den Go-basierten Player-Agentansible/fuer Deployment und Provisionierungcompose/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.ymlmit 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:
gitgoin Version1.24.xmake
Spaeter zusaetzlich sinnvoll:
dockerunddocker composepostgresql-clientmosquitto-clientsgolangci-lint
Fuer Container-Builds liegen erste Dockerfiles in:
server/backend/Dockerfileplayer/agent/Dockerfile
Schnellstart
Repository klonen:
git clone git.az-it.net:az/morz-infoboard.git
cd morz-infoboard
Dokumentationsbasis lesen:
README.mdPLAN.mdTECH-STACK.mddocs/SCHEMA.mddocs/OFFENE-ARCHITEKTURFRAGEN.mddocs/LAYOUT-JSON.md
Build-Kommandos
Backend bauen
cd server/backend
go build ./...
Agent bauen
cd player/agent
go build ./...
Alternativ ueber Makefile
make build
Aktuell bedeutet das:
make buildbaut Backend und Agentmake build-backendbaut nurserver/backendmake build-agentbaut nurplayer/agentmake run-backendstartet das Backendmake run-agentstartet den Agentenmake fmtformatiert beide Go-Modulemake lintprueft beide Go-Module mitgolangci-lint
Hinweis:
- auf dem aktuellen System dieser Session sind
makeundgonicht installiert; die Befehle sind fuer den Entwicklungsrechner vorbereitet
Lokaler Start
Backend lokal starten
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:
MORZ_INFOBOARD_HTTP_ADDR=:18080 go run ./cmd/api
MORZ_INFOBOARD_HTTP_ADDR=:8080 \
MORZ_INFOBOARD_STATUS_STORE_PATH=/tmp/screen-status.json \
go run ./cmd/api
Agent lokal starten
cd player/agent
go run ./cmd/agent
Standardwerte:
MORZ_INFOBOARD_SCREEN_ID=unset-screenMORZ_INFOBOARD_SERVER_URL=http://127.0.0.1:8080MORZ_INFOBOARD_MQTT_BROKER=(leer = MQTT wird uebersprungen)MORZ_INFOBOARD_PLAYER_ADDR=127.0.0.1:8090MORZ_INFOBOARD_PLAYER_CONTENT_URL=(leer = kein Inhalt eingebettet)
Optional:
MORZ_INFOBOARD_MQTT_USERNAME– MQTT-BenutzernameMORZ_INFOBOARD_MQTT_PASSWORD– MQTT-PasswortMORZ_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:
MORZ_INFOBOARD_SCREEN_ID=info01-dev \
MORZ_INFOBOARD_SERVER_URL=http://127.0.0.1:8080 \
go run ./cmd/agent
Beispiel mit MQTT:
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 Gruppenansible/host_vars/<host>/vars.yml– host-spezifische Variablen (screen_id,ansible_host,ansible_user)ansible/group_vars/signage_players/vars.yml– globale Defaultsansible/group_vars/signage_players/vault.yml– verschluesselte Zugangsdaten (gitignored)
Vault-Datei anlegen:
ansible-vault create ansible/group_vars/signage_players/vault.yml
Inhalt:
vault_mqtt_username: "benutzername"
vault_mqtt_password: "passwort"
In vars.yml referenzieren:
morz_mqtt_username: "{{ vault_mqtt_username }}"
morz_mqtt_password: "{{ vault_mqtt_password }}"
Deployment ausfuehren
cd ansible
ansible-playbook site.yml -i inventory.yml --ask-vault-pass
Das Playbook erledigt:
- Agent-Binary cross-kompilieren (lokal,
GOOS=linux GOARCH=arm64) - Binary und Konfiguration auf den Zielrechner uebertragen
- systemd-Unit fuer den Agent anlegen und starten
- journald auf RAM-Speicherung konfigurieren (SD-Karte schonen)
- X11-Paketstack und Chromium installieren
- Kiosk-Startskript und systemd-Unit fuer die Anzeige anlegen
Rollen
signage_player– Agent, Konfiguration, systemd-Unit, journaldsignage_display– X11, Chromium, Kiosk-Service
Aktuelle Architekturentscheidungen mit direkter Auswirkung auf Entwicklung
message_wallwird serverseitig in konkrete Screen-Szenen aufgeloest- Kampagnengruppen werden serverseitig in konkrete Screen-Assignments expandiert
playlist_itemshaben im finalen Implementierungsschema keinen direktenscreen_id-Fremdschluessel- Provisionierung wird worker-/jumphost-faehig geplant
- API-Fehler sollen einen einheitlichen Fehlerumschlag nutzen
Empfohlene naechste Implementierungsschritte
- Backend: einheitliches Fehlerformat und Routing-Grundstruktur anlegen
- Backend: Konfigurations- und App-Lifecycle stabilisieren
- Agent und Backend: den HTTP-Statuspfad als Grundlage fuer Identitaet, Persistenz und spaetere Admin-Vorschau erweitern
- Agent: danach MQTT-spezifische Reachability und feinere Connectivity-Schwellenlogik aufsetzen
- Danach die Netzwerk-, Sync- und Kommandopfade schrittweise produktionsnah ausbauen
End-to-End-Entwicklungstest (Backend + Agent)
Backend und Agent koennen lokal gegeneinander laufen. Reihenfolge:
- Backend starten (Terminal 1):
cd server/backend
MORZ_INFOBOARD_STATUS_STORE_PATH=/tmp/screen-status.json go run ./cmd/api
- Agent starten (Terminal 2):
cd player/agent
MORZ_INFOBOARD_SCREEN_ID=info01-dev \
MORZ_INFOBOARD_SERVER_URL=http://127.0.0.1:8080 \
go run ./cmd/agent
- Status pruefen:
# 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/statusmit 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/statusfuer Gesamt-Uebersicht mit Query-FilternGET /api/v1/screens/{screenId}/statusfuer Einzelscreen-DetailsDELETE /api/v1/screens/{screenId}/statuszum Loeschen von Screen-Eintraegen- HTML-Diagnoseseite unter
/statusmit 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) ausstale,server_connectivityundstatusabgeleitet- 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
statusundserver_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_playerundsignage_displayfuer 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 --rebaseoder gleichwertig den aktuellen Stand holen - bei paralleler Arbeit zuerst in den Dokumenten pruefen, ob neue Architekturentscheidungen getroffen wurden
- falls lokale Tools abweichen, mindestens
go versionundmake --versionpruefen