# Document de passation : flux « Leads PME »

Exemple du document remis avec chaque projet. Ici pour le flux de démonstration : un formulaire
Typeform ou Tally entre, le lead sort qualifié dans le CRM, avec une proposition de rendez-vous et une
alerte à l'équipe. Les services tiers de cette démo (CRM, modèle de langage, agenda, email, Slack) sont
**simulés** par de petits faux services ; les données sont fictives.

Version de n8n : 2.43.8 (image `n8nio/n8n:2.43.8`, épinglée par son digest
`sha256:a18edcf018198b33b5488fb47ededafe11e0b10d28f65b9535b7c447c9ce3b2c`). Remis le 31 octobre 2026.

## 1. Ce que fait le flux

1. **Réception** : webhook `POST /webhook/lead`. Accepte la forme des webhooks Typeform (réponses
   repérées par la `ref` du champ) et Tally (champs repérés par leur libellé).
2. **Normalisation et validation** : email en minuscules et sans espaces, téléphone suisse remis au
   format +41, budget en nombre. Refus si le nom, l'email, l'identifiant de soumission ou le
   consentement au recontact manque, ou si l'email ou le téléphone est invalide. Un refus répond
   `422` avec la liste des erreurs et poste une note dans `#ops-alertes`. Rien n'est écrit.
3. **Dédoublonnage** : recherche du contact par email dans le CRM.
   - même soumission déjà reçue (renvoi du webhook, rejeu) : **rejeu**, aucune étape ne produit un
     second effet ;
   - même personne, nouvelle soumission : **doublon**, le contact est mis à jour, pas de second email.
4. **Qualification par le modèle** (simulé dans la démo) : score de 0 à 100, catégorie, motif.
   Délai de 4 s, deux tentatives. La réponse est **contrôlée dans le code** (score entier dans les
   bornes, catégorie connue et cohérente avec le score, motif de 280 caractères au plus). Réponse hors
   contrat, illisible ou trop lente : le lead part en qualification manuelle, il n'est jamais perdu ni
   classé au hasard. Un rejeu ou un doublon reprend la qualification déjà enregistrée, sans nouvel appel.
5. **CRM** : création ou mise à jour du contact, clé d'idempotence = identifiant de soumission.
6. **Suite** : lead chaud (score 60 ou plus) : trois créneaux de 30 minutes proposés par email.
   Sinon : accusé de réception. Doublon : pas d'email.
7. **Alerte** : message dans `#ventes` avec le contact, le score et la suite donnée.

## 2. Le standard de livraison

| Garantie | Comment elle est tenue | Où la voir |
|---|---|---|
| Une panne se voit | Workflow d'erreur « Alerte d'échec » désigné dans les réglages du flux : il écrit l'incident (exécution, étape, message) et poste dans `#ops-alertes`. | Cas « CRM en panne » |
| Une erreur passagère se rattrape seule | Reprise sur chaque appel externe : CRM 3 tentatives à 2 s, modèle 2 tentatives à 0,5 s, autres 3 tentatives à 1 s. | Cas « CRM instable » |
| Rejouer ne crée pas de doublon | Clé `Idempotency-Key` sur le CRM, l'agenda, l'email et Slack, dérivée de l'identifiant de soumission. | Cas « livraison répétée » et rejeu après panne |
| Le modèle ne décide pas seul | Contrôles obligatoires en code après chaque réponse ; repli en qualification manuelle. | Cas « modèle trop lent » et « hors contrat » |
| Aucune donnée invalide n'entre | Validation avant toute écriture, rejet tracé. | Cas « formulaire malformé » |
| Le client peut reprendre | Ce document, l'export JSON des deux workflows, le jeu de cas rejouable. | Ce dossier |

## 3. Installation chez le client

1. Importer `flux-leads.n8n.json` et `alerte-echec.n8n.json` (menu Workflows, Import from file, ou
   `n8n import:workflow --input=<fichier>`).
2. **Publier les deux workflows.** Constaté sur n8n 2.43.8 : un workflow d'erreur non publié n'est
   pas appelé (« Workflow "errorAlertDemo01" is not active and cannot be executed »).
3. Dans le nœud « Réglages du client » : seuil du lead chaud, canaux Slack.
4. Remplacer chaque nœud « (simulé) » par le nœud ou l'appel du vrai service (CRM, modèle, agenda,
   email, Slack), avec ses identifiants rangés dans les identifiants chiffrés de n8n. Aucun secret
   n'est écrit dans un workflow ni dans ce document.
5. Rejouer le jeu de cas sur l'instance du client avant la mise en service.

## 4. Exploiter

- **Une alerte `#ops-alertes` arrive** : ouvrir l'exécution citée, corriger la cause (souvent le
  service tiers), puis rejouer la soumission (renvoi depuis l'outil de formulaire, ou bouton de
  nouvelle tentative de l'exécution dans n8n). Le rejeu est sans risque de doublon.
- **Un formulaire est rejeté** : la note liste les champs en cause. Un champ renommé dans Typeform
  garde sa `ref` ; dans Tally, vérifier le libellé dans « Normaliser et valider ».
- **Leads « à qualifier »** : étiquette `qualification-manuelle` dans le CRM, à traiter à la main.
- **Rétention** : les exécutions réussies et en échec sont toutes gardées dans la démo ; chez le
  client, régler la durée de conservation selon sa politique de données.

## 5. Rejouer la démo

```sh
automation/up.sh          # faux services + n8n 2.43.8 en local, port 5703, 512 Mo
automation/import.sh      # import et publication des deux workflows (CLI officielle de n8n)
automation/run-cases.sh   # joue les 8 cas, relève les exécutions, écrit evidence/RESULTATS.md
automation/export.sh      # exporte les workflows tels que n8n les a enregistrés
automation/down.sh        # supprime conteneurs, réseau et volume
```

## 6. Limites connues

- Les services tiers sont simulés : la forme des appels suit les usages courants (recherche puis
  mise à jour, clé d'idempotence, réponse de chat au format compatible OpenAI), pas l'API exacte d'un
  CRM donné. Le branchement au vrai CRM du client fait partie du projet.
- Le dédoublonnage se fait par email. Un même prospect avec deux emails crée deux contacts.
- Pas testé : deux livraisons de la même soumission arrivées en même temps (les cas les jouent
  l'une après l'autre), la charge (plusieurs centaines de formulaires par minute), le mode file
  d'attente de n8n.
