feat: rename CLAUDE.md to TalkTime, retro-document features, add PROJ-11 chat spec

- CLAUDE.md header/description now match actual project (TalkTime), not starter-kit template
- Retro-documented already-built MVP features as PROJ-1..PROJ-10 in features/INDEX.md
- Corrected PROJ-9: Matrix User Provisioning, room sync and reconciliation were already implemented, not just health-check
- Added PROJ-11 requirements spec for basic chat (Matrix Client-Server API, team scope, text-only MVP)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0143yYvjesjHndBACoweyK67
This commit is contained in:
patrickandClaude Sonnet 5 committed 2026-09-11 17:18:22 +02:00
1 parent 90669b4568
commit b1d662fa5b
13 files changed
+285 -3

No files matched your search

+2 -2
View File
@@ -1,6 +1,6 @@
# AI Coding Starter Kit # TalkTime
> A self-hosted Vite/React + Fastify template with an AI-powered development workflow using specialized skills for Requirements, Architecture, Frontend, Backend, QA, and Deployment. > Selbst hostbare, DSGVO-freundliche Kommunikations- und Verwaltungsplattform für Sportvereine (Matrix/Synapse-Backend). Vite/React + Fastify Stack mit KI-gestütztem Entwicklungsworkflow über spezialisierte Skills für Requirements, Architecture, Frontend, Backend, QA und Deployment.
## Tech Stack ## Tech Stack
+14 -1
View File
@@ -12,7 +12,20 @@
| ID | Feature | Status | Spec | Created | | ID | Feature | Status | Spec | Created |
|----|---------|--------|------|---------| |----|---------|--------|------|---------|
| PROJ-1 | Auth (Login/Logout/Session) | Deployed | [PROJ-1-auth.md](PROJ-1-auth.md) | 2026-09-11 |
| PROJ-2 | Verein anlegen + Vereinsadministrator | Deployed | [PROJ-2-verein-und-vereinsadministrator.md](PROJ-2-verein-und-vereinsadministrator.md) | 2026-09-11 |
| PROJ-3 | Mitgliederverwaltung | Deployed | [PROJ-3-mitgliederverwaltung.md](PROJ-3-mitgliederverwaltung.md) | 2026-09-11 |
| PROJ-4 | Abteilungsverwaltung | Deployed | [PROJ-4-abteilungsverwaltung.md](PROJ-4-abteilungsverwaltung.md) | 2026-09-11 |
| PROJ-5 | Mannschaftsverwaltung (inkl. Saison) | Deployed | [PROJ-5-mannschaftsverwaltung.md](PROJ-5-mannschaftsverwaltung.md) | 2026-09-11 |
| PROJ-6 | Rollen & Berechtigungen (RBAC) | Deployed | [PROJ-6-rollen-und-berechtigungen.md](PROJ-6-rollen-und-berechtigungen.md) | 2026-09-11 |
| PROJ-7 | Einladungssystem | Deployed | [PROJ-7-einladungssystem.md](PROJ-7-einladungssystem.md) | 2026-09-11 |
| 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 |
Noch nicht gestartet (siehe [docs/PRD.md](../docs/PRD.md) Core Features): Passwort-Reset, dedizierte Tenant-Isolation-Tests. P2 (Medien-Anhänge, Push) bewusst aus PROJ-11 ausgeklammert, siehe dessen Non-Goals.
<!-- Add features above this line --> <!-- Add features above this line -->
## Next Available ID: PROJ-1 ## Next Available ID: PROJ-12
+28
View File
@@ -0,0 +1,28 @@
# PROJ-1: Auth (Login/Logout/Session)
**Status:** Deployed
**Created:** 2026-09-11 (retro-dokumentiert, tatsächlich gebaut in commit 5e6ee2c)
## Summary
E-Mail/Passwort-Auth mit JWT-Session für TalkTime. Grundlage für alle geschützten Routen.
## Built
- `backend/src/routes/auth.ts` — Register/Login, bcrypt-Hash, JWT-Ausgabe, Rate-Limit auf Auth-Endpunkten
- `backend/src/types.d.ts` — JWT-Payload-Typisierung (`FastifyJWT`)
- `frontend/src/components/auth/LoginForm.tsx`, `RegisterForm.tsx`
- `frontend/src/pages/LoginPage.tsx`, `RegisterPage.tsx`
- `frontend/src/lib/auth-context.tsx` — Session-State im Frontend
- `frontend/src/routes/ProtectedRoute.tsx` — Redirect bei fehlender Session
## Acceptance Criteria
- [x] Registrierung mit E-Mail + Passwort, Passwort gehasht (bcrypt, Cost 12)
- [x] Login liefert JWT, generische Fehlermeldung bei falschen Zugangsdaten (kein User-Enumeration-Leak)
- [x] Geschützte Frontend-Routen leiten unauthentifizierte Nutzer zum Login um
- [x] Geschützte Backend-Routen verifizieren JWT via `request.jwtVerify()`
## Open Items
- Passwort-Reset (siehe PRD P0) noch nicht gebaut
- E-Mail-Verification laut PRD P1 noch offen
## Notes
Retro-Spec: Feature war bereits produktiv im Code, INDEX.md/Spec wurden nachträglich nachgezogen.
+20
View File
@@ -0,0 +1,20 @@
# PROJ-10: Deployment (Docker Compose + Synapse Installer)
**Status:** Deployed
**Created:** 2026-09-11 (retro-dokumentiert, gebaut in b5ac041, 51426a9, 90669b4)
## Summary
Deployment-Grundlage: Docker Compose für Backend/Frontend/Postgres, plus universelles `install.sh` für Synapse auf Bare-Metal/Proxmox-LXC.
## Built
- Docker Compose Setup für backend/frontend/postgres (b5ac041)
- Synapse-Doku bereinigt/gehärtet, Defaults sicherer (51426a9)
- `install.sh` für Synapse Bare-Metal/Proxmox-LXC (90669b4)
## Acceptance Criteria
- [x] `docker compose up` bringt Backend+Frontend+Postgres hoch
- [x] Synapse lässt sich per Skript auf separatem Host/LXC installieren (PRD-Constraint: Synapse separat betrieben)
- [x] Keine Secrets im Repo, Doku nutzt Platzhalter
## Notes
Retro-Spec. Eigentlicher `/deploy`-Skill-Workflow (git pull + rsync + systemd auf Produktivserver) noch nicht gegen echten Server verifiziert.
+46
View File
@@ -0,0 +1,46 @@
# PROJ-11: Chat (Matrix Client-Server API)
**Status:** Planned
**Created:** 2026-09-11
## Summary
Eigene Chat-Oberfläche für Team-Räume, die bereits über [[PROJ-9]] (Synapse-Integration) automatisch angelegt und mit Mitgliedern befüllt werden. Nutzer senden/lesen Nachrichten über die Matrix Client-Server API, ohne je ein eigenes Matrix-Passwort zu sehen. MVP: nur Text, kein Medien-Upload, kein Push (siehe Non-Goals).
## Dependencies
- Requires: [[PROJ-9]] (Synapse-Integration) — Matrix-User-Provisionierung und Team-Raum-Anlage müssen vor dem ersten Chat-Zugriff eines Mitglieds gelaufen sein
- Requires: [[PROJ-1]] (Auth) — TalkTime-Session/JWT identifiziert den Nutzer gegenüber dem Backend
- Requires: [[PROJ-5]] (Mannschaftsverwaltung) — Chat ist an Team-Zugehörigkeit gebunden
## User Stories
1. Als Team-Mitglied will ich im Team-Tab die aktuelle Konversation lesen, um informiert zu sein, ohne WhatsApp zu brauchen.
2. Als Team-Mitglied will ich eine Nachricht in den Team-Chat schreiben, die alle anderen Raum-Mitglieder sofort sehen.
3. Als neues Team-Mitglied will ich beim ersten Öffnen die volle bisherige Historie des Team-Chats sehen.
4. Als Mitglied ohne fertig provisionierten Matrix-Account will ich einen klaren Hinweis sehen ("Chat wird eingerichtet") statt eines Fehlers.
5. Als Trainer will ich sehen, wer meine Nachricht bereits gelesen hat (Lesebestätigung).
## Acceptance Criteria
- [ ] Chat erscheint als Tab in der bestehenden Team-Detailansicht (`TeamsPage`)
- [ ] Backend liefert pro angefragtem Nutzer ein Matrix-Access-Token (serverseitig via Admin-API geholt/gecacht), Frontend erhält nie Matrix-Passwort/Admin-Token
- [ ] Frontend nutzt Matrix Client-Server `/sync` (long-polling, z.B. via matrix-js-sdk) für eingehende Nachrichten — kein separater WebSocket-Server im TalkTime-Backend
- [ ] Alle Mitglieder eines Team-Raums können Text-Nachrichten senden (kein Rollen-Gate)
- [ ] Neues Raum-Mitglied sieht beim Beitritt die volle bisherige Historie (Room-History-Visibility entsprechend gesetzt beim Anlegen des Raums in [[PROJ-9]])
- [ ] Ungelesen-Zähler pro Raum sichtbar, Lesebestätigung (Read Receipts) wird über Matrix-Standard-Mechanismus übertragen
- [ ] Fehlt `members.matrixUserId` noch (Provisioning nicht durchgelaufen), zeigt UI "Chat wird eingerichtet" und pollt, statt Fehler zu werfen
- [ ] Kein Medien-Upload, kein Push in diesem Feature (siehe Non-Goals)
## Edge Cases
- Mitglied hat `matrixUserId = null` (Provisioning pending/failed) → Hinweis-Zustand statt Absturz, kein manueller Retry-Button im MVP
- Sync-Job `create_team_room` noch nicht gelaufen (Team gerade erst angelegt) → Chat-Tab zeigt "Raum wird eingerichtet", kein Nachrichtenverlauf
- Synapse nicht erreichbar (Health-Check negativ) → Chat-UI zeigt Verbindungsfehler, kein Retry-Loop, der Synapse flutet
- Nachricht senden schlägt fehl (z.B. Access-Token abgelaufen) → Backend holt Token neu, ein automatischer Retry, danach Fehleranzeige im Frontend
- Mitglied wird aus Team entfernt während Chat offen ist → nächster `/sync` liefert Room-Leave-Event, Frontend entfernt Raum aus Liste
- Sehr lange Historie (viele hundert Nachrichten) → Pagination/Backfill über Matrix `/messages`-Endpunkt, nicht alles auf einmal laden
## Non-Goals (für dieses Feature)
- Medien-Anhänge (Bilder/Dateien) — eigenes P2-Feature laut PRD
- Push-Benachrichtigungen — eigenes P2-Feature laut PRD
- Abteilungs-weite Chats (`chat_rooms.scope='department'`) — nur Team-Scope im MVP
- Nachrichten löschen/bearbeiten, Reactions, Threads
## 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.
@@ -0,0 +1,24 @@
# PROJ-2: Verein anlegen + Vereinsadministrator
**Status:** Deployed
**Created:** 2026-09-11 (retro-dokumentiert, gebaut in commit 5e6ee2c)
## Summary
Anlage einer Vereins-Organisation (Tenant) samt Vereinsadministrator (CLUB_ADMIN), inkl. Umschalten zwischen mehreren Vereinen für Nutzer mit mehreren Mitgliedschaften.
## Built
- `backend/src/routes/organizations.ts`
- `frontend/src/components/dashboard/CreateOrganizationForm.tsx`
- `frontend/src/components/dashboard/OrganizationSwitcher.tsx`
- `frontend/src/lib/organization-context.tsx`
## Acceptance Criteria
- [x] Nutzer kann neuen Verein anlegen und wird automatisch CLUB_ADMIN
- [x] Multi-Tenant: ein Nutzer kann Mitglied mehrerer Vereine sein, Frontend erlaubt Wechsel
- [x] Tenant-Isolation in Route-Handlern geprüft (kein DB-RLS-Backstop, siehe `.claude/rules/security.md`)
## Open Items
- Dedizierte Tenant-Isolation-Sicherheitstests (PRD-Erfolgsmetrik: 0 Cross-Club-Vorfälle) noch nicht als QA-Suite gebaut
## Notes
Retro-Spec.
+23
View File
@@ -0,0 +1,23 @@
# PROJ-3: Mitgliederverwaltung
**Status:** Deployed
**Created:** 2026-09-11 (retro-dokumentiert, gebaut in 5e6ee2c + b38a5a4)
## Summary
Mitglieder eines Vereins verwalten: Liste, Status-Aktionen (aktivieren/deaktivieren), Anbindung an Matrix-Membership-Sync (deaktivierte Mitglieder werden aus Matrix-Räumen entfernt).
## Built
- `backend/src/routes/members.ts`
- `frontend/src/pages/MembersPage.tsx`
- Mitglied-Status-Aktionen + Deaktivierungs-Sync (commit b38a5a4)
## Acceptance Criteria
- [x] Mitgliederliste pro Verein abrufbar (paginiert)
- [x] Status ändern (aktiv/inaktiv) durch berechtigte Rollen
- [x] Deaktivierung löst Sync-Schritt Richtung Matrix aus
## Open Items
- Vollständige Membership-Sync mit Outbox/Retry/Reconciliation laut PRD noch nicht fertig — aktuell nur direkter Sync-Aufruf, kein Retry-Mechanismus geprüft
## Notes
Retro-Spec.
+18
View File
@@ -0,0 +1,18 @@
# PROJ-4: Abteilungsverwaltung
**Status:** Deployed
**Created:** 2026-09-11 (retro-dokumentiert, gebaut in 5e6ee2c)
## Summary
Abteilungen innerhalb eines Vereins anlegen/verwalten (z.B. Fußball, Handball) als Strukturebene über Mannschaften.
## Built
- `backend/src/routes/departments.ts`
- `frontend/src/pages/DepartmentsPage.tsx`
## Acceptance Criteria
- [x] Abteilungen anlegen/auflisten pro Verein
- [x] Zugriff auf Abteilungsdaten tenant-isoliert
## Notes
Retro-Spec.
+20
View File
@@ -0,0 +1,20 @@
# PROJ-5: Mannschaftsverwaltung (inkl. Saison)
**Status:** Deployed
**Created:** 2026-09-11 (retro-dokumentiert, gebaut in 5e6ee2c)
## Summary
Mannschaften pro Abteilung, gebunden an Saisons.
## Built
- `backend/src/routes/teams.ts`
- `backend/src/routes/seasons.ts`
- `frontend/src/pages/TeamsPage.tsx`
## Acceptance Criteria
- [x] Mannschaft einer Abteilung + Saison zuordnen
- [x] Saison anlegen/verwalten
- [x] Mannschaftsliste im Frontend
## Notes
Retro-Spec.
@@ -0,0 +1,21 @@
# PROJ-6: Rollen & Berechtigungen (RBAC)
**Status:** Deployed
**Created:** 2026-09-11 (retro-dokumentiert, gebaut in 5e6ee2c + b38a5a4)
## Summary
Rollenmodell (CLUB_ADMIN, Trainer, Co-Trainer, Betreuer, Mitglied, ...) und Rechteverwaltung pro Verein/Mannschaft.
## Built
- `backend/src/routes/roles.ts`
- `frontend/src/pages/RolesPage.tsx` (inkl. UI-Erweiterung aus b38a5a4)
## Acceptance Criteria
- [x] Rollen einem Mitglied zuweisen/entziehen
- [x] Rollenprüfung in geschützten Route-Handlern (kein RLS-Backstop)
## Open Items
- CLUB_MANAGER, PARENT, ASSISTANT_COACH, SUPERVISOR als eigene Rollen laut PRD P1 noch nicht vollständig
## Notes
Retro-Spec.
+20
View File
@@ -0,0 +1,20 @@
# PROJ-7: Einladungssystem
**Status:** Deployed
**Created:** 2026-09-11 (retro-dokumentiert, gebaut in 5e6ee2c)
## Summary
Mitglieder per Einladungslink zu einem Verein hinzufügen, ohne dass Telefonnummern nötig sind (DSGVO-Ziel).
## Built
- `backend/src/routes/invitations.ts` (245 Zeilen — größte Route, Token-Handling + Annahme-Flow)
- `frontend/src/components/dashboard/InviteMemberForm.tsx`
- `frontend/src/pages/AcceptInvitationPage.tsx`
## Acceptance Criteria
- [x] Admin/Trainer kann Einladung mit E-Mail versenden
- [x] Einladungslink mit Token, Annahme-Seite erstellt Account + Mitgliedschaft
- [x] Abgelaufene/ungültige Tokens werden abgelehnt
## Notes
Retro-Spec.
+18
View File
@@ -0,0 +1,18 @@
# PROJ-8: Audit Log
**Status:** Deployed
**Created:** 2026-09-11 (retro-dokumentiert, gebaut in 5e6ee2c + b38a5a4)
## Summary
Protokollierung sicherheits-/verwaltungsrelevanter Aktionen (Rollenänderung, Mitglieder-Status, Einladungen) pro Verein.
## Built
- `backend/src/routes/audit.ts`
- `frontend/src/pages/AuditLogPage.tsx` (UI aus b38a5a4)
## Acceptance Criteria
- [x] Audit-Einträge pro Verein abrufbar (tenant-isoliert)
- [x] Relevante Admin-Aktionen erzeugen Log-Eintrag
## Notes
Retro-Spec.
@@ -0,0 +1,31 @@
# PROJ-9: Synapse-Integration (Health Check, User Provisioning, Raum-Sync)
**Status:** Deployed
**Created:** 2026-09-11 (retro-dokumentiert, gebaut in 5e6ee2c; Korrektur 2026-09-11 — Provisioning/Sync war bereits gebaut, initiale Retro-Doku war unvollständig)
## Summary
Vollständige Synapse-Anbindung: Health-Check, automatische Matrix-User-Provisionierung bei Einladungsannahme, automatische Team-Raum-Anlage/-Zuordnung, Mitgliederstatus-Sync über Outbox-Queue mit Retry+Backoff, periodische Reconciliation. Admin-Token bleibt serverseitig (PRD-Constraint).
## Built
- `backend/src/services/synapse.ts` — Synapse Admin/Client-API-Wrapper (`healthCheck`, `createUser`, `getUser`, `deactivateUser`, `reactivateUser`, `createRoom`, `addUserToRoom`, `removeUserFromRoom`)
- `backend/src/services/sync-worker.ts` — Outbox-Queue (`sync_jobs`-Tabelle) mit vier Jobtypen (`provision_matrix_user`, `create_team_room`, `join_team_room`, `leave_team_room`), exponentiellem Backoff (1min→30min, max. 5 Versuche), 30s-Poll-Worker, `runReconciliation()` alle 10min (vergleicht lokalen Mitgliederstatus gegen Synapse, loggt Abweichungen in Audit-Log statt automatisch zu korrigieren)
- `backend/src/routes/synapse.ts` — `GET /api/synapse/health`
- Trigger-Stellen: `backend/src/routes/invitations.ts` (Provisionierung bei Einladungsannahme), `backend/src/routes/teams.ts` (Raum-Anlage + Join/Leave bei Team-Zuordnung)
- Schema: `members.matrixUserId`, `chat_rooms` (matrixRoomId, scope, department/team-Zuordnung), `sync_jobs` (status/attempts/lastError)
## Acceptance Criteria
- [x] Backend kann Synapse-Erreichbarkeit prüfen
- [x] Synapse Admin Token verlässt Backend nie
- [x] Neues Mitglied bekommt bei Einladungsannahme automatisch Matrix-Account (Localpart-Kollision wird durch Suffix aufgelöst)
- [x] Neue Mannschaft bekommt automatisch Matrix-Raum
- [x] Mitglied wird bei Team-Zuordnung automatisch in Raum aufgenommen/entfernt
- [x] Fehlgeschlagene Sync-Jobs werden mit Backoff wiederholt (max. 5 Versuche, dann `failed`)
- [x] Reconciliation-Job erkennt Abweichungen zwischen TalkTime- und Synapse-Status
## Open Items
- Grundlegender Chat (eigene Oberfläche via Matrix Client-Server API, Nachrichten senden/lesen) — **noch nicht gebaut**, siehe [[PROJ-11]]
- Manueller Resync-Trigger in der UI bei erkannten Reconciliation-Abweichungen (PRD P1) fehlt noch
- Abteilungs-weite Räume (`chat_rooms.scope`) — Schema unterstützt es, Provisionierungs-Logik existiert bisher nur für `team`-Scope
## Notes
Korrigierte Retro-Spec. Ursprüngliche Version dieser Datei unterschätzte den Baufortschritt — Provisioning/Raum-Sync/Reconciliation liefen bereits produktiv.