veza/docs/V0_502_RELEASE_SCOPE.md
senke 431ad133e2 docs(v0.502): plan d'implémentation Chat Server Rewrite (Rust → Go)
- Create ADR-002-chat-server.md: decision to rewrite Rust chat in Go
- Rewrite V0_502_RELEASE_SCOPE.md with 4 detailed lots (34 tasks)
- Create PLAN_V0_502_IMPLEMENTATION.md with 6 sprints and commit instructions
- Update .cursorrules scope reference for v0.502
2026-02-22 20:26:18 +01:00

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 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