From 8b6114c3e84abef819f114e480d095584edb1f91 Mon Sep 17 00:00:00 2001 From: patrick Date: Fri, 11 Sep 2026 18:52:39 +0200 Subject: [PATCH] docs(PROJ-11): add technical design for chat feature Direct browser-to-Synapse connection via matrix-js-sdk, backend only mints a short-lived per-member access token (no chat proxy, no new WebSocket server, no new DB table). Status set to In Progress. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_0143yYvjesjHndBACoweyK67 --- features/INDEX.md | 2 +- features/PROJ-11-chat.md | 46 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/features/INDEX.md b/features/INDEX.md index a53ceec..36f4da5 100644 --- a/features/INDEX.md +++ b/features/INDEX.md @@ -22,7 +22,7 @@ | PROJ-8 | Audit Log | Deployed | [PROJ-8-audit-log.md](PROJ-8-audit-log.md) | 2026-09-11 | | PROJ-9 | Synapse-Integration (Health Check, User Provisioning, Raum-Sync) | Deployed | [PROJ-9-synapse-integration-health-check.md](PROJ-9-synapse-integration-health-check.md) | 2026-09-11 | | PROJ-10 | Deployment (Docker Compose + Synapse Installer) | Deployed | [PROJ-10-deployment.md](PROJ-10-deployment.md) | 2026-09-11 | -| PROJ-11 | Chat (Matrix Client-Server API) | Planned | [PROJ-11-chat.md](PROJ-11-chat.md) | 2026-09-11 | +| PROJ-11 | Chat (Matrix Client-Server API) | In Progress | [PROJ-11-chat.md](PROJ-11-chat.md) | 2026-09-11 | | PROJ-12 | Automatische Löschfrist für ausgetretene Mitglieder (DSGVO) | Planned | [PROJ-12-mitglieder-loeschfrist.md](PROJ-12-mitglieder-loeschfrist.md) | 2026-09-11 | Noch nicht gestartet (siehe [docs/PRD.md](../docs/PRD.md) Core Features): dedizierte Tenant-Isolation-Tests. P2 (Medien-Anhänge, Push) bewusst aus PROJ-11 ausgeklammert, siehe dessen Non-Goals. diff --git a/features/PROJ-11-chat.md b/features/PROJ-11-chat.md index 16a1bbe..79e703e 100644 --- a/features/PROJ-11-chat.md +++ b/features/PROJ-11-chat.md @@ -44,3 +44,49 @@ Eigene Chat-Oberfläche für Team-Räume, die bereits über [[PROJ-9]] (Synapse- ## Notes Matrix-Access-Token-Handling ist sicherheitsrelevant (Token-Mapping TalkTime-User → Matrix-User) — Architektur-Skill sollte hier besonders auf Token-Lifetime, Caching-Ort (nicht im Frontend!) und Re-Auth-Flow eingehen. `backend-security-coder`/`frontend-security-coder`-Subagenten bei der Umsetzung hinzuziehen. + +## Tech Design (Solution Architect) + +### A) Komponenten-Struktur + +``` +TeamsPage (bestehend) +└── Team-Detailansicht (bestehend, wird um Tabs erweitert) + ├── Tab "Übersicht" (bestehend, unverändert) + └── Tab "Chat" (NEU) + ├── Verbindungshinweis + │ ("Chat wird eingerichtet" | "Raum wird eingerichtet" | Verbindungsfehler) + ├── Nachrichtenliste + │ ├── Nachrichten-Gruppen nach Tag + │ ├── Einzelne Nachricht (Absender, Zeit, Text) + │ └── Lesebestätigungs-Anzeige ("gelesen von: …") + ├── Verlauf-Nachladen ("Ältere Nachrichten laden", beim Hochscrollen) + └── Eingabefeld + Senden-Button +``` + +Der Chat-Tab ist nur sichtbar/aktiv, wenn ein Team ausgewählt ist. Ungelesen-Zähler erscheint zusätzlich als kleines Badge auf der Team-Kachel/dem Tab selbst, damit Mitglieder neue Nachrichten auch außerhalb des offenen Chats bemerken. + +### B) Datenfluss (in einfachen Worten) + +TalkTime-Backend und Browser haben hier unterschiedliche Aufgaben: + +1. **Backend (einmalig pro Sitzung):** Wenn der Chat-Tab geöffnet wird, fragt der Browser das TalkTime-Backend: "Gib mir Zugang zum Matrix-Chat." Das Backend prüft die normale TalkTime-Anmeldung (JWT), schaut nach, ob für dieses Mitglied schon ein Matrix-Konto existiert, und besorgt sich von Synapse — mit dem streng geheimen Admin-Zugang, der nie den Server verlässt — einen zeitlich befristeten Zugangsschlüssel *für genau dieses eine Mitglied*. Diesen Schlüssel bekommt der Browser, nicht den Admin-Zugang. +2. **Browser (laufend):** Mit diesem Schlüssel spricht der Browser direkt mit dem Matrix-Server (Synapse) — Nachrichten senden, neue Nachrichten empfangen (durch ständiges "gibt's was Neues?"-Nachfragen, das ist der Matrix-Standardmechanismus), Lesebestätigungen senden. Das TalkTime-Backend ist an diesem laufenden Austausch nicht mehr beteiligt und sieht die Nachrichteninhalte nicht — das passt zur Vorgabe, keine Nachrichteninhalte in der TalkTime-Datenbank zu speichern. +3. **Läuft der Zugangsschlüssel ab:** Der Browser merkt das am nächsten fehlgeschlagenen Versuch, fragt automatisch einen neuen beim Backend an und macht weiter — für das Mitglied unsichtbar, außer der allererste Versuch schlägt fehl (dann Fehleranzeige). + +Kein neuer Datenspeicher in der TalkTime-Datenbank nötig — Mitglied-zu-Matrix-Zuordnung existiert bereits (`matrixUserId` aus [[PROJ-9]]), Nachrichten selbst liegen ausschließlich bei Synapse. + +### C) Tech-Entscheidungen (Begründung) + +- **Direkte Verbindung Browser ↔ Synapse statt Umweg über TalkTime-Backend:** Das TalkTime-Backend müsste sonst für jeden gleichzeitig aktiven Chat eine eigene Dauerverbindung zu Synapse offenhalten — das skaliert schlecht und macht das Backend zum Nadelöhr. Bei einer direkten Verbindung übernimmt Synapse selbst diese Last, wofür es gebaut ist. +- **Offizielle Matrix-Client-Bibliothek (matrix-js-sdk) statt Marke-Eigenbau:** Nachrichten-Abgleich, "was ist neu"-Erkennung und Lesebestätigungen nach Matrix-Standard sind fummelig selbst zu bauen und fehleranfällig. Die Bibliothek ist der De-facto-Standard für genau diesen Zweck. +- **Zugangsschlüssel wird vom Backend ausgestellt, nie ein Matrix-Passwort:** Mitglieder haben laut PRD kein eigenes Matrix-Passwort (DSGVO-Ziel: kein zusätzliches Konto-Geheimnis). Das Backend nutzt seinen Admin-Zugang, um im Namen des Mitglieds einen befristeten Schlüssel zu erzeugen, ohne ein Passwort zu kennen oder zu speichern. +- **Kein eigener Push-/WebSocket-Server:** Für "grundlegenden Chat" reicht der Matrix-Standardmechanismus; ein eigener Echtzeit-Server wäre zusätzlicher Betriebsaufwand ohne Mehrwert in diesem Umfang. + +### D) Abhängigkeiten (neue Pakete) + +- **Frontend:** `matrix-js-sdk` — offizielle Matrix-Client-Bibliothek, übernimmt Verbindungsaufbau, Nachrichtenabgleich, Lesebestätigungen +- **Backend:** keine neuen Pakete — nutzt die bereits vorhandene Synapse-Anbindung aus [[PROJ-9]] + +### Offene Infrastruktur-Voraussetzung +Damit der Browser Synapse direkt erreichen kann, muss der Matrix-Server auch außerhalb des internen Netzes (bzw. für alle Nutzer-Endgeräte) erreichbar sein, inklusive TLS — aktuell (Testaufbau) läuft Synapse nur auf der internen LXC-IP ohne TLS. Das ist eine Deployment-Voraussetzung für den produktiven Einsatz dieses Features, keine Backend-/Frontend-Codeänderung.