Aller au contenu principal

Machine à états des leads

Diagramme

                     Scan Outlook


┌─────────────────────┐
│ Produits détectés? │
└─────────────────────┘
Oui │ │ Non
▼ ▼
┌──────────┐ ┌────────┐
│ devis │ │ ignore │
│non demandé│ └────────┘
└──────────┘

│ POST /api/generate-quote

┌───────────────┐
│ devis demandé │
└───────────────┘

│ (réception PDF dans bdd/quotes/)
│ POST /api/match-quote ou upload

┌───────────────┐
│ devis reçu │
└───────────────┘

│ POST /api/send?direct=1

┌───────────────┐
│ traité │
└───────────────┘

Valeurs JSON

Valeur JSONLabel UIDéclencheur
ignoreIgnoréScan sans produit détecté
devis non demandeDevis non demandéScan avec produit détecté
devis demandeDevis demandéPOST /api/generate-quote (envoi réel)
devis recuDevis reçuPDF associé au lead
traiteTraitéPOST /api/send?direct=1

Transitions automatiques

Lors du scan (Invoke-Scan)

if ($products.Count -eq 0) {
$status = 'ignore'
} else {
$status = 'devis non demande'
}
# Si un QUOTE_*.pdf est détecté en PJ du mail
if ($hasQuotePdf) {
$status = 'devis recu'
}

Lors de l'envoi de la demande de devis

Invoke-GenerateQuotedevis demande (seulement si preview=0)

Lors de l'association d'un devis

Invoke-MatchQuote ou upload → si status == 'devis demande'devis recu

Lors de l'envoi client

Invoke-Send avec direct=1traite

Synchronisation frontend

Le statut affiché dans l'UI est lu depuis CURRENT.status (état global app.js).

  • badge.js : STATUS_LABELS mappe les valeurs JSON → labels affichés
  • mselect.js : ALL_STATUSES liste les statuts pour les filtres

Ces deux constantes doivent rester synchronisées avec les valeurs JSON ci-dessus.

Modification manuelle du statut

L'utilisateur peut changer le statut manuellement via le badge cliquable dans lead-detail.js :

async function changeStatus(s) {
await api(`/api/lead?id=${CURRENT.id}`, { method: 'POST', body: { status: s } });
CURRENT.status = s;
renderDetail();
}

Il n'y a pas de validation des transitions côté backend — tout statut valide est accepté.