Une commande est affichée « en cours » depuis neuf jours. Le commerce pense qu’elle attend le paiement, la logistique qu’elle est prête à partir et le support qu’un fournisseur doit répondre. Chacun lit le même statut, mais prend une décision différente. Le client reçoit une promesse vague et personne ne sait quelle action fera réellement avancer le dossier.
Cette zone grise naît rarement d’un manque de couleurs dans l’interface. Elle apparaît quand un mot mélange plusieurs faits, une attente et une responsabilité. Ajouter « en cours 2 » ou « traitement manuel » calme le besoin immédiat, puis dégrade les règles, les indicateurs et les intégrations. Le statut devient un résumé que plus personne ne peut expliquer.
Le vrai enjeu est d’éviter le risque qu’un mot produise plusieurs décisions. Un workflow robuste ne cherche pas le nombre minimal d’états à tout prix. Il décrit des situations métier observables, des transitions autorisées, leurs préconditions et leurs effets. Il distingue ce qui s’est passé de ce qui doit se passer. Le run peut ainsi retrouver pourquoi un dossier est bloqué, qui peut agir et comment reprendre sans correction directe en base.
Dans une démarche de développement web sur mesure, ce contrat relie domaine, interface, API, traitements asynchrones et support. Voici comment le construire à partir des dossiers réels.
Nommer une réalité métier observable
Un état répond à une question stable : le contrat est-il signé, la facture est-elle exigible, le colis a-t-il été remis au transporteur ? Il ne doit pas remplacer une note, une priorité ou le nom de la personne chargée du prochain geste. « Urgent », « litigieux » et « à rappeler » sont des attributs ou des tâches, pas nécessairement des étapes du cycle de vie.
Définissez chaque statut par des critères d’entrée vérifiables, les actions encore possibles et un critère de sortie. Ajoutez des exemples et contre-exemples. « Validé » reste ambigu tant qu’on ignore qui valide quoi : données, prix, conformité ou livraison. Le glossaire doit pouvoir être compris par le métier, le développeur et le support sans traductions différentes.
Distinguer état, motif et sous-processus
Une commande annulée garde un état « annulée » et un motif séparé : doublon, refus du client, stock indisponible ou fraude. Le motif explique la décision sans multiplier les états finaux. Si le motif ouvre un cycle propre avec droits et délais, modélisez plutôt un sous-processus relié, comme un litige ou un remboursement.
Dessiner le cycle de vie avant l’écran
Rejouez des dossiers nominaux, interrompus, corrigés et annulés. Pour chacun, inscrivez les faits dans l’ordre, l’acteur et la décision. Le diagramme vient après : il doit refléter le travail, pas l’organigramme ni les onglets existants. Les chemins rarement utilisés sont précieux, car ils révèlent les états artificiels et les sorties absentes.
Identifiez un début, plusieurs fins explicites et les attentes. Un état final n’accepte plus d’action métier ordinaire ; une réouverture crée une transition nommée et tracée. Un dossier archivé n’est pas forcément terminé : l’archivage relève souvent de la conservation, tandis que la clôture relève du domaine.
Traiter les branches parallèles
Paiement, préparation et contrôle documentaire peuvent progresser en parallèle. Les fusionner dans un seul statut produit une explosion combinatoire : « payé-partiel-prêt », puis ses variantes. Portez chaque cycle séparément et calculez une vue de synthèse pour l’utilisateur. La synthèse n’est jamais la source des transitions détaillées.
Contractualiser les transitions métier
Une transition possède une commande, un état de départ, un état d’arrivée, un acteur, des préconditions et des effets. « Expédier » exige par exemple une allocation de stock et une adresse exploitable ; elle crée un mouvement, une preuve et éventuellement un message. Le contrat précise aussi ce qui reste inchangé quand l’action échoue.
Les invariants simples peuvent être soutenus par des contraintes en base. La documentation officielle de PostgreSQL sur les contraintes rappelle cependant qu’une contrainte de ligne ne remplace pas une règle qui dépend d’autres lignes ou d’un processus. Gardez la validation métier dans le domaine et utilisez la base comme dernier rempart pour les propriétés qu’elle sait garantir.
Rendre les commandes idempotentes
Un double clic ou un message rejoué ne doit pas expédier deux fois. La commande porte une clé d’idempotence et retourne le résultat déjà produit. Le journal relie demande, transition et effets. Si une étape externe réussit puis que la réponse se perd, la reprise interroge cet état au lieu de relancer aveuglément l’effet.
Séparer état, action et autorisation
Masquer un bouton ne protège pas la transition. L’autorisation s’évalue côté serveur à partir du rôle, du périmètre, de l’état courant et parfois d’une séparation de fonctions. Un responsable peut approuver un montant dans son agence sans pouvoir approuver sa propre demande. Le refus donne une raison exploitable, pas seulement un code générique.
Évitez d’encoder le droit dans le statut, comme « validé-manager ». Le fait est « validé » ; l’auteur et sa délégation appartiennent à la trace. Cette séparation permet de faire évoluer les responsabilités sans migrer toutes les données historiques ni inventer un état par niveau hiérarchique.
Préserver une action de réparation
Le support ne doit pas choisir arbitrairement un état final. Préparez des commandes de réparation bornées : réémettre une notification, rattacher une preuve, reprendre une synchronisation ou demander une nouvelle validation. Chacune vérifie ses préconditions et laisse une trace. Les corrections de données restent exceptionnelles, revues et réconciliées.
Porter le temps et les attentes
« En attente » ne dit ni de qui, ni depuis quand, ni jusqu’à quand. Modélisez la cause, le responsable attendu, la date de début et l’échéance applicable. Une attente fournisseur et une attente client n’ont pas le même rappel, la même escalade ni le même effet sur un engagement de délai.
Les délais doivent utiliser une horloge définie : jours ouvrés, fuseau du site ou instant UTC. Un traitement planifié cherche les attentes échues à partir des données, puis émet une commande idempotente. Il ne réécrit pas silencieusement le statut pour « débloquer » les files.
Conserver date métier et date technique
La date d’effet d’une décision peut différer de sa date d’enregistrement. Conservez les deux lorsqu’elles influencent facturation, conformité ou reporting. Une correction tardive ne doit pas donner l’illusion qu’elle était connue hier. L’historique explique le dossier avec les informations disponibles à chaque instant.
Cas concret : commande partiellement expédiée
Une commande de douze articles reçoit huit unités ; quatre sont attendues. L’ancien système propose « partiellement traitée », état qui mélange allocation, expédition et reste à servir. Le service client ne sait pas si un colis existe. Le nouveau modèle sépare lignes allouées, expéditions et décision commerciale sur le reliquat.
La première expédition passe de préparée à remise au transporteur avec un identifiant de preuve. Le reliquat conserve une quantité et une attente d’approvisionnement. Le client peut accepter le délai, substituer un produit ou annuler le reste. Chaque choix est une commande et produit ses propres effets financiers.
Sur vingt dossiers pilotes, l’équipe vérifie douze scénarios : livraison totale, fractionnement, refus, perte de réponse transporteur, substitution et annulation après première expédition. Le seuil n’est pas universel : le go local exige ici zéro double mouvement, zéro quantité négative et une explication support obtenue depuis le numéro de commande sans lecture de logs techniques.
Traduire les états entre systèmes
L’ERP, le transporteur et le portail n’ont pas nécessairement le même cycle. Maintenez une table de correspondance versionnée aux frontières, avec les valeurs inconnues en quarantaine. Ne forcez pas un statut local riche dans une valeur externe plus pauvre : envoyez la valeur compatible et conservez la précision dans le système propriétaire.
Les événements publiés décrivent un fait, comme ShipmentHandedOver, avec identifiant, version d’agrégat et date d’effet. Le consommateur construit sa projection. Un message ancien ne doit pas faire reculer l’état ; il est ignoré, rapproché ou déclenche une alerte selon le contrat. La dernière date reçue n’est pas une règle d’autorité.
Versionner le vocabulaire public
Ajouter une valeur à une énumération peut casser un consommateur qui traite tous les cas de façon exhaustive. Publiez une politique d’évolution, un état de repli explicite et des tests de contrat. Lors du retrait, mesurez les anciennes versions encore émises et lues avant de supprimer la correspondance.
Implémenter sans éparpiller les règles
La commande reçoit l’identifiant, la version attendue, l’acteur et les entrées métier. Le domaine vérifie état, droits et dépendances, puis produit la transition et ses effets à journaliser. La transaction écrit l’état et une boîte de sortie. Un worker publie ensuite les messages avec retry borné ; l’idempotence protège les consommateurs.
La sortie comprend nouvel état, version, motif, horodatage et identifiant de corrélation. Le monitoring suit refus par motif, attentes échues, conflits de version, retries et âge des boîtes de sortie. Le rollback de déploiement désactive une nouvelle commande sans effacer les transitions déjà valides ; une compensation métier traite les effets externes engagés.
Tester les propriétés, pas seulement les chemins
Les tests unitaires couvrent la matrice des transitions et les invariants. Les tests d’intégration provoquent concurrence, réponse perdue, doublon et message hors ordre. Une propriété utile affirme qu’aucune suite de commandes autorisées ne produit quantité négative ou état sans sortie. La recette métier rejoue ensuite des dossiers avec leurs preuves.
Observer blocages et transitions
Compter les dossiers par statut décrit un stock, pas la santé du workflow. Mesurez l’âge par type d’attente, la fréquence des retours, les refus, les réparations et les transitions manuelles. Reliez chaque indicateur à une action : contacter, corriger une règle, augmenter une capacité ou réduire le périmètre.
Contre-intuitivement, un nombre élevé de refus explicites peut être plus sain qu’un workflow qui accepte tout puis demande des corrections. Le bon signal associe motif, coût et issue. Un seuil est qualifié localement après observation de cycles comparables ; il ne devient pas une promesse générale copiée d’une autre activité.
Pour qui ce travail devient prioritaire
La démarche est prioritaire quand le support modifie des statuts, quand deux équipes interprètent différemment « terminé », quand une intégration peut faire reculer un dossier ou quand les délais contractuels dépendent d’une attente. Elle concerne produit, experts métier, développeurs, QA, data et opérations.
Une petite application linéaire peut commencer par une table simple et une méthode centrale. Un produit multicanal, asynchrone ou réglementé a besoin plus tôt de commandes, transitions versionnées et trace. La sophistication se décide par les risques et les effets, jamais par goût architectural.
Erreurs fréquentes sur les statuts
Créer un statut pour chaque écran
L’interface change plus vite que le domaine. Un onglet ou une couleur doit souvent être une vue calculée. Sinon, une refonte graphique oblige à migrer le cycle de vie et rend les API incompréhensibles.
Autoriser les sauts administrateur
Le saut contourne préconditions et effets. Préférez une commande de réparation qui explique la cause, contrôle les relations et déclenche les compensations nécessaires. Le rôle administrateur ne supprime pas les invariants métier.
Multiplier les états d’attente
Une attente devient lisible avec cause, responsable et échéance. La décliner en dizaines de statuts empêche les analyses transverses et rend chaque nouvelle cause coûteuse. Gardez un vocabulaire stable et des dimensions séparées.
Décision : ajouter, calculer ou retirer un statut
Ajoutez un statut s’il change durablement les actions autorisées, les invariants ou la responsabilité et s’il possède des critères d’entrée et de sortie. Calculez une vue si le terme résume plusieurs cycles sans les commander. Utilisez un motif lorsque seule l’explication varie. Retirez une valeur si aucune décision ne dépend plus d’elle.
Si un nouveau terme remplace une phrase de support répétée, alors testez-le sur des dossiers. En revanche, refusez-le s’il sert uniquement à ranger un écran. À éviter : convertir une incertitude métier non tranchée en option technique.
- Commencer par les états qui bloquent argent, droit ou promesse client.
- Documenter critères, acteurs, effets et chemins de réparation.
- Tester les transitions avec concurrence et messages rejoués.
- Élargir après une recette support sur des dossiers représentatifs.
Plan d’action sur cinq semaines
Semaines un et deux : observer et fermer le vocabulaire
Choisissez trente dossiers, dont dix bloqués ou corrigés. Reconstituez faits, décisions, attentes et actions. Demandez à deux métiers d’expliquer chaque statut sans se concerter ; les divergences deviennent les premiers sujets. Écrivez définitions, critères, fins, motifs et sous-processus.
Dessinez les cycles parallèles et la matrice des transitions. Identifiez l’autorité de chaque fait, les permissions et les effets externes. Décidez quelles vues resteront calculées. Préparez la correspondance avec les systèmes voisins et la stratégie pour les valeurs inconnues.
Semaines trois à cinq : implémenter, perturber et ouvrir
Centralisez les commandes sur un premier flux. Ajoutez version attendue, journal, boîte de sortie et métriques. Migrez les dossiers par règle explicite ; les cas ambigus rejoignent une file de qualification. Comparez l’ancien et le nouveau calcul sans changer encore le parcours utilisateur.
Provoquez double clic, deux acteurs concurrents, message ancien, transporteur indisponible et délai échu. Vérifiez l’absence de double effet, l’explication du refus et la reprise depuis l’identifiant métier. Le support joue la procédure avec ses droits réels.
Activez un périmètre et observez un cycle complet. Le verdict rapproche attentes échues, corrections, retours et temps de diagnostic. Étendez si les invariants tiennent et si chaque zone grise produit désormais une action connue ; sinon, réduisez le vocabulaire ou scindez le sous-processus avant le prochain lot.
Préparez enfin le retrait des anciennes valeurs : listez API, exports, règles de notification, recherches et indicateurs qui les lisent encore. Chaque consommateur reçoit une correspondance et une date. Pendant une fenêtre définie, comparez l’état calculé dans les deux modèles et examinez toute divergence avec le métier. La bascule n’est complète que lorsque plus aucun appel n’écrit l’ancien vocabulaire, que les dossiers restants possèdent une règle de migration et que le support ne dépend plus de la table historique pour interpréter un cas.
Clôturez la vague par une revue de dix dossiers choisis après activation, et non dans le jeu préparé. Pour chacun, l’équipe retrouve l’état, le motif, l’attente, l’acteur et les effets depuis l’interface. Elle compare ensuite la chronologie aux mouvements externes et aux notifications. Toute divergence ouvre un test de non-régression et une correction attribuée. Le responsable métier signe les définitions réellement observées ; le responsable du run confirme que les commandes de réparation couvrent les incidents sans modification directe. Cette recette de sortie protège le prochain élargissement.
- Rejouer les dossiers et définir les situations observables.
- Contractualiser transitions, droits, temps et effets.
- Tester concurrence, intégrations et réparation.
- Ouvrir progressivement puis retirer les anciennes valeurs.
Approfondir modèles et workflows
Maintenir le dictionnaire dans le temps
Après le pilote, attribuez chaque cycle à un propriétaire fonctionnel et chaque transition à une équipe technique. La revue trimestrielle ne compte pas seulement les statuts : elle cherche les valeurs sans entrée récente, les dossiers immobilisés, les réparations répétées et les correspondances devenues obsolètes. Un statut inutilisé peut être retiré ; un motif qui modifie systématiquement les actions signale peut-être un sous-processus manquant. Les décisions sont enregistrées avec une date d’effet afin que documentation, code et données évoluent ensemble.
Les tableaux de bord doivent conserver leur sens pendant ce changement. Versionnez la définition des durées et des fins de cycle, puis recalculez seulement si l’usage analytique le permet. Un indicateur historique fondé sur « terminé » ne doit pas mélanger clôture commerciale et livraison physique après refonte. Publiez la rupture ou maintenez deux séries pendant la transition. Cette rigueur protège les comparaisons sans transformer le workflow transactionnel en modèle de reporting.
Modéliser les exceptions terrain
Le guide sur le modèle de données face aux exceptions aide à distinguer faits, périodes, dérogations et projections.
Tester les chemins non nominaux
Poursuivez avec les tests de workflows à nombreuses exceptions et l’observabilité des workflows métier. Appliquez-les à une transition et à son effet réel.
- Un statut décrit une situation, pas une opinion.
- Une transition porte la décision et ses effets.
- Une réparation reste explicite, autorisée et traçable.
Conclusion : rendre l’état explicable
Les zones grises disparaissent lorsque le vocabulaire rejoint les faits, que les cycles parallèles restent séparés et que chaque transition possède un contrat. Le statut cesse d’être une étiquette vague ; il devient une conséquence vérifiable du travail réalisé.
Les droits côté serveur, l’idempotence, les versions et le journal protègent l’exécution. Les motifs, attentes et commandes de réparation donnent au support une action sûre. L’observation révèle les blocages avant qu’ils ne deviennent des corrections quotidiennes.
Commencez par le statut que deux équipes expliquent différemment. Rejouez les dossiers, nommez la réalité et fermez les transitions. Ce petit périmètre donnera une grammaire réutilisable au reste du produit.
- Un vocabulaire partagé.
- Des transitions testées.
- Une reprise lisible.
Dawap peut accompagner cette refonte de développement web sur mesure : audit des workflows, modèle de domaine, implémentation, intégrations, recette et préparation du run.