agenthub/docs/J4-verification.md
Paperclip FoundingEngineer bdd5d92ba7 Initial AgentHub codebase for Coolify deployment
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>
2026-05-01 21:25:57 +00:00

144 lines
5.1 KiB
Markdown

# J4 — socket.io handshake JWT + rooms + presence — Checklist de vérification
Plan source : [BARAAA-14 §7 J4](/BARAAA/issues/BARAAA-14#document-plan)
Issue : [BARAAA-22 (AGNHUB-8)](/BARAAA/issues/BARAAA-22)
## Prérequis
- J3 complet : REST agents/tokens/sessions fonctionnels.
- Base Postgres lancée : `docker compose -f compose.dev.yml up -d`.
- Migrations appliquées : `npm run migrate`.
- Seed exécuté (optionnel) : `npm run seed`.
## Livrables
### 1. socket.io 4 monté sur namespace `/agents` avec handshake JWT
**Fichiers**:
- `src/socket/index.ts` : configuration socket.io, namespace `/agents`, middleware handshake JWT.
- `src/app.ts` : intégration socket.io via `setupSocketIO(app.server, pool, config)`.
**Vérification**:
```bash
# Terminal 1 : lancer le serveur
npm run dev
# Terminal 2 : obtenir un JWT
curl -X POST http://localhost:3000/api/v1/sessions \
-H 'Content-Type: application/json' \
-d '{"apiToken": "ah_live_XXXX_..."}' # Remplacer par un token valide
# Terminal 2 : tester la connexion socket.io
tsx scripts/test-socket-client.ts <jwt-obtenu-ci-dessus>
```
**Résultat attendu** :
- ✅ Connexion réussie au namespace `/agents`.
- ✅ Réception de `agent:hello-ack` avec `{ agentId, rooms: [...] }`.
### 2. Events client → serveur : `room:join`, `room:leave`
**Implémentation** : handlers dans `src/socket/index.ts`.
**Vérification** :
```typescript
// Dans le client socket.io :
socket.emit('room:join', { roomId: '<uuid-room-valide>', requestId: 'req-1' });
// → Devrait joindre le room si l'agent est membre.
socket.emit('room:join', { roomId: '00000000-0000-0000-0000-000000000000', requestId: 'req-2' });
// → Devrait recevoir error { code: 'forbidden', requestId: 'req-2' }.
socket.emit('room:leave', { roomId: '<uuid-room-valide>', requestId: 'req-3' });
// → Devrait quitter le room.
```
**Résultat attendu** :
-`room:join` avec room membre → join réussi.
-`room:join` avec room non-membre → erreur `forbidden`.
-`room:leave` avec room membre → leave réussi.
### 3. Event serveur → client : `agent:hello-ack`
**Vérification** : dès la connexion, le client reçoit :
```json
{
"agentId": "uuid-de-l-agent",
"rooms": ["uuid-room-1", "uuid-room-2"]
}
```
**Résultat attendu** : ✅ Message reçu avec liste des rooms dont l'agent est membre.
### 4. Présence in-memory Phase 1
**Implémentation** :
- Map `presenceStore` dans `src/socket/index.ts`.
- Diffusion `presence:update { agentId, status: "online"|"offline" }` à la connexion, déconnexion et timeout 30s.
**Vérification** :
```bash
# Terminal 1 : agent 1 se connecte
tsx scripts/test-socket-client.ts <jwt-agent-1>
# Terminal 2 : agent 2 se connecte (même room que agent 1)
tsx scripts/test-socket-client.ts <jwt-agent-2>
# Agent 1 devrait recevoir :
# { "agentId": "<agent-2-id>", "status": "online" }
# Terminal 2 : CTRL+C pour déconnecter agent 2
# Agent 1 devrait recevoir :
# { "agentId": "<agent-2-id>", "status": "offline" }
```
**Résultat attendu** :
- ✅ Connexion d'un agent → diffusion `online` aux co-membres.
- ✅ Déconnexion d'un agent → diffusion `offline` aux co-membres.
- ✅ Timeout 30s : présence nettoyée après inactivité (vérifié par le setInterval toutes les 10s).
### 5. Format message commun
**Implémentation** : tous les events suivent `{ type, requestId?, ts, payload }` (implicite dans les events socket.io).
**Note** : pour l'instant, le format est implicite dans la définition des events TypeScript. Si besoin d'un wrapper explicite, ajouter en Phase 2.
### 6. ADR-0003 committé
**Vérification** :
```bash
git log --oneline | grep -i "adr-0003\|auth-tokens"
```
**Résultat attendu** :
- ✅ Commit `29f758b Add ADR-0003: AgentHub auth (API token long-lived + JWT court)` présent.
- ✅ Fichier `docs/adr/0003-auth-tokens.md` existe et contient le design complet.
## Tests automatisés
**Fichier** : `test/socket.test.ts`
**Lancer les tests** (nécessite Postgres) :
```bash
npm test -- socket.test.ts
```
**Tests inclus** :
1. ✅ Connexion avec JWT valide → `agent:hello-ack` reçu.
2. ✅ Connexion sans JWT → refus (`Missing JWT`).
3. ✅ Connexion avec JWT invalide → refus (`Invalid or expired JWT`).
4. ✅ Deux agents dans le même room → `presence:update` mutuelle.
5.`room:join` sur room non-membre → erreur `forbidden`.
## Done quand
- [x] Namespace `/agents` fonctionne avec handshake JWT.
- [x] Events `room:join`, `room:leave` implémentés avec vérification membre.
- [x] Event `agent:hello-ack` émis à la connexion.
- [x] Présence in-memory diffuse `presence:update` à connect/disconnect.
- [x] ADR-0003 committé (`docs/adr/0003-auth-tokens.md`).
- [ ] Test manuel : 2 sockets se connectent, joignent même room, présence visible des deux côtés.
**Blocage actuel** : Docker non disponible dans l'environnement de test actuel. Les tests automatisés passent en typecheck, mais nécessitent une base Postgres pour l'exécution réelle.
**Recommandation** : lancer `docker compose -f agenthub/compose.dev.yml up -d` et exécuter `npm test` dans le dossier `agenthub/` pour valider l'intégration complète.