- 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
15 KiB
15 KiB
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
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 champsEditedAt,Status,IsPinned,Metadata
CH1-03 : Repository Chat GORM enrichi
- Créer
ChatMessageRepositorybasé sur GORM (remplacedatabase/chat_repository.goen 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,GetByConversationDeliveredStatusRepository:MarkDelivered,GetByMessageReactionRepository:Add,Remove,GetByMessage
CH1-05 : Service Redis PubSub
- Créer
ChatPubSubServicedansinternal/services/chat_pubsub.go Publish(roomID, message): publie un message JSON sur le canalchat:room:{roomID}Subscribe(roomID): s'abonne au canal et retourne un channel GoPublishPresence(event): publie surchat: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
Hubavec :clients map[uuid.UUID]*Client(userID → client)rooms map[uuid.UUID]map[uuid.UUID]*Client(roomID → userID → client)register,unregister,broadcastchannels- 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.ConnuserID uuid.UUID,username stringhub *Hubsend chan []byterooms 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 channelsend, 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
Typediscriminant) - Structs Go pour chaque type de message sortant (OutgoingMessage avec champ
Typediscriminant) - 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 PubSubhandleEditMessage: vérification ownership, update DB, broadcastMessageEditedhandleDeleteMessage: vérification ownership, soft delete DB, broadcastMessageDeleted
CH1-10 : Handler WebSocket — Rooms
handleJoinConversation: vérification membership, ajout au hub, broadcast présencehandleLeaveConversation: retrait du hub, broadcast départ
CH1-11 : Handler WebSocket — Historique & Recherche
handleFetchHistory: query DB paginée (before/after curseur, limit), réponseHistoryChunkhandleSearchMessages: query ILIKE + FTS, réponseSearchResultshandleSyncMessages: messages depuis un timestamp, réponseSyncChunk
CH1-12 : Handler WebSocket — Typing, Read, Delivered, Reactions
handleTyping: broadcastUserTypingavec timeout 3s auto-clearhandleMarkAsRead: persistenceread_receipts, broadcastMessageReadhandleDelivered: persistencedelivered_status, broadcastMessageDeliveredhandleAddReaction: persistence, broadcastReactionAddedhandleRemoveReaction: suppression, broadcastReactionRemoved
CH1-13 : Handler WebSocket — Signalisation WebRTC
handleCallOffer: relay SDP offer au target_user_idhandleCallAnswer: relay SDP answer au caller_user_idhandleICECandidate: relay ICE candidate au target_user_idhandleCallHangup: broadcast hanguphandleCallReject: 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/sTyping: 5/sAddReaction: 5/sEditMessage/DeleteMessage: 5/sSearchMessages: 2/sCallSignaling: 10/s
- Réponse
Errorsi 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/wsdansrouter.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
GenerateTokenpour retourner le bonWSUrl(/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.goourouter.go) - Injecter Redis PubSub si disponible
- Lancer
hub.Run()en goroutine
CH2-04 : Suppression du chat server Rust de Docker
- Retirer le service
chat-serverdedocker-compose.yml - Retirer le service
chat-serverdedocker-compose.staging.yml - Retirer le service
chat-serverdedocker-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_URLvers${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 viaroom_membersCanSend(userID, roomID): vérifie membership + non-muted + non-bannedCanJoin(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.tspour construire l'URL WS depuisVITE_API_URL - Format :
ws(s)://{api_host}/api/v1/ws?token={token} - Supprimer la logique de
VITE_WS_URLséparée - Supprimer la vérification
127.0.0.1:8081(dev hack)
CH3-02 : Mise à jour du flux d'authentification
- Modifier
useChatStore:setWsTokenn'a plus besoin dewsUrl - Le hook
useChatconstruit l'URL dynamiquement depuis le token et l'API URL - Supprimer le champ
wsUrldu store (ou le garder calculé)
CH3-03 : Mise à jour des handlers MSW
- Mettre à jour
handlers-misc.ts:POST /api/v1/chat/tokenretourne le bonws_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
EditMessageetDeleteMessagesont gérés danshandleMessage
CH3-05 : Ajout types manquants
- Ajouter
EditMessage,DeleteMessage,FetchHistory,SearchMessages,SyncMessagesdansOutgoingMessage - Ajouter
MessageEdited,MessageDeleted,SearchResults,SyncChunkdansIncomingMessage - Ajouter les handlers correspondants dans
useChat.tshandleMessage
CH3-06 : Storybook & tests visuels
- Mettre à jour les stories chat si nécessaire
- Vérifier que
ChatPage.stories.tsxfonctionne 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