279 lines
12 KiB
Markdown
279 lines
12 KiB
Markdown
<!-- status: build -->
|
|
<!-- started: 2026-04-29 -->
|
|
<!-- verified: 2026-05-03 -->
|
|
<!-- component: gateway, ui-nyla, teams-bot -->
|
|
|
|
# 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").
|
|
- **Namenskonvention**: `TeamsbotSession` hat `startedByUserId` (nicht
|
|
`userId`/`ownerUserId`). `MeetingModule.ownerUserId` ist konsistent
|
|
mit dem bestehenden Pattern.
|
|
|
|
## 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:
|
|
- `platform-core/modules/features/teamsbot/datamodelTeamsbot.py` -- neue
|
|
Klasse `TeamsbotMeetingModule`, FK `TeamsbotSession.moduleId`
|
|
(nullable in Uebergangsphase).
|
|
- `platform-core/modules/features/teamsbot/interfaceFeatureTeamsbot.py` --
|
|
CRUD fuer `MeetingModule`.
|
|
- `platform-core/modules/features/teamsbot/routeFeatureTeamsbot.py` --
|
|
neue Routen `/modules/...`, `agentRun`-Event sauberer schicken,
|
|
`stats`-Payload kontinuierlich anreichern.
|
|
- `platform-core/modules/features/teamsbot/mainTeamsbot.py` -- RBAC-Keys
|
|
auf 5 Tabs, optional Default-MeetingModule-Templates.
|
|
- Frontend:
|
|
- `ui-nyla/src/types/mandate.ts` 244-252 -- TeamsBot-Sidebar
|
|
3 -> 5 Eintraege.
|
|
- `ui-nyla/src/pages/FeatureView.tsx` 159-163 -- View-Mapping
|
|
aktualisieren.
|
|
- `ui-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.
|
|
- `ui-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: <toolName>...")
|
|
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 |
|
|
| 2026-05-03 | Alle Zeilennummern gegen Codebase verifiziert, alle korrekt | Pre-Build-Audit |
|
|
|
|
## 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
|
|
|
|
- [ ] `ui-nyla/src/types/mandate.ts` 244-252 TeamsBot-Eintraege
|
|
auf 5 Eintraege.
|
|
- [ ] `ui-nyla/src/App.tsx` Routes ergaenzen (`assistant`,
|
|
`modules`).
|
|
- [ ] `ui-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 | ui-nyla/src/types/__tests__/mandate.test.ts | pending |
|
|
| T2 | 2,3 | e2e | ja | ui-nyla/tests/e2e/teamsbot-modules-crud.spec.ts | pending |
|
|
| T3 | 4 | unit | ja | ui-nyla/src/pages/views/teamsbot/__tests__/TeamsbotSessionView_agentRun.test.tsx | pending |
|
|
| T4 | 5 | integration | ja | ui-nyla/tests/integration/teamsbot-stats-binding.spec.ts | pending |
|
|
| T5 | 6 | manual | nein | -- | pending |
|
|
| T6 | 7 | integration | ja | platform-core/tests/features/teamsbot/test_migration_modules.py | pending |
|
|
| T7 | 8,9 | manual | nein | -- | pending |
|
|
|
|
## Links
|
|
|
|
- Audit-Quelle: Subagent-Report 2026-04-29.
|
|
- Aktueller Code: `platform-core/modules/features/teamsbot/`,
|
|
`ui-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
|