teammeeting-dokuwiki/INTEGRATIONSPLAN.md
2025-11-19 19:22:24 +01:00

467 lines
18 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

# Integrationsplan: Metabase & Teamup → DokuWiki (All-Inkl)
## 1. Zielbild
Automatisierter Ablauf jeden **1. des Monats um 03:00 Uhr**:
1. Gitea Action startet ein Shell-Skript auf *Hobbybackend1*.
2. Skript erzeugt:
- einen **Metabase-PDF-Export** einer Registerkarte (Dashboard/Frage),
- **zwei Teamup-Kalenderübersichten** als Bilder (jeweils eine Woche, über Datum definiert).
3. Skript überträgt PDF/Bilder per SSH/SCP auf den **All-Inkl-Server** ins DokuWiki-Dateisystem.
4. Skript erzeugt oder aktualisiert eine **DokuWiki-Seite für das Monatsmeeting**, welche die neuen Dateien referenziert.
---
## Verantwortlichkeiten
- Owner / Betrieb: `it@hobbyhimmel.de` (Ansprechpartner für Ausfälle, Secrets & Deploy)
- Maintainer (Skripte / Runner): Hobbybackend1-Admin (Repository-Owner)
- DokuWiki-Admin: Wiki-Administrator (z. B. für API-Zugriff und Namespace-Setup)
Hinweis: Für dieses Hobbyprojekt genügt eine schlanke Aufgabenverteilung — Owner ist primärer Kontakt für Störungen.
## 2. Architektur & Datenfluss
- **Gitea (Repository + Actions)**
- Enthält:
- Shell-Skript(e)
- ggf. Hilfsskripte (z.B. Node/Puppeteer-Renderer)
- GitHub-/Gitea-Action Workflow
- **Trigger:** `schedule` → monatlich.
- **Hobbybackend1 (Docker-Host)**
- Stack: `metabase`
- Container: `metabase-metabase-1`
- Führt das Shell-Skript aus (über Gitea Action Runner).
- Headless-Browser (z.B. **Puppeteer / Playwright** in Docker oder lokal installiert) rendert:
- Metabase-Registerkarte export siehe https://www.metabase.com/docs/latest/api
- Teamup-Ansichten export siehe https://apidocs.teamup.com/docs/api/
- **All-Inkl-Server (DokuWiki)**
- Per SSH erreichbar.
- Skript überträgt Dateien (`scp`/`rsync`) nach `data/media/...`.
- Skript erzeugt/aktualisiert `data/pages/...` mit DokuWiki-Seite für das entsprechende Monatsmeeting.
---
## 3. Voraussetzungen
### 3.1. Infrastruktur
1. **Gitea**
- Repository für das Skript (z.B. `hobbyhimmel/teammeeting-dokuwiki`).
- Gitea Action Runner auf *Hobbybackend1* konfiguriert.
2. **Hobbybackend1**
- Zugriff auf Metabase-Container `metabase-metabase-1`.
- Node.js + Puppeteer/Playwright **oder** ein Docker-Image, das URLs per Headless-Browser in PDF/PNG rendert.
- Netzwerkzugriff auf:
- Metabase-URL (intern, z.B. `http://metabase-metabase-1:3000` oder über Hostname).
- Teamup-URLs.
3. **All-Inkl / DokuWiki**
- SSH-Zugang: User + SSH-Key (passwortlos aus Skript verwendbar).
- Kenntnis der DokuWiki-Verzeichnisse (typischerweise):
- Seiten: `.../data/pages/...`
- Medien: `.../data/media/...`
- Namespace für Meetings, z.B. `:teammeetings:folien:`.
### 3.2. Gitea-Secrets
In Gitea als **Repository-Secrets** hinterlegen (Bezeichnungen Beispiel):
- **Metabase**
- `METABASE_URL` Basis-URL (intern von Hobbybackend1 aus erreichbar).
- `METABASE_USER` Benutzer für Login.
- `METABASE_PASSWORD` Passwort oder API-Key (je nach Login-Strategie).
- Optional: `METABASE_DASHBOARD_ID` oder `METABASE_CARD_ID`.
- **Teamup**
- `TEAMUP_BASE_URL` Basis-URL zum Kalender (inkl. Calendar-Key).
- Optional: `TEAMUP_API_KEY` falls API genutzt wird.
- **DokuWiki / All-Inkl**
- `ALLINKL_SSH_HOST` z.B. `sshXXX.all-inkl.com`.
- `ALLINKL_SSH_USER` SSH-User.
- `ALLINKL_USER` All-Inkl-User.
- `ALLINKL_SSH_KEY` privater SSH-Key (optional; häufig nicht nötig, wenn die DokuWiki-API verwendet wird). Wenn verwendet: als secret file oder String in Kombination mit `ssh-agent`.
- `ALLINKL_BASE_PATH` Pfad zum DokuWiki, z.B. `/www/htdocs/<ALLINKL_USER>/wiki.neu.hobbyhimmel.de/data`.
- `ALLINKL_MEETING_NAMESPACE` z.B. `teammeetings/folien` (Dateipfade ohne Doppelpunkt).
- Optional (bei API-Nutzung): `DOKUWIKI_API_URL` und `DOKUWIKI_API_TOKEN` (empfohlen statt direktem Dateizugriff)
- **Allgemein**
- `TZ` Zeitzone (z.B. `Europe/Berlin`), falls im Skript nötig.
Hinweis zur Secret-Handhabung:
- Für lokale Tests nutze eine `.env`-Datei (niemals einchecken). Beispiele stehen im Repo in einer `.env.example` (nur Platzhalter).
- In Gitea die Secrets als Repository-Secrets anlegen. Verwende `DOKUWIKI_API_TOKEN` falls die API genutzt wird; `ALLINKL_SSH_KEY` wird nur beim Fallback über SSH benötigt.
---
## 4. Shell-Skript-Design
### 4.1. Hauptaufgaben des Skripts
1. **Datum & Kontext bestimmen**
- Ausführungsdatum ist immer der **1. des Monats**.
- Skript ermittelt:
- `YEAR` aktuelles Jahr.
- `MONTH` aktueller Monat (ggf. auch vorheriger Monat, je nach Reporting-Logik).
- Generiert z.B. einen Identifier `MEETING_ID="${YEAR}-${MONTH}"`.
2. **Export Metabase**
- Aufruf eines Hilfsskripts (z.B. `render_metabase.sh` oder Node-Skript):
- Parameter: Dashboard-ID / Card-ID, Dateiname, ggf. Filter (z.B. Zeitraum).
- Ausgabe: `metabase-report-${MEETING_ID}.???` im lokalen Arbeitsverzeichnis.
3. **Export Teamup → Kalenderbilder**
- Definition der **zwei Wochen**, die exportiert werden sollen:
- Es werden immer die ersten zwei Wochen des aktuellen Monats genommen.
- Für jede Woche:
- URL zu Teamup generieren (inkl. `startDate`, `endDate` oder ähnlichen Parametern).
- Ausgabe: `teamup-week1-${MEETING_ID}.png`, `teamup-week2-${MEETING_ID}.png`.
4. **Transfer zum All-Inkl-Server**
- Medienpfad bestimmen, z.B.:
`MEDIA_DIR="${ALLINKL_BASE_PATH}/data/media/${TEAM_MEETING_NAMESPACE}"`
- Falls nicht existent: per `ssh` Ordner anlegen.
- Dateien per `scp` oder `rsync -e ssh` kopieren:
- `metabase-report-${MEETING_ID}.pdf`
- `teamup-week1-${MEETING_ID}.png`
- `teamup-week2-${MEETING_ID}.png`.
5. **DokuWiki-Seite erzeugen/aktualisieren**
- Seitenpfad bestimmen, z.B.:
`PAGE_FILE="${WIKI_BASE_PATH}/data/pages/${WIKI_MEETING_NAMESPACE}/${MEETING_ID}.txt"`
- Per `ssh` Remote-Here-Doc schreiben:
Empfehlung: Wenn möglich die DokuWiki-API (`DOKUWIKI_API_URL` + `DOKUWIKI_API_TOKEN`) verwenden, statt direkt auf `data/pages` zu schreiben. API-Aufrufe sind robuster gegenüber Dateirechten/Ownership auf All-Inkl.
Beispiel (API, einfaches PUT via curl an ein Plugin / XML-RPC-Endpoint - anpassen je nach Wiki-Setup):
```bash
curl -sS -X POST "${DOKUWIKI_API_URL}" \
-H "Authorization: Bearer ${DOKUWIKI_API_TOKEN}" \
-F "id=${WIKI_MEETING_NAMESPACE}:${MEETING_ID}" \
-F "text=$(cat newpage.txt)"
```
Fallback (wenn API nicht möglich): per SSH/Here-Doc wie bisher. Achte hier auf korrekte Ownership/Encoding beim Schreiben nach `data/pages`.
Platzhalter `<DATUM_A>` und `<DATUM_B>` werden im Shell-Skript vor dem Upload ersetzt.
### 4.2. Schnittstellen zum Headless-Browser
- Generische Hilfsfunktionen, z.B.:
```bash
render_metabase_pdf() {
local url="$1" # z. B. "$METABASE_URL/dashboard/${METABASE_DASHBOARD_ID}?date=${MEETING_ID}"
local outfile="$2"
node scripts/render_pdf.js "$url" "$outfile"
}
render_url_to_png() {
local url="$1"
local outfile="$2"
node scripts/render_png.js "$url" "$outfile"
}
```
- `render_pdf.js` / `render_png.js` verwenden Puppeteer/Playwright, loggen sich ggf. bei Metabase ein und erzeugen die Dateien.
---
## 5. Gitea Action: Workflow-Definition
### 5.1. Workflow-Datei `.gitea/workflows/monthly-report.yml`
```yaml
name: Monthly Metabase & Teamup Export
on:
schedule:
- cron: '0 2 1 * *'
workflow_dispatch:
jobs:
export-and-upload:
runs-on: hobbybackend1 # Label des Act-Runners
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: |
npm ci
- name: Run export script
env:
METABASE_URL: ${{ secrets.METABASE_URL }}
METABASE_USER: ${{ secrets.METABASE_USER }}
METABASE_PASSWORD: ${{ secrets.METABASE_PASSWORD }}
METABASE_DASHBOARD_ID: ${{ secrets.METABASE_DASHBOARD_ID }}
TEAMUP_BASE_URL: ${{ secrets.TEAMUP_BASE_URL }}
TEAMUP_API_KEY: ${{ secrets.TEAMUP_API_KEY }}
WIKI_SSH_HOST: ${{ secrets.WIKI_SSH_HOST }}
WIKI_SSH_USER: ${{ secrets.WIKI_SSH_USER }}
WIKI_SSH_KEY: ${{ secrets.WIKI_SSH_KEY }}
WIKI_BASE_PATH: ${{ secrets.WIKI_BASE_PATH }}
WIKI_MEETING_NAMESPACE: ${{ secrets.WIKI_MEETING_NAMESPACE }}
TZ: Europe/Berlin
run: |
mkdir -p ~/.ssh
echo "$WIKI_SSH_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan "$WIKI_SSH_HOST" >> ~/.ssh/known_hosts
./scripts/monthly_export.sh
```
> **Hinweis zur Zeit:**
> - Gitea/Aktions-Cron läuft typischerweise in UTC.
> - Wenn du 03:00 Uhr **Europe/Berlin** willst, musst du den `cron`-Wert ggf. anpassen (Sommer-/Winterzeit beachten). Beispiel oben `0 2 1 * *` wäre 03:00 MEZ, aber 04:00 MESZ hier vorher genau prüfen.
---
## 6. Teamup: Wochenansichten als Bild
### 6.1. URL-Strategie
- Teamup erlaubt üblicherweise Links mit Datumsparametern, z.B.:
- `?view=week&date=YYYY-MM-DD` für eine Wochenansicht.
- Das Skript berechnet:
- `WEEK1_DATE` ISO-Datum (Montag der ersten gewünschten Woche).
- `WEEK2_DATE` ISO-Datum (Montag der zweiten gewünschten Woche).
- Für jede Woche wird eine URL gebaut:
```bash
TEAMUP_URL_WEEK1="${TEAMUP_BASE_URL}?view=week&date=${WEEK1_DATE}"
TEAMUP_URL_WEEK2="${TEAMUP_BASE_URL}?view=week&date=${WEEK2_DATE}"
```
### 6.2. Rendering
- Aufruf z.B.:
```bash
render_url_to_png "$TEAMUP_URL_WEEK1" "teamup-week1-${MEETING_ID}.png"
render_url_to_png "$TEAMUP_URL_WEEK2" "teamup-week2-${MEETING_ID}.png"
```
- Im Headless-Browser-Skript wird:
1. Seite geladen.
2. Auf ausreichende Ladezeit gewartet.
3. `page.screenshot({ path: outfile, fullPage: true })` ausgeführt.
---
## 7. Test- & Rollout-Plan
1. **Lokaler Test des Headless-Browsers**
- Auf Hobbybackend1 die Node-Skripte (`render_pdf.js` / `render_png.js`) mit Test-URLs ausprobieren.
- verifizieren, dass Metabase-Login und Teamup-Laden funktionieren.
2. **SSH/Dateipfade testen**
- Manuell per `ssh` und `scp` eine Test-PDF und Test-PNG ins DokuWiki `data/media` übertragen.
- testweise eine Seite unter `data/pages` anlegen und im Browser prüfen.
3. **Shell-Skript `monthly_export.sh` lokal laufen lassen**
- Mit Test-Umgebungsvariablen (ohne Gitea) ausführen.
- Prüfen, ob alle Schritte durchlaufen und Dateien in DokuWiki korrekt landen.
4. **Gitea Action mit `workflow_dispatch`**
- Workflow manuell starten, Log-Ausgaben prüfen.
- Validieren, dass der Action Runner auf Hobbybackend1 das Skript erfolgreich ausführt.
5. **Schedule aktiv beobachten**
- Nach dem ersten echten Lauf (1. des Monats) kontrollieren:
- Sind PDF/Bilder generiert?
- Ist die neue DokuWiki-Seite da und korrekt verlinkt?
6. **Feinjustierung**
- Falls nötig: Cron-Zeit, Dateinamen, Seitentemplate, Wochenlogik (z.B. „nächste + übernächste Woche“) anpassen.
---
## Akzeptanzkriterien
- Metabase-PDF existiert unter `${MEDIA_DIR}/metabase-report-${MEETING_ID}.pdf` und Dateigröße > 50 KB.
- Zwei Teamup-PNGs existieren unter `${MEDIA_DIR}` und sind in der erzeugten DokuWiki-Seite verlinkt.
- DokuWiki-Seite `${WIKI_MEETING_NAMESPACE}:${MEETING_ID}` ist im Wiki sichtbar und referenziert die Medien.
- Action-Log zeigt Exit-Code 0; bei Fehlern wird ein Fehler-Log-Eintrag erzeugt und an `it@hobbyhimmel.de` gemeldet (oder als Issue im Repo dokumentiert).
Diese Kriterien sind bewusst minimal gehalten und reichen für den Hobbybetrieb eines Vereins aus.
## 8. Erweiterungen (optional)
- Mehrere Metabase-Registerkarten / Dashboards pro Meeting.
- Automatische Verlinkung aus einer Übersichtsseite (z.B. `:teammeetings:start`) auf die neuen Monatsseiten.
- Fehlerreport per Mail oder in DokuWiki-Logseite, wenn Exports fehlschlagen.
- Optionale Parameter, um das Skript für „ad hoc Exports“ außerhalb des Monatslaufes zu nutzen (z.B. `./monthly_export.sh 2025-03`).
---
## Umsetzung: Lokaler Testplan (Metabase, Teamup, DokuWiki)
Ziel: Die drei beteiligten APIs lokal auf deinem PC (Windows, `cmd.exe`) testen und verifizieren, dass:
- ein Metabase-Export erzeugt werden kann,
- Teamup-Daten (oder Screenshots der Wochenansicht) erzeugt werden können,
- eine DokuWiki-Seite erstellt/aktualisiert und Medien eingebunden werden können.
Hinweis: Lege lokal eine `.env`-Datei an (niemals einchecken). Nutze eine `.env.example` im Repo mit Platzhaltern.
Basic-Prüfwerkzeuge (lokal installieren/prüfen):
- `curl` (Windows 10+ meist vorhanden),
- `jq` (hilfreich für JSON-Auswertung),
- `node` + `npm` (falls du Puppeteer/Playwright oder Node-Renderer nutzen willst),
- optional `wkhtmltopdf`/Headless Chrome für Rendering.
1) Metabase — lokaler API-Test
Zweck: Authentifizieren und einen PDF- oder JSON-Export eines Dashboards/Cards abrufen.
Vorgehen:
- Voraussetzungen: Metabase ist von deinem PC aus erreichbar (z. B. via VPN oder Port-Forwarding auf `http://localhost:3000`).
- Env-Variablen (Beispiel in `.env`):
- `METABASE_URL=http://localhost:3000`
- `METABASE_USER=...`
- `METABASE_PASSWORD=...`
- `METABASE_CARD_ID=123` (oder `METABASE_DASHBOARD_ID`)
Schritte (vereinfachtes Beispiel):
1. Auth (Session-Token) anfordern — Beispiel (ersetze Platzhalter):
```cmd
curl -s -X POST "%METABASE_URL%/api/session" -H "Content-Type: application/json" -d "{\"username\": \"%METABASE_USER%\", \"password\": \"%METABASE_PASSWORD%\"}"
```
2. Export anfragen (Beispiel: PDF-Export eines Cards/Dashboards). Je nach Metabase-Version kann der Pfad variieren. Beispiel-Form (Platzhalter):
```cmd
curl -s -X POST "%METABASE_URL%/api/card/%METABASE_CARD_ID%/query/pdf" -H "Content-Type: application/json" -H "X-Metabase-Session: <SESSION_TOKEN>" --output metabase-report.pdf
```
Validierung:
- Datei `metabase-report.pdf` existiert und ist > 50 KB.
- Öffne die Datei lokal im PDF-Viewer und prüfe, ob Daten sichtbar sind.
Troubleshooting:
- Auth schlägt fehl → Credentials prüfen, ggf. IP-Restrictions.
- Endpoint nicht vorhanden → Metabase-Dokumentation zur API-Version prüfen (Session-API / Export-Endpoints variieren).
2) Teamup — lokaler API-Test
Zweck: Kalenderdaten per API abrufen oder Wochenansicht via Headless-Browser rendern.
Vorgehen:
- Env-Variablen:
- `TEAMUP_CALENDAR_BASE=https://api.teamup.com`
- `TEAMUP_CALENDAR_KEY=dein_calendar_key` (oder `TEAMUP_PUBLIC_URL` für Web-Rendering)
- Optional: `TEAMUP_API_KEY=...` falls benötigt
API-Request (Events im Zeitraum abrufen) — Beispiel:
```cmd
curl -s -H "Teamup-Token: %TEAMUP_API_KEY%" "%TEAMUP_CALENDAR_BASE%/v2/calendars/%TEAMUP_CALENDAR_KEY%/events?startDate=2025-11-01&endDate=2025-11-14" | jq '.'
```
Alternativ (wenn du die Web-Ansicht als Bild willst):
- Öffne die Wochen-URL (z. B. `%TEAMUP_PUBLIC_URL%?view=week&date=YYYY-MM-DD`) mit einem Headless-Renderer (Puppeteer) und erstelle `teamup-week1.png`.
Validierung:
- API: JSON-Antwort mit Events (Array) und HTTP 200.
- Screenshot: `teamup-week1.png` ist vorhanden und lesbar.
Troubleshooting:
- 403/401 → API-Key oder Zugriff prüfen.
- Keine Events → Zeitraum / Kalenderkey kontrollieren.
3) DokuWiki — lokaler API-Test (empfohlen: API) oder SSH-Fallback
Zweck: Eine Testseite erzeugen und Medien verlinken, um Upload & Sichtbarkeit zu prüfen.
Vorgehen (API-Variante, wenn `DOKUWIKI_API_URL` + `DOKUWIKI_API_TOKEN` vorhanden):
- Env-Variablen:
- `DOKUWIKI_API_URL=https://wiki.example.com/lib/exe/rest.php/bin/actions` (Beispiel passe an)
- `DOKUWIKI_API_TOKEN=...`
- `WIKI_MEETING_NAMESPACE=teammeetings`
- `MEETING_ID=2025-11`
Beispiel (allgemeines curl-Pattern; Plugin/Endpoint anpassen):
```cmd
set /p PAGE_TEXT=< newpage.txt
curl -s -X POST "%DOKUWIKI_API_URL%" -H "Authorization: Bearer %DOKUWIKI_API_TOKEN%" -F "id=%WIKI_MEETING_NAMESPACE%:%MEETING_ID%" -F "text=%PAGE_TEXT%"
```
Wenn keine API verfügbar ist (SSH-Fallback):
- Upload der Medien per `scp` oder `rsync -e ssh` in `${ALLINKL_BASE_PATH}/data/media/...` und Schreiben der Seite per SSH-Here-Doc (wie im Plan beschrieben).
Validierung:
- Nach API-Request: die Seite im Browser öffnen (z. B. `https://wiki.example.com/doku.php?do=show&id=%WIKI_MEETING_NAMESPACE%:%MEETING_ID%`) → HTTP 200 und sichtbarer Inhalt.
- Medien sind im Wiki sichtbar und korrekt verlinkt.
Troubleshooting:
- API 401/403 → Token prüfen / Plugin aktivieren.
- SSH-Fallback: Dateirechte und Ownership prüfen (All-Inkl kann hier beschränken).
4) `.env.example` — minimale Variablen (Beispiel zum Anlegen)
```
# Metabase
METABASE_URL=
METABASE_USER=
METABASE_PASSWORD=
METABASE_CARD_ID=
# Teamup
TEAMUP_CALENDAR_BASE=
TEAMUP_CALENDAR_KEY=
TEAMUP_API_KEY=
# DokuWiki (API bevorzugt)
DOKUWIKI_API_URL=
DOKUWIKI_API_TOKEN=
WIKI_MEETING_NAMESPACE=teammeetings
# Fallback/SSH (nur falls nötig)
ALLINKL_SSH_HOST=
ALLINKL_SSH_USER=
ALLINKL_BASE_PATH=
# TZ
TZ=Europe/Berlin
```
5) Ablauf für lokale Durchführung (kurz)
1. `.env` aus `.env.example` anlegen und mit echten (lokal gültigen) Werten füllen.
2. Prüfe Tools: `curl --version`, `node --version` (falls Renderer benötigt), `jq --version`.
3. Metabase-Test ausführen (Auth → Export → Datei prüfen).
4. Teamup-Test ausführen (API → JSON prüfen oder Screenshot erzeugen).
5. DokuWiki-Test ausführen (API → Seite prüfen). Falls API nicht vorhanden, teste SSH-Fallback.
6. Wenn alle drei Tests grün sind, kannst du `monthly_export.sh` lokal im Dry-Run-Mode ausführen und anschließend per Gitea-Action in den Runner überführen.
6) Minimal gewünschte Ergebnisse (zum Abhaken)
- [ ] Metabase PDF lokal erzeugt und geprüft
- [ ] Teamup-Daten/API oder Screenshots erzeugt und geprüft
- [ ] DokuWiki-Seite erstellt/aktualisiert und Medien referenziert
Wenn du möchtest, erstelle ich als nächstes eine `.env.example`-Datei im Repo und ein sehr kleines Shell-Skript-Skeleton (`./scripts/test_apis.sh`) mit den obenstehenden curl-Beispielen (ohne Secrets). Sag kurz Bescheid, ob ich das anlegen soll.