Add TeamPulse design spec
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
commit
3ba945f283
132
docs/superpowers/specs/2026-05-16-teampulse-design.md
Normal file
132
docs/superpowers/specs/2026-05-16-teampulse-design.md
Normal file
@ -0,0 +1,132 @@
|
||||
# TeamPulse — Design-Dokument
|
||||
|
||||
**Datum:** 2026-05-16
|
||||
**Status:** Zur Implementierung freigegeben
|
||||
|
||||
---
|
||||
|
||||
## Ziel
|
||||
|
||||
Ein Python-Script, das den Chat eines laufenden Microsoft Teams-Meetings überwacht, alle Personen erfasst, die in einem definierten Zeitfenster eine Nachricht gepostet haben, und ein Memo mit Name und E-Mail-Adresse der Teilnehmer erzeugt.
|
||||
|
||||
Ausgangslage: Nutzer ohne Admin-Rechte, kein Zugriff auf Microsoft Graph API / Azure AD App-Registrierung.
|
||||
|
||||
---
|
||||
|
||||
## Architektur
|
||||
|
||||
```
|
||||
main.py
|
||||
├── auth.py — Playwright-Session verwalten (Login, Persistenz)
|
||||
├── monitor.py — Teams-Chat pollen, Trigger erkennen, Nachrichten sammeln
|
||||
├── resolver.py — Sender-Name → E-Mail via Profilkarte (mit lokalem Cache)
|
||||
└── memo.py — Markdown-Memo erzeugen und speichern
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Komponenten
|
||||
|
||||
### `auth.py`
|
||||
- Startet Playwright mit persistentem User-Data-Verzeichnis (`~/.teampulse/session`)
|
||||
- Beim ersten Start: sichtbares Browser-Fenster für manuellen SSO/MFA-Login
|
||||
- Bei bekannter Session: headless, unsichtbar im Hintergrund
|
||||
- Erkennt Session-Ablauf (Login-Redirect) und öffnet Browser-Fenster zur Re-Authentifizierung
|
||||
- Liest beim Start den Display-Namen des eingeloggten Nutzers aus → wird als „Moderator" gespeichert
|
||||
|
||||
### `monitor.py`
|
||||
- Öffnet Teams Web im Hintergrund-Browser
|
||||
- Nutzer navigiert einmalig manuell zur Meeting-Chat-URL
|
||||
- Pollt den Chat-DOM alle ~2 Sekunden auf neue Nachrichten
|
||||
- Erkennt Trigger-Befehle (nur wenn gepostet vom eingeloggten Nutzer):
|
||||
- `!start "Name des Vortragenden"` → startet Zeitfenster, speichert Vortragendenname
|
||||
- `!stop` → beendet Zeitfenster
|
||||
- Fallback: Enter-Taste in der Konsole als alternativer Trigger
|
||||
- Sammelt während des Zeitfensters: `{ sender: str, timestamp: str }`
|
||||
- Reconnect-Logik bei Seitenreload oder Verbindungsverlust (gesammelte Daten bleiben erhalten)
|
||||
|
||||
### `resolver.py`
|
||||
- Iteriert nach `!stop` über alle eindeutigen Sender
|
||||
- Prüft `~/.teampulse/cache.json` — bekannte Namen werden nicht erneut aufgelöst
|
||||
- Für unbekannte Sender: klickt Profilkarte im Teams-Web → extrahiert E-Mail
|
||||
- Fehlerbehandlung:
|
||||
- Profilkarte nicht ladbar → `<nicht auflösbar>`
|
||||
- Externer Gast → als Gast markieren: `<gast@extern.com>` oder `<externer Gast>`
|
||||
- Cache wird bei jedem neuen Eintrag sofort geschrieben
|
||||
|
||||
### `memo.py`
|
||||
- Filtert Vortragenden und Moderator aus der Teilnehmerliste
|
||||
- Sortiert verbleibende Einträge nach E-Mail-Adresse
|
||||
- Erzeugt Markdown-Ausgabe (siehe Format unten)
|
||||
- Speichert Datei als `audit_YYYYMMDD_HHMM.md` im aktuellen Verzeichnis
|
||||
- Gibt Inhalt zusätzlich in der Konsole aus
|
||||
|
||||
---
|
||||
|
||||
## Trigger-Verhalten
|
||||
|
||||
| Aktion | Chat-Befehl | Konsole |
|
||||
|---|---|---|
|
||||
| Zeitfenster starten | `!start "Anna Bauer"` | Enter drücken |
|
||||
| Zeitfenster beenden | `!stop` | Enter drücken |
|
||||
|
||||
- Nur Befehle vom eingeloggten Nutzer werden als Trigger akzeptiert
|
||||
- `!start` ohne Anführungszeichen oder ohne Namen → Warnung, Zeitfenster startet mit Platzhalter „Unbekannter Vortragender"
|
||||
- Mehrfaches `!start` ohne `!stop` → zweites `!start` überschreibt das erste (kein Fehler)
|
||||
|
||||
---
|
||||
|
||||
## Ausgabeformat
|
||||
|
||||
```markdown
|
||||
# Meeting Chat Audit
|
||||
Zeitfenster: 10:03:42 – 10:47:15
|
||||
|
||||
## Teilnehmer am Vortrag von Anna Bauer (4)
|
||||
_Moderator: Oliver Hofmann — Vortragender und Moderator ausgeschlossen_
|
||||
|
||||
- Klaus Huber <k.huber@company.com>
|
||||
- Max Mustermann <m.mustermann@company.com>
|
||||
- Sandra Vogel <s.vogel@company.com>
|
||||
- Thomas Wolf <t.wolf@company.com>
|
||||
|
||||
_Sortiert nach E-Mail-Adresse. Erstellt: 2026-05-16 10:51_
|
||||
```
|
||||
|
||||
- Keine Nachrichten im Zeitfenster → Hinweis „Keine Chat-Aktivität in diesem Zeitfenster"
|
||||
- Nicht auflösbare E-Mails → Eintrag trotzdem aufgeführt, E-Mail als `<nicht auflösbar>`
|
||||
|
||||
---
|
||||
|
||||
## Technologie-Stack
|
||||
|
||||
| Komponente | Wahl |
|
||||
|---|---|
|
||||
| Sprache | Python 3.11+ |
|
||||
| Browser-Automation | Playwright (sync API) |
|
||||
| Cache | JSON-Datei (`~/.teampulse/cache.json`) |
|
||||
| Ausgabe | Markdown |
|
||||
| Plattform | Mac, Windows, Linux |
|
||||
|
||||
---
|
||||
|
||||
## Randfälle
|
||||
|
||||
| Situation | Verhalten |
|
||||
|---|---|
|
||||
| Session abgelaufen | Sichtbarer Browser für Re-Auth, danach wieder headless |
|
||||
| Profilkarte nicht ladbar | `<nicht auflösbar>`, kein Absturz |
|
||||
| Externer Gast | Als Gast markiert |
|
||||
| `!start` ohne Namen | Warnung + Platzhalter |
|
||||
| `!start` von anderem Nutzer | Ignoriert |
|
||||
| Seitenreload während Monitoring | Automatischer Reconnect, keine Datenverlust |
|
||||
| Keine Nachrichten im Fenster | Memo mit entsprechendem Hinweis |
|
||||
|
||||
---
|
||||
|
||||
## Nicht im Scope
|
||||
|
||||
- Graph API / Azure AD Integration
|
||||
- GUI / Web-Dashboard
|
||||
- Mehrere gleichzeitige Zeitfenster
|
||||
- Historische Chat-Auswertung (vergangene Meetings)
|
||||
Loading…
x
Reference in New Issue
Block a user