docs signalR
This commit is contained in:
@@ -186,26 +186,154 @@ function handleCallHungUp(event, mainWindow) {
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Récupération de la liste des terminaux
|
||||
### 4. Récupération et sélection des terminaux téléphoniques
|
||||
|
||||
#### Processus complet de récupération des terminaux
|
||||
|
||||
La récupération des terminaux se fait en deux phases : récupération depuis le serveur et affichage dans l'interface de connexion.
|
||||
|
||||
##### Côté processus principal (main.js)
|
||||
|
||||
```javascript
|
||||
// Obtenir les terminaux disponibles
|
||||
async function getTerminalList(connection, serviceProvider) {
|
||||
// Handler IPC pour récupérer les terminaux
|
||||
ipcMain.handle('get-terminal-list', async () => {
|
||||
try {
|
||||
const terminals = await connection.invoke(
|
||||
const terminals = await signalRConnection.invoke(
|
||||
'GetTerminalListByServiceProvider',
|
||||
serviceProvider
|
||||
config.ServiceProvider // Ex: 'RDVPREM' depuis la config
|
||||
);
|
||||
|
||||
console.log('Terminaux disponibles:', terminals);
|
||||
// Retourne un tableau de numéros: ["3001", "3002", "3003", ...]
|
||||
return terminals;
|
||||
} catch (error) {
|
||||
console.error('Erreur récupération terminaux:', error);
|
||||
return [];
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
##### Côté renderer - Interface de sélection
|
||||
|
||||
```javascript
|
||||
// Au chargement de la page de connexion
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
try {
|
||||
// Afficher un loader
|
||||
const terminalSelect = document.getElementById('terminal-select');
|
||||
terminalSelect.innerHTML = '<option value="">Chargement des terminaux...</option>';
|
||||
|
||||
// Récupérer les terminaux disponibles depuis le serveur
|
||||
const terminals = await ipcRenderer.invoke('get-terminal-list');
|
||||
|
||||
if (terminals && terminals.length > 0) {
|
||||
populateTerminalSelect(terminals);
|
||||
|
||||
// Restaurer la dernière sélection si disponible
|
||||
const lastTerminal = localStorage.getItem('last-terminal');
|
||||
if (lastTerminal && terminals.includes(lastTerminal)) {
|
||||
terminalSelect.value = lastTerminal;
|
||||
}
|
||||
} else {
|
||||
showError('Aucun terminal téléphonique disponible');
|
||||
terminalSelect.innerHTML = '<option value="">Aucun terminal disponible</option>';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Erreur chargement terminaux:', error);
|
||||
showError('Impossible de récupérer la liste des terminaux');
|
||||
}
|
||||
});
|
||||
|
||||
// Remplir le select avec les terminaux
|
||||
function populateTerminalSelect(terminals) {
|
||||
const select = document.getElementById('terminal-select');
|
||||
select.innerHTML = '<option value="">Sélectionner un terminal...</option>';
|
||||
|
||||
terminals.forEach(terminal => {
|
||||
const option = document.createElement('option');
|
||||
option.value = terminal;
|
||||
option.textContent = `Poste ${terminal}`;
|
||||
select.appendChild(option);
|
||||
});
|
||||
}
|
||||
|
||||
// Intégration dans le formulaire de connexion
|
||||
async function handleLogin(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const terminal = document.getElementById('terminal-select').value;
|
||||
|
||||
// Validation : terminal obligatoire
|
||||
if (!terminal) {
|
||||
showError('Veuillez sélectionner un terminal téléphonique');
|
||||
return;
|
||||
}
|
||||
|
||||
const credentials = {
|
||||
email: document.getElementById('email').value,
|
||||
password: document.getElementById('password').value,
|
||||
terminal: terminal
|
||||
};
|
||||
|
||||
// Sauvegarder le terminal pour la prochaine connexion
|
||||
localStorage.setItem('last-terminal', terminal);
|
||||
|
||||
// Connexion avec le terminal sélectionné
|
||||
const result = await ipcRenderer.invoke('agent-login', credentials);
|
||||
|
||||
if (result.success) {
|
||||
// Le terminal est maintenant associé à la session
|
||||
// Il sera affiché dans le titre de la fenêtre
|
||||
console.log(`Connecté sur le poste ${terminal}`);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
##### Interface HTML correspondante
|
||||
|
||||
```html
|
||||
<!-- Formulaire de connexion avec sélection du terminal -->
|
||||
<form id="loginForm">
|
||||
<div class="form-group">
|
||||
<label for="email">Email</label>
|
||||
<input type="email" id="email" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">Mot de passe</label>
|
||||
<input type="password" id="password" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="terminal-select">Terminal téléphonique</label>
|
||||
<select id="terminal-select" required>
|
||||
<option value="">Chargement...</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button type="submit">Se connecter</button>
|
||||
</form>
|
||||
```
|
||||
|
||||
#### Points importants sur les terminaux
|
||||
|
||||
1. **ServiceProvider** : Le paramètre configuré dans `config.json` détermine quels terminaux sont disponibles pour l'organisation
|
||||
|
||||
2. **Filtrage serveur** : Le serveur filtre automatiquement les terminaux selon :
|
||||
- Le fournisseur de service (ServiceProvider)
|
||||
- Les droits de l'organisation
|
||||
- La disponibilité des postes
|
||||
- Les terminaux déjà utilisés par d'autres agents
|
||||
|
||||
3. **Validation obligatoire** : Un agent DOIT sélectionner un terminal pour se connecter - c'est ce qui permet le routage des appels
|
||||
|
||||
4. **Affichage contextuel** : Après connexion, le terminal est affiché dans le titre :
|
||||
```javascript
|
||||
mainWindow.setTitle(`SimpleConnect - Agent: ${user} (${firstName} ${lastName}) - Tel: ${terminal}`);
|
||||
```
|
||||
|
||||
5. **Association terminal-agent** : Cette association permet au serveur SignalR de router les événements IPBX vers le bon agent
|
||||
|
||||
### 5. Déconnexion propre
|
||||
|
||||
```javascript
|
||||
|
||||
452
docs/WORKFLOW_AGENT.md
Normal file
452
docs/WORKFLOW_AGENT.md
Normal file
@@ -0,0 +1,452 @@
|
||||
# Workflow complet d'un agent SimpleConnect
|
||||
|
||||
## Vue d'ensemble
|
||||
|
||||
Ce document décrit le parcours complet d'un agent utilisant SimpleConnect, depuis la connexion jusqu'à la déconnexion, en passant par la gestion des appels et l'utilisation des différentes fonctionnalités.
|
||||
|
||||
## 1. Lancement de l'application
|
||||
|
||||
### Actions au démarrage
|
||||
|
||||
```javascript
|
||||
// L'agent lance l'application SimpleConnect
|
||||
// Initialisation automatique des composants
|
||||
```
|
||||
|
||||
**Processus système** :
|
||||
- Connexion automatique au serveur SignalR (configuré dans `config.json`)
|
||||
- Vérification de la disponibilité du service
|
||||
- Récupération de la liste des terminaux téléphoniques disponibles
|
||||
- Création du fichier de log journalier
|
||||
- Génération du dashboard initial (état : application ouverte, non connecté)
|
||||
|
||||
## 2. Phase de connexion
|
||||
|
||||
### 2.1 Interface de connexion
|
||||
|
||||
L'agent arrive sur l'écran de connexion avec :
|
||||
- Champ email
|
||||
- Champ mot de passe
|
||||
- Sélecteur de terminal téléphonique (liste dynamique)
|
||||
- Bouton de connexion
|
||||
|
||||
### 2.2 Processus d'authentification
|
||||
|
||||
```javascript
|
||||
// Envoi des credentials au serveur
|
||||
AgentLogin(email, password, terminal) → Serveur SignalR
|
||||
|
||||
// Réponse du serveur avec les informations complètes
|
||||
{
|
||||
accessCode: "AGENT001",
|
||||
firstName: "Marie",
|
||||
lastName: "DUPONT",
|
||||
terminal: "3001",
|
||||
connList: [ // Centres/files assignés à l'agent
|
||||
{
|
||||
code: "centre1",
|
||||
applicationName: "https://pro.doctolib.fr",
|
||||
accessCode: "user_cardio",
|
||||
password: "pass123"
|
||||
},
|
||||
{
|
||||
code: "centre2",
|
||||
applicationName: "https://pro.mondocteur.fr",
|
||||
accessCode: "user_clinique",
|
||||
password: "pass456"
|
||||
}
|
||||
// ...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 Post-connexion
|
||||
|
||||
**Actions automatiques après connexion réussie** :
|
||||
1. Génération dynamique des onglets selon les centres assignés
|
||||
2. Création des webviews pour chaque plateforme
|
||||
3. Auto-connexion aux plateformes médicales (injection des credentials)
|
||||
4. Mise à jour de l'interface :
|
||||
- Titre fenêtre : "SimpleConnect - Agent: Marie DUPONT - Tel: 3001"
|
||||
- Nom agent affiché dans l'interface
|
||||
- Statut : "Disponible" (indicateur vert)
|
||||
5. Activation de l'écoute des événements IPBX
|
||||
6. Mise à jour du dashboard JSON avec les informations de connexion
|
||||
|
||||
## 3. Phase d'activité - Gestion des appels
|
||||
|
||||
### 3.1 État disponible
|
||||
|
||||
**L'agent est prêt à recevoir des appels** :
|
||||
- Statut : indicateur vert "Disponible"
|
||||
- Peut naviguer librement entre les onglets
|
||||
- Peut consulter les plannings de manière proactive
|
||||
- Statistiques visibles : appels traités, RDV pris
|
||||
|
||||
### 3.2 Réception d'un appel entrant
|
||||
|
||||
#### Séquence d'événements
|
||||
|
||||
```
|
||||
1. Patient appelle le centre
|
||||
↓
|
||||
2. Système IPBX détecte l'appel
|
||||
↓
|
||||
3. Serveur SignalR envoie IpbxEvent
|
||||
↓
|
||||
4. Client reçoit : {eventCode: 1, terminal: "3001", queueName: "centre1"}
|
||||
↓
|
||||
5. Interface réagit automatiquement
|
||||
```
|
||||
|
||||
#### Actions système
|
||||
|
||||
**Notification immédiate** :
|
||||
```javascript
|
||||
// Alerte visuelle
|
||||
showIncomingCallAlert({
|
||||
centreName: "Centre Cardio Lyon",
|
||||
patientInfo: "Marie LAMBERT - 0612345678",
|
||||
motif: "Consultation urgente"
|
||||
});
|
||||
|
||||
// Son de notification
|
||||
playNotificationSound();
|
||||
```
|
||||
|
||||
**Auto-acceptation** :
|
||||
- Timer de 3 secondes avant acceptation automatique
|
||||
- Ou acceptation manuelle immédiate par l'agent
|
||||
|
||||
#### Basculement automatique
|
||||
|
||||
```javascript
|
||||
// Le système identifie le centre concerné
|
||||
selectCenter('centre1');
|
||||
|
||||
// Bascule sur le bon onglet/webview
|
||||
switchToTab('Centre Cardio Lyon');
|
||||
|
||||
// Mise à jour du statut
|
||||
updateStatus('EN APPEL - Centre Cardio Lyon');
|
||||
```
|
||||
|
||||
### 3.3 Pendant l'appel
|
||||
|
||||
**Actions possibles de l'agent** :
|
||||
|
||||
1. **Prise de RDV** :
|
||||
- Navigation dans le planning actif
|
||||
- Recherche de créneaux disponibles
|
||||
- Validation du RDV directement dans la webview
|
||||
|
||||
2. **Prise de notes** :
|
||||
```javascript
|
||||
// Zone de notes rapides
|
||||
quickNotes.value = "Patient souhaite mardi matin de préférence";
|
||||
saveNotes(); // Sauvegarde horodatée
|
||||
```
|
||||
|
||||
3. **Consultation documentation** :
|
||||
```javascript
|
||||
// Ouverture wiki interne (nouvelle fenêtre)
|
||||
OpenDoc("http://wiki.interne/protocoles");
|
||||
|
||||
// Consultation infos patient (fenêtre séparée)
|
||||
OpenDoc("http://crm.interne/patient/12345");
|
||||
```
|
||||
|
||||
4. **Informations contextuelles** :
|
||||
- Historique des derniers appels du patient (si disponible)
|
||||
- Procédures spécifiques au centre
|
||||
- Tarifs et modalités
|
||||
|
||||
### 3.4 Fin d'appel
|
||||
|
||||
#### Séquence de libération
|
||||
|
||||
```
|
||||
1. Patient/Agent raccroche
|
||||
↓
|
||||
2. Système IPBX détecte la fin d'appel
|
||||
↓
|
||||
3. Serveur SignalR envoie IpbxEvent
|
||||
↓
|
||||
4. Client reçoit : {eventCode: 2, terminal: "3001", queueName: "centre1"}
|
||||
↓
|
||||
5. Libération automatique de la file
|
||||
```
|
||||
|
||||
#### Actions post-appel
|
||||
|
||||
```javascript
|
||||
// Mise à jour automatique
|
||||
updateStatus('DISPONIBLE');
|
||||
callStats.calls++;
|
||||
callStats.appointments++; // Si RDV pris
|
||||
|
||||
// Sauvegarde dans l'historique
|
||||
saveCallHistory({
|
||||
timestamp: new Date().toISOString(),
|
||||
duration: 180, // secondes
|
||||
centre: "centre1",
|
||||
status: "completed",
|
||||
appointment: true
|
||||
});
|
||||
```
|
||||
|
||||
## 4. Fonctionnalités disponibles pendant la session
|
||||
|
||||
### 4.1 Navigation multi-centres
|
||||
|
||||
```javascript
|
||||
// L'agent peut gérer plusieurs centres simultanément
|
||||
centres = [
|
||||
{ id: 'centre1', nom: 'Centre Cardio Lyon', couleur: '#FF6B6B' },
|
||||
{ id: 'centre2', nom: 'Clinique Saint-Jean', couleur: '#4ECDC4' },
|
||||
{ id: 'centre3', nom: 'Cabinet Dr Martin', couleur: '#45B7D1' }
|
||||
];
|
||||
|
||||
// Navigation libre entre les onglets (hors appel)
|
||||
selectCenter('centre2'); // Changement manuel
|
||||
```
|
||||
|
||||
### 4.2 Outils de productivité
|
||||
|
||||
**Statistiques temps réel** :
|
||||
```javascript
|
||||
{
|
||||
calls: 15, // Appels traités aujourd'hui
|
||||
appointments: 12, // RDV confirmés
|
||||
avgDuration: 180, // Durée moyenne en secondes
|
||||
successRate: 80 // Taux de conversion
|
||||
}
|
||||
```
|
||||
|
||||
**Notes et historique** :
|
||||
```javascript
|
||||
// Notes rapides par appel
|
||||
saveNotes({
|
||||
content: "Patient à rappeler pour confirmation",
|
||||
centre: "centre1",
|
||||
timestamp: new Date()
|
||||
});
|
||||
|
||||
// Consultation historique
|
||||
getCallHistory(); // 100 derniers appels
|
||||
```
|
||||
|
||||
### 4.3 Fenêtres auxiliaires
|
||||
|
||||
```javascript
|
||||
// Documentation (DocXplore)
|
||||
childClientDocXplore = new BrowserWindow({
|
||||
x: 1920, y: 0, // Position configurée
|
||||
title: "SimpleConnect / Wiki"
|
||||
});
|
||||
|
||||
// Informations client
|
||||
childClientDoc = new BrowserWindow({
|
||||
x: 2880, y: 0, // Position configurée
|
||||
title: "SimpleConnect / Infos client"
|
||||
});
|
||||
```
|
||||
|
||||
## 5. Processus de déconnexion
|
||||
|
||||
### 5.1 Déclenchement
|
||||
|
||||
La déconnexion peut être initiée par :
|
||||
- Clic sur le bouton "Déconnexion"
|
||||
- Fermeture de l'application (croix de fenêtre)
|
||||
- Timeout de session (si configuré)
|
||||
|
||||
### 5.2 Confirmation et nettoyage
|
||||
|
||||
```javascript
|
||||
// Dialogue de confirmation
|
||||
if (confirm('Voulez-vous vraiment vous déconnecter ?')) {
|
||||
// 1. Notification au serveur
|
||||
AgentLogoff(agentId);
|
||||
|
||||
// 2. Nettoyage local
|
||||
currentAgent = null;
|
||||
currentCentres = [];
|
||||
webviews = {};
|
||||
|
||||
// 3. Fermeture des fenêtres auxiliaires
|
||||
if (childClientDocXplore) childClientDocXplore.close();
|
||||
if (childClientDoc) childClientDoc.close();
|
||||
|
||||
// 4. Génération log final
|
||||
writeDashboardLog({
|
||||
"PrestaConnect": {
|
||||
"Connexion": {
|
||||
"Connecte": "Non",
|
||||
"Date_Deconnexion": new Date().toISOString()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 5. Retour page connexion ou fermeture
|
||||
showLoginPage(); // ou app.quit()
|
||||
}
|
||||
```
|
||||
|
||||
## 6. Logs et monitoring
|
||||
|
||||
### 6.1 Structure du dashboard
|
||||
|
||||
**Fichier** : `./log/log-Dashboard.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"PrestaConnect": {
|
||||
"Ouverture": {
|
||||
"Ouvert": "Oui",
|
||||
"Date": "2024-12-04T10:00:00.000Z",
|
||||
"IP_Client": "192.168.1.50",
|
||||
"IP_Serveur": "10.90.20.201:8002",
|
||||
"Liste_Telephones": ["3001", "3002", "3003"]
|
||||
},
|
||||
"Connexion": {
|
||||
"Connecte": "Oui",
|
||||
"Date": "2024-12-04T10:01:00.000Z",
|
||||
"Agent": "AGENT001",
|
||||
"Telephone": "3001",
|
||||
"Nom_Agent": "Marie DUPONT",
|
||||
"Nombre_Files": 3,
|
||||
"Files": [
|
||||
{
|
||||
"Nom_File": "centre1",
|
||||
"URL_File": "https://pro.doctolib.fr"
|
||||
},
|
||||
{
|
||||
"Nom_File": "centre2",
|
||||
"URL_File": "https://pro.mondocteur.fr"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.2 Logs détaillés
|
||||
|
||||
**Fichier** : `./log/YYYY-MM-DD-log.txt`
|
||||
|
||||
```
|
||||
[2024-12-04 10:00:00.123] [info] Start application
|
||||
[2024-12-04 10:00:01.456] [info] ip: 10.90.20.201:8002
|
||||
[2024-12-04 10:00:02.789] [info] SignalR connected
|
||||
[2024-12-04 10:01:00.123] [info] Agent login: AGENT001
|
||||
[2024-12-04 10:05:30.456] [info] IpbxEvent received: eventCode=1, terminal=3001
|
||||
[2024-12-04 10:08:45.789] [info] IpbxEvent received: eventCode=2, terminal=3001
|
||||
```
|
||||
|
||||
## 7. Mode développement et simulation
|
||||
|
||||
### 7.1 Panneau de test CTI
|
||||
|
||||
En mode développement (`NODE_ENV=development`), un panneau de test permet :
|
||||
|
||||
```javascript
|
||||
// Simulation d'appels
|
||||
ctiSimulator.generateRandomCall();
|
||||
|
||||
// Simulation automatique
|
||||
ctiSimulator.startAutoSimulation(30); // Un appel toutes les 30 secondes
|
||||
|
||||
// Scénarios prédéfinis
|
||||
ctiSimulator.simulateScenarios():
|
||||
- "Appel urgent"
|
||||
- "Patient régulier"
|
||||
- "Nouveau patient"
|
||||
- "Demande résultats"
|
||||
```
|
||||
|
||||
### 7.2 Statistiques de simulation
|
||||
|
||||
```javascript
|
||||
{
|
||||
total: 45, // Total appels simulés
|
||||
today: 15, // Appels aujourd'hui
|
||||
answered: 14, // Appels traités
|
||||
missed: 1, // Appels manqués
|
||||
average_duration: 180 // Durée moyenne
|
||||
}
|
||||
```
|
||||
|
||||
## 8. Diagramme d'états
|
||||
|
||||
```
|
||||
┌─────────────┐
|
||||
│ DÉCONNECTÉ │
|
||||
└─────┬───────┘
|
||||
│ Connexion
|
||||
↓
|
||||
┌─────────────┐
|
||||
│ CONNEXION │
|
||||
└─────┬───────┘
|
||||
│ Authentification réussie
|
||||
↓
|
||||
┌─────────────┐ Appel entrant ┌─────────────┐
|
||||
│ DISPONIBLE │ ←─────────────────→ │ EN APPEL │
|
||||
└─────┬───────┘ Fin d'appel └─────────────┘
|
||||
│
|
||||
│ Déconnexion
|
||||
↓
|
||||
┌─────────────┐
|
||||
│ DÉCONNEXION │
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
## 9. Points clés du workflow
|
||||
|
||||
### Avantages pour l'agent
|
||||
|
||||
1. **Zéro friction** : Pas de recherche manuelle de plateforme
|
||||
2. **Contexte automatique** : Basculement instantané vers le bon planning
|
||||
3. **Productivité maximale** : Auto-connexion, notes rapides, historique
|
||||
4. **Traçabilité complète** : Tous les événements sont enregistrés
|
||||
5. **Multi-tâches optimisé** : Gestion simultanée de plusieurs centres
|
||||
|
||||
### Optimisations système
|
||||
|
||||
1. **Reconnexion automatique** SignalR en cas de perte réseau
|
||||
2. **Sessions persistantes** dans les webviews
|
||||
3. **Cache local** des dernières sélections (terminal, notes)
|
||||
4. **Logs structurés** pour analyse et monitoring
|
||||
5. **Mode simulation** pour formation et tests
|
||||
|
||||
## 10. Cas d'usage spéciaux
|
||||
|
||||
### 10.1 Appel urgent
|
||||
|
||||
```javascript
|
||||
// Identification par priorité haute
|
||||
if (callData.priority === 'high') {
|
||||
// Notification visuelle renforcée
|
||||
showUrgentCallAlert(callData);
|
||||
// Son différent
|
||||
playUrgentSound();
|
||||
// Auto-acceptation immédiate
|
||||
acceptCall(callData);
|
||||
}
|
||||
```
|
||||
|
||||
### 10.2 Patient régulier
|
||||
|
||||
```javascript
|
||||
// Affichage historique patient
|
||||
if (callData.lastVisit) {
|
||||
showPatientHistory({
|
||||
lastVisit: callData.lastVisit,
|
||||
appointments: callData.appointmentHistory
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 10.3 Multi-files simultanées
|
||||
|
||||
L'agent peut recevoir des appels de différentes files et le système bascule automatiquement vers la bonne plateforme à chaque appel, permettant une gestion fluide multi-centres.
|
||||
Reference in New Issue
Block a user