diff --git a/docs/handoff.md b/docs/handoff.md index 9cc41ff..ec0da7b 100644 --- a/docs/handoff.md +++ b/docs/handoff.md @@ -1,6 +1,6 @@ # Übergabe -Stand **2026-09-17**, letztes gebautes Paket 0.5.4. Wer hier weitermacht, +Stand **2026-09-23**, letztes gebautes Paket 0.5.4. Wer hier weitermacht, liest zuerst diese Seite, dann [`07-mvp-plan.md`](07-mvp-plan.md). Für Abdu selbst gibt es das [Handbuch](handbuch/handbuch.pdf). @@ -20,7 +20,7 @@ Auslöser bis zum fertigen Short steht im Code vollständig. Geprüft ist sie | S5 Onboarding + Sichtung | offen | | | S6 Erstchatter-Begrüßung | offen | | -193 Tests, alle grün. Was noch fehlt, steht vollständig in +280 Tests, alle grün. Was noch fehlt, steht vollständig in [`offene-punkte.md`](offene-punkte.md). ## Neu: der Dienst läuft zentral @@ -47,9 +47,10 @@ systemd (`abdulive-hub`). Der Container hat keinen Zugang zum Repo - das Skript schiebt den Arbeitsstand als Archiv hinüber. Der Discord-Teil der Zugangsdaten ist übertragen, der Bot hängt am Hub und -meldet beim Start "Rollen-Knöpfe sind scharf". Die Twitch-Broadcaster-App ist -hinterlegt und geprüft (Client-ID registriert, Secret passt - Twitch stellt -darauf ein App-Token aus). **Was fehlt, ist der Klick von Abdu**, siehe unten. +meldet beim Start "Rollen-Knöpfe sind scharf". **Abdu hat am 2026-09-23 sein +Konto verbunden** (`abdulive_`, alle 9 Scopes). Damit laufen Helix mit +Nutzer-Token und EventSub. Der Chat liest weiter anonym mit, weil das +Bot-Konto noch nicht verbunden ist. **Das kostet ADR-0005 seine Hauptbegründung.** "Bindet nur auf 127.0.0.1" gilt für den Hub nicht mehr. An seine Stelle treten ein Passwort für alles, was ein @@ -76,10 +77,9 @@ Der Hub steht auf `mode: draft` - der Post geht vollständig, aber in Webhook ist damit nachgewiesen. Zum Scharfschalten: `mode: live` in `/var/lib/abdulive/config/config.yaml`. -**Ausgelöst hat er noch nie**, und das liegt nicht am Broadcaster, sondern an -Twitch: die Erkennung des Stream-Starts hängt am Helix-Polling, und das -braucht ein Broadcaster-Token. Solange das fehlt, wartet der Ping auf ein -Ereignis, das nie kommt. +**Ausgelöst hat er noch nie.** Bis zum 2026-09-23 fehlte das +Broadcaster-Token; das ist jetzt da. Der nächste Stream ist der erste echte +Durchlauf, im Entwurfsmodus. ## Das Overlay steht @@ -92,13 +92,61 @@ gegen die tote Browser-Source nach einem Neustart getan ist, steht in [`apps/overlay-server/README.md`](../apps/overlay-server/README.md). Abos, Raids und Bits kommen über IRC-USERNOTICE herein, das wird jetzt -ausgewertet. **Follows fehlen** - die gibt es nur über EventSub. +ausgewertet. **Follows fehlen** - die gibt es nur über EventSub. EventSub +läuft inzwischen, abonniert ist aber nur `channel_points_custom_reward_redemption.add`. +Follows wären ein zweites Abonnement (`channel.follow`, Version 2, braucht +`moderator:read:followers`, der Scope ist schon da). + +**Kamerarahmen, Entwurf** (`/kamera`, 520×380 auf 0,0): ein Rahmen rechts und +unten um die Facecam, darunter eine Platte mit Kanal, Kategorie, Zuschauern +und Laufzeit. Soll die Statusleiste ersetzen, die als unschön empfunden wird. +Über der Kamera liegt bewusst nichts, weil genau dieser Bereich für die +Shorts ausgeschnitten wird. Noch nicht ausgerollt, Rückmeldung zur Richtung +steht aus. Ansehen: `node apps/cli/main.ts overlay --demo`, dann +`http://127.0.0.1:4791/kamera?probe=1`. Zum Ansehen ohne Stream: auf der Übersichtsseite gibt es unter **Ausprobieren** für jede Einblendung, jede Chat-Variante und jeden Effekt einen Knopf. Die Ereignisse gehen nur an die Browser-Sources. Dasselbe im Dauerbetrieb: `abdulive overlay --demo` oder der Knopf „Vorführung starten". +## Kanalpunkte: „Nachricht vorlesen" läuft + +Seit 2026-09-23 scharf. Der Weg: EventSub meldet die Einlösung, der Hub +prüft (`apps/hub/src/rewards.ts`), Piper spricht, `/tts` spielt ab. + +| | | +|---|---| +| Belohnung | „Nachricht vorlesen", 1000 Punkte, Texteingabe Pflicht | +| Freigabe | keine, wird direkt vorgelesen | +| Schutz | Wortfilter (29 Einträge), 200 Zeichen, 3 je Person und Stunde, „Sofort still" auf der Übersichtsseite | +| Stimme | Piper, `de_DE-mls-medium`, Sprecher 0 | + +**Die Stimme entsteht im Hub, nicht im Browser.** Zuerst lief es über +`speechSynthesis` in der Browser-Quelle. Das hat in OBS gesprochen, aber +amerikanisch: OBS' Browser sah keine deutsche Stimme und die Seite nahm die +erste beliebige. Piper liegt unter `/opt/piper` im LXC (2 Kerne: 200 Zeichen +in 0,7 s), das Stimmenmodell unter `models/piper/`. Beides überlebt jedes +Ausrollen; eingerichtet mit `scripts/install-piper.sh`. Proben aller 236 +mls-Sprecher lassen sich mit `--speaker N` erzeugen. + +**Die Belohnung muss über die API angelegt sein** (`abdulive rewards:anlegen`). +Nur die App, die eine Belohnung angelegt hat, darf deren Einlösungen +abschließen oder erstatten. Im Dashboard sieht man davon nichts. Titel, +Kosten und Abklingzeit darf man dort ändern; löschen und neu anlegen nicht, +dann ist die ID weg, die in der Hub-Konfiguration steht. + +**Der Wortfilter normalisiert vorher**: Leetspeak, Punkte zwischen den +Buchstaben, gezogene Buchstaben, Akzente. Einträge ab 5 Buchstaben werden im +zusammengezogenen Text gesucht, kürzere nur am Wortanfang, sonst stünde +„nazi" in „kann azubi". Die Liste steht nur in der Hub-Konfiguration, nicht +im Repo. + +**Der YAML-Leser konnte keine Listen aus Maps.** `- titel: X` zerfiel in +Zeichenketten, jede Belohnung war ohne Meldung unwirksam - auch das Beispiel +in `config.example.yaml`. Behoben und getestet; die bestehenden Dateien +werden nachweislich gleich gelesen wie vorher. + ## Der Discord-Server steht Dazugekommen seit der letzten Übergabe, und kein Teil des MVP: der @@ -302,9 +350,9 @@ oben. ## Die drei Dinge, die Abdu tun muss -1. **Broadcaster-Konto verbinden.** Das ist jetzt der Flaschenhals: ohne - Broadcaster-Token gibt es keine Zuschauerzahlen, keine Stream-Sitzungen und - damit auch keinen Go-Live-Ping. +1. ~~**Broadcaster-Konto verbinden.**~~ Erledigt am 2026-09-23. Der Rest + dieses Punkts bleibt als Nachschlag stehen, falls neu verbunden werden + muss. Die beiden Twitch-Apps (dev.twitch.tv/console/apps) kann auch jemand anders anlegen, sie hängen nicht am Kanal. Seit dem Umzug in den Hub brauchen sie @@ -326,7 +374,8 @@ oben. 3. **Layout umstellen** nach [`obs-layout.md`](obs-layout.md), danach `abdulive calibrate` zur Kontrolle. -Ohne Punkt 1 liest das Toolkit den Chat anonym mit und kann nichts senden. +Das Bot-Konto ist noch nicht verbunden: bis dahin liest das Toolkit den +Chat anonym mit und kann nichts senden. Ohne Punkt 2 gibt es keine Clips. Ohne Punkt 3 sitzt der Ausschnitt schief. Dazu eine Kleinigkeit mit Wirkung: das Bot-Konto sollte Moderator sein @@ -354,9 +403,12 @@ malt. Das war vorher nicht zu erraten. `mode: live`. Das ist der kleinste verbleibende Handgriff mit der größten Wirkung. -**`apps/recap` bauen.** Der Webhook liegt bereit, der Hub hat die Daten, und -anders als S2 hängt daran nichts. Guter Nebenweg, wenn der Stream-PC gerade -nicht verfügbar ist. +**Den Kamerarahmen fertig machen** und die Statusleiste damit ablösen. + +**`apps/recap` bauen.** Angefangen, aber nicht committet: `apps/recap/src/recap.ts` +und Ergänzungen in `packages/db/src/repos.ts` liegen nur im Arbeitsstand +(die Typprüfung meckert dort noch über `url: undefined`). Der Webhook liegt +bereit, der Hub hat die Daten. **Danach S5.** Nicht wegen des Codes, sondern weil das Werkzeug ohne Sichtungsseite für Abdu nicht bedienbar ist. Die Kette funktioniert, aber sie