# TeamsBot Greenfield-IA: MeetingModule + Live-Update-Fixes ## Beschreibung und Kontext Die TeamsBot-UI ist aktuell: - 3 Tabs (Dashboard "Uebersicht", Sitzungen, Einstellungen). - Kein Meeting-Entity -- alles ist `TeamsbotSession.meetingLink`. Wer z.B. ein wiederkehrendes Weekly-Standup ueber Wochen verfolgen will, muss die Sessions per Datum suchen. - Kein "Modul"-Konzept fuer Reihen (wie der User wuenscht). - Live-Updates haengen an SSE in `TeamsbotSessionView.tsx` mit `useEffect`-Deps `[instanceId, sessionId]` only (Z. 327-328) + `eslint-disable` -- reagiert daher NICHT zuverlaessig auf Status-Wechsel und auf neue `agentRun`-Events. Letztere sind nur `_dlog`, NICHT in der UI sichtbar. - `stats`-Payload aus `getSession`-API (`routeFeatureTeamsbot.py` 357-358) wird vom Frontend ignoriert. - Dashboard-Counts haben 10s Lag (Polling). **Geschaeftstreiber:** User finden sich nicht zurecht; Live-Bedienung wirkt fragil ("zeigt das hier ueberhaupt was Aktuelles?"). Mit Modul- of-Sessions-IA (analog ComCoach) und sauberen Live-Update-Pfaden wird TeamsBot zum verlaesslichen Meeting-Tool. ## Fokus und kritische Details - **Live-Update ist UX-kritisch** -- Session-State, agentRun-Indicator und Stats muessen waehrend laufender Meetings sichtbar pulsieren. - SSE-`useEffect`-Deps nicht naiv aufschnueren -- sonst Reconnect- Flicker bei jedem Status-Bit-Wechsel. Loesung: dedizierter Reconnect- Hook, der nur reconnektet wenn (a) sessionId wechselt oder (b) Session von "terminal" zurueck zu "active" geht (sehr selten). - Backend `stats`-Payload bereits vorhanden, nur nicht gebunden. - `MeetingModule` ist additiv -- alte `TeamsbotSession`-Eintraege bekommen `moduleId` per Migration (Default-Modul "Adhoc"). ## Ziel und Nicht-Ziele - Ziel: - 5-Tab-IA (Dashboard, Assistent, Module, Live-Session, Einstellungen). - `MeetingModule`-Entity (Reihe + KPIs + Default-Bot + Default- Director-Prompts). - 4 Live-Update-Fixes (siehe unten F-fix-1 .. F-fix-4). - NICHT: Aenderung an Bot-Bridge (.NET Media-Bridge bleibt). - NICHT: WebSocket-Migration im Frontend (SSE bleibt, ist Architektur- Entscheid). - NICHT: Multi-Mandate-Sharing von Modulen. ## Betroffene Module - Gateway: - `gateway/modules/features/teamsbot/datamodelTeamsbot.py` -- neue Klasse `TeamsbotMeetingModule`, FK `TeamsbotSession.moduleId` (nullable in Uebergangsphase). - `gateway/modules/features/teamsbot/interfaceFeatureTeamsbot.py` -- CRUD fuer `MeetingModule`. - `gateway/modules/features/teamsbot/routeFeatureTeamsbot.py` -- neue Routen `/modules/...`, `agentRun`-Event sauberer schicken, `stats`-Payload kontinuierlich anreichern. - `gateway/modules/features/teamsbot/mainTeamsbot.py` -- RBAC-Keys auf 5 Tabs, optional Default-MeetingModule-Templates. - Frontend: - `frontend_nyla/src/types/mandate.ts` 244-252 -- TeamsBot-Sidebar 3 -> 5 Eintraege. - `frontend_nyla/src/pages/FeatureView.tsx` 159-163 -- View-Mapping aktualisieren. - `frontend_nyla/src/pages/views/teamsbot/` -- vorhandene Komponenten aufteilen: - `TeamsbotDashboardView` -- KPIs erweitern (Modul-Aggregate + Gamification). - `TeamsbotAssistantView` (NEU) -- Wizard. - `TeamsbotModulesView` (NEU) -- Modul-CRUD + Sessions je Modul. - `TeamsbotSessionView` -- bleibt, jetzt nur Live-Session. - `TeamsbotSettingsView` -- bleibt. - `frontend_nyla/src/api/teamsbotApi.ts` -- Module-API + neuer Reconnect-Hook. - DB-Migration: ja (additive Tabelle + nullable FK). ## Zieldatenmodell ```mermaid flowchart LR Inst[FeatureInstance teamsbot] --> Mod[MeetingModule] Mod --> Sess[TeamsbotSession meetingLink] Sess --> Trans[Transcript] Sess --> Resp[BotResponse] Sess --> Dir[DirectorPrompt] Mod --> Kpi[ModuleKpi/Goals] Mod --> DefBot[Default Bot] Mod --> DefDir[Default Director Prompts] ``` `MeetingModule` Felder (Auszug): | Feld | Typ | Bedeutung | |------|-----|-----------| | `id` | UUID | PK | | `instanceId` | UUID | FeatureInstance-Scope | | `mandateId` | UUID | Tenant | | `ownerUserId` | UUID | Owner | | `title` | text | "Weekly Standup", "Q3 Sales Review-Reihe" | | `seriesType` | enum | `weekly` \| `biweekly` \| `monthly` \| `adhoc` \| `project` | | `defaultBotId` | UUID? | `TeamsbotSystemBot` | | `defaultDirectorPrompts` | jsonb | Liste vorausgefuellter Director-Prompts | | `goals` | text | -- | | `kpiTargets` | jsonb | -- | | `status` | enum | `active` \| `archived` \| `completed` | ## IA: 5 Tabs (final) | # | Tab | Zweck | Komponente | |---|------|-------|-------------| | 1 | Dashboard | Gamification (Talking-Time, Director-Trefferquote, beliebteste Prompts), aktive Module/Sessions, Quick-Action "Neues Meeting" | `TeamsbotDashboardView` | | 2 | Assistent | Wizard: Modul waehlen oder neu -> Meeting-Link/Auto-Join -> Bot starten | `TeamsbotAssistantView` | | 3 | Module | CRUD-Liste aller Meeting-Module, pro Modul aufklappbare Session-Liste | `TeamsbotModulesView` | | 4 | Live-Session | aktive Sitzung: Regie-Panel, UDB-Sidebar, Transkript, Antworten, Bot-Status, MFA, Stats-Karten | `TeamsbotSessionView` (refactor) | | 5 | Einstellungen | Bot-Account, Stimme, System-Bots (SysAdmin) | `TeamsbotSettingsView` | ## Use-Case-Mapping | Use-Case | Tab(s) | Hauptaktion | |----------|--------|-------------| | 1 Gamification-Dashboard | Dashboard | Talking-Time + Modul-KPIs | | 2 Assistent: neues Meeting | Assistent -> Live-Session | Wizard durchklicken | | 3 Session-Operations | Live-Session | Stop, Director-Prompts, MFA, Stats | | 4 Listen CRUD | Module | Module + Sessions je Modul pflegen | | 5 Instanzen-Einstellungen | Einstellungen | Bot, Stimme, System-Bots | ## Live-Update-Fixes (parallel zur IA) ### F-fix-1: SSE-Reconnect-Hook - Problem: `useEffect` `[instanceId, sessionId]`-only haengt nicht an `session.status` -> Reconnect bei legitimen Status-Wechseln nicht garantiert. - Loesung: Eigener Hook `useTeamsbotSessionStream(instanceId, sessionId, isTerminal)` der intern reconnectet wenn `isTerminal` von `true` -> `false` flippt (z.B. nach manuellem Re-Start einer beendeten Session). Andere Status-Bits triggern KEINEN Reconnect. ### F-fix-2: agentRun-Event sichtbar - Problem: `agentRun`-SSE-Events sind nur `_dlog` (`TeamsbotSessionView.tsx` 290-293). - Loesung: Status-Bubble in der Live-View ("Agent denkt nach: ...") als kurzlebige animierte Komponente. ### F-fix-3: stats-Karten - Problem: `getSession`-API liefert `stats` (Sprechminuten, Bot- Antworten, Latenz) -- Frontend ignoriert. - Loesung: Header-Karten in `TeamsbotSessionView` gebunden an `session.stats`. Aktualisierung kommt automatisch via SSE `sessionState`-Events (Backend muss `stats` mitliefern -- ggf. Backend-Anpassung in `routeFeatureTeamsbot.py`). ### F-fix-4: Dashboard-Counts ohne 10s-Lag - Problem: Dashboard pollt `listSessions` alle 10s. - Option A (kleiner Eingriff): bei aktiver Session 3s-Polling, sonst 30s. - Option B (besser): SSE-Channel pro Mandate `/api/teamsbot/{instanceId}/dashboard/stream` mit "session-tick"- Events (Counter-Updates push, kein Polling). - **Default:** Option A in Phase 4, Option B als Follow-up. ## Entscheidungen | Datum | Entscheidung | Begruendung | |-------|-------------|------------| | 2026-04-29 | Neues `MeetingModule`-Entity additiv | Reihen-Konzept gewuenscht; bestehende Sessions in "Adhoc"-Modul | | 2026-04-29 | 5 Tabs (statt 3) | Use-Cases brauchen klare Trennung Assistent/Module/Live | | 2026-04-29 | SSE bleibt (kein WS) | Architektur stabil, Browser-Bot nutzt WS, Frontend nicht | | 2026-04-29 | Dashboard-Counts: Adaptive Polling jetzt, SSE-Channel als Follow-up | Pragmatisch, schnell sichtbar | ## Umsetzungs-Checkliste ### Phase 1 -- Backend Datenmodell + Routes - [ ] `datamodelTeamsbot.py`: - Neue Klasse `TeamsbotMeetingModule`. - `TeamsbotSession.moduleId Optional[UUID]` additiv. - [ ] DB-Migration: `script_db_init_teamsbot_meeting_modules.py` -- legt Tabelle an, erzeugt pro `instanceId` ein Default-`Adhoc`-Modul, setzt bestehende Sessions auf dieses Modul. - [ ] `interfaceFeatureTeamsbot.py` -- CRUD-Methoden fuer Module. - [ ] `routeFeatureTeamsbot.py`: - Neue Routen `GET/POST/PUT/DELETE /modules/...`. - `getSession` liefert `stats` (existiert), `listSessions` ergaenzt `moduleId` im Payload. - SSE: `sessionState`-Event traegt jetzt auch `stats`. - SSE: `agentRun`-Event sauberer schicken (toolName, status: `started`/`finished`/`failed`). ### Phase 2 -- Backend Live-Stats anreichern - [ ] `_buildSessionStats(session) -> SessionStats` zentral, in jedem `sessionState`-SSE-Event aufrufen (nicht nur on-demand). ### Phase 3 -- Frontend Routing & Sidebar - [ ] `frontend_nyla/src/types/mandate.ts` 244-252 TeamsBot-Eintraege auf 5 Eintraege. - [ ] `frontend_nyla/src/App.tsx` Routes ergaenzen (`assistant`, `modules`). - [ ] `frontend_nyla/src/pages/FeatureView.tsx` View-Mapping aktualisieren. ### Phase 4 -- Frontend Komponenten - [ ] NEU `TeamsbotAssistantView` -- Wizard 3 Steps (Modul- Auswahl/Neu, Meeting-Link, Bot-Auswahl) -> "Bot starten" -> Navigation `live-session?sessionId=...`. - [ ] NEU `TeamsbotModulesView` -- Liste, CRUD, aufklappbare Sessions. - [ ] `TeamsbotSessionView` Refactor: - Reconnect-Hook (F-fix-1) integrieren. - Status-Bubble fuer agentRun (F-fix-2). - Stats-Karten im Header binden (F-fix-3). - [ ] `TeamsbotDashboardView`: - Polling adaptiv (F-fix-4 Option A). - Modul-Aggregate-Sektion ergaenzen (Top-Module nach Session-Count, Talking-Time-Verteilung etc.). ### Phase 5 -- Doku - [ ] `wiki/b-reference/teams-bot/architecture.md` Module-Sektion ergaenzen, Live-Update-Pfade dokumentieren. - [ ] `wiki/TOPICS.md` ggf. Eintrag "TeamsBot Module". ## Akzeptanzkriterien | # | Kriterium (Given-When-Then) | Prio | |---|-----------------------------|------| | 1 | Given Sidebar TeamsBot, When User es oeffnet, Then sieht er 5 Tabs (Dashboard, Assistent, Module, Live-Session, Einstellungen) | must | | 2 | Given Tab Module, When User auf "Neues Modul" klickt, Then kann er Titel, Series-Typ, Default-Bot, Director-Prompts, KPIs setzen | must | | 3 | Given Modul existiert, When User auf "Neue Session" klickt, Then wird eine `TeamsbotSession` mit `moduleId` angelegt und im Live-Tab geoeffnet | must | | 4 | Given Live-Session laeuft, When der Backend-Agent ein Tool aufruft, Then erscheint im UI ein Status-Bubble "Agent denkt nach" mit Tool-Name | must | | 5 | Given Live-Session laeuft, When sich Sprechminuten/Bot-Antworten/Latenz aendern, Then aktualisieren die Stats-Karten ohne Page-Reload | must | | 6 | Given Session terminiert (z.B. Stop), When User auf gleicher Seite bleibt, Then schliesst die SSE sauber, kein Reconnect-Loop | must | | 7 | Given Bestand-Sessions ohne Modul, When Migration laeuft, Then sind alle Sessions im Default-`Adhoc`-Modul je Instanz einsortiert | must | | 8 | Given Dashboard offen, When eine aktive Session laeuft, Then aktualisieren die Counter spaetestens nach 3s | should | | 9 | Given keine aktive Session, When Dashboard offen, Then aktualisiert es nur alle 30s | should | ## Testplan | ID | AC | Art | Automatisiert | Repo-Pfad | Status | |----|----|-----|--------------|-----------|--------| | T1 | 1 | unit | ja | frontend_nyla/src/types/__tests__/mandate.test.ts | pending | | T2 | 2,3 | e2e | ja | frontend_nyla/tests/e2e/teamsbot-modules-crud.spec.ts | pending | | T3 | 4 | unit | ja | frontend_nyla/src/pages/views/teamsbot/__tests__/TeamsbotSessionView_agentRun.test.tsx | pending | | T4 | 5 | integration | ja | frontend_nyla/tests/integration/teamsbot-stats-binding.spec.ts | pending | | T5 | 6 | manual | nein | -- | pending | | T6 | 7 | integration | ja | gateway/tests/features/teamsbot/test_migration_modules.py | pending | | T7 | 8,9 | manual | nein | -- | pending | ## Links - Audit-Quelle: Subagent-Report 2026-04-29. - Aktueller Code: `gateway/modules/features/teamsbot/`, `frontend_nyla/src/pages/views/teamsbot/`. - Wiki: `wiki/b-reference/teams-bot/architecture.md`, `wiki/c-work/4-done/2026-04-teamsbot-director-prompts.md`. ## Abschluss - [ ] `wiki/b-reference/teams-bot/architecture.md` aktualisiert - [ ] `wiki/TOPICS.md` ggf. neuer Eintrag - [ ] Dieses Dokument -> `z-archive/` verschoben