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
|
```javascript
|
||||||
// Obtenir les terminaux disponibles
|
// Handler IPC pour récupérer les terminaux
|
||||||
async function getTerminalList(connection, serviceProvider) {
|
ipcMain.handle('get-terminal-list', async () => {
|
||||||
try {
|
try {
|
||||||
const terminals = await connection.invoke(
|
const terminals = await signalRConnection.invoke(
|
||||||
'GetTerminalListByServiceProvider',
|
'GetTerminalListByServiceProvider',
|
||||||
serviceProvider
|
config.ServiceProvider // Ex: 'RDVPREM' depuis la config
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log('Terminaux disponibles:', terminals);
|
console.log('Terminaux disponibles:', terminals);
|
||||||
|
// Retourne un tableau de numéros: ["3001", "3002", "3003", ...]
|
||||||
return terminals;
|
return terminals;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Erreur récupération terminaux:', error);
|
console.error('Erreur récupération terminaux:', error);
|
||||||
return [];
|
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
|
### 5. Déconnexion propre
|
||||||
|
|
||||||
```javascript
|
```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