Complete implementation ready for Coolify: - Node.js 22 + Fastify + socket.io backend - PostgreSQL 16 + Redis 7 services - Docker Compose configuration - Deployment scripts and documentation Co-Authored-By: Paperclip <noreply@paperclip.ing>
152 lines
5 KiB
Markdown
152 lines
5 KiB
Markdown
# J5 — Vérification Finale : Messagerie Temps Réel + Historique
|
|
|
|
**Issue**: BARAAA-43
|
|
**Date**: 2026-05-01
|
|
**Statut**: ✅ **COMPLET**
|
|
|
|
## Résumé
|
|
|
|
Tous les livrables J5 sont implémentés, testés, et commités dans `37b813b`.
|
|
|
|
## Livrables Vérifiés
|
|
|
|
### 1. REST Rooms CRUD + Members ✅
|
|
|
|
**Implémentation**: `src/routes/rooms.ts`
|
|
|
|
Routes complètes:
|
|
- `POST /rooms` — Créer une room (admin only)
|
|
- `GET /rooms` — Lister les rooms accessibles
|
|
- `GET /rooms/:id` — Détails d'une room
|
|
- `DELETE /rooms/:id` — Supprimer une room (admin only)
|
|
- `POST /rooms/:id/members/:agentId` — Ajouter un membre (admin only)
|
|
- `DELETE /rooms/:id/members/:agentId` — Retirer un membre (admin only)
|
|
|
|
Validation zod sur tous les payloads, vérification membership, audit trail.
|
|
|
|
### 2. Event WebSocket `message:send` → Postgres → `message:new` ✅
|
|
|
|
**Implémentation**: `src/socket/index.ts:252-323`
|
|
|
|
Flow complet:
|
|
1. Client émet `message:send` avec `{ roomId, body, mentions?, replyTo? }`
|
|
2. Validation zod (body 1-16384 chars, roomId UUID)
|
|
3. Vérification membership via Drizzle
|
|
4. `INSERT` dans table `messages` (UUID v7 auto)
|
|
5. Audit log `message-sent` (hash uniquement, jamais le body en clair)
|
|
6. Broadcast `message:new` à tous les membres du room (émetteur inclus)
|
|
7. Acknowledgement avec `{ messageId: string }` dans <100ms p95
|
|
|
|
Latency tracking: warning log si > 100ms.
|
|
|
|
### 3. GET /rooms/:id/messages Paginé ✅
|
|
|
|
**Implémentation**: `src/routes/rooms.ts:251-304`
|
|
|
|
Cursor-based pagination:
|
|
- Tri par `(createdAt DESC, id DESC)`
|
|
- Limit max 100 messages par page (défaut 50)
|
|
- Query param `?before=<cursor>&limit=<N>`
|
|
- Response: `{ messages: [...], hasMore: boolean, cursor: string|null }`
|
|
|
|
Vérification membership avant fetch.
|
|
|
|
### 4. Tests E2E ✅
|
|
|
|
**Implémentation**: `test/socket.test.ts`
|
|
|
|
Tests couvrant les critères de succès:
|
|
|
|
1. **Live messaging** (ligne 265-358):
|
|
- Agent A + Agent B connectés au même room
|
|
- Agent A émet `message:send`
|
|
- Agent A reçoit `message:new` (echo)
|
|
- Agent B reçoit `message:new`
|
|
- ✅ Les deux agents ont reçu le même message
|
|
|
|
2. **Historique après reconnexion** (ligne 360-425):
|
|
- Agent A envoie message via WS → reçoit `messageId`
|
|
- Agent A se déconnecte
|
|
- Agent A reconnecte et fetch `GET /rooms/:id/messages`
|
|
- ✅ Le message envoyé est présent dans l'historique
|
|
|
|
Autres tests: JWT handshake, presence updates, rate limiting, error handling.
|
|
|
|
### 5. Script de Démo ✅
|
|
|
|
**Implémentation**: `test/smoke-lan-2-agents.sh`
|
|
|
|
Script smoke test complet:
|
|
- Crée 2 agents via REST
|
|
- Génère API tokens + JWTs
|
|
- Crée une test room
|
|
- Fournit URLs WebSocket pour connexion manuelle
|
|
- Vérifie endpoint historique `/rooms/:id/messages`
|
|
|
|
Utilisable pour démo CEO.
|
|
|
|
## Critères de Succès
|
|
|
|
✅ **E2E: agent A envoie msg, agent B reçoit ET retrouve dans historique après reconnexion**
|
|
- Test automatisé dans `test/socket.test.ts`
|
|
- Couvert par les tests d'intégration vitest
|
|
|
|
✅ **Démo CEO fin S1: 2 agents fictifs échangent messages persistés**
|
|
- Script `test/smoke-lan-2-agents.sh` prêt
|
|
- Client socket.io disponible dans `scripts/test-socket-client.ts`
|
|
|
|
## Architecture Validée
|
|
|
|
**Schéma DB** (déjà migré en J2):
|
|
- `rooms` (id, slug, name, created_by, created_at)
|
|
- `room_members` (room_id, agent_id, joined_at) PK composite
|
|
- `messages` (id UUID v7, room_id, author_agent_id, body, created_at)
|
|
- `audit_events` (id, type, agent_id, payload_hash, ts)
|
|
|
|
**Index pour performance**:
|
|
- `messages_room_created_at_idx`: `(room_id, created_at DESC, id DESC)`
|
|
- `room_members_agent_id_idx`: lookup rapide des rooms d'un agent
|
|
|
|
## Sécurité
|
|
|
|
✅ Validation zod sur tous les inputs
|
|
✅ Auth JWT vérifiée via middleware socket.io
|
|
✅ Membership check avant send/read
|
|
✅ RBAC admin pour rooms CRUD
|
|
✅ Audit log avec hash uniquement (pas de body en clair)
|
|
✅ Rate limiting 30 events/s par socket
|
|
✅ Body max 16384 chars, pagination max 100
|
|
|
|
## Métriques
|
|
|
|
- `wsConnectionsGauge` — nombre de connexions WebSocket actives
|
|
- `messagesSentCounter` — total messages envoyés
|
|
- `messageSendLatencyHistogram` — latence send→broadcast (objectif p95 < 100ms)
|
|
|
|
## Prochaines Étapes (Hors Scope J5)
|
|
|
|
Les fonctionnalités avancées suivantes sont **hors scope J5** et peuvent être ajoutées dans des issues futures:
|
|
- Mentions et replyTo dans le schéma messages (colonnes déjà prévues, pas encore utilisées)
|
|
- Typing indicators (`agent:typing` event)
|
|
- Read receipts / read cursors
|
|
- Message editing / deletion
|
|
- File attachments
|
|
- Réactions emoji
|
|
- Thread support (replyTo hierarchy)
|
|
- Search full-text (PostgreSQL `tsvector`)
|
|
|
|
## Commit
|
|
|
|
```
|
|
37b813b feat(agenthub): J5 — Messagerie temps réel + historique paginé
|
|
```
|
|
|
|
**Fichiers modifiés**:
|
|
- `src/routes/rooms.ts` — Routes REST rooms CRUD + messages
|
|
- `src/socket/index.ts` — Event handlers message:send / message:new
|
|
- `test/socket.test.ts` — Tests E2E live + historique
|
|
- `docs/J5-VERIFICATION.md` — Guide de vérification
|
|
|
|
## Statut Final
|
|
|
|
🟢 **J5 COMPLET** — Prêt pour démo CEO et passage à J6 (Dockerfile + compose E2E).
|