Merge pull request 'feat: aligner event handler Socket.IO sur le contrat snake_case (#20)' (#21) from feat/#20-snake-case-events into feat/prd-19-snake-case-events

This commit is contained in:
2026-03-19 17:40:23 +01:00
4 changed files with 70 additions and 11 deletions

View File

@@ -43,7 +43,7 @@ bun test # 8 tests unitaires socketio-adapter
- **Sessions webview isolées** : partition Electron unique par centre, auto-connexion via preload script - **Sessions webview isolées** : partition Electron unique par centre, auto-connexion via preload script
- **Socket.IO reconnexion** : illimitée (2s→10s backoff) - **Socket.IO reconnexion** : illimitée (2s→10s backoff)
- **IPC principal** : `login-agent`, `get-terminal-list`, `server-status`, `switch-to-center`, `release-center` - **IPC principal** : `login-agent`, `get-terminal-list`, `server-status`, `switch-to-center`, `release-center`
- **Protocole serveur** : auth au handshake, events `login_ok`/`login_error`/`ipbx_event`/`logout``logout_ok` - **Protocole serveur** : auth au handshake, events `login_ok`/`login_error`/`call_event`/`logout``logout_ok` (champs snake_case : `event_code`, `queue_name`, `terminal`)
- **Terminaux** : REST `GET /terminals?provider=RDVPREM` (pas Socket.IO) - **Terminaux** : REST `GET /terminals?provider=RDVPREM` (pas Socket.IO)
- **Logs** : `~/.simpleconnect-ng/socketio.log` - **Logs** : `~/.simpleconnect-ng/socketio.log`
- **Notes** : sauvegarde auto après 2s d'inactivité, 50 versions, sync localStorage + fichier - **Notes** : sauvegarde auto après 2s d'inactivité, 50 versions, sync localStorage + fichier

18
main.js
View File

@@ -208,19 +208,19 @@ function handleCallPickedUp(event) {
if (!mainWindow || !agentConnectionInfo) return; if (!mainWindow || !agentConnectionInfo) return;
const centres = processApplicationUrls(agentConnectionInfo.connList); const centres = processApplicationUrls(agentConnectionInfo.connList);
const centre = centres.find(c => c.queueName === event.queueName); const centre = centres.find(c => c.queueName === event.queue_name);
if (centre) { if (centre) {
log(`Basculement vers le centre: ${centre.nom}`); log(`Basculement vers le centre: ${centre.nom}`);
mainWindow.webContents.send('switch-to-center', { mainWindow.webContents.send('switch-to-center', {
centreId: centre.id, centreId: centre.id,
centreName: centre.nom, centreName: centre.nom,
queueName: event.queueName, queue_name: event.queue_name,
terminal: event.terminal, terminal: event.terminal,
eventType: 'call_pickup' eventType: 'call_pickup'
}); });
} else { } else {
log(`${c.yellow}Aucun centre trouvé pour la file: ${event.queueName}${c.reset}`); log(`${c.yellow}Aucun centre trouvé pour la file: ${event.queue_name}${c.reset}`);
} }
} }
@@ -228,9 +228,9 @@ function handleCallPickedUp(event) {
function handleCallHungUp(event) { function handleCallHungUp(event) {
if (!mainWindow) return; if (!mainWindow) return;
log(`Fin d'appel sur la file: ${event.queueName}`); log(`Fin d'appel sur la file: ${event.queue_name}`);
mainWindow.webContents.send('release-center', { mainWindow.webContents.send('release-center', {
queueName: event.queueName, queue_name: event.queue_name,
terminal: event.terminal, terminal: event.terminal,
eventType: 'call_hangup' eventType: 'call_hangup'
}); });
@@ -245,9 +245,9 @@ function setupEventHandlers() {
serviceProvider: config.socketio.serviceProvider serviceProvider: config.socketio.serviceProvider
}); });
// Ecouter les evenements d'appels IPBX // Ecouter les evenements d'appels IPBX (contrat snake_case du serveur)
adapter.on('ipbx_event', (data) => { adapter.on('call_event', (data) => {
log('ipbx_event recu', data); log('call_event recu', data);
if (!agentConnectionInfo) return; if (!agentConnectionInfo) return;
@@ -257,7 +257,7 @@ function setupEventHandlers() {
return; return;
} }
switch (data.eventCode) { switch (data.event_code) {
case 1: case 1:
handleCallPickedUp(data); handleCallPickedUp(data);
break; break;

View File

@@ -153,7 +153,7 @@ document.addEventListener('DOMContentLoaded', async () => {
// Écouter la libération de centre après raccrochage // Écouter la libération de centre après raccrochage
ipcRenderer.on('release-center', (event, data) => { ipcRenderer.on('release-center', (event, data) => {
console.log('Libération de la file:', data.queueName); console.log('Libération de la file:', data.queue_name);
// Mettre à jour le statut // Mettre à jour le statut
updateAgentStatus('DISPONIBLE'); updateAgentStatus('DISPONIBLE');

View File

@@ -128,4 +128,63 @@ describe("SocketIOAdapter", () => {
expect(states).toEqual(["connecting", "connected", "reconnecting", "connected"]); expect(states).toEqual(["connecting", "connected", "reconnecting", "connected"]);
}); });
test("on('call_event') recoit les champs snake_case du serveur", async () => {
const received = [];
adapter.on('call_event', (data) => received.push(data));
const p = adapter.connect("1234", "pass", "2001");
socket._fire("login_ok", { accessCode: "1234" });
await p;
// Le serveur envoie un call_event avec champs snake_case
socket._fire("call_event", {
event_code: 1,
queue_name: "FILE_CENTRE_A",
terminal: "2001",
});
expect(received).toHaveLength(1);
expect(received[0].event_code).toBe(1);
expect(received[0].queue_name).toBe("FILE_CENTRE_A");
expect(received[0].terminal).toBe("2001");
});
test("on('call_event') enregistré avant connect() est dispatché après connexion", async () => {
const received = [];
// Enregistrer le handler AVANT connect (comme le fait main.js)
adapter.on('call_event', (data) => received.push(data));
const p = adapter.connect("1234", "pass", "2001");
socket._fire("login_ok", { accessCode: "1234" });
await p;
// Le serveur envoie un call_event
socket._fire("call_event", {
event_code: 2,
queue_name: "FILE_CENTRE_B",
terminal: "2001",
});
expect(received).toHaveLength(1);
expect(received[0].event_code).toBe(2);
expect(received[0].queue_name).toBe("FILE_CENTRE_B");
});
test("off('call_event') supprime le handler", async () => {
const received = [];
adapter.on('call_event', (data) => received.push(data));
const p = adapter.connect("1234", "pass", "2001");
socket._fire("login_ok", { accessCode: "1234" });
await p;
// Supprimer le handler
adapter.off('call_event');
// L'event ne devrait plus être capté
socket._fire("call_event", { event_code: 1, queue_name: "FILE", terminal: "2001" });
expect(received).toHaveLength(0);
});
}); });