Exemples JSON & Squelettes — Phases 1→14

AutomationSequence V8

Référence JSON complète — Actions V6 + V7 + 44 nouvelles actions V8 — 7 scénarios complets. Cliquer "Copier" pour utiliser un bloc directement.
V6 : 101 actions V7/V8 : +44 actions 7 scénarios complets Ollama offline 100% compat. V6
01Variables & Types
📦SetVariable — 6 types + opérations List/DictVariables
JSON Copier
[
  { "type": "SetVariable", "varName": "NOM", "varValue": "DUPONT Jean", "varType": "string" },
  { "type": "SetVariable", "varName": "AGE", "varValue": "42", "varType": "int" },
  { "type": "SetVariable", "varName": "ACTIF", "varValue": "true", "varType": "bool" },
  { "type": "SetVariable", "varName": "SERVICES", "varValue": "[\"Cardio\",\"Neuro\",\"\"]", "varType": "list" },
  { "type": "SetVariable", "varName": "CONTACT", "varValue": "{\"nom\":\"DUPONT\",\"id_dossier\":\"654321\"}", "varType": "dict" },
  // List ops
  { "type": "ListAppend", "varName": "ID_DOSSIER_LIST", "value": "654321" },
  { "type": "ListGet", "listVar": "ID_DOSSIER_LIST", "index": 0, "varName": "PREMIER" },
  { "type": "ListLength", "varName": "ID_DOSSIER_LIST", "outVar": "NB" },
  // Dict ops
  { "type": "DictSet", "varName": "STATS", "key": "ok", "value": "0" },
  { "type": "DictGet", "dictVar": "STATS", "key": "ok", "varName": "NB_OK" },
  { "type": "LogMessage", "level": "INFO", "message": "Contact $VAR{NOM}, âge $VAR{AGE}, ID_DOSSIER $VAR{PREMIER}" }
]
02If / Else — 13 opérateurs dont 2 nouveaux V7/V8
Tous les opérateurs If V8Conditions
JSON Copier
[
  // Égalité / inégalité
  { "type": "If", "ifVar": "STATUT", "ifOp": "==", "ifValue": "OK" },
  { "type": "LogMessage", "level": "INFO", "message": "Statut OK" },
  { "type": "EndIf" },

  // Numérique
  { "type": "If", "ifVar": "SCORE", "ifOp": ">=", "ifValue": "80" },
  { "type": "SetVariable", "varName": "MENTION", "varValue": "BIEN" },
  { "type": "Else" },
  { "type": "SetVariable", "varName": "MENTION", "varValue": "PASSABLE" },
  { "type": "EndIf" },

  // Regex — valider un ID_DOSSIER
  { "type": "If", "ifVar": "ID_DOSSIER", "ifOp": "regex", "ifValue": "^\\d{6,8}$" },
  { "type": "LogMessage", "level": "INFO", "message": "ID valide : $VAR{ID_DOSSIER}" },
  { "type": "EndIf" },

  // startswith + endswith — nouveauté V7+
  { "type": "If", "ifVar": "NOM_MEDECIN", "ifOp": "startswith", "ifValue": "Dr." },
  { "type": "LogMessage", "level": "INFO", "message": "Médecin détecté" },
  { "type": "EndIf" },

  { "type": "If", "ifVar": "FICHIER", "ifOp": "endswith", "ifValue": ".pdf" },
  { "type": "LogMessage", "level": "INFO", "message": "Fichier PDF : $VAR{FICHIER}" },
  { "type": "EndIf" }
]
03Boucles & ForEach
🔁ForEach CSV + RepeatBlock + GotoLabelBoucles
ForEach sur CSV Copier
[
  { "type": "ForEach", "forVar": "LIGNE", "forSource": "csv",
    "forCSV": "C:\\data\\donnees.csv" },
    { "type": "DictGet", "dictVar": "LIGNE", "key": "ID_DOSSIER", "varName": "ID_DOSSIER" },
    { "type": "DictGet", "dictVar": "LIGNE", "key": "NOM", "varName": "NOM" },
    { "type": "LogMessage", "level": "INFO", "message": "Traitement : $VAR{NOM} — ID $VAR{ID_DOSSIER}" },
  { "type": "EndForEach" }
]
04Macros & CallSequence V8
📦DefineMacro + CallSequence scope local + returnVarV7/V8
JSON Copier
[
  // Macro réutilisable avec paramètres
  { "type": "DefineMacro", "macroName": "SAISIR_CHAMP" },
    { "type": "LeftClick", "x": "$VAR{POS_X}", "y": "$VAR{POS_Y}" },
    { "type": "TypeTextClipboard", "text": "$VAR{VALEUR}" },
  { "type": "EndMacro" },

  { "type": "CallMacro", "macroName": "SAISIR_CHAMP",
    "macroParams": { "POS_X": "500", "POS_Y": "320", "VALEUR": "$VAR{ID_DOSSIER}" } },

  // CallSequence V8 — scope isolé + returnVar
  { "type": "CallSequence",
    "seqPath": "C:\\seq\\valider_id.json",
    "scope": "local",
    "returnVar": "VALIDATION_OK",
    "inputVars": { "ID_DOSSIER": "$VAR{ID_DOSSIER}" } },
  { "type": "LogMessage", "level": "INFO", "message": "Validation ID_DOSSIER : $VAR{VALIDATION_OK}" }
]
05OCR & Vision
🔍ReadTextOnScreen → RegexExtract → ClickOnTextOCR Tesseract
JSON Copier
[
  { "type": "ReadTextOnScreen",
    "x": 0, "y": 0, "w": 800, "h": 400,
    "lang": "fra", "varName": "OCR_TEXTE", "preprocess": true },
  { "type": "RegexExtract",
    "source": "OCR_TEXTE", "pattern": "ID_DOSSIER[:\\s]*(\\d{6,8})",
    "varName": "ID_DOSSIER", "group": 1 },
  { "type": "ClickOnText", "text": "Valider",
    "x": 0, "y": 0, "w": 1920, "h": 1080,
    "lang": "fra", "ignoreCase": true },
  { "type": "WaitForTextOnScreen", "text": "Traitement terminé",
    "timeout": 30000, "lang": "fra", "varName": "OCR_RESULT" }
]
06CSV / Excel / SQLite
📊ReadCSV → SQLite → WriteExcelDonnées
JSON Copier
[
  { "type": "ReadCSV", "path": "C:\\data\\entrees.csv",
    "varName": "LIGNES", "delimiter": ";" },
  { "type": "ListLength", "varName": "LIGNES", "outVar": "NB" },
  { "type": "SQLiteQuery",
    "dbPath": "C:\\db\\donnees.db",
    "sql": "SELECT * FROM records WHERE categorie = '$VAR{SERVICE}'",
    "varName": "SQL_RESULTS" },
  { "type": "WriteExcel",
    "path": "C:\\rapports\\rapport.xlsx",
    "sheet": "Résultats", "varName": "SQL_RESULTS" }
]
07Vault — Secrets chiffrés
🔐VaultStore → VaultGet → utilisation dans SendMailSécurité
JSON Copier
[
  { "type": "VaultStore", "alias": "SMTP_PASSWORD", "value": "MonMotDePasse" },
  { "type": "VaultGet", "alias": "SMTP_PASSWORD", "varName": "SMTP_PWD" },
  { "type": "SendMail",
    "smtpHost": "smtp.mon-serveur.local", "smtpPort": 587,
    "smtpUser": "automation@mon-serveur.local", "smtpPass": "$VAR{SMTP_PWD}",
    "mailTo": "[email protected]",
    "subject": "Rapport automatique $VAR{DATE}",
    "body": "<p>Traitement terminé. $VAR{NB_OK} OK.</p>",
    "useTLS": true }
]
08Réseau général Phase 8 V8
🏓PingHost + HttpRequest + TCPSendRéseau bas niveau
JSON Copier
[
  // Vérifier l'accessibilité d'un serveur (TCP connect)
  { "type": "PingHost", "host": "srv-app.mon-serveur.local", "port": 443,
    "timeout": 5, "varName": "SRV_DISPO" },
  { "type": "If", "ifVar": "SRV_DISPO", "ifOp": "==", "ifValue": "false" },
    { "type": "LogMessage", "level": "ERROR", "message": "Serveur applicatif inaccessible !" },
  { "type": "EndIf" },

  // Requête API REST
  { "type": "HttpRequest", "url": "https://api.mon-serveur.local/records/$VAR{ID_DOSSIER}",
    "method": "GET", "authType": "Bearer", "authValue": "$VAR{API_TOKEN}",
    "varName": "API_RESP", "varStatus": "HTTP_STATUS" },

  // TCP brut vers équipement distant
  { "type": "TCPSend", "host": "192.168.10.50", "port": 9000,
    "data": "GET_STATUS\\r\\n", "varName": "DEVICE_RESP", "timeout": 5 }
]
09SSH & SFTP V8
🐧SSHCommand + SFTPGet + SFTPPutSSH / SFTP — paramiko
JSON Copier
[
  { "type": "VaultGet", "alias": "SSH_PASS_SRV1", "varName": "SSH_PWD" },

  // Exécuter une commande sur serveur Linux
  { "type": "SSHCommand",
    "host": "srv-linux-01.mon-serveur.local", "port": 22,
    "username": "automation", "password": "$VAR{SSH_PWD}",
    "command": "ls /var/exports/*.csv | wc -l",
    "varStdout": "NB_FICHIERS", "varCode": "SSH_RC", "timeout": 30 },

  // Télécharger un fichier CSV
  { "type": "SFTPGet",
    "host": "srv-linux-01.mon-serveur.local", "port": 22,
    "username": "automation", "password": "$VAR{SSH_PWD}",
    "remotePath": "/var/exports/resultats.csv",
    "localPath": "C:\\tmp\\resultats.csv" },

  // Envoyer un rapport traité
  { "type": "SFTPPut",
    "host": "srv-linux-01.mon-serveur.local", "port": 22,
    "username": "automation", "password": "$VAR{SSH_PWD}",
    "localPath": "C:\\rapports\\rapport.xlsx",
    "remotePath": "/var/rapports/rapport.xlsx" }
]
10LDAP / Active Directory V8
👤ADGetUserInfo + ADCheckGroup + LDAPSearchLDAP / AD — ldap3
JSON Copier
[
  { "type": "VaultGet", "alias": "LDAP_PASS", "varName": "LDAP_PWD" },

  { "type": "ADGetUserInfo",
    "ldapHost": "ad.mon-serveur.local", "ldapPort": 389,
    "ldapUser": "[email protected]", "ldapPass": "$VAR{LDAP_PWD}",
    "searchBase": "DC=mon-domaine,DC=local",
    "username": "mon.utilisateur", "varName": "USER_INFO" },
  { "type": "DictGet", "dictVar": "USER_INFO",
    "key": "displayName", "varName": "NOM_COMPLET" },

  { "type": "ADCheckGroup",
    "ldapHost": "ad.mon-serveur.local",
    "ldapUser": "[email protected]", "ldapPass": "$VAR{LDAP_PWD}",
    "searchBase": "DC=mon-domaine,DC=local",
    "username": "mon.utilisateur", "groupName": "GRP__AUTOMATION",
    "varName": "EST_MEMBRE" }
]
11IMAP — Messagerie V8
📧IMAPReadLast + IMAPGetAttachment + IMAPMarkReadIMAP natif
JSON Copier
[
  { "type": "VaultGet", "alias": "MAIL_PWD", "varName": "MPWD" },

  { "type": "IMAPReadLast",
    "imapHost": "mail.mon-serveur.local", "imapPort": 993,
    "imapUser": "[email protected]", "imapPass": "$VAR{MPWD}",
    "mailbox": "INBOX", "criteria": "UNSEEN FROM [email protected]",
    "varSubject": "SUJET", "varBody": "CORPS", "varFrom": "FROM" },

  { "type": "IMAPGetAttachment",
    "imapHost": "mail.mon-serveur.local",
    "imapUser": "[email protected]", "imapPass": "$VAR{MPWD}",
    "criteria": "UNSEEN FROM [email protected]",
    "savePath": "C:\\imports\\serveur", "filenamePattern": "*.pdf",
    "varName": "PJ_PATH" },

  { "type": "IMAPMarkRead",
    "imapHost": "mail.mon-serveur.local",
    "imapUser": "[email protected]", "imapPass": "$VAR{MPWD}",
    "criteria": "FROM [email protected] UNSEEN", "maxMark": 10 }
]
12HL7 / Serveur V8
🏥HL7Send ADT^A01 + HL7ParseMessageHL7 MLLP — Serveur
JSON Copier
[
  { "type": "HL7Send",
    "host": "hl7-engine.mon-serveur.local", "port": 2575,
    "message": "MSH|^~\\&|AS400|ORG|APP|ORG||ADT^A01|MSG001|P|2.5\rPID|||$VAR{ID_DOSSIER}^^^^ID_DOSSIER||$VAR{NOM}||$VAR{DDN}|M",
    "varName": "HL7_ACK", "timeout": 10 },

  { "type": "If", "ifVar": "HL7_ACK", "ifOp": "contient", "ifValue": "AA" },
    { "type": "LogMessage", "level": "INFO", "message": "ADT envoyé — ACK AA" },
  { "type": "Else" },
    { "type": "LogMessage", "level": "ERROR", "message": "ACK inattendu : $VAR{HL7_ACK}" },
  { "type": "EndIf" },

  { "type": "HL7ParseMessage", "sourceVar": "HL7_ACK", "varName": "HL7_SEGMENTS" }
]
13IA / LLM Phase 9 V8
🤖OCR + LLMOCRCorrect + LLMExtractFields + LLMClassifyOllama local — 100% offline
Pipeline complet offline : OCR → correction LLM → extraction champs → classification document. Aucune donnée ne quitte le réseau local.
JSON Copier
[
  { "type": "ExtractTextFromImage",
    "path": "$VAR{SCAN_PATH}", "lang": "fra", "varName": "OCR_BRUT" },

  { "type": "LLMOCRCorrect",
    "sourceVar": "OCR_BRUT",
    "context": "compte-rendu",
    "varName": "OCR_CORRIGE",
    "provider": "ollama", "ollamaModel": "llama3" },

  { "type": "LLMExtractFields",
    "sourceVar": "OCR_CORRIGE",
    "fields": ["NomContact", "DateNaissance", "ID_DOSSIER", "Diagnostic"],
    "varName": "CHAMPS", "varPrefix": "EXT_",
    "provider": "ollama", "ollamaModel": "llama3" },

  { "type": "LLMClassify",
    "sourceVar": "OCR_CORRIGE",
    "categories": ["Ordonnance", "Compte-rendu", "Résultat analyse", "Autre"],
    "varName": "TYPE_DOC", "varConfidence": "CONFIANCE" },

  { "type": "LogMessage", "level": "INFO",
    "message": "Type: $VAR{TYPE_DOC} | ID_DOSSIER: $VAR{EXT_ID_DOSSIER} | Contact: $VAR{EXT_NomContact}" }
]
14Multi-machine Phase 11 V8
🖥️RemoteRunSequence + SharedVarSet/GetMulti-machine
JSON Copier
[
  { "type": "VaultGet", "alias": "AGENT_TOKEN", "varName": "ATOKEN" },

  // Vérifier l'état de l'agent distant
  { "type": "AgentStatus", "agentHost": "PC-POSTE-01",
    "agentToken": "$VAR{ATOKEN}", "varOnline": "AGENT_OK" },

  // Lancer une séquence sur le poste distant et attendre
  { "type": "RemoteRunSequence",
    "agentHost": "PC-POSTE-01", "agentToken": "$VAR{ATOKEN}",
    "seqPath": "C:\\seq\\traitement.json",
    "varsIn": { "ID_DOSSIER": "$VAR{ID_DOSSIER}", "DATE": "$VAR{DATE}" },
    "returnVars": ["RESULT"], "varPrefix": "LABO_",
    "wait": true, "timeout": 120 },

  // Variables partagées réseau — incrémenter un compteur global
  { "type": "SharedVarLock", "sharedFile": "Z:\\automate\\shared.json",
    "lockName": "COMPTEUR", "action": "acquire", "varName": "LOCK_OK" },
  { "type": "SharedVarGet", "sharedFile": "Z:\\automate\\shared.json",
    "key": "GLOBAL_TRAITES", "varName": "C", "default": "0" },
  { "type": "CounterIncrement", "varName": "C", "step": 1 },
  { "type": "SharedVarSet", "sharedFile": "Z:\\automate\\shared.json",
    "key": "GLOBAL_TRAITES", "value": "$VAR{C}" },
  { "type": "SharedVarLock", "sharedFile": "Z:\\automate\\shared.json",
    "lockName": "COMPTEUR", "action": "release" }
]
15Engine V2 — Async & Checkpoint V8
AsyncAction + AwaitAsync — opération longue en arrière-planEngine V8
JSON Copier
[
  // Lancer un backup SSH sans bloquer la séquence
  { "type": "AsyncAction", "asyncId": "BACKUP",
    "action": { "type": "SSHCommand",
      "host": "srv-backup.mon-serveur.local", "username": "automation",
      "password": "$VAR{SSH_PWD}",
      "command": "rsync -avz /data/ /backups/",
      "varStdout": "BACKUP_LOG", "timeout": 300 } },

  // Pendant ce temps — traitement local
  { "type": "LogMessage", "level": "INFO", "message": "Backup démarré, traitement local..." },
  { "type": "ReadCSV", "path": "C:\\data.csv", "varName": "DATA" },

  // Attendre la fin du backup (max 6 min)
  { "type": "AwaitAsync", "asyncId": "BACKUP",
    "varOk": "BACKUP_OK", "varMsg": "BACKUP_MSG", "timeout": 360 },

  { "type": "LogMessage", "level": "INFO",
    "message": "Backup : $VAR{BACKUP_OK} — $VAR{BACKUP_MSG}" }
]
16Plugin API Phase 7 V8
🔌Actions du plugin exemple livréPlugin Exemple
JSON Copier
[
  // Plugin_LogID — extraire l'ID_DOSSIER depuis un texte OCR
  { "type": "Plugin_LogID", "sourceVar": "OCR_TEXTE", "outVar": "ID_DOSSIER" },

  // Plugin_FormatDossier — nom dossier standard
  { "type": "Plugin_FormatDossier",
    "nom": "$VAR{NOM}", "prenom": "$VAR{PRENOM}", "id_dossier": "$VAR{ID_DOSSIER}",
    "outVar": "DOSSIER_NOM" },

  // Plugin_GetService — résoudre un code UF en libellé
  { "type": "Plugin_GetService", "uf": "5010", "outVar": "SERVICE_LIB" },

  { "type": "LogMessage", "level": "INFO",
    "message": "Dossier : $VAR{DOSSIER_NOM} — Service : $VAR{SERVICE_LIB}" }
]
💡
Copiez plugins/mon_plugin_exemple/, renommez-le, modifiez manifest.json et plugin.py. Cliquez "🔄 Hot-reload" dans l'onglet Plugins — aucun redémarrage nécessaire.
17Audit & Vault V2 Phase 12 V8
📋Vérifier l'intégrité du journal d'auditSécurité avancée
Script Python d'audit (RunPython) Copier
[
  // Vérifier l'intégrité du journal d'audit via RunPython
  { "type": "RunPython",
    "code": "from audit import get_audit\naud = get_audit()\nok, msg, nb = aud.verify()\nctx['vars'].set('AUDIT_OK', 'true' if ok else 'false')\nctx['vars'].set('AUDIT_MSG', msg)\nctx['vars'].set('AUDIT_NB', str(nb))\noutput = f'Audit: {nb} entrees, integrite={ok}'",
    "varName": "PY_OUT" },

  { "type": "If", "ifVar": "AUDIT_OK", "ifOp": "==", "ifValue": "false" },
    { "type": "LogMessage", "level": "ERROR",
      "message": "ALERTE SÉCURITÉ : intégrité audit compromise ! $VAR{AUDIT_MSG}" },
    { "type": "SendMail", "mailTo": "[email protected]",
      "subject": "ALERTE : Journal audit compromis",
      "body": "$VAR{AUDIT_MSG}", "smtpHost": "smtp.mon-serveur.local", "smtpPort": 587,
      "smtpUser": "automation@mon-serveur.local", "smtpPass": "$VAR{SMTP_PWD}", "useTLS": true },
  { "type": "EndIf" },

  { "type": "LogMessage", "level": "INFO",
    "message": "Audit : $VAR{AUDIT_NB} entrées vérifiées — $VAR{AUDIT_MSG}" }
]
SC-1Scénario : Connexion automatique à une application
Vault → LaunchApp → WaitForWindow → LoginScénario complet
Séquence complète Copier
[
  { "type": "Comment", "text": "=== Connexion automatique HOSPILOG ===" },
  { "type": "VaultGet", "alias": "HOSPILOG_PWD", "varName": "PWD" },
  { "type": "LaunchApp", "appPath": "C:\\Program Files\\Hospilog\\hospilog.exe" },
  { "type": "WaitForWindow", "windowTitle": "Connexion", "timeout": 10000, "breakOnError": true },
  { "type": "Delay", "duration": 500 },
  { "type": "LeftClick", "x": 500, "y": 320 },
  { "type": "TypeTextClipboard", "text": "t.ruard" },
  { "type": "KeyPress", "key": "TAB" },
  { "type": "TypeTextClipboard", "text": "$VAR{PWD}" },
  { "type": "KeyPress", "key": "ENTER" },
  { "type": "WaitForWindow", "windowTitle": "Accueil", "timeout": 15000 },
  { "type": "LogMessage", "level": "INFO", "message": "Connecté à HOSPILOG" }
]
SC-2Scénario : Batch OCR — extraction ID depuis dossiers scannés
ListFiles → ForEach → ExtractTextFromImage → RegexExtract → SQLiteScénario complet
Séquence complète Copier
[
  { "type": "Comment", "text": "=== Batch OCR extraction ID ===" },
  { "type": "SetVariable", "varName": "NB_OK", "varValue": "0", "varType": "int" },
  { "type": "SetVariable", "varName": "NB_KO", "varValue": "0", "varType": "int" },
  { "type": "ListFiles", "path": "C:\\scans", "pattern": "*.pdf", "varName": "SCANS" },

  { "type": "ForEach", "forVar": "SCAN", "forSource": "list", "forList": "SCANS" },

    { "type": "ExtractTextFromImage", "path": "$VAR{SCAN}",
      "lang": "fra", "varName": "OCR_TEXT" },

    { "type": "RegexExtract", "source": "OCR_TEXT",
      "pattern": "ID_DOSSIER[:\\s]*(\\d{6,8})", "varName": "ID_DOSSIER", "group": 1 },

    { "type": "If", "ifVar": "ID_DOSSIER", "ifOp": "!=", "ifValue": "" },
      { "type": "SQLiteExecute", "sql": "INSERT OR IGNORE INTO extractions(scan,id_dossier,ts) VALUES('$VAR{SCAN}','$VAR{ID_DOSSIER}',datetime('now'))" },
      { "type": "CounterIncrement", "varName": "NB_OK", "step": 1 },
    { "type": "Else" },
      { "type": "LogMessage", "level": "WARN", "message": "ID non trouvé dans $VAR{SCAN}" },
      { "type": "CounterIncrement", "varName": "NB_KO", "step": 1 },
    { "type": "EndIf" },

  { "type": "EndForEach" },

  { "type": "TextToSpeech", "text": "Batch OCR terminé. $VAR{NB_OK} scans traités. $VAR{NB_KO} ID non détectés.", "rate": 140 }
]
SC-3Scénario V8 : Récupération automatique résultats serveur via SFTP V8
PingHost → SFTPList → ForEach → SFTPGet → ReadCSV → SQLite → SFTPDeleteScénario complet V8
Séquence complète Copier
[
  { "type": "Comment", "text": "=== SC-3 : Récupération résultats serveur via SFTP ===" },
  { "type": "VaultGet", "alias": "SFTP_SERVER_PWD", "varName": "SFTP_PWD" },

  // Vérifier l'accès au serveur distant
  { "type": "PingHost", "host": "sftp-serveur.mon-serveur.local", "port": 22, "timeout": 5, "varName": "SERVEUR_DISPO" },
  { "type": "If", "ifVar": "SERVEUR_DISPO", "ifOp": "==", "ifValue": "false" },
    { "type": "LogMessage", "level": "ERROR", "message": "Serveur SFTP inaccessible", "breakOnError": true },
  { "type": "EndIf" },

  // Lister les fichiers CSV disponibles
  { "type": "SFTPList",
    "host": "sftp-serveur.mon-serveur.local", "port": 22,
    "username": "automation", "password": "$VAR{SFTP_PWD}",
    "remotePath": "/exports/resultats", "pattern": "*.csv",
    "varName": "FICHIERS_SERVEUR" },
  { "type": "ListLength", "varName": "FICHIERS_SERVEUR", "outVar": "NB_FICHIERS" },
  { "type": "LogMessage", "level": "INFO", "message": "$VAR{NB_FICHIERS} fichier(s) fichier(s) à télécharger" },

  // Télécharger et traiter chaque fichier
  { "type": "ForEach", "forVar": "FNAME", "forSource": "list", "forList": "FICHIERS_SERVEUR" },

    { "type": "SFTPGet",
      "host": "sftp-serveur.mon-serveur.local", "port": 22,
      "username": "automation", "password": "$VAR{SFTP_PWD}",
      "remotePath": "/exports/resultats/$VAR{FNAME}",
      "localPath": "C:\\imports\\serveur\\$VAR{FNAME}" },

    { "type": "ReadCSV", "path": "C:\\imports\\serveur\\$VAR{FNAME}",
      "varName": "RESULTATS", "delimiter": ";" },

    { "type": "SQLiteExecute",
      "dbPath": "C:\\db\\donnees.db",
      "sql": "INSERT INTO imports (fichier, nb_lignes, ts) VALUES ('$VAR{FNAME}', (SELECT count(*) FROM json_each('$VAR{RESULTATS}')), datetime('now'))" },

    // Supprimer le fichier distant après traitement
    { "type": "SFTPDelete",
      "host": "sftp-serveur.mon-serveur.local", "port": 22,
      "username": "automation", "password": "$VAR{SFTP_PWD}",
      "remotePath": "/exports/resultats/$VAR{FNAME}" },

  { "type": "EndForEach" },

  { "type": "ToastNotification", "title": "Résultats",
    "message": "$VAR{NB_FICHIERS} fichier(s) importés depuis le serveur distant", "timeout": 8 }
]
SC-4Scénario V8 : IA — extraction intelligente de documents V8
ListFiles → ForEach → OCR → LLMOCRCorrect → LLMExtractFields → LLMClassify → SQLiteScénario IA — Ollama local
Séquence complète (100% offline avec Ollama) Copier
[
  { "type": "Comment", "text": "=== SC-4 : Extraction IA documents (Ollama offline) ===" },
  { "type": "SetVariable", "varName": "NB_TRAITES", "varValue": "0", "varType": "int" },
  { "type": "ListFiles", "path": "C:\\dossiers_scans", "pattern": "*.png", "varName": "IMAGES" },

  { "type": "ForEach", "forVar": "IMG", "forSource": "list", "forList": "IMAGES" },

    // 1. OCR Tesseract
    { "type": "ExtractTextFromImage", "path": "$VAR{IMG}", "lang": "fra", "varName": "OCR_BRUT" },

    // 2. Correction OCR par LLM local
    { "type": "LLMOCRCorrect", "sourceVar": "OCR_BRUT",
      "context": "document AutomationSequence",
      "varName": "OCR_OK", "provider": "ollama", "ollamaModel": "llama3" },

    // 3. Extraction champs structurés
    { "type": "LLMExtractFields", "sourceVar": "OCR_OK",
      "fields": ["NomContact", "DateNaissance", "ID_DOSSIER", "Medecin", "Service", "Diagnostic"],
      "varName": "CHAMPS", "varPrefix": "F_",
      "provider": "ollama", "ollamaModel": "llama3" },

    // 4. Classifier le type de document
    { "type": "LLMClassify", "sourceVar": "OCR_OK",
      "categories": ["Ordonnance", "Compte-rendu", "Résultat analyse", "Consentement", "Autre"],
      "varName": "TYPE_DOC", "provider": "ollama", "ollamaModel": "llama3" },

    // 5. Stocker dans SQLite
    { "type": "SQLiteExecute",
      "dbPath": "C:\\db\\extraction_ia.db",
      "sql": "INSERT INTO extractions(img,id_dossier,contact,medecin,service,diagnostic,type_doc,ts) VALUES('$VAR{IMG}','$VAR{F_ID_DOSSIER}','$VAR{F_NomContact}','$VAR{F_Medecin}','$VAR{F_Service}','$VAR{F_Diagnostic}','$VAR{TYPE_DOC}',datetime('now'))" },

    { "type": "CounterIncrement", "varName": "NB_TRAITES", "step": 1 },
  { "type": "EndForEach" },

  { "type": "LLMSummarize",
    "sourceVar": "OCR_OK", "maxWords": 50,
    "tone": "technique", "varName": "RESUME_FINAL",
    "provider": "ollama" },

  { "type": "LogMessage", "level": "INFO", "message": "Extraction IA terminée : $VAR{NB_TRAITES} dossiers traités" }
]
SC-5Scénario V8 : Traitement parallèle sur 3 postes distants V8
ParallelBlock → 3x RemoteRunSequence → collect résultats → rapportScénario Multi-machine
Séquence complète Copier
[
  { "type": "Comment", "text": "=== SC-5 : Traitement parallèle 3 postes ===" },
  { "type": "VaultGet", "alias": "AGENT_TOKEN", "varName": "ATOKEN" },

  // Vérifier les 3 agents
  { "type": "AgentStatus", "agentHost": "PC-POSTE-01", "agentToken": "$VAR{ATOKEN}", "varOnline": "A1_OK" },
  { "type": "AgentStatus", "agentHost": "PC-POSTE-02", "agentToken": "$VAR{ATOKEN}", "varOnline": "A2_OK" },
  { "type": "AgentStatus", "agentHost": "PC-CARDIO-03", "agentToken": "$VAR{ATOKEN}", "varOnline": "A3_OK" },

  // Lancer les 3 séquences en parallèle (max 3 workers)
  { "type": "ParallelBlock", "maxWorkers": 3 },

    { "type": "RemoteRunSequence",
      "agentHost": "PC-POSTE-01", "agentToken": "$VAR{ATOKEN}",
      "seqPath": "C:\\seq\\traitement_donnees.json",
      "varsIn": { "POSTE": "POSTE-01" },
      "returnVars": ["NB_OK"], "varPrefix": "L1_",
      "wait": true, "timeout": 180 },

    { "type": "RemoteRunSequence",
      "agentHost": "PC-POSTE-02", "agentToken": "$VAR{ATOKEN}",
      "seqPath": "C:\\seq\\traitement_radio.json",
      "returnVars": ["NB_OK"], "varPrefix": "R2_",
      "wait": true, "timeout": 180 },

    { "type": "RemoteRunSequence",
      "agentHost": "PC-CARDIO-03", "agentToken": "$VAR{ATOKEN}",
      "seqPath": "C:\\seq\\traitement_cardio.json",
      "returnVars": ["NB_OK"], "varPrefix": "C3_",
      "wait": true, "timeout": 180 },

  { "type": "EndParallel" },

  { "type": "LogMessage", "level": "INFO",
    "message": "Résultats — Poste1: $VAR{L1_NB_OK} | Poste2: $VAR{R2_NB_OK} | Poste3: $VAR{C3_NB_OK}" }
]
SC-6Scénario : Sauvegarde et archivage automatique de fichiers
ListFiles → ForEach → FileCopy → SQLite → ToastScénario complet
Séquence complète Copier
[
  { "type": "Comment", "text": "=== Archivage automatique exports quotidiens ===" },
  { "type": "RunPython",
    "code": "from datetime import datetime\nctx['vars'].set('DATE', datetime.now().strftime('%Y%m%d'))\nctx['vars'].set('ARCHIVE_DIR', f\"D:\\\\archives\\\\{datetime.now().strftime('%Y%m%d')}\\\\\\\")output = 'Date initialisée'" },
  { "type": "ListFiles", "path": "C:\\exports", "pattern": "*.csv", "varName": "FICHIERS" },
  { "type": "ListLength", "varName": "FICHIERS", "outVar": "NB" },
  { "type": "LogMessage", "level": "INFO", "message": "$VAR{NB} fichiers à archiver" },

  { "type": "ForEach", "forVar": "F", "forSource": "list", "forList": "FICHIERS" },
    { "type": "RunPython",
      "code": "import os\nf=ctx['vars'].get('F')\nbn=os.path.basename(f)\nctx['vars'].set('FNAME',bn)\nctx['vars'].set('DEST',ctx['vars'].get('ARCHIVE_DIR')+bn)\noutput=f'Archivage {bn}'" },
    { "type": "FileCopy", "src": "$VAR{F}", "dst": "$VAR{DEST}" },
    { "type": "SQLiteExecute",
      "sql": "INSERT INTO archives(fichier,dest,ts) VALUES('$VAR{FNAME}','$VAR{DEST}',datetime('now'))" },
  { "type": "EndForEach" },

  { "type": "ToastNotification", "title": "Archivage",
    "message": "$VAR{NB} fichiers archivés le $VAR{DATE}", "timeout": 8 }
]
SC-7Scénario V8 : Onboarding automatisé — création compte AD + mail bienvenue V8
ReadCSV → ForEach → ADGetUserInfo → LDAPSearch → SendMail → SQLiteScénario Onboarding RH
Séquence complète Copier
[
  { "type": "Comment", "text": "=== SC-7 : Onboarding RH — vérification comptes AD + mail bienvenue ===" },
  { "type": "VaultGet", "alias": "LDAP_PASS", "varName": "LPWD" },
  { "type": "VaultGet", "alias": "SMTP_PASSWORD", "varName": "SMTP_PWD" },

  // Lire la liste des nouveaux arrivants depuis RH
  { "type": "ReadCSV", "path": "C:\\rh\\nouveaux_arrivants.csv",
    "varName": "ARRIVANTS", "delimiter": ";" },

  { "type": "ForEach", "forVar": "PERSONNE", "forSource": "list", "forList": "ARRIVANTS" },

    { "type": "DictGet", "dictVar": "PERSONNE", "key": "login", "varName": "LOGIN" },
    { "type": "DictGet", "dictVar": "PERSONNE", "key": "email", "varName": "EMAIL" },
    { "type": "DictGet", "dictVar": "PERSONNE", "key": "service", "varName": "SERVICE" },

    // Vérifier que le compte AD existe bien
    { "type": "ADGetUserInfo",
      "ldapHost": "ad.mon-serveur.local", "ldapPort": 389,
      "ldapUser": "[email protected]", "ldapPass": "$VAR{LPWD}",
      "searchBase": "DC=mon-domaine,DC=local",
      "username": "$VAR{LOGIN}", "varName": "AD_INFO" },
    { "type": "DictGet", "dictVar": "AD_INFO", "key": "displayName", "varName": "NOM_COMPLET" },

    // Vérifier appartenance groupe service
    { "type": "ADCheckGroup",
      "ldapHost": "ad.mon-serveur.local",
      "ldapUser": "[email protected]", "ldapPass": "$VAR{LPWD}",
      "searchBase": "DC=mon-domaine,DC=local",
      "username": "$VAR{LOGIN}",
      "groupName": "GRP_$VAR{SERVICE}",
      "varName": "DANS_GROUPE" },

    // Envoyer le mail de bienvenue si compte OK
    { "type": "If", "ifVar": "NOM_COMPLET", "ifOp": "!=", "ifValue": "" },
      { "type": "SendMail",
        "smtpHost": "smtp.mon-serveur.local", "smtpPort": 587,
        "smtpUser": "automation@mon-serveur.local", "smtpPass": "$VAR{SMTP_PWD}",
        "mailTo": "$VAR{EMAIL}",
        "subject": "Bienvenue sur AutomationSequence, $VAR{NOM_COMPLET}",
        "body": "<h2>Bienvenue $VAR{NOM_COMPLET}</h2><p>Votre compte AD ($VAR{LOGIN}) est actif. Service : $VAR{SERVICE}. Appartenance groupe : $VAR{DANS_GROUPE}.</p>",
        "useTLS": true },
      { "type": "SQLiteExecute",
        "sql": "INSERT INTO onboarding(login,nom,email,service,groupe_ok,ts) VALUES('$VAR{LOGIN}','$VAR{NOM_COMPLET}','$VAR{EMAIL}','$VAR{SERVICE}','$VAR{DANS_GROUPE}',datetime('now'))" },
    { "type": "EndIf" },

  { "type": "EndForEach" },
  { "type": "LogMessage", "level": "INFO", "message": "Onboarding RH term