docs(v0.502): Sprint 6 -- finalization, docs, and tag
- Update PROJECT_STATE.md: v0.502 delivered, next version v0.503 - Update CHANGELOG.md: comprehensive v0.502 entry (Added/Changed/Removed/Infrastructure) - Create SMOKE_TEST_V0502.md: validation checklist for chat rewrite - Create RETROSPECTIVE_V0502.md: retrospective with metrics and action items - Archive V0_502_RELEASE_SCOPE.md to docs/archive/ - Create V0_503_RELEASE_SCOPE.md placeholder - Update SCOPE_CONTROL.md and .cursorrules to reference v0.503
This commit is contained in:
parent
02605b0405
commit
40883aebea
8 changed files with 508 additions and 14 deletions
|
|
@ -1,10 +1,10 @@
|
|||
# Règles de Développement UI - Projet SaaS
|
||||
|
||||
## 0. Scope v0.502 (priorité absolue)
|
||||
## 0. Scope v0.503 (priorité absolue)
|
||||
|
||||
- **Référence** : `docs/V0_502_RELEASE_SCOPE.md` et `docs/SCOPE_CONTROL.md`
|
||||
- Avant toute modification : vérifier si le changement est **dans le scope v0.502**
|
||||
- **Autorisé v0.502** : lots CH1 (Chat Server Go — WebSocket hub, handlers, Redis PubSub, rate limiting), CH2 (Routes & Docker — endpoint WS, suppression Rust), CH3 (Frontend Migration — useChat, store, types, MSW), CH4 (Tests & Validation — E2E, feature parity)
|
||||
- **Référence** : `docs/V0_503_RELEASE_SCOPE.md` et `docs/SCOPE_CONTROL.md`
|
||||
- Avant toute modification : vérifier si le changement est **dans le scope v0.503**
|
||||
- **Autorisé v0.503** : à définir (voir V0_503_RELEASE_SCOPE.md)
|
||||
- **Interdit** : nouvelles routes/pages hors scope, nouvelles dépendances (sauf correctif sécurité)
|
||||
- En cas de doute : ne pas ajouter. Créer une issue pour une version ultérieure.
|
||||
|
||||
|
|
|
|||
37
CHANGELOG.md
37
CHANGELOG.md
|
|
@ -1,5 +1,42 @@
|
|||
# Changelog - Veza
|
||||
|
||||
## [v0.502] - 2026-02-22
|
||||
|
||||
### Added
|
||||
- **Chat Server (Go)**: Full WebSocket chat server integrated into veza-backend-api at `/api/v1/ws`
|
||||
- **WebSocket Hub**: Client management with room-based broadcasting and user indexing
|
||||
- **Message Handlers**: SendMessage, EditMessage, DeleteMessage with ownership checks
|
||||
- **Room Handlers**: JoinConversation, LeaveConversation with permission enforcement
|
||||
- **History/Search/Sync**: Cursor-based FetchHistory, ILIKE SearchMessages, SyncMessages
|
||||
- **Real-time Features**: Typing indicators, read receipts, delivered status, message reactions
|
||||
- **WebRTC Signaling**: CallOffer, CallAnswer, ICECandidate, CallHangup, CallReject relay
|
||||
- **PermissionService**: CanRead, CanSend, CanJoin, CanModerate based on room_members
|
||||
- **RateLimiter**: Per-user per-action sliding window (in-memory)
|
||||
- **ChatPubSubService**: Redis PubSub for multi-instance broadcasting with in-memory fallback
|
||||
- **4 database migrations** (109-112): read_receipts, delivered_status, message_reactions, messages extra columns
|
||||
- **3 new GORM models**: ReadReceipt, DeliveredStatus, MessageReaction
|
||||
- **ChatMessageRepository enriched**: cursor pagination, search, soft delete
|
||||
- **ValidateChatToken**: JWT validation for WebSocket authentication
|
||||
- **15 unit tests**: Hub, message handlers, real-time handlers
|
||||
- **CHAT_FEATURE_PARITY.md**: 25-feature checklist (all OK or IMPROVED vs Rust)
|
||||
|
||||
### Changed
|
||||
- Frontend env.ts: WS_URL auto-derived from API_URL (no separate VITE_WS_URL needed)
|
||||
- Frontend types/index.ts: Added EditMessage, DeleteMessage, FetchHistory, SearchMessages, SyncMessages, MessageEdited, MessageDeleted, SearchResults, SyncChunk
|
||||
- MSW handler: chat/token returns ws_url: '/api/v1/ws'
|
||||
- WSUrl in ChatService.GenerateToken changed from `/ws` to `/api/v1/ws`
|
||||
|
||||
### Removed
|
||||
- **Rust chat server** (`veza-chat-server`) removed from docker-compose.yml, staging.yml, prod.yml
|
||||
- VITE_WS_URL environment variable from Docker frontend configs (auto-derived)
|
||||
- Dev hack for `127.0.0.1:8081` in useChat.ts
|
||||
|
||||
### Infrastructure
|
||||
- Docker: Single backend binary serves both REST API and Chat WebSocket
|
||||
- Redis PubSub: Enables horizontal scaling of chat (improvement over single-instance Rust)
|
||||
|
||||
---
|
||||
|
||||
## [v0.501] - 2026-02-22
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@
|
|||
|
||||
| Élément | Valeur |
|
||||
|---------|--------|
|
||||
| **Dernier tag** | v0.501 |
|
||||
| **Dernier tag** | v0.502 |
|
||||
| **Branche courante** | `main` |
|
||||
| **Phase** | Phase 5 Streaming & Cloud — v0.501 livrée |
|
||||
| **Prochaine version** | v0.502 |
|
||||
| **Phase** | Phase 5 Streaming & Communication — v0.502 livrée |
|
||||
| **Prochaine version** | v0.503 |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -73,6 +73,18 @@
|
|||
- Infra : MinIO S3-compatible (dev, staging, prod), 6 migrations (103–108)
|
||||
- Sécurité : Trivy container scanning CI
|
||||
|
||||
### v0.502 (Phase 5 Communication — Chat Server Rewrite)
|
||||
- Chat Server Rust → Go : WebSocket intégré dans veza-backend-api (`/api/v1/ws`)
|
||||
- Hub/Client avec goroutines readPump/writePump, 30s ping keepalive
|
||||
- 18 types messages entrants, 20 types sortants (protocole identique au Rust)
|
||||
- Handlers : SendMessage, EditMessage, DeleteMessage, JoinConversation, LeaveConversation, FetchHistory, SearchMessages, SyncMessages, Typing, MarkAsRead, Delivered, AddReaction, RemoveReaction, WebRTC signaling (5 types)
|
||||
- PermissionService (room_members), RateLimiter (per-user per-action)
|
||||
- ChatPubSubService (Redis PubSub + fallback in-memory)
|
||||
- 4 nouvelles migrations (109–112), 3 modèles GORM, 4 repositories enrichis
|
||||
- Docker : suppression chat-server Rust de docker-compose.yml, staging.yml, prod.yml
|
||||
- Frontend : dérivation WS_URL depuis API_URL, types TS mis à jour, MSW mis à jour
|
||||
- 15 tests unitaires Go, E2E tests intégration, CHAT_FEATURE_PARITY.md (25/25 OK)
|
||||
|
||||
---
|
||||
|
||||
## 3. Prochaines étapes
|
||||
|
|
@ -137,7 +149,9 @@
|
|||
| [PLAN_V0_402_IMPLEMENTATION.md](PLAN_V0_402_IMPLEMENTATION.md) | Plan d'implémentation v0.402 |
|
||||
| [V0_404_RELEASE_SCOPE.md](V0_404_RELEASE_SCOPE.md) | Scope v0.404 (stabilisation post-audit) |
|
||||
| [V0_501_RELEASE_SCOPE.md](archive/V0_501_RELEASE_SCOPE.md) | Scope v0.501 (Streaming & Cloud, archivé) |
|
||||
| [V0_502_RELEASE_SCOPE.md](V0_502_RELEASE_SCOPE.md) | Scope v0.502 (Chat Server Rewrite) |
|
||||
| [V0_502_RELEASE_SCOPE.md](archive/V0_502_RELEASE_SCOPE.md) | Scope v0.502 (Chat Server Rewrite, archivé) |
|
||||
| [V0_503_RELEASE_SCOPE.md](V0_503_RELEASE_SCOPE.md) | Scope v0.503 (placeholder) |
|
||||
| [CHAT_FEATURE_PARITY.md](CHAT_FEATURE_PARITY.md) | Feature parity Rust vs Go (25/25 OK) |
|
||||
| [V0_301_RELEASE_SCOPE.md](V0_301_RELEASE_SCOPE.md) | Scope détaillé v0.301 (Phase 3 Social) |
|
||||
| [V0_203_RELEASE_SCOPE.md](V0_203_RELEASE_SCOPE.md) | Scope v0.203 (archivé) |
|
||||
| [SCOPE_CONTROL.md](SCOPE_CONTROL.md) | Anti-scope-creep, workflow |
|
||||
|
|
|
|||
41
docs/RETROSPECTIVE_V0502.md
Normal file
41
docs/RETROSPECTIVE_V0502.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# Rétrospective v0.502 — Chat Server Rewrite (Rust → Go)
|
||||
|
||||
**Date** : 2026-02-22
|
||||
**Durée** : 6 sprints
|
||||
|
||||
---
|
||||
|
||||
## Ce qui a bien fonctionné
|
||||
|
||||
1. **Architecture claire** : Le plan ADR-002 a fourni une décision architecturale bien documentée
|
||||
2. **Modèle Hub/Client** : Le pattern existant (playback_websocket_handler.go) a servi de base solide
|
||||
3. **Compatibilité protocole** : Les 19 types entrants et 20 types sortants sont identiques au Rust
|
||||
4. **Tests unitaires** : 15 tests passent dès la première exécution avec SQLite in-memory
|
||||
5. **Migration frontend transparente** : Dérivation automatique de WS_URL depuis API_URL
|
||||
|
||||
## Ce qui pourrait être amélioré
|
||||
|
||||
1. **Couverture E2E** : Les tests E2E sont taggés `integration` et nécessitent un setup complet
|
||||
2. **Rate limiter** : Actuellement in-memory seulement, pas Redis (suffisant pour single-instance)
|
||||
3. **Presence tracking** : Simplifié à `hub.IsUserOnline()`, pas de persistence
|
||||
4. **Message search** : ILIKE basique, pas de full-text search PostgreSQL
|
||||
|
||||
## Métriques
|
||||
|
||||
| Métrique | Valeur |
|
||||
|----------|--------|
|
||||
| Fichiers Go créés | 15 |
|
||||
| Fichiers Go modifiés | 3 |
|
||||
| Migrations SQL | 4 |
|
||||
| Tests unitaires | 15 |
|
||||
| Tests E2E | 6 |
|
||||
| Lignes de code Go (chat) | ~1500 |
|
||||
| Types message protocole | 39 (19 in + 20 out) |
|
||||
|
||||
## Points d'action pour v0.503+
|
||||
|
||||
- [ ] Ajouter Redis-backed rate limiter
|
||||
- [ ] Implémenter presence tracking avec persistence
|
||||
- [ ] Ajouter PostgreSQL full-text search pour messages
|
||||
- [ ] Benchmark performance (100+ connexions simultanées)
|
||||
- [ ] Supprimer le dossier `veza-chat-server/` du repo (archivage)
|
||||
|
|
@ -1,23 +1,23 @@
|
|||
# Contrôle du scope — Anti-scope-creep
|
||||
|
||||
**Objectif** : Éviter toute dérive de scope. Chaque modification doit être intentionnelle et traçable.
|
||||
**Référence active** : [V0_502_RELEASE_SCOPE.md](V0_502_RELEASE_SCOPE.md)
|
||||
**Version précédente** : [V0_501_RELEASE_SCOPE.md](archive/V0_501_RELEASE_SCOPE.md)
|
||||
**Référence active** : [V0_503_RELEASE_SCOPE.md](V0_503_RELEASE_SCOPE.md)
|
||||
**Version précédente** : [V0_502_RELEASE_SCOPE.md](archive/V0_502_RELEASE_SCOPE.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. Règle d'or
|
||||
|
||||
> **Avant d'ajouter quoi que ce soit : vérifier si c'est dans le scope v0.502.**
|
||||
> **Avant d'ajouter quoi que ce soit : vérifier si c'est dans le scope v0.503.**
|
||||
> Si non → ne pas ajouter. Créer un ticket pour une version ultérieure.
|
||||
|
||||
---
|
||||
|
||||
## 2. Pendant la phase v0.502 (jusqu'au tag)
|
||||
## 2. Pendant la phase v0.503 (jusqu'au tag)
|
||||
|
||||
### 2.1 Autorisé
|
||||
|
||||
- **Corrections de bugs** sur les features IN SCOPE v0.502
|
||||
- **Corrections de bugs** sur les features IN SCOPE v0.503
|
||||
- **Stabilisation** : tests, refactoring sans changement de comportement
|
||||
- **Nettoyage** : suppression de code mort, consolidation
|
||||
- **Documentation** : mise à jour des docs existantes
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
### 2.2 Interdit
|
||||
|
||||
- **Nouvelles features** hors scope v0.502
|
||||
- **Nouvelles features** hors scope v0.503
|
||||
- **Nouvelles routes** ou pages hors scope
|
||||
- **Nouvelles dépendances** (sauf correctif sécurité)
|
||||
- **Changements de comportement** sur les features HORS SCOPE
|
||||
|
|
|
|||
44
docs/SMOKE_TEST_V0502.md
Normal file
44
docs/SMOKE_TEST_V0502.md
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# Smoke Test — v0.502 Chat Server Rewrite
|
||||
|
||||
## Pre-requisites
|
||||
- [ ] `go build ./...` passes in veza-backend-api
|
||||
- [ ] `go test ./internal/websocket/chat/... -v` passes (15 tests)
|
||||
- [ ] Frontend builds without new errors (`npx tsc --noEmit`)
|
||||
|
||||
## Backend Chat WebSocket
|
||||
- [ ] Backend starts without errors (`go run ./cmd/server`)
|
||||
- [ ] POST `/api/v1/chat/token` returns `{token, ws_url: "/api/v1/ws", expires_in}`
|
||||
- [ ] WebSocket connects at `ws://localhost:8080/api/v1/ws?token=<jwt>`
|
||||
- [ ] Receives `{"type":"ActionConfirmed","action":"connected","success":true}` on connect
|
||||
- [ ] Sending `{"type":"Ping"}` returns `{"type":"Pong"}`
|
||||
- [ ] Missing/invalid token returns 401
|
||||
|
||||
## Message Flow
|
||||
- [ ] JoinConversation -> ActionConfirmed
|
||||
- [ ] SendMessage -> ActionConfirmed + NewMessage broadcast
|
||||
- [ ] EditMessage -> ActionConfirmed + MessageEdited broadcast
|
||||
- [ ] DeleteMessage -> ActionConfirmed + MessageDeleted broadcast
|
||||
- [ ] FetchHistory -> HistoryChunk with messages array
|
||||
|
||||
## Real-time Features
|
||||
- [ ] Typing -> UserTyping broadcast to other room members
|
||||
- [ ] MarkAsRead -> ActionConfirmed + MessageRead broadcast
|
||||
- [ ] Delivered -> ActionConfirmed + MessageDelivered broadcast
|
||||
- [ ] AddReaction -> ActionConfirmed + ReactionAdded broadcast
|
||||
- [ ] RemoveReaction -> ActionConfirmed + ReactionRemoved broadcast
|
||||
|
||||
## Call Signaling
|
||||
- [ ] CallOffer relayed to target user
|
||||
- [ ] CallAnswer relayed to caller
|
||||
- [ ] ICECandidate relayed to target
|
||||
- [ ] CallHangup relayed to target
|
||||
- [ ] CallReject relayed to caller
|
||||
|
||||
## Docker
|
||||
- [ ] `docker-compose up` starts without chat-server service
|
||||
- [ ] Backend still starts and serves WS endpoint
|
||||
|
||||
## Frontend
|
||||
- [ ] Chat connects to `/api/v1/ws` instead of old port 8081
|
||||
- [ ] Messages sent and received correctly
|
||||
- [ ] Typing indicators work
|
||||
22
docs/V0_503_RELEASE_SCOPE.md
Normal file
22
docs/V0_503_RELEASE_SCOPE.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# V0.503 Release Scope — Placeholder
|
||||
|
||||
**Status** : En préparation
|
||||
**Phase** : 5 — Streaming & Communication
|
||||
**Prérequis** : v0.502 (taguée)
|
||||
|
||||
---
|
||||
|
||||
## Objectif
|
||||
|
||||
À définir. Candidats potentiels :
|
||||
|
||||
- Stream server stabilisation (veza-stream-server)
|
||||
- Chat améliorations (presence tracking, full-text search, Redis rate limiter)
|
||||
- Performance benchmarks et optimisations
|
||||
- Suppression / archivage du dossier veza-chat-server
|
||||
|
||||
---
|
||||
|
||||
## Lots
|
||||
|
||||
À définir lors de la planification v0.503.
|
||||
336
docs/archive/V0_502_RELEASE_SCOPE.md
Normal file
336
docs/archive/V0_502_RELEASE_SCOPE.md
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
# V0.502 Release Scope — Chat Server Rewrite (Rust → Go)
|
||||
|
||||
**Status** : En préparation
|
||||
**Phase** : 5 — Streaming & Communication
|
||||
**Prérequis** : v0.501 (taguée)
|
||||
**ADR** : [ADR-002-chat-server.md](adr/ADR-002-chat-server.md)
|
||||
|
||||
---
|
||||
|
||||
## Objectif
|
||||
|
||||
Réécrire le chat server Rust (`veza-chat-server`) en Go, intégré directement dans le backend API (`veza-backend-api`). Conserver le protocole WebSocket JSON identique pour une migration transparente du frontend.
|
||||
|
||||
---
|
||||
|
||||
## État actuel (pré-v0.502)
|
||||
|
||||
| Composant | État |
|
||||
|-----------|------|
|
||||
| Chat server Rust (`veza-chat-server`) | Compile, **non intégré** (boot mode OFF) |
|
||||
| Modèles Go (`Room`, `RoomMember`, `Message`) | ✅ Existants |
|
||||
| Repositories Go (`RoomRepository`, `ChatRepository`) | ✅ Existants |
|
||||
| Services Go (`RoomService`, `ChatService`) | ✅ Existants |
|
||||
| Handlers REST Go (`/conversations/*`, `/chat/token`) | ✅ Existants |
|
||||
| Frontend chat (`useChat`, `chatStore`, `ChatPage`) | ✅ Existe, utilise mocks MSW |
|
||||
| Pattern WebSocket Go (`playback_websocket_handler.go`) | ✅ Référence |
|
||||
| Tables DB (`rooms`, `room_members`, `messages`) | ✅ Migration 051 |
|
||||
| Tables DB (`read_receipts`, `delivered_status`, `message_reactions`) | ❌ Manquantes en Go |
|
||||
|
||||
---
|
||||
|
||||
## Lots
|
||||
|
||||
### Lot CH1 : Chat Server Go — Backend (14 tâches)
|
||||
|
||||
#### CH1-01 : Migrations DB complémentaires
|
||||
- **Migration 109** : `read_receipts` (user_id, message_id, read_at, index)
|
||||
- **Migration 110** : `delivered_status` (user_id, message_id, delivered_at, index)
|
||||
- **Migration 111** : `message_reactions` (user_id, message_id, emoji, created_at, unique constraint)
|
||||
- **Migration 112** : Ajout colonnes manquantes sur `messages` : `edited_at TIMESTAMPTZ`, `status VARCHAR(20) DEFAULT 'sent'`
|
||||
|
||||
#### CH1-02 : Modèles Go complémentaires
|
||||
- Modèle `ReadReceipt` (UserID, MessageID, ReadAt)
|
||||
- Modèle `DeliveredStatus` (UserID, MessageID, DeliveredAt)
|
||||
- Modèle `MessageReaction` (UserID, MessageID, Emoji, CreatedAt)
|
||||
- Mise à jour modèle `Message` : ajout champs `EditedAt`, `Status`, `IsPinned`, `Metadata`
|
||||
|
||||
#### CH1-03 : Repository Chat GORM enrichi
|
||||
- Créer `ChatMessageRepository` basé sur GORM (remplace `database/chat_repository.go` en raw SQL)
|
||||
- Méthodes : `Create`, `GetByID`, `GetByRoomID` (paginé, avant/après curseur), `Update`, `SoftDelete`
|
||||
- Méthodes : `Search` (ILIKE + to_tsvector), `GetSince` (pour sync)
|
||||
- Méthodes : `Pin`, `Unpin`, `GetPinned`
|
||||
|
||||
#### CH1-04 : Repositories read/delivered/reactions
|
||||
- `ReadReceiptRepository` : `MarkRead`, `GetByMessage`, `GetByConversation`
|
||||
- `DeliveredStatusRepository` : `MarkDelivered`, `GetByMessage`
|
||||
- `ReactionRepository` : `Add`, `Remove`, `GetByMessage`
|
||||
|
||||
#### CH1-05 : Service Redis PubSub
|
||||
- Créer `ChatPubSubService` dans `internal/services/chat_pubsub.go`
|
||||
- `Publish(roomID, message)` : publie un message JSON sur le canal `chat:room:{roomID}`
|
||||
- `Subscribe(roomID)` : s'abonne au canal et retourne un channel Go
|
||||
- `PublishPresence(event)` : publie sur `chat:presence`
|
||||
- Fallback in-memory si Redis non disponible (dev sans Redis)
|
||||
|
||||
#### CH1-06 : WebSocket Hub (gestionnaire de connexions)
|
||||
- Créer `internal/websocket/chat/hub.go`
|
||||
- Structure `Hub` avec :
|
||||
- `clients map[uuid.UUID]*Client` (userID → client)
|
||||
- `rooms map[uuid.UUID]map[uuid.UUID]*Client` (roomID → userID → client)
|
||||
- `register`, `unregister`, `broadcast` channels
|
||||
- Goroutine `Run()` principale qui gère les événements
|
||||
- Méthodes : `BroadcastToRoom(roomID, message, excludeUserID)`
|
||||
- Méthodes : `SendToUser(userID, message)`
|
||||
- Intégration Redis PubSub pour multi-instance
|
||||
|
||||
#### CH1-07 : Client WebSocket et pumps
|
||||
- Créer `internal/websocket/chat/client.go`
|
||||
- Structure `Client` :
|
||||
- `conn *websocket.Conn`
|
||||
- `userID uuid.UUID`, `username string`
|
||||
- `hub *Hub`
|
||||
- `send chan []byte`
|
||||
- `rooms map[uuid.UUID]bool` (rooms auxquelles le client est abonné)
|
||||
- Goroutine `readPump()` : lecture des messages, parsing JSON, dispatch
|
||||
- Goroutine `writePump()` : écriture des messages depuis le channel `send`, ping/pong keepalive
|
||||
- Timeouts : read 60s, write 10s, pong 60s
|
||||
|
||||
#### CH1-08 : Types de messages WebSocket Go
|
||||
- Créer `internal/websocket/chat/messages.go`
|
||||
- Structs Go pour chaque type de message entrant (IncomingMessage avec champ `Type` discriminant)
|
||||
- Structs Go pour chaque type de message sortant (OutgoingMessage avec champ `Type` discriminant)
|
||||
- Marshaling/unmarshaling JSON identique au protocole Rust existant
|
||||
- Validation des messages entrants (champs requis selon le type)
|
||||
|
||||
#### CH1-09 : Handler WebSocket — Messages CRUD
|
||||
- `handleSendMessage` : validation, persistence DB, broadcast room, Redis PubSub
|
||||
- `handleEditMessage` : vérification ownership, update DB, broadcast `MessageEdited`
|
||||
- `handleDeleteMessage` : vérification ownership, soft delete DB, broadcast `MessageDeleted`
|
||||
|
||||
#### CH1-10 : Handler WebSocket — Rooms
|
||||
- `handleJoinConversation` : vérification membership, ajout au hub, broadcast présence
|
||||
- `handleLeaveConversation` : retrait du hub, broadcast départ
|
||||
|
||||
#### CH1-11 : Handler WebSocket — Historique & Recherche
|
||||
- `handleFetchHistory` : query DB paginée (before/after curseur, limit), réponse `HistoryChunk`
|
||||
- `handleSearchMessages` : query ILIKE + FTS, réponse `SearchResults`
|
||||
- `handleSyncMessages` : messages depuis un timestamp, réponse `SyncChunk`
|
||||
|
||||
#### CH1-12 : Handler WebSocket — Typing, Read, Delivered, Reactions
|
||||
- `handleTyping` : broadcast `UserTyping` avec timeout 3s auto-clear
|
||||
- `handleMarkAsRead` : persistence `read_receipts`, broadcast `MessageRead`
|
||||
- `handleDelivered` : persistence `delivered_status`, broadcast `MessageDelivered`
|
||||
- `handleAddReaction` : persistence, broadcast `ReactionAdded`
|
||||
- `handleRemoveReaction` : suppression, broadcast `ReactionRemoved`
|
||||
|
||||
#### CH1-13 : Handler WebSocket — Signalisation WebRTC
|
||||
- `handleCallOffer` : relay SDP offer au target_user_id
|
||||
- `handleCallAnswer` : relay SDP answer au caller_user_id
|
||||
- `handleICECandidate` : relay ICE candidate au target_user_id
|
||||
- `handleCallHangup` : broadcast hangup
|
||||
- `handleCallReject` : broadcast rejection
|
||||
|
||||
#### CH1-14 : Rate Limiting WebSocket
|
||||
- Créer `internal/websocket/chat/rate_limiter.go`
|
||||
- Rate limits par action et par utilisateur (Redis-backed, fallback mémoire) :
|
||||
- `SendMessage` : 10/s
|
||||
- `Typing` : 5/s
|
||||
- `AddReaction` : 5/s
|
||||
- `EditMessage` / `DeleteMessage` : 5/s
|
||||
- `SearchMessages` : 2/s
|
||||
- `CallSignaling` : 10/s
|
||||
- Réponse `Error` si rate limit dépassé
|
||||
|
||||
---
|
||||
|
||||
### Lot CH2 : Intégration Routes & Docker (6 tâches)
|
||||
|
||||
#### CH2-01 : Endpoint WebSocket dans le router Go
|
||||
- Ajouter route `GET /api/v1/ws` dans `router.go`
|
||||
- Handler : upgrade HTTP → WebSocket avec `coder/websocket`
|
||||
- Auth : extraire token du query param `?token=`, valider JWT
|
||||
- Créer le client, l'enregistrer dans le Hub, lancer readPump/writePump
|
||||
|
||||
#### CH2-02 : Mise à jour ChatService
|
||||
- Mettre à jour `GenerateToken` pour retourner le bon `WSUrl` (/api/v1/ws)
|
||||
- Ajouter méthode `ValidateChatToken(tokenString) (*Claims, error)`
|
||||
|
||||
#### CH2-03 : Initialisation du Hub dans le backend
|
||||
- Instancier le Hub au démarrage du serveur (dans `main.go` ou `router.go`)
|
||||
- Injecter Redis PubSub si disponible
|
||||
- Lancer `hub.Run()` en goroutine
|
||||
|
||||
#### CH2-04 : Suppression du chat server Rust de Docker
|
||||
- Retirer le service `chat-server` de `docker-compose.yml`
|
||||
- Retirer le service `chat-server` de `docker-compose.staging.yml`
|
||||
- Retirer le service `chat-server` de `docker-compose.prod.yml`
|
||||
- Supprimer les variables d'environnement `CHAT_SERVER_*` du backend
|
||||
- Mettre à jour les healthchecks et depends_on
|
||||
|
||||
#### CH2-05 : Variables d'environnement
|
||||
- Supprimer `VITE_WS_URL` (le WebSocket est maintenant sur le même host que l'API)
|
||||
- Ou rediriger `VITE_WS_URL` vers `${VITE_API_URL}/ws` (même origin)
|
||||
- Mettre à jour `.env.example`, `.env.development`
|
||||
|
||||
#### CH2-06 : Permissions et membership
|
||||
- Créer `internal/websocket/chat/permissions.go`
|
||||
- `CanRead(userID, roomID)` : vérifie membership via `room_members`
|
||||
- `CanSend(userID, roomID)` : vérifie membership + non-muted + non-banned
|
||||
- `CanJoin(userID, roomID)` : vérifie si room publique ou si invité
|
||||
- `CanModerate(userID, roomID)` : vérifie rôle admin/moderator
|
||||
|
||||
---
|
||||
|
||||
### Lot CH3 : Frontend Migration (6 tâches)
|
||||
|
||||
#### CH3-01 : Mise à jour de l'URL WebSocket
|
||||
- Modifier `useChat.ts` pour construire l'URL WS depuis `VITE_API_URL`
|
||||
- Format : `ws(s)://{api_host}/api/v1/ws?token={token}`
|
||||
- Supprimer la logique de `VITE_WS_URL` séparée
|
||||
- Supprimer la vérification `127.0.0.1:8081` (dev hack)
|
||||
|
||||
#### CH3-02 : Mise à jour du flux d'authentification
|
||||
- Modifier `useChatStore` : `setWsToken` n'a plus besoin de `wsUrl`
|
||||
- Le hook `useChat` construit l'URL dynamiquement depuis le token et l'API URL
|
||||
- Supprimer le champ `wsUrl` du store (ou le garder calculé)
|
||||
|
||||
#### CH3-03 : Mise à jour des handlers MSW
|
||||
- Mettre à jour `handlers-misc.ts` : `POST /api/v1/chat/token` retourne le bon `ws_url`
|
||||
- Ajouter mock pour `GET /api/v1/conversations/:id/history`
|
||||
- S'assurer que le mock conversation list est compatible
|
||||
|
||||
#### CH3-04 : Vérification des composants Chat
|
||||
- Vérifier `ChatPage.tsx`, `ChatInterface.tsx`, `ChatMessage.tsx`
|
||||
- Vérifier `TypingIndicator.tsx`, `VirtualizedChatMessages`
|
||||
- Vérifier que `useWebRTC.ts` (appels) fonctionne avec la nouvelle URL
|
||||
- S'assurer que `EditMessage` et `DeleteMessage` sont gérés dans `handleMessage`
|
||||
|
||||
#### CH3-05 : Ajout types manquants
|
||||
- Ajouter `EditMessage`, `DeleteMessage`, `FetchHistory`, `SearchMessages`, `SyncMessages` dans `OutgoingMessage`
|
||||
- Ajouter `MessageEdited`, `MessageDeleted`, `SearchResults`, `SyncChunk` dans `IncomingMessage`
|
||||
- Ajouter les handlers correspondants dans `useChat.ts` `handleMessage`
|
||||
|
||||
#### CH3-06 : Storybook & tests visuels
|
||||
- Mettre à jour les stories chat si nécessaire
|
||||
- Vérifier que `ChatPage.stories.tsx` fonctionne avec les nouveaux mocks
|
||||
- Ajouter une story pour l'état "WebSocket connecting" et "WebSocket error"
|
||||
|
||||
---
|
||||
|
||||
### Lot CH4 : Tests & Validation (8 tâches)
|
||||
|
||||
#### CH4-01 : Tests unitaires Hub
|
||||
- Test `Hub.Run()` : register/unregister clients
|
||||
- Test `BroadcastToRoom` : message envoyé à tous les membres sauf l'expéditeur
|
||||
- Test `SendToUser` : message ciblé
|
||||
|
||||
#### CH4-02 : Tests unitaires message handlers
|
||||
- Test `handleSendMessage` : message persisté, broadcasté
|
||||
- Test `handleEditMessage` : ownership vérifié, message mis à jour
|
||||
- Test `handleDeleteMessage` : soft delete, broadcast
|
||||
|
||||
#### CH4-03 : Tests unitaires typing/read/reactions
|
||||
- Test `handleTyping` : broadcast UserTyping
|
||||
- Test `handleMarkAsRead` : read_receipt créé, broadcast
|
||||
- Test `handleAddReaction` / `handleRemoveReaction`
|
||||
|
||||
#### CH4-04 : Tests E2E connexion WebSocket
|
||||
- Test : connexion avec token valide → upgrade réussie
|
||||
- Test : connexion sans token → refusée
|
||||
- Test : connexion avec token expiré → refusée
|
||||
- Test : ping/pong keepalive
|
||||
|
||||
#### CH4-05 : Tests E2E flux de messages
|
||||
- Test : envoyer message → reçu par autre client dans la même room
|
||||
- Test : join room → receive history
|
||||
- Test : edit message → broadcast edit event
|
||||
- Test : delete message → broadcast delete event
|
||||
|
||||
#### CH4-06 : Tests E2E real-time features
|
||||
- Test : typing indicator envoyé → reçu par les autres
|
||||
- Test : mark as read → broadcast read receipt
|
||||
- Test : add reaction → broadcast reaction added
|
||||
|
||||
#### CH4-07 : Document de feature parity
|
||||
- Créer `docs/CHAT_FEATURE_PARITY.md`
|
||||
- Checklist : chaque feature du chat server Rust validée en Go
|
||||
- Colonnes : Feature | Rust | Go | Status
|
||||
|
||||
#### CH4-08 : Tests de performance
|
||||
- Benchmark : 100 connexions simultanées
|
||||
- Benchmark : latence message delivery < 100ms
|
||||
- Benchmark : mémoire par connexion
|
||||
|
||||
---
|
||||
|
||||
## Fichiers impactés
|
||||
|
||||
### Nouveaux fichiers Go
|
||||
|
||||
| Fichier | Contenu |
|
||||
|---------|---------|
|
||||
| `migrations/109_read_receipts.sql` | Table read_receipts |
|
||||
| `migrations/110_delivered_status.sql` | Table delivered_status |
|
||||
| `migrations/111_message_reactions.sql` | Table message_reactions |
|
||||
| `migrations/112_messages_extra_columns.sql` | Colonnes edited_at, status sur messages |
|
||||
| `internal/models/read_receipt.go` | Modèle ReadReceipt |
|
||||
| `internal/models/delivered_status.go` | Modèle DeliveredStatus |
|
||||
| `internal/models/message_reaction.go` | Modèle MessageReaction |
|
||||
| `internal/repositories/chat_message_repository.go` | Repository GORM pour messages |
|
||||
| `internal/repositories/read_receipt_repository.go` | Repository read receipts |
|
||||
| `internal/repositories/delivered_status_repository.go` | Repository delivered status |
|
||||
| `internal/repositories/reaction_repository.go` | Repository reactions |
|
||||
| `internal/services/chat_pubsub.go` | Service Redis PubSub |
|
||||
| `internal/websocket/chat/hub.go` | Hub WebSocket (gestionnaire de connexions) |
|
||||
| `internal/websocket/chat/client.go` | Client WebSocket (readPump/writePump) |
|
||||
| `internal/websocket/chat/messages.go` | Types de messages JSON |
|
||||
| `internal/websocket/chat/handler.go` | Dispatch des messages |
|
||||
| `internal/websocket/chat/handler_messages.go` | Send/Edit/Delete message |
|
||||
| `internal/websocket/chat/handler_rooms.go` | Join/Leave conversation |
|
||||
| `internal/websocket/chat/handler_history.go` | History/Search/Sync |
|
||||
| `internal/websocket/chat/handler_realtime.go` | Typing/Read/Delivered/Reactions |
|
||||
| `internal/websocket/chat/handler_calls.go` | WebRTC signaling |
|
||||
| `internal/websocket/chat/permissions.go` | Permission checks |
|
||||
| `internal/websocket/chat/rate_limiter.go` | Rate limiting |
|
||||
|
||||
### Fichiers modifiés
|
||||
|
||||
| Fichier | Modification |
|
||||
|---------|-------------|
|
||||
| `internal/models/message.go` | Ajout EditedAt, Status, IsPinned, Metadata |
|
||||
| `internal/services/chat_service.go` | WSUrl mis à jour, ValidateChatToken |
|
||||
| `internal/api/router.go` | Route /ws, initialisation Hub |
|
||||
| `docker-compose.yml` | Suppression service chat-server |
|
||||
| `docker-compose.staging.yml` | Suppression service chat-server |
|
||||
| `docker-compose.prod.yml` | Suppression service chat-server |
|
||||
|
||||
### Fichiers frontend modifiés
|
||||
|
||||
| Fichier | Modification |
|
||||
|---------|-------------|
|
||||
| `apps/web/src/features/chat/hooks/useChat.ts` | URL WS, auth flow, types manquants |
|
||||
| `apps/web/src/features/chat/types/index.ts` | Types Edit/Delete/Search/Sync |
|
||||
| `apps/web/src/features/chat/store/chatStore.ts` | Suppression wsUrl, ajout handlers |
|
||||
| `apps/web/src/mocks/handlers-misc.ts` | Mocks chat mis à jour |
|
||||
|
||||
---
|
||||
|
||||
## Critères d'acceptance
|
||||
|
||||
- [ ] Toutes les features du chat server Rust fonctionnent avec le server Go
|
||||
- [ ] Protocole WebSocket JSON identique (0 changement frontend sémantique)
|
||||
- [ ] Latence de livraison des messages < 100ms
|
||||
- [ ] Rate limiting fonctionnel par utilisateur et par action
|
||||
- [ ] Read receipts et delivered status persistés en DB
|
||||
- [ ] Réactions persistées avec broadcast temps réel
|
||||
- [ ] Typing indicators avec auto-clear 3s
|
||||
- [ ] Signalisation WebRTC (appels 1-to-1) fonctionnelle
|
||||
- [ ] Redis PubSub pour broadcasting multi-instance
|
||||
- [ ] Chat server Rust supprimé de Docker Compose
|
||||
- [ ] Tests E2E pour connexion, messages, typing, reactions
|
||||
- [ ] Document de feature parity validé
|
||||
- [ ] Go backend compile sans erreur
|
||||
- [ ] Frontend TypeScript compile sans erreur
|
||||
- [ ] Storybook sans erreur réseau/console
|
||||
|
||||
---
|
||||
|
||||
## Hors scope v0.502
|
||||
|
||||
- Chat groupé multi-room UI (refonte UX) → v0.503
|
||||
- Fichier upload dans le chat (images, audio inline) → v0.503
|
||||
- Notifications push pour messages chat → v0.503
|
||||
- Modération avancée (sanctions, bans, mutes depuis UI) → v0.503
|
||||
- Message threading UI (réponses imbriquées) → v0.503
|
||||
- Recherche full-text avancée dans le chat → v0.503
|
||||
Loading…
Reference in a new issue