[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"theme-db":3,"$fKnz2vuX4bZz1LbUTiuFsvSZ3e07l5_5fqNYp4Tzdhi8":22,"megamenu":103,"$fnw-inheA-foDSB4p5sL1RSxzWJh_ca6Q7LwyoIomop4":160,"footer-db":164,"header-db":182,"$f3sQ0NuhH_9O3ATKsk3HX2-EsSOws_2Ryun_sp3dOi8M":193,"$flEk2E6KVkXpIvKI2feaxjihddXvVfzbMnvt2FHrWbaw":251,"$f39PCwUKgrH4dCfpER9oVsNr25rYopS9XrpuXE6Udhzs":252},{"theme":4},{"colors":5,"typography":13,"ui":17,"defaultColorMode":21},{"primary":6,"secondary":7,"background":8,"foreground":9,"muted":10,"headerBg":11,"footerBg":12,"topBarBg":9,"topBarText":11},"#4F46E5","#0D9488","#F9FAFB","#111827","#6B7280","#ffffff","#020617",{"fontFamily":14,"fontUrl":15,"baseFontSize":16},"Inter, system-ui, sans-serif","https:\u002F\u002Ffonts.googleapis.com\u002Fcss2?family=Inter:wght@400;500;600;700&family=Playfair+Display:ital,wght@0,400;0,700;0,800;0,900;1,400;1,700&display=swap","16px",{"borderRadius":18,"contentWidth":19,"shadow":20},"lg","7xl",true,"light",{"columns":23},[24,40,70,91],{"title":25,"links":26},"Plateforme",[27,31,34,37],{"label":28,"href":29,"external":30},"Offre Starter (2 500 €)","\u002Foffre-starter",false,{"label":32,"href":33,"external":30},"Devenir Ambassadeur","\u002Fambassadeur",{"label":35,"href":36,"external":30},"Modules PrestaShop","\u002Fmodules",{"label":38,"href":39,"external":20},"CodeMyShop.com","https:\u002F\u002Fcodemyshop.com",{"title":41,"links":42},"Le Synedre",[43,46,49,52,55,58,61,64,67],{"label":44,"href":45,"external":30},"L'histoire","\u002Fsynedre",{"label":47,"href":48,"external":30},"Constitution","\u002Fsynedre\u002Fconstitution",{"label":50,"href":51,"external":30},"L'équipe","\u002Fequipe",{"label":53,"href":54,"external":30},"Le réacteur en direct","\u002Freacteur",{"label":56,"href":57,"external":30},"Le Drill (entraînement)","\u002Fdrill",{"label":59,"href":60,"external":30},"Protocole de réunion","\u002Fsynedre\u002Freunion",{"label":62,"href":63,"external":30},"Les agents IA","\u002Fagents-ia",{"label":65,"href":66,"external":30},"La Conduite","\u002Fsynedre\u002Fconduite",{"label":68,"href":69,"external":30},"Charte plateforme","\u002Fsynedre\u002Fcharte",{"title":71,"links":72},"Ressources",[73,76,79,82,85,88],{"label":74,"href":75,"external":30},"Blog","\u002Fblog",{"label":77,"href":78,"external":30},"Academy","\u002Facademy",{"label":80,"href":81,"external":30},"Dictionnaire","\u002Fdictionnaire",{"label":83,"href":84,"external":30},"Expertise PrestaShop","\u002Fexpertise",{"label":86,"href":87,"external":30},"Flywheel","\u002Fflywheel",{"label":89,"href":90,"external":30},"Manifeste","\u002Fmanifeste",{"title":92,"links":93},"À propos",[94,97,100],{"label":95,"href":96,"external":30},"Alexandre Carette","\u002Fa-propos",{"label":98,"href":99,"external":30},"Dossier de presse","\u002Fpresse",{"label":101,"href":102,"external":30},"Contact","\u002Fcontact",{"items":104},[105,114,120,126,134,142,148,154],{"id":106,"type":107,"label":108,"href":84,"icon":110,"description":110,"badge":110,"groupTitle":110,"style":110,"gridColumns":110,"cssClass":110,"psCategoryId":110,"showPsChildren":30,"position":111,"children":112,"psChildren":113},41,"link",{"fr":109},"Expertise",null,0,[],[],{"id":115,"type":107,"label":116,"href":75,"icon":110,"description":110,"badge":110,"groupTitle":110,"style":110,"gridColumns":110,"cssClass":110,"psCategoryId":110,"showPsChildren":30,"position":117,"children":118,"psChildren":119},42,{"fr":74},1,[],[],{"id":121,"type":107,"label":122,"href":36,"icon":110,"description":110,"badge":110,"groupTitle":110,"style":110,"gridColumns":110,"cssClass":110,"psCategoryId":110,"showPsChildren":30,"position":123,"children":124,"psChildren":125},43,{"fr":35},2,[],[],{"id":127,"type":107,"label":128,"href":130,"icon":110,"description":110,"badge":110,"groupTitle":110,"style":110,"gridColumns":110,"cssClass":110,"psCategoryId":110,"showPsChildren":30,"position":131,"children":132,"psChildren":133},44,{"fr":129},"Outils IA","\u002Foutils-ia",3,[],[],{"id":135,"type":107,"label":136,"href":29,"icon":110,"description":110,"badge":110,"groupTitle":110,"style":138,"gridColumns":110,"cssClass":110,"psCategoryId":110,"showPsChildren":30,"position":139,"children":140,"psChildren":141},45,{"fr":137},"Offre Starter ✨",{"highlight":20},4,[],[],{"id":143,"type":107,"label":144,"href":78,"icon":110,"description":110,"badge":110,"groupTitle":110,"style":110,"gridColumns":110,"cssClass":110,"psCategoryId":110,"showPsChildren":30,"position":145,"children":146,"psChildren":147},46,{"fr":77},5,[],[],{"id":149,"type":107,"label":150,"href":96,"icon":110,"description":110,"badge":110,"groupTitle":110,"style":110,"gridColumns":110,"cssClass":110,"psCategoryId":110,"showPsChildren":30,"position":151,"children":152,"psChildren":153},47,{"fr":92},6,[],[],{"id":155,"type":107,"label":156,"href":102,"icon":110,"description":110,"badge":110,"groupTitle":110,"style":110,"gridColumns":110,"cssClass":110,"psCategoryId":110,"showPsChildren":30,"position":157,"children":158,"psChildren":159},48,{"fr":101},7,[],[],{"academy":161,"blog":162,"expertise":163},[],[],[],{"footer":165},{"theme":166,"description":110,"hours":110,"logo":167,"contact":170,"social":171,"bottomBar":181},"dark",{"src":168,"href":169,"alt":95},"\u002Flogo-ac.svg","\u002F",{"email":110,"phone":110,"address":110,"cta":110},[172,175,178],{"platform":173,"href":174,"label":173},"linkedin","https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Falexandre-carette\u002F",{"platform":176,"href":177,"label":176},"malt","https:\u002F\u002Fwww.malt.fr\u002Fprofile\u002Falexandrecarette",{"platform":179,"href":180,"label":179},"github","https:\u002F\u002Fgithub.com\u002Fprest4cafe",{"copyright":110},{"header":183},{"logo":184,"topBar":187,"contactEmail":190,"features":191,"navBar":110},{"src":168,"alt":185,"text":95,"href":169,"class":186},"Alexandre Carette — Architecte E-commerce Souverain","h-10 w-10",{"message":110,"showLanguages":30,"align":188,"languages":189},"left",[],"contact@alexandrecarette.fr",{"showSearch":30,"showWishlist":30,"showLogin":20,"showContact":30,"showCart":30,"stickyHeader":20,"headerLayout":192},"inline",{"id":194,"title":195,"category":196,"subcategory":197,"slug":198,"coverImage":199,"thumbnailImage":200,"content":201,"faq":202,"metaDescription":248,"active":20,"datePublished":249,"dateUpdated":249,"readingTime":250,"mentor":110,"audioEnabled":30,"audioUrl":249,"author":110},99,"La Révolution S.O.A.P : pourquoi nous avons supprimé 20 000 lignes","tech","architecture","architecture--revolution-soap","https:\u002F\u002Falexandrecarette.fr\u002Fblog-covers\u002Fcover-tech--architecture--revolution-1775924786.webp","https:\u002F\u002Falexandrecarette.fr\u002Fblog-covers\u002Fthumb-tech--architecture--revolution-1775924786.webp","\u003Cp class=\"lead\">\nLe 11 avril 2026, j’ai supprimé 20 000 lignes de code du monorepo CodeMyShop en un seul commit. \u003Ccode>113 files changed, 558 insertions(+), 20349 deletions(-)\u003C\u002Fcode>. Aucun utilisateur final ne s’en est aperçu. Ce chantier a duré quatre phases étalées sur deux semaines, et il a transformé notre architecture d’un \u003Cstrong>système de fichiers statiques\u003C\u002Fstrong> vers une \u003Cstrong>plateforme d’orchestration DB-First\u003C\u002Fstrong> que nous appelons désormais S.O.A.P (Service Orchestration and Automation Platform). L’opération était risquée, elle a été totale, et elle a surtout été \u003Cstrong>réversible à chaque étape\u003C\u002Fstrong>. Si vous opérez une stack qui mélange fichiers \u003Ccode>.md\u003C\u002Fcode>, scripts Python \u003Cem>one-shot\u003C\u002Fem> et table de base de données, vous avez probablement déjà le même goulot d’étranglement que nous avions. Voici comment nous l’avons identifié, comment nous l’avons contourné sans downtime, et ce que vous pouvez appliquer tel quel.\n\u003C\u002Fp>\n\u003Ch2 id=\"les-quatre-problématiques-dune-architecture-fichiers-first\">Les quatre problématiques d’une architecture fichiers-first\u003C\u002Fh2>\n\u003Cp class=\"article-nav-context\" style=\"font-size:0.9em;color:#64748b;margin:0.5em 0 1.5em;\">Cet article fait partie de notre dossier \u003Ca href=\"\u002Fblog\u002Ftech\u002F\" title=\"Tous nos articles tech\">tech\u003C\u002Fa> &rsaquo; \u003Ca href=\"\u002Fblog\u002Ftech\u002Farchitecture\u002F\" title=\"Articles architecture\">architecture\u003C\u002Fa>.\u003C\u002Fp>\n\n\u003Cp>Avant la bascule, CodeMyShop reposait sur trente profils d’agents IA stockés dans \u003Ccode>agents\u002F\u003Cem>.md\u003C\u002Fcode>, onze workflows dans \u003Ccode>workflows\u002F\u003C\u002Fem>.md\u003C\u002Fcode>, et quarante-sept scripts \u003Ccode>publish_*.py\u003C\u002Fcode> dans \u003Ccode>automation\u002F\u003C\u002Fcode>. Le système fonctionnait. Le problème n’était pas la fiabilité — il était la \u003Cstrong>friction cumulée\u003C\u002Fstrong>.\u003C\u002Fp>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>\nSymptôme observé\n\u003C\u002Fth>\n\u003Cth>\nOrigine structurelle\n\u003C\u002Fth>\n\u003Cth>\nCoût mesuré\n\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\nDésynchronisation prod ↔︎ fichier\n\u003C\u002Ftd>\n\u003Ctd>\nDeux sources de vérité (disque + base) maintenues à la main\n\u003C\u002Ftd>\n\u003Ctd>\n1 incident prod de 5 min le 7 avril (Academy et Dictionnaire à 0 entrée)\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\nTemps de correction d’une faute de frappe dans un profil d’agent\n\u003C\u002Ftd>\n\u003Ctd>\nÉdition fichier → commit → push → build → redéploy\n\u003C\u002Ftd>\n\u003Ctd>\n~15 min \u002F correction × 30 agents × 3 modifs\u002Fjour\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\nImpossibilité de lister les articles par statut\n\u003C\u002Ftd>\n\u003Ctd>\n1 script Python par article, aucune table centrale\n\u003C\u002Ftd>\n\u003Ctd>\nPas de pipeline, pas de republication, pas de filtrage\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\nConflits de merge sur données éditables\n\u003C\u002Ftd>\n\u003Ctd>\nFichiers versionnés pour du contenu qui n’a rien à faire en git\n\u003C\u002Ftd>\n\u003Ctd>\nBloque les sessions parallèles, crée de la dette quotidienne\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch2 id=\"comment-nous-avons-basculé-en-quatre-phases\">Comment nous avons basculé en quatre phases\u003C\u002Fh2>\n\u003Cp>L’incident du 7 avril a été le déclencheur. Ce matin-là, une mise à jour apparemment anodine — renommer une convention de slug partagée entre le code Nuxt et la base de données — a laissé la production en mode dégradé pendant cinq minutes. L’Academy et le Dictionnaire affichaient zéro entrée sur les pages publiques, les crawlers sont passés dessus, et nos propres monitors n’ont rien vu parce qu’ils pinguaient des URLs qui renvoyaient bien un HTTP 200 avec du vide dedans. La cause racine tenait en une phrase : nous avions exécuté l’\u003Ccode>UPDATE\u003C\u002Fcode> de la base avant de déployer le code aligné. Cinq minutes de désynchronisation suffisent à casser la confiance d’un crawler Google. Le dimanche suivant, nous avons décidé de transformer cette cicatrice en architecture.\u003C\u002Fp>\n\u003Cp>Le principe directeur de toute la réarchitecture : \u003Cstrong>aucune phase ne doit produire de fenêtre vulnérable en production\u003C\u002Fstrong>. Si une phase échoue, elle doit pouvoir être annulée en une commande. Cette contrainte a dicté l’ordre des opérations — un ordre contre-intuitif qui consiste à déployer le code \u003Cem>avant\u003C\u002Fem> les données. Nous avons découpé le chantier en quatre phases, chacune révocable, chacune auditée avant de passer à la suivante, chacune déployée sans demander d’autorisation spéciale au reste de l’équipe.\u003C\u002Fp>\n\u003Ch3 id=\"phase-1-poser-le-schéma-db\">Phase 1 — Poser le schéma DB\u003C\u002Fh3>\n\u003Cp>Nous avons créé trois tables dans la base MariaDB existante : \u003Ccode>ps_ac_agents\u003C\u002Fcode> (avec une colonne \u003Ccode>content_md\u003C\u002Fcode> de type \u003Ccode>mediumtext\u003C\u002Fcode>), \u003Ccode>ps_ac_workflows\u003C\u002Fcode> sur le même modèle, et \u003Ccode>ps_ac_article_draft\u003C\u002Fcode> — la table centrale de la pipeline de contenu avec ses champs \u003Ccode>title\u003C\u002Fcode>, \u003Ccode>slug\u003C\u002Fcode>, \u003Ccode>meta_data\u003C\u002Fcode> (JSON), \u003Ccode>content_md\u003C\u002Fcode>, \u003Ccode>status\u003C\u002Fcode> (\u003Ccode>draft\u003C\u002Fcode> \u002F \u003Ccode>ready\u003C\u002Fcode> \u002F \u003Ccode>published\u003C\u002Fcode> \u002F \u003Ccode>archived\u003C\u002Fcode>). À ce stade, les tables étaient vides, personne ne les lisait. Aucun risque.\u003C\u002Fp>\n\u003Ch3 id=\"phase-2-écrire-les-façades-active-record\">Phase 2 — Écrire les façades Active Record\u003C\u002Fh3>\n\u003Cp>Chaque table reçoit une classe Python qui encapsule \u003Ccode>create()\u003C\u002Fcode>, \u003Ccode>update()\u003C\u002Fcode>, \u003Ccode>get()\u003C\u002Fcode>, \u003Ccode>validate()\u003C\u002Fcode>. Un hook \u003Cem>pre-commit\u003C\u002Fem> refuse tout script qui tente d’écrire en \u003Ccode>ps_ac_*\u003C\u002Fcode> en SQL brut sans passer par une façade. Ce n’est pas un lint amical — c’est un barrage. Cette couche rend les mutations \u003Cstrong>auditables et testables\u003C\u002Fstrong>, et elle concentre la logique de validation en un seul endroit.\u003C\u002Fp>\n\u003Ch3 id=\"phase-3-déployer-le-code-avec-dual-read\">Phase 3 — Déployer le code avec \u003Cem>dual-read\u003C\u002Fem>\u003C\u002Fh3>\n\u003Cp>C’est l’étape qui rend le cutover invisible. Tous les consommateurs (scripts d’audit, runner d’agents, générateur de cover, processeur de cicatrices) ont été patchés pour lire \u003Cstrong>en priorité\u003C\u002Fstrong> la nouvelle source (DB) et \u003Cstrong>retomber\u003C\u002Fstrong> sur l’ancienne (fichiers) si la DB est vide. Nous déployons ce code, nous le laissons tourner trois jours en production, nous surveillons les logs. Résultat : la prod continue de servir exactement la même chose, mais elle est déjà prête à basculer. Si un bug apparaît pendant ces trois jours, on corrige sans urgence — les deux sources tiennent encore.\u003C\u002Fp>\n\u003Ch3 id=\"phase-4-la-suppression-massive\">Phase 4 — La suppression massive\u003C\u002Fh3>\n\u003Cp>Samedi 11 avril, filet de sécurité posé sous forme de tag git \u003Ccode>pre-phase4-cutover\u003C\u002Fcode>. Puis dans un seul commit :\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>git rm agents\u002F*.md\u003C\u002Fcode> (30 fichiers)\u003C\u002Fli>\n\u003Cli>\u003Ccode>git rm workflows\u002F*.md\u003C\u002Fcode> (11 fichiers)\u003C\u002Fli>\n\u003Cli>\u003Ccode>git rm automation\u002Fpublish_*.py\u003C\u002Fcode> (47 fichiers)\u003C\u002Fli>\n\u003Cli>Réécriture de dix-huit scripts Python pour retirer les références aux fichiers supprimés\u003C\u002Fli>\n\u003Cli>Mise à jour de \u003Ccode>CLAUDE.md\u003C\u002Fcode> pour graver la nouvelle doctrine\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Le commit a touché 113 fichiers, supprimé 20 349 lignes, ajouté 558. Aucun rebuild spécial, aucun redéploy d’urgence, aucun incident. La prod lisait déjà la DB depuis trois jours — la suppression des fichiers n’a changé que le nombre d’inodes sur le disque.\u003C\u002Fp>\n\u003Ch2 id=\"les-solutions-apportées-problème-par-problème\">Les solutions apportées, problème par problème\u003C\u002Fh2>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>\nProblème\n\u003C\u002Fth>\n\u003Cth>\nSolution DB-First\n\u003C\u002Fth>\n\u003Cth>\nGain opérationnel\n\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\nDésynchronisation prod ↔︎ fichier\n\u003C\u002Ftd>\n\u003Ctd>\nUne seule source : \u003Ccode>ps_ac_*\u003C\u002Fcode> en MariaDB, façades Active Record obligatoires\n\u003C\u002Ftd>\n\u003Ctd>\nClasse entière de bugs éliminée — impossible d’avoir deux valeurs divergentes\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\nTemps de correction d’un profil d’agent\n\u003C\u002Ftd>\n\u003Ctd>\n\u003Ccode>UPDATE ps_ac_agents.content_md\u003C\u002Fcode> en SQL, zéro redéploy\n\u003C\u002Ftd>\n\u003Ctd>\n15 min → 2 secondes, édition à chaud pour tous les agents\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\nPipeline de contenu inexistante\n\u003C\u002Ftd>\n\u003Ctd>\nMoteur unique \u003Ccode>ac_publisher_engine.py\u003C\u002Fcode> lit \u003Ccode>ps_ac_article_draft\u003C\u002Fcode>\n\u003C\u002Ftd>\n\u003Ctd>\nListe, filtre, republie, archive — toutes actions en une commande\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\nConflits de merge sur données éditables\n\u003C\u002Ftd>\n\u003Ctd>\nDonnées hors git, code seul dans git\n\u003C\u002Ftd>\n\u003Ctd>\nSessions parallèles sans friction, dette quotidienne supprimée\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch2 id=\"ce-que-ça-change-pour-un-commerçant\">Ce que ça change pour un commerçant\u003C\u002Fh2>\n\u003Cp>L’architecture S.O.A.P n’est pas un exercice de style technique. Elle conditionne \u003Cstrong>la vitesse de modification\u003C\u002Fstrong> d’une boutique en ligne. Quand vous utilisez un site sous CodeMyShop et que vous voulez ajouter une fonction multi-devise, il n’y a plus de script à écrire : la fonction s’active par une mutation en base, et votre front Nuxt la sert à la seconde suivante. Quand vous voulez publier un article, vous insérez un enregistrement dans \u003Ccode>ps_ac_article_draft\u003C\u002Fcode>, vous appelez le moteur, votre article est en ligne. Quand vous voulez modifier votre menu principal, vous éditez la ligne correspondante — aucun redéploy. C’est exactement le principe que nous décrivons dans le module \u003Ca href=\"\u002Fblog\u002Fprestashop\u002Farchitecture\u002Fprestashop-headless-nuxt-nextjs-souverainete\" style=\"text-decoration:underline;\">Architecture headless souveraine en Nuxt 3\u003C\u002Fa>, et c’est le cœur de notre \u003Ca href=\"\u002Fflywheel\" style=\"text-decoration:underline;\">boucle Flywheel\u003C\u002Fa> : chaque seconde gagnée à l’exécution est une seconde rendue à la pensée stratégique.\u003C\u002Fp>\n\u003Cp>Prenons un exemple concret. Un commerçant de fruits secs découvre, un vendredi à 16h, qu’un concurrent vient de sortir une promotion sur les dattes. Sur une stack traditionnelle, réagir demande d’éditer un fichier de configuration, de committer, de pousser, d’attendre le build du front, puis de vérifier que rien n’a cassé — compter vingt à quarante minutes dans le meilleur des cas, et la promotion est déjà obsolète. Sur CodeMyShop, il ouvre son back-office, il écrit une règle de remise dans la table \u003Ccode>ps_ac_promotions\u003C\u002Fcode>, elle est visible sur le front en trois secondes, et il retourne à son café. La différence n’est pas une différence d’outil — c’est une différence de \u003Cstrong>champ des possibles\u003C\u002Fstrong>. Ce qui coûtait trop cher à tenter devient gratuit, et le commerçant commence à expérimenter là où il subissait avant.\u003C\u002Fp>\n\u003Cblockquote style=\"border-left:4px solid #6366f1;padding:1em 1.5em;background:#f8fafc;margin:2em 0;\">\n\u003Cstrong>Source d’autorité — Martin Fowler, \u003Cem>Patterns of Enterprise Application Architecture\u003C\u002Fem>\u003C\u002Fstrong>\u003Cbr> Le pattern Active Record, formalisé par Martin Fowler en 2002, repose sur un principe simple : \u003Cem>« An object that wraps a row in a database table, encapsulates the database access, and adds domain logic on that data. »\u003C\u002Fem> Vingt-deux ans plus tard, ce pattern reste la réponse la plus solide pour éliminer la divergence entre le code applicatif et l’état persistant. Nous l’appliquons sans modification théorique — uniquement avec un garde-fou supplémentaire sous forme de hook \u003Cem>pre-commit\u003C\u002Fem> qui refuse tout \u003Cem>raw SQL\u003C\u002Fem> hors façade. Référence : \u003Ca href=\"https:\u002F\u002Fmartinfowler.com\u002FeaaCatalog\u002FactiveRecord.html\" style=\"text-decoration:underline;\" rel=\"noopener\">martinfowler.com\u002FeaaCatalog\u002FactiveRecord.html\u003C\u002Fa>.\n\u003C\u002Fblockquote>\n\u003Ch2 id=\"conclusion-la-vitesse-de-correction-est-la-vraie-métrique\">Conclusion — la vitesse de correction est la vraie métrique\u003C\u002Fh2>\n\u003Cp>Si vous retenez une seule chose de ce chantier, retenez celle-ci : \u003Cstrong>le nombre de secondes entre le moment où vous décidez un changement et le moment où la production le reflète\u003C\u002Fstrong> est la métrique qui sépare les stacks qui scalent des stacks qui stagnent. Chaque friction fichier, chaque script \u003Cem>one-shot\u003C\u002Fem>, chaque synchro manuelle ajoute des minutes à cette métrique. Au bout de quelques mois, cette dette devient une architecture qui se maintient elle-même plutôt qu’un outil au service de votre stratégie.\u003C\u002Fp>\n\u003Cp>La bascule DB-First n’est pas un projet d’ingénieur. C’est une décision stratégique qui rend votre équipe \u003Cem>capable de changer d’avis\u003C\u002Fem> sans payer un redéploiement. Sur CodeMyShop, cette vitesse de modification est désormais de \u003Cstrong>moins de trois secondes\u003C\u002Fstrong> pour n’importe quelle donnée runtime. C’est le seuil à partir duquel un commerçant peut expérimenter sans crainte — et c’est le seuil qui transforme un site vitrine en terrain de jeu.\u003C\u002Fp>\n\u003Cdiv style=\"margin:2em 0;padding:1.8em 2em;background:linear-gradient(135deg,#6366f1 0%,#4f46e5 100%);border-radius:12px;color:#fff;text-align:center;\">\n\u003Ch3 style=\"margin:0 0 0.6em 0;color:#fff;\">\nVotre architecture vous ralentit ?\n\u003C\u002Fh3>\n\u003Cp style=\"margin:0 0 1.2em 0;color:#e0e7ff;\">\nAudit gratuit de 30 minutes : je regarde votre stack actuelle, je repère les goulots d’étranglement, je vous dis exactement par où commencer. Zéro engagement, zéro commercial.\n\u003C\u002Fp>\n\u003Cp>\u003Ca href=\"https:\u002F\u002Fcalendly.com\u002Falexandrecarette\u002Faudit-architecture\" style=\"display:inline-block;padding:0.9em 1.8em;background:#fff;color:#4f46e5;text-decoration:none;font-weight:600;border-radius:8px;\">Réserver 30 min avec Alexandre →\u003C\u002Fa>\u003C\u002Fp>\n\u003C\u002Fdiv>\n\n\u003Cdiv class=\"articles-lies\" style=\"margin:2em 0;padding:1.5em;border:1px solid #e2e8f0;border-radius:12px;background:#f8fafc;\">\n\u003Ch3 style=\"margin:0 0 0.8em 0;font-size:1em;color:#334155;\">Articles dans le même univers\u003C\u002Fh3>\n\u003Cul style=\"margin:0;padding-left:1.2em;list-style:disc;\">\n\u003Cli>\u003Ca href=\"\u002Fblog\u002Fprestashop\u002Fdeveloppement\u002Fheadless-vs-shopify-comparatif\">PrestaShop Headless ou Shopify : pourquoi bâtir son propre Hub\u003C\u002Fa>\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n\n\n\u003Cdiv class=\"article-sources\" style=\"margin:2em 0;padding:1.5em;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc;\">\n\u003Ch3 style=\"margin:0 0 0.8em 0;font-size:1em;color:#334155;\">\nSources citées\n\u003C\u002Fh3>\n\u003Cul style=\"margin:0;padding-left:1.2em;color:#475569;font-size:0.92em;\">\n\u003Cli>\nMartin Fowler, \u003Cem>Patterns of Enterprise Application Architecture\u003C\u002Fem>, Addison-Wesley, 2002 — chapitre \u003Cem>Active Record\u003C\u002Fem> (\u003Ca href=\"https:\u002F\u002Fmartinfowler.com\u002FeaaCatalog\u002FactiveRecord.html\" rel=\"noopener\">martinfowler.com\u002FeaaCatalog\u002FactiveRecord.html\u003C\u002Fa>)\n\u003C\u002Fli>\n\u003Cli>\nGoogle Cloud, \u003Cem>DORA 2024 State of DevOps Report\u003C\u002Fem> — métrique \u003Cem>Lead time for changes\u003C\u002Fem> (\u003Ca href=\"https:\u002F\u002Fcloud.google.com\u002Fdevops\u002Fstate-of-devops\" rel=\"noopener\">cloud.google.com\u002Fdevops\u002Fstate-of-devops\u003C\u002Fa>)\n\u003C\u002Fli>\n\u003Cli>\nMariaDB Foundation, documentation officielle \u003Ccode>MEDIUMTEXT\u003C\u002Fcode> et \u003Ccode>InnoDB\u003C\u002Fcode> (\u003Ca href=\"https:\u002F\u002Fmariadb.com\u002Fkb\u002Fen\u002F\" rel=\"noopener\">mariadb.com\u002Fkb\u002Fen\u002F\u003C\u002Fa>)\n\u003C\u002Fli>\n\u003Cli>\nAlexandre Carette, \u003Cem>Journal de chantier CodeMyShop — commits \u003Ccode>9fcd1a53\u003C\u002Fcode> et \u003Ccode>f86afa22\u003C\u002Fcode>\u003C\u002Fem> (préprod, 11 avril 2026)\n\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n\n\u003Cdiv style=\"background:#f8fafc;border-left:4px solid #4F46E5;padding:16px 20px;margin:24px 0;border-radius:0 8px 8px 0;\">\u003Cp style=\"margin:0;font-size:14px;\">\u003Cstrong>Approfondir dans l'Academy\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp style=\"margin:4px 0 0;font-size:13px;\">\u003Ca href=\"\u002Facademy\u002Farchitecture-headless\" style=\"text-decoration:underline;color:#4F46E5;\">Module : Architecture Headless de A à Z &rarr;\u003C\u002Fa>\u003C\u002Fp>\u003C\u002Fdiv>",[203,206,209,212,215,218,221,224,227,230,233,236,239,242,245],{"q":204,"a":205},"Qu’est-ce qu’une architecture S.O.A.P (Service Orchestration and Automation Platform) ?","Une architecture S.O.A.P est un modèle dans lequel une plateforme centrale orchestre des services spécialisés à partir d’une source unique de vérité. Contrairement au protocole SOAP des années 2000, S.O.A.P désigne ici une approche d’infrastructure : la base de données est l’autel, les Active Record sont les façades, et chaque service (cron, script Python, agent IA) consomme la même source. Les équivalents commerciaux connus sont n8n, Retool Workflows ou Salesforce Flow — mais CodeMyShop la rend souveraine, hébergée sur un VPS contrôlé par le commerçant.",{"q":207,"a":208},"Pourquoi parle-t-on de DB-First ?","DB-First signifie que la base de données est la seule source de vérité pour les données runtime : profils, workflows, articles, configurations, menus, FAQ, etc. Les fichiers .json, .ts ou .md ne sont plus utilisés pour stocker ces données — ils deviennent uniquement des producteurs de code (logique métier). Cette séparation stricte élimine la classe entière de bugs liés aux désynchronisations fichier\u002FDB.",{"q":210,"a":211},"Quels sont les symptômes d’un système qui a trop de sources de vérité ?","Plusieurs signaux : (1) il existe des scripts dont le seul rôle est de synchroniser un fichier vers une base ; (2) les incidents prod sont régulièrement causés par une divergence entre deux sources ; (3) chaque modification de donnée exige un redéploiement complet ; (4) les développeurs hésitent entre modifier le fichier ou modifier la DB pour le même champ. Un seul de ces symptômes suffit à déclencher une refonte DB-First.",{"q":213,"a":214},"Comment reconnaître du code mort dans un monorepo ?","Du code mort est un code qui s’exécute sans apporter de valeur : des scripts qui dupliquent une logique déjà centralisée, des fichiers que plus aucun consommateur ne lit, des fonctions conservées au cas où depuis des mois. Un bon test : supprimer le fichier, relancer la suite de tests et faire tourner la prod pendant 48h. Si rien ne casse et aucun utilisateur ne remonte d’anomalie, c’est du code mort. Nous en avons supprimé 20 349 lignes en une seule opération.",{"q":216,"a":217},"Qu’est-ce que le pattern Active Record concrètement ?","Le pattern Active Record encapsule l’accès à une table dans une classe dédiée (AgentEntity, WorkflowEntity, ArticleEntity). Chaque classe expose des méthodes create(), update(), get(), validate(). Aucun script métier n’a le droit d’écrire en SQL brut dans les tables couvertes — un hook de pré-commit bloque ce type de code. L’avantage : la logique de validation vit à un seul endroit et chaque mutation passe par un gardien.",{"q":219,"a":220},"Pourquoi MariaDB et pas PostgreSQL pour CodeMyShop ?","Parce que CodeMyShop repose sur un cœur PrestaShop qui utilise nativement MySQL\u002FMariaDB. Conserver le même moteur que PrestaShop évite de maintenir deux bases en parallèle et profite de l’écosystème d’outils (phpMyAdmin, dump\u002Frestore PS, modules PS). MariaDB offre aussi un bon support des fonctionnalités historiques (FULLTEXT, InnoDB optimisé) et reste totalement gratuit, sans licence commerciale cachée.",{"q":222,"a":223},"Comment déployer un cutover de 20 000 lignes sans downtime ?","En appliquant l’ordre inverse de l’intuition : (1) on déploie le nouveau code avant de migrer les données ; (2) le nouveau code lit la nouvelle source (DB) avec un fallback sur l’ancienne (fichier) ; (3) on migre les données sans bouger le code ; (4) on supprime les anciens fichiers dans un commit dédié ; (5) on nettoie le fallback. À chaque étape, la prod reste servie par au moins une des deux sources. Zéro fenêtre vulnérable.",{"q":225,"a":226},"Qu’est-ce qu’un dual-read lors d’une migration ?","Un dual-read est un mécanisme transitoire où le code tente de lire la nouvelle source en priorité, et retombe sur l’ancienne si le résultat est vide. Pendant la phase de bascule, cette approche permet de déployer le code avant d’avoir fini de migrer les données. Une fois la migration terminée, le fallback est retiré dans un commit séparé. C’est la technique qui rend un cutover massif invisible à l’utilisateur final.",{"q":228,"a":229},"Pourquoi supprimer des fichiers .md améliore-t-il la vitesse d’itération ?","Parce que chaque fichier exige un cycle complet commit → push → deploy → rebuild pour que son contenu soit disponible en production. Une modification d’une ligne dans un profil d’agent prenait quinze minutes en moyenne. La même modification via un UPDATE en base prend deux secondes et est immédiatement lue par tous les consommateurs. Sur trente agents actifs modifiés plusieurs fois par jour, le gain cumulé dépasse plusieurs heures hebdomadaires.",{"q":231,"a":232},"Quelle est la différence entre un SaaS et un PaaS souverain comme CodeMyShop ?","Un SaaS (Shopify, Wix) fait tourner votre boutique sur ses propres serveurs : vous louez un service, vous ne possédez rien. Un PaaS souverain comme CodeMyShop installe votre propre VPS isolé (un serveur dédié dans un datacenter français OVH) avec votre boutique, votre base, vos clés API. Vous possédez tout, vous pouvez exporter tout, et aucune donnée ne transite par un intermédiaire. La différence se voit le jour où un SaaS augmente ses prix de 40 % ou bloque votre compte : en PaaS souverain, ça n’existe pas.",{"q":234,"a":235},"Quels sont les risques d’une source statique pour des données runtime ?","Une source statique (fichier .json ou .ts committé en dur) crée trois classes de risques : (1) désynchronisation avec la DB lorsqu’un module écrit directement en base sans repasser par le fichier ; (2) redéploiement obligatoire pour chaque modification, ce qui exclut l’édition par des non-développeurs ; (3) conflits de merge git sur des fichiers éditables par plusieurs contributeurs. Une donnée qui change en production ne devrait jamais vivre dans un fichier versionné.",{"q":237,"a":238},"Comment s’assurer qu’un refactor ne casse pas la prod ?","Trois garde-fous combinés : (1) un tag git posé avant l’opération pour un rollback instantané ; (2) une phase de dual-read qui tourne en prod plusieurs jours avant la suppression finale, de sorte qu’un bug apparaît AVANT le point de non-retour ; (3) une batterie de tests automatisés qui exerce les chemins critiques. Sur le cutover du 11 avril, ces trois mécanismes ont permis de supprimer 20 000 lignes sans qu’aucun utilisateur final ne sente le changement.",{"q":240,"a":241},"Qu’est-ce qu’une cicatrice dans la méthode CodeMyShop ?","Une cicatrice est une erreur passée gravée dans la mémoire du système pour ne plus jamais être reproduite. Chaque incident prod génère une cicatrice datée, avec la cause racine et le check qui aurait dû la détecter. Les cicatrices sont stockées dans la table ps_ac_cicatrices et injectées dans le prompt de chaque agent IA avant qu’il n’agisse. C’est une forme de mémoire institutionnelle qui permet au système de s’améliorer à chaque session, plutôt que de répéter les mêmes erreurs à l’infini.",{"q":243,"a":244},"Combien de temps a pris le passage fichiers → DB-First ?","Deux semaines de préparation étalées sur quatre phases : Phase 1 (schéma DB, 3 jours), Phase 2 (Active Record, 4 jours), Phase 3 (dual-read déployé en prod, 3 jours de surveillance), Phase 4 (cutover final en une session de 5 heures le 11 avril). La dernière phase a supprimé 20 349 lignes et touché 113 fichiers en un seul commit. Le temps total aurait pu être réduit, mais nous avons privilégié la sécurité à la vitesse — zéro incident pendant toute l’opération.",{"q":246,"a":247},"Est-ce que cette architecture peut être appliquée à d’autres projets ?","Oui, le pattern est agnostique. Il fonctionne pour toute stack où : (a) vous avez plus de trois sources de vérité différentes ; (b) les données runtime sont partiellement stockées dans des fichiers ; (c) vous ressentez une friction croissante entre modifier une donnée et la voir en prod. Le prérequis est d’avoir une base de données capable de porter une colonne texte moyenne (MediumText en MySQL, Text en PostgreSQL) pour accueillir les contenus markdown. Le reste — Active Record, hooks pre-commit, dual-read — se réplique en quelques jours de travail.","20 000 lignes de code mort supprimées en un commit : pourquoi CodeMyShop a basculé vers une architecture S.O.A.P souveraine, DB-First sur MariaDB.","",8,[],[253],{"id":194,"title":195,"category":196,"subcategory":197,"slug":198,"linkRewrite":254,"excerpt":248,"coverImage":199,"thumbnailImage":200,"nuxtUrl":255,"datePublished":256,"dateUpdated":257,"readingTime":258,"faqCount":258},"tech--architecture--revolution-soap","\u002Fblog\u002Ftech\u002Farchitecture\u002Frevolution-soap","2026-04-11T16:18:16.000Z","2026-04-12T06:01:04.000Z",15]