Une marketplace migre son moteur de commandes. Pendant le pilote, l’ancien et le nouveau socle reçoivent le même checkout. Le legacy réserve le stock et envoie l’ordre au vendeur ; le nouveau système fait exactement la même chose afin de « prouver » son fonctionnement. Une commande acheteur produit alors deux sous-commandes et deux emails, tandis qu’un seul paiement existe.
Le problème n’est pas le principe de comparer deux résultats. Il vient de deux autorités qui écrivent, appellent les partenaires et corrigent leurs propres écarts. Les équipes passent ensuite des heures à déterminer quelle commande annuler, quel stock restaurer et quelle chronologie montrer au support.
Le vrai enjeu d’un double run dans une marketplace opérateur est de mesurer l’équivalence du nouveau socle en neutralisant ses effets jusqu’à ce qu’il mérite l’autorité. Contre-intuitivement, un système peut produire des résultats plus justes en shadow tout en étant encore incapable de reprendre le run.
Vous allez comprendre comment définir l’autorité, répliquer les entrées, comparer, qualifier les divergences, basculer puis réconcilier. Le parcours de refonte et migration marketplace relie entrées, sorties, owner, instrumentation, monitoring, dépendances, seuils, file, retry et rollback.
Définir la mission du double run
Choisir ce qui doit être prouvé
Le double run peut vérifier calcul, décision, état, performance ou exploitabilité. Une migration de commission compare montant et ventilation ; une migration de commande compare transitions et effets ; une recherche compare résultats et latence. Le périmètre cite les décisions attendues.
La cible n’est pas « zéro différence » par principe. Certaines divergences sont des corrections volontaires. Le dossier relie chaque nouvelle règle à une attente approuvée et distingue amélioration, régression, écart de données ou différence sans impact.
Définir début, fin et coût maximal
Le run possède cohortes, durée, volume, owners et critères de sortie. Il fixe aussi un budget de calcul, stockage, revue et support. Une comparaison permanente devient vite un troisième système à maintenir.
Le calendrier tient compte des saisons et cas rares. Deux semaines calmes peuvent valider le flux nominal sans rencontrer retour, remboursement ou clôture mensuelle. La durée couvre les cycles qui portent réellement le risque.
La décision économique compare coût du double run au coût d’une bascule aveugle. Une cohorte étroite mais représentative apporte davantage qu’une copie totale dont personne ne peut examiner les millions de différences.
Attribuer une autorité par effet
Construire une matrice d’écriture
Pour chaque objet, la matrice nomme le système qui peut créer, modifier, publier et compenser. Commande, stock, paiement, facture, notification et webhook ont une autorité unique. Le nouveau socle peut écrire dans son espace shadow sans atteindre les consommateurs réels.
L’autorité peut changer par cohorte, mais jamais au milieu d’une opération sans token de bascule. La décision conserve entity_id, old_owner, new_owner, effective_at et migration_version. Les API refusent toute écriture hors autorité.
Séparer calcul et effet externe
Le nouveau moteur calcule une commission, prépare un ordre ou simule un email, puis écrit le résultat dans un sink de comparaison. PSP, vendeur, transporteur et acheteur ne reçoivent rien tant que le mode reste shadow.
Les adaptateurs d’effet possèdent un guard central. Un simple flag dans l’interface ne suffit pas, car jobs, retry et callbacks peuvent contourner le front. Le test provoque chaque canal et prouve que le shadow ne sort pas.
Alimenter les deux socles sans dérive
Capturer une entrée canonique
L’événement source contient identifiant, version, horodatage, payload normalisé et contexte de policy. Il est persisté avant distribution. Ancien et nouveau consommateurs lisent le même fait, plutôt que deux requêtes reconstruites à des instants différents.
Les données sensibles sont minimisées, mais les champs qui influencent la décision restent présents. Un snapshot prix ou stock évite que le second moteur consulte une valeur déjà modifiée et crée un faux écart.
Gérer ordre, retry et retard
Chaque consommateur suit le numéro de séquence et la clé d’idempotence. Un retry ne crée pas une nouvelle comparaison. Les événements hors ordre attendent ou sont rejoués selon domaine. Le retard de chaque socle est mesuré avant de conclure à une divergence.
Si le nouveau système dépasse cinq minutes de retard, alors le verdict reste « non comparable » jusqu’au rattrapage. Il ne doit pas être classé faux. Une file morte expose cause, tentative, owner et procédure.
La rétention permet de rejouer une période après correction du comparateur. Les entrées originales restent immuables, tandis que les sorties portent la version de code. L’équipe ne modifie pas un échantillon pour faire disparaître une régression.
Rapprocher identités et versions
Maintenir des mappings explicites
Un vendeur, produit ou statut peut porter des identifiants différents. Le mapping conserve legacy_id, target_id, type, source et validité. Une absence rejoint une file de résolution ; elle ne crée pas automatiquement un nouvel objet.
Les fusions et splits sont versionnés. Plusieurs anciennes offres peuvent converger vers un produit canonique, tandis qu’une ancienne catégorie se répartit. Le comparateur comprend cette cardinalité avant de juger les sorties.
Comparer des états au même moment
Les snapshots portent business_time et processing_time. Une commande confirmée à 10 h ne se compare pas à sa projection shadow de 10 h 05 sans tenir compte des événements intermédiaires. Une fenêtre d’attente ferme les résultats.
La policy et les référentiels sont également figés. Une taxe calculée avec deux versions différentes est un écart de configuration, pas forcément de moteur. Le rapport affiche ces dépendances avec le verdict.
Comparer des résultats équivalents
Normaliser avant de comparer
Ordre des lignes, formats de date, arrondis et identifiants techniques peuvent différer sans impact métier. Le normaliseur produit une représentation canonique par domaine. Il conserve aussi les valeurs brutes pour l’investigation.
Les tolérances sont explicites : zéro centime pour un total comptable, quelques millisecondes pour une date technique, ordre indifférent pour une liste sans priorité. Une tolérance large ne masque jamais un champ contractuel.
Comparer décision et raison
Deux systèmes peuvent refuser la même commande pour des causes différentes. Le verdict examine statut, montant, effets attendus et reason codes. Une égalité de sortie avec une logique incorrecte reste une divergence à comprendre.
Par exemple, les deux moteurs calculent 12 euros de commission, mais l’un les attribue au vendeur et l’autre à l’opérateur. Le total égal ne suffit pas ; la ventilation et le ledger projeté doivent concorder.
Les résultats volumineux utilisent des checksums par sous-ensemble avant une comparaison détaillée. Cette étape localise rapidement la catégorie, le vendeur ou la période différente sans perdre les preuves unitaires. Le rapport conserve l’algorithme de normalisation, car un changement de tri ou d’arrondi pourrait autrement modifier le verdict sans évolution des deux moteurs.
Qualifier les divergences
Créer une taxonomie actionnable
Les catégories sont donnée source, mapping, configuration, règle attendue, bug legacy, bug cible, timing ou comparateur. Chaque écart reçoit severity, population, owner et prochaine action. « Différent » n’est pas un ticket exploitable.
Le tri priorise impact financier, promesse acheteur, volume et caractère irréversible. Une différence de libellé peut attendre ; un statut qui autorise deux remboursements bloque la cohorte même sur un seul cas.
Éviter de corriger les deux côtés
Le comité décide quel comportement représente la cible. Il corrige le nouveau socle, accepte la différence ou ouvre une évolution métier séparée. Le legacy ne change pas uniquement pour faire converger le rapport avant son retrait.
Chaque exception possède expiry et justification. Si plus de 20 % des écarts restent « acceptés temporairement » après deux semaines, alors le double run ne prouve plus l’équivalence. L’extension est différée jusqu’au nettoyage.
Neutraliser les doubles effets
Intercepter les sorties du shadow
Emails, webhooks, écritures PSP, stock, factures et appels vendeur sont redirigés vers des sinks. Le sink conserve payload, destination théorique et clé d’idempotence. Le comparateur les rapproche des vrais effets legacy.
Les dépendances non simulables reçoivent un adapter contractuel qui valide la requête sans exécuter l’action. Une sandbox externe n’est utilisée que si elle reproduit les règles nécessaires et ne mélange pas ses identifiants à la production.
Empêcher les callbacks de revenir
Un fournisseur peut répondre à un appel shadow et injecter un événement. Les URLs de callback, secrets et topics sont séparés. Un event provenance=shadow ne franchit jamais le guard des effets réels.
Le monitoring alerte sur toute tentative bloquée. Zéro sortie observée pendant un test sans provoquer de tentative ne constitue pas une preuve. La recette déclenche chaque adapter et vérifie journal, rejet et absence d’effet externe.
Le coût caché vient souvent des notifications secondaires : analytics, CRM ou support peuvent créer une tâche depuis un événement shadow. L’inventaire couvre donc tous les consommateurs et pas seulement les partenaires transactionnels.
Basculer par cohortes
Choisir une population révélatrice
La première cohorte combine faible blast radius et diversité suffisante : vendeurs actifs, commandes multi-lignes, remboursements et plusieurs moyens de paiement. Éviter tous les cas difficiles crée un canary rassurant mais inutile.
La règle d’affectation est déterministe et stable. Une commande ne change pas de système parce que le vendeur a été ajouté à une cohorte après sa création. Les objets enfants héritent de l’autorité de leur parent.
Transférer l’autorité explicitement
La bascule vérifie mappings, lag nul, files vides et monitoring actif. Elle écrit un token d’autorité avant d’ouvrir les effets du nouveau socle. Le legacy passe en lecture ou refuse les nouvelles écritures de la cohorte.
Les seuils couvrent erreurs, divergences, latence, support et réconciliation. Si une commande critique devient incohérente ou si la divergence non expliquée dépasse 0,5 %, alors la cohorte revient au précédent owner.
Les communications internes précisent quel système sert chaque cohorte et comment retrouver l’information. Le support ne doit jamais choisir au hasard entre deux back-offices. Son écran part de l’identifiant métier et affiche autorité, date de bascule, statut de comparaison et action autorisée pour éviter les corrections concurrentes.
Réconcilier les objets ouverts
Traiter les commandes en cours
Une commande créée dans le legacy peut finir après la bascule. La stratégie choisit maintien jusqu’à clôture ou migration d’état. Elle n’alterne pas par étape. Paiement, sous-commandes, expéditions et remboursements restent attachés au même owner.
La migration produit un manifeste avec snapshot, événements, mappings et checksum. Le nouveau système importe en mode vérification, puis accuse chaque objet. Les anomalies bloquent la commande concernée, pas toute la cohorte.
Fermer les écarts financiers et opérationnels
Le job rapproche commandes, PSP, ledger, stock et notifications. Il cherche effet legacy sans projection cible, effet cible non autorisé, montants divergents et statuts impossibles. Chaque écart possède correction compensatoire.
Les opérations ne modifient pas directement les agrégats. Elles relancent un événement idempotent ou appliquent une compensation approuvée. Le tableau garde valeur avant, après et source pour l’audit.
La clôture financière constitue un test séparé. Les totaux par devise, vendeur et journée sont rapprochés, puis les centimes d’écart sont expliqués ligne par ligne. Une moyenne n’est pas acceptable : une erreur positive peut en masquer une négative et laisser deux comptes faux malgré un total global exact.
Préparer un rollback réel
Définir la fenêtre de retour
Le rollback est simple tant que le nouveau socle n’a pas produit d’effet exclusif. Après des commandes réelles, il faut transférer états et événements au legacy ou conserver le nouveau comme owner de la cohorte existante.
La stratégie précise jusqu’à quel point le retour automatique reste possible. Au-delà, le repli ferme les nouvelles entrées et stabilise les objets en cours au lieu d’improviser une migration inverse.
Répéter la procédure
L’exercice provoque latence, file morte, mapping absent et divergence financière. L’équipe exécute gel, transfert d’autorité, reprise des entrées et réconciliation. Le chronomètre révèle les dépendances orales.
Le rollback conserve les preuves du nouveau système. Il ne supprime pas ses objets pour faire revenir les dashboards au vert. Les données deviennent read-only avec un lien vers la décision de retour.
Fermer le double run et le legacy
Définir les critères de sortie
Le go exige couverture des scénarios, divergences critiques à zéro, taux résiduel sous seuil, performance et reprise opérationnelle prouvées. Les exceptions restantes possèdent owner et date, sans masquer un domaine non testé.
Le rapport présente population, période, versions, écarts et décisions. Un score global n’efface pas une régression rare à fort impact. Chaque owner signe la capacité qu’il reprend.
Décommissionner les dépendances
Le retrait ferme écritures, jobs, secrets, callbacks, dashboards, accès et procédures legacy. Les archives restent consultables selon besoin. Les mappings nécessaires aux historiques sont conservés.
Une alerte détecte tout appel résiduel après extinction. Les coûts d’infrastructure et licences sont suivis jusqu’à zéro. Un ancien système laissé « au cas où » continue de recevoir des corrections et empêche la fin réelle de migration.
Le plan de décommissionnement attribue chaque dépendance à un consommateur et exige une preuve de retrait. Les tâches planifiées sont observées sur leur cycle le plus long avant arrêt. Les accès humains deviennent lecture seule, puis sont supprimés après validation de l’archive et de la procédure de consultation historique.
Adapter la méthode et éviter les erreurs
Pour qui le double run convient
Il est utile lorsque calculs, états ou effets doivent être prouvés sur du trafic réel et que le risque de bascule est élevé. Une migration simple de contenu statique peut préférer une recette et un canary classiques.
Domain owners, Architecture, Platform, Data, Operations, Finance et Support partagent critères et écarts. Une petite équipe peut réduire la cohorte, mais elle ne renonce ni à l’autorité unique ni à la réconciliation.
Erreurs fréquentes du double run
Laisser les deux systèmes écrire, comparer des données prises à des moments différents, tolérer sans owner et corriger le legacy pour embellir le rapport sont les erreurs majeures. Une sandbox non représentative donne une confiance artificielle.
Une autre erreur consiste à prolonger indéfiniment la comparaison. Enfin, oublier CRM, analytics ou emails laisse des doubles effets hors du périmètre visible. La matrice d’autorité doit couvrir toute la chaîne.
Plan d’action pour conduire le double run
Semaines 1 à 4 : contrat et shadow
La première semaine ferme périmètre, autorité et scénarios. La deuxième construit événements canoniques et mappings. La troisième neutralise les effets. La quatrième lance le shadow et calibre normalisation, tolérances et taxonomie d’écarts.
Les tests couvrent retry, ordre, retard, mapping absent, arrondi, callback, effet externe et commande ouverte. Chaque cas attend sorties legacy, cible, verdict, owner et action.
Semaines 5 à 8 : autorité et sortie
La cinquième semaine traite les divergences et répète le rollback. La sixième bascule une cohorte. La septième réconcilie les objets ouverts. La huitième étend ou arrête selon les seuils décidés avant le test.
Les entrées sont événements, versions et mappings ; les sorties sont projections, écarts, manifestes et compensations. L’instrumentation suit lag, effets bloqués, divergences, files et support. Le runbook nomme owners et dépendances.
Le go exige autorité unique prouvée, aucun effet shadow externe, réconciliation complète et rollback chronométré. Une personne extérieure au projet doit expliquer cinq écarts et reprendre une commande en file morte.
Si la revue manuelle dépasse la capacité ou si les écarts inconnus stagnent trois jours, alors la cohorte n’augmente pas. L’équipe améliore comparateur et données avant de financer davantage de trafic.
- À faire d’abord : fermer mission, autorité, entrées et effets neutralisés.
- À tester ensuite : mappings, comparaison, divergences, bascule et réconciliation.
- À différer : les cohortes larges tant que le rollback dépend d’une personne.
- À refuser : tout double run où les deux socles produisent le même effet réel.
Ressources complémentaires migration
Borner le périmètre de bascule
Le MVP marketplace avant ouverture aide à sélectionner les capacités qui doivent être prouvées.
La méthode pour ouvrir une première catégorie fournit une cohorte métier cohérente.
Structurer données et opérations
Le catalogue PIM marketplace stabilise identités, versions et mappings.
Les écrans du back-office opérateur réunissent écarts, autorité et reprise.
Conclusion : comparer pour décider
Un double run utile commence par une autorité unique et des entrées communes, avant tout indicateur de convergence.
Normalisation, taxonomie d’écarts et sinks rendent les différences explicables sans exposer les partenaires à deux effets. Le rapport conserve les versions nécessaires pour reproduire chaque comparaison.
Cohortes, réconciliation, rollback et critères de sortie transforment la comparaison en décision de migration. Cette discipline protège aussi le support et la finance contre les corrections contradictoires qui survivraient autrement longtemps après la bascule technique.
Dawap peut vous accompagner pour sécuriser cette transition dans votre marketplace opérateur.