[{"data":1,"prerenderedAt":11779},["ShallowReactive",2],{"search-api":-1,"content-query-O20KZJwPUL":3},[4,472,1258,2105,4095,4560,5097,9920,10587],{"_path":5,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":9,"description":10,"id":11,"date":12,"listed":13,"nocomments":7,"hidden":7,"categories":14,"tags":15,"--cover":19,"readingTime":20,"body":25,"_type":466,"_id":467,"_source":468,"_file":469,"_stem":470,"_extension":471},"/fr/dette-technique/ingenierie-logicielle-avantage-concurrentiel","dette-technique",false,"","L'ingénierie logicielle comme avantage concurrentiel durable","Dans un monde où l'IA accélère tout le monde, la qualité d'engineering devient le différenciateur durable. Ce que les CTOs qui l'ont compris font différemment.",36,"2026-03-27",true,[6],[16,17,18],"Engineering Excellence","Avantage Compétitif","Leadership","covers/articles/ingenierie-avantage-concurrentiel.jpg",{"text":21,"minutes":22,"time":23,"words":24},"8 min read",7.68,460800,1536,{"type":26,"children":27,"toc":452},"root",[28,36,51,60,65,69,76,81,86,96,99,105,112,117,122,128,133,138,144,149,162,165,178,181,187,192,202,212,222,232,242,245,251,256,266,276,286,291,294,300,305,315,333,351,361,364,370,385,398,411,424,437,440],{"type":29,"tag":30,"props":31,"children":33},"element","h1",{"id":32},"lingénierie-logicielle-comme-avantage-concurrentiel-durable",[34],{"type":35,"value":9},"text",{"type":29,"tag":37,"props":38,"children":39},"p",{},[40,42,49],{"type":35,"value":41},"J'ai accompagné un client dans le secteur de la santé, 35 développeurs, pendant 12 mois. Quand j'ai commencé, le ",{"type":29,"tag":43,"props":44,"children":46},"a",{"href":45},"/fr/pratiques-agiles/reduire-work-in-progress-velocite",[47],{"type":35,"value":48},"lead time",{"type":35,"value":50}," était de 6 semaines, le taux de bugs de prod était élevé, et deux développeurs seniors venaient de partir en citant \"l'environnement technique trop dégradé\". Douze mois plus tard : lead time à 1,5 semaine, taux de bugs de prod en baisse de 65%, et deux nouveaux seniors recrutés qui avaient cité explicitement la qualité de l'environnement technique comme raison principale de rejoindre. Au moment de la prochaine levée de fonds, la due diligence technique est devenue un argument de valorisation, plus un risque à minimiser.",{"type":29,"tag":37,"props":52,"children":53},{},[54],{"type":29,"tag":55,"props":56,"children":57},"strong",{},[58],{"type":35,"value":59},"L'IA a rendu le code accessible à tout le monde. Elle n'a pas rendu la qualité d'engineering accessible à tout le monde. Et c'est là que se creuse le prochain écart concurrentiel.",{"type":29,"tag":37,"props":61,"children":62},{},[63],{"type":35,"value":64},"En 2024-2025, les outils de génération de code ont nivelé la vitesse de production du code. Une startup de 5 personnes peut générer autant de code qu'une équipe de 50 il y a 3 ans. Ce nivellement a changé les règles du jeu : la compétition ne se joue plus sur qui écrit le code le plus vite, mais sur qui le maintient, l'améliore, et le gouverne le mieux.",{"type":29,"tag":66,"props":67,"children":68},"hr",{},[],{"type":29,"tag":70,"props":71,"children":73},"h2",{"id":72},"lia-comme-égalisateur-et-révélateur",[74],{"type":35,"value":75},"L'IA comme égalisateur et révélateur",{"type":29,"tag":37,"props":77,"children":78},{},[79],{"type":35,"value":80},"L'IA a réduit le coût marginal de production de code à presque zéro. Un développeur augmenté par Copilot produit 20 à 40% de code supplémentaire selon les études GitHub. C'est un gain réel.",{"type":29,"tag":37,"props":82,"children":83},{},[84],{"type":35,"value":85},"Mais ce gain amplifie ce qui existe déjà. Une équipe avec de bonnes pratiques d'architecture, de test, et de revue de code bénéficie pleinement de l'IA : le code généré est bien intégré, testé, et maintenu. Une équipe avec de mauvaises pratiques produit plus de dette technique plus rapidement. L'IA amplifie les équipes solides et fragilise les équipes fragiles.",{"type":29,"tag":37,"props":87,"children":88},{},[89,94],{"type":29,"tag":55,"props":90,"children":91},{},[92],{"type":35,"value":93},"La donnée qui change tout",{"type":35,"value":95}," : le State of DevOps Report 2023 (DORA) montre que les équipes \"elite\" ont un deployment frequency 973 fois supérieur aux équipes \"low performers\", et un lead time 6 570 fois inférieur. L'IA n'a pas réduit cet écart. Elle l'a amplifié. Ce n'est pas de la théorie : c'est le résultat de 10 ans de données sur des milliers d'équipes.",{"type":29,"tag":66,"props":97,"children":98},{},[],{"type":29,"tag":70,"props":100,"children":102},{"id":101},"les-3-dimensions-de-lavantage-engineering",[103],{"type":35,"value":104},"Les 3 dimensions de l'avantage engineering",{"type":29,"tag":106,"props":107,"children":109},"h3",{"id":108},"dimension-1-la-vitesse-de-livraison-time-to-market",[110],{"type":35,"value":111},"Dimension 1 : La vitesse de livraison (time-to-market)",{"type":29,"tag":37,"props":113,"children":114},{},[115],{"type":35,"value":116},"La capacité à livrer des fonctionnalités en semaines plutôt qu'en mois est un avantage concurrentiel direct. Sur les marchés où les cycles d'innovation sont courts, une équipe qui déploie en production plusieurs fois par semaine peut itérer sur le feedback utilisateur 10 fois plus vite qu'une équipe qui déploie une fois par mois.",{"type":29,"tag":37,"props":118,"children":119},{},[120],{"type":35,"value":121},"Ce n'est pas une métrique technique, c'est une métrique business. Chaque semaine gagnée sur le lead time est une semaine d'avance sur le concurrent qui a eu la même idée.",{"type":29,"tag":106,"props":123,"children":125},{"id":124},"dimension-2-la-qualité-comme-réducteur-de-risque",[126],{"type":35,"value":127},"Dimension 2 : La qualité comme réducteur de risque",{"type":29,"tag":37,"props":129,"children":130},{},[131],{"type":35,"value":132},"Dans les secteurs régulés (finance, assurance, santé), la qualité d'engineering est une condition de survie réglementaire. Un incident lié à un code de mauvaise qualité peut déclencher une enquête de l'autorité de tutelle, une amende significative, et un dommage réputationnel durable. J'ai vu cela chez des clients dans le secteur bancaire, Canal+, BNP Paribas, Agirc-Arrco, où un incident technique mal géré avait des conséquences réglementaires immédiates.",{"type":29,"tag":37,"props":134,"children":135},{},[136],{"type":35,"value":137},"Mais dans tous les secteurs, la qualité réduit le coût opérationnel. Une équipe avec une absorption de dette technique à 20% (vs 40%) a 20% de capacité supplémentaire disponible pour l'innovation. Sur une équipe de 50 développeurs, c'est 10 développeurs-équivalents récupérés sans recrutement.",{"type":29,"tag":106,"props":139,"children":141},{"id":140},"dimension-3-lattractivité-des-talents",[142],{"type":35,"value":143},"Dimension 3 : L'attractivité des talents",{"type":29,"tag":37,"props":145,"children":146},{},[147],{"type":35,"value":148},"Les meilleurs développeurs choisissent leurs employeurs sur les pratiques techniques, pas seulement sur la rémunération. Une enquête Stack Overflow 2023 montre que 62% des développeurs considèrent la qualité technique de l'environnement de travail comme un critère de choix primaire.",{"type":29,"tag":37,"props":150,"children":151},{},[152,154,160],{"type":35,"value":153},"Une équipe avec un ",{"type":29,"tag":43,"props":155,"children":157},{"href":156},"/fr/dette-technique/introduction-maturite-engineering-5-niveaux",[158],{"type":35,"value":159},"niveau 4-5 de maturité engineering",{"type":35,"value":161}," attire et retient les développeurs seniors. Une équipe au niveau 1-2 a un turnover plus élevé et un coût de recrutement proportionnel. Le cercle vicieux : les bons développeurs partent à cause de la dette, les remplaçants sont moins expérimentés, la dette augmente.",{"type":29,"tag":66,"props":163,"children":164},{},[],{"type":29,"tag":166,"props":167,"children":172},"cta",{"cta":168,"href":169,"title":170,"type":171},"Réserver mon diagnostic gratuit →","https://app.kamanga.fr/forms/discovery-call","Votre engineering est-il un avantage concurrentiel ou un frein à la croissance ?","call",[173],{"type":29,"tag":37,"props":174,"children":175},{},[176],{"type":35,"value":177},"Vous sentez que votre engineering ne vous donne pas l'avantage qu'il devrait donner : le lead time est trop long, les bugs reviennent, les bons développeurs hésitent à rejoindre l'équipe. Un diagnostic de maturité engineering prend 2 jours. Il produit une vue claire de votre position et un plan d'action concret pour transformer votre engineering en levier de croissance.",{"type":29,"tag":66,"props":179,"children":180},{},[],{"type":29,"tag":70,"props":182,"children":184},{"id":183},"ce-que-les-équipes-délite-font-différemment",[185],{"type":35,"value":186},"Ce que les équipes d'élite font différemment",{"type":29,"tag":37,"props":188,"children":189},{},[190],{"type":35,"value":191},"La recherche DORA identifie 5 pratiques qui distinguent les équipes \"elite\" des autres, indépendamment de la taille ou du secteur :",{"type":29,"tag":37,"props":193,"children":194},{},[195,200],{"type":29,"tag":55,"props":196,"children":197},{},[198],{"type":35,"value":199},"1. Le trunk-based development",{"type":35,"value":201}," : intégration sur la branche principale au moins une fois par jour, feature flags pour isoler le code non-terminé. Réduit le coût de merge et les conflits d'intégration.",{"type":29,"tag":37,"props":203,"children":204},{},[205,210],{"type":29,"tag":55,"props":206,"children":207},{},[208],{"type":35,"value":209},"2. La suite de tests automatisés",{"type":35,"value":211}," : tests qui s'exécutent en moins de 10 minutes sur chaque commit, avec un objectif de non-régression garanti. Conditionne la confiance pour déployer fréquemment.",{"type":29,"tag":37,"props":213,"children":214},{},[215,220],{"type":29,"tag":55,"props":216,"children":217},{},[218],{"type":35,"value":219},"3. Le continuous deployment",{"type":35,"value":221}," : automatisation complète du pipeline de déploiement. Aucune intervention manuelle entre le commit et la prod. Réduit le risque humain et le lead time.",{"type":29,"tag":37,"props":223,"children":224},{},[225,230],{"type":29,"tag":55,"props":226,"children":227},{},[228],{"type":35,"value":229},"4. Le monitoring et l'observabilité",{"type":35,"value":231}," : visibilité temps réel sur les métriques de performance et d'erreur. MTTR \u003C 1 heure pour les incidents P1.",{"type":29,"tag":37,"props":233,"children":234},{},[235,240],{"type":29,"tag":55,"props":236,"children":237},{},[238],{"type":35,"value":239},"5. La culture du learning",{"type":35,"value":241}," : blameless post-mortems, partage de knowledge structuré, temps dédié à l'apprentissage. Les équipes qui apprennent progressent ; les autres stagnent. C'est ce que les travaux de Nicole Forsgren sur la culture DevOps démontrent de façon rigoureuse.",{"type":29,"tag":66,"props":243,"children":244},{},[],{"type":29,"tag":70,"props":246,"children":248},{"id":247},"comment-traduire-la-qualité-engineering-en-langage-board",[249],{"type":35,"value":250},"Comment traduire la qualité engineering en langage board",{"type":29,"tag":37,"props":252,"children":253},{},[254],{"type":35,"value":255},"Le board ne comprend pas \"maturité engineering\" ou \"dette technique\". Il comprend :",{"type":29,"tag":37,"props":257,"children":258},{},[259,264],{"type":29,"tag":55,"props":260,"children":261},{},[262],{"type":35,"value":263},"Risque opérationnel",{"type":35,"value":265}," : \"Notre taux d'incidents de prod génère X€ de coût direct et Y€ de risque réglementaire par an. Un investissement de Z€ en qualité technique réduit ce risque de 70% en 12 mois.\"",{"type":29,"tag":37,"props":267,"children":268},{},[269,274],{"type":29,"tag":55,"props":270,"children":271},{},[272],{"type":35,"value":273},"Efficacité du capital",{"type":35,"value":275}," : \"Nous investissons 40% de notre capacité engineering à maintenir l'existant. Un programme de 6 mois ramène ce chiffre à 20%, soit l'équivalent de 8 développeurs à plein temps récupérés pour l'innovation.\"",{"type":29,"tag":37,"props":277,"children":278},{},[279,284],{"type":29,"tag":55,"props":280,"children":281},{},[282],{"type":35,"value":283},"Avantage compétitif",{"type":35,"value":285}," : \"Notre lead time actuel de 6 semaines signifie que nous mettons 6 semaines à répondre aux opportunités de marché. Nos principaux concurrents sont à 2 semaines. Le delta nous coûte X% de chiffre d'affaires sur les opportunités time-sensitive.\"",{"type":29,"tag":37,"props":287,"children":288},{},[289],{"type":35,"value":290},"Ces trois angles permettent à un board de comprendre que l'investissement en qualité engineering n'est pas une dépense technique, c'est un levier de performance business. Ce changement de cadrage est souvent ce qui débloque les budgets que les CTOs n'arrivaient pas à obtenir en présentant le sujet dans sa version technique.",{"type":29,"tag":66,"props":292,"children":293},{},[],{"type":29,"tag":70,"props":295,"children":297},{"id":296},"le-plan-daction-pour-les-12-prochains-mois",[298],{"type":35,"value":299},"Le plan d'action pour les 12 prochains mois",{"type":29,"tag":37,"props":301,"children":302},{},[303],{"type":35,"value":304},"Si vous êtes au niveau 2-3 aujourd'hui et souhaitez faire de l'engineering un avantage concurrentiel, voici la séquence :",{"type":29,"tag":37,"props":306,"children":307},{},[308,313],{"type":29,"tag":55,"props":309,"children":310},{},[311],{"type":35,"value":312},"Trimestre 1",{"type":35,"value":314}," : Mesurer. Implémenter les 4 métriques DORA, quantifier l'absorption de la dette technique, identifier les 2-3 modules critiques qui génèrent le plus de coûts.",{"type":29,"tag":37,"props":316,"children":317},{},[318,323,325,331],{"type":29,"tag":55,"props":319,"children":320},{},[321],{"type":35,"value":322},"Trimestre 2",{"type":35,"value":324}," : Stabiliser. Programme de réduction de la dette sur les modules critiques, stabilisation de la CI/CD, installation des ",{"type":29,"tag":43,"props":326,"children":328},{"href":327},"/fr/dette-technique/outils-analyse-statique-2026",[329],{"type":35,"value":330},"outils d'analyse statique",{"type":35,"value":332},".",{"type":29,"tag":37,"props":334,"children":335},{},[336,341,343,349],{"type":29,"tag":55,"props":337,"children":338},{},[339],{"type":35,"value":340},"Trimestre 3",{"type":35,"value":342}," : Accélérer. Réduction du lead time sur un flux de delivery cible, introduction du continuous deployment, formation sur les pratiques avancées (TDD, ",{"type":29,"tag":43,"props":344,"children":346},{"href":345},"/fr/dette-technique/pair-programming-roi-conditions",[347],{"type":35,"value":348},"pair programming ciblé",{"type":35,"value":350},").",{"type":29,"tag":37,"props":352,"children":353},{},[354,359],{"type":29,"tag":55,"props":355,"children":356},{},[357],{"type":35,"value":358},"Trimestre 4",{"type":35,"value":360}," : Consolider et mesurer le ROI. Comparer les métriques de T4 vs T1. Préparer le business case pour le prochain cycle d'investissement.",{"type":29,"tag":66,"props":362,"children":363},{},[],{"type":29,"tag":70,"props":365,"children":367},{"id":366},"faq-sur-lengineering-comme-avantage-concurrentiel",[368],{"type":35,"value":369},"FAQ sur l'engineering comme avantage concurrentiel",{"type":29,"tag":371,"props":372,"children":373},"details",{},[374,380],{"type":29,"tag":375,"props":376,"children":377},"summary",{},[378],{"type":35,"value":379},"1. L'IA ne va-t-elle pas rendre ces investissements obsolètes en quelques années ?",{"type":29,"tag":37,"props":381,"children":382},{},[383],{"type":35,"value":384},"Non, et c'est précisément l'inverse. L'IA rend les pratiques d'engineering solides plus importantes, pas moins. Le code généré par l'IA doit être testé, reviewé, maintenu et gouverné. Une équipe sans bonnes pratiques génère de la dette technique à la vitesse de l'IA. Une équipe avec de bonnes pratiques bénéficie pleinement de la productivité de l'IA tout en maintenant la qualité.",{"type":29,"tag":371,"props":386,"children":387},{},[388,393],{"type":29,"tag":375,"props":389,"children":390},{},[391],{"type":35,"value":392},"2. Ces pratiques sont-elles accessibles aux petites équipes (\u003C 10 développeurs) ?",{"type":29,"tag":37,"props":394,"children":395},{},[396],{"type":35,"value":397},"Oui, et souvent plus rapidement. Une équipe de 8 développeurs peut atteindre le niveau 4 en 6 mois : la coordination est simple, les standards s'adoptent vite, et l'impact de chaque amélioration est immédiatement visible. Les pratiques DORA (CI/CD, trunk-based development, monitoring) s'appliquent quelle que soit la taille de l'équipe.",{"type":29,"tag":371,"props":399,"children":400},{},[401,406],{"type":29,"tag":375,"props":402,"children":403},{},[404],{"type":35,"value":405},"3. Comment prouver la valeur de l'investissement engineering à un investisseur lors d'une due diligence ?",{"type":29,"tag":37,"props":407,"children":408},{},[409],{"type":35,"value":410},"Quatre métriques convaincantes pour une due diligence : deployment frequency (> 1/semaine), lead time (\u003C 1 semaine), change failure rate (\u003C 5%), MTTR (\u003C 1 heure). Ces chiffres montrent la capacité à itérer rapidement et à maintenir la stabilité. Je recommande de préparer un \"engineering health report\" avant toute due diligence : c'est ce qui a fait la différence pour ce client dont je parlais.",{"type":29,"tag":371,"props":412,"children":413},{},[414,419],{"type":29,"tag":375,"props":415,"children":416},{},[417],{"type":35,"value":418},"4. Par où commencer si le board ne voit pas encore la valeur de l'engineering ?",{"type":29,"tag":37,"props":420,"children":421},{},[422],{"type":35,"value":423},"Commencer par un incident et le transformer en business case. La prochaine fois qu'un incident de prod a un impact business mesurable, calculer le coût total : temps de résolution, impact sur le revenu, coût réputationnel. Montrer que des pratiques standard auraient prévenu cet incident. Un seul incident bien documenté vaut mieux que dix slides de théorie.",{"type":29,"tag":371,"props":425,"children":426},{},[427,432],{"type":29,"tag":375,"props":428,"children":429},{},[430],{"type":35,"value":431},"5. Comment maintenir les standards de qualité quand la croissance crée une pression intense sur la livraison ?",{"type":29,"tag":37,"props":433,"children":434},{},[435],{"type":35,"value":436},"La croissance augmente la pression et teste les standards. Les équipes qui maintiennent la qualité pendant la croissance ont toutes une chose en commun : le \"budget technique\" est non-négociable. 20% de la capacité de l'équipe est protégée pour la qualité, les tests, et la réduction de la dette, quelles que soient les pressions externes. Sans ce budget explicite et défendu par le CTO, la qualité se dégrade invariablement sous la pression.",{"type":29,"tag":66,"props":438,"children":439},{},[],{"type":29,"tag":166,"props":441,"children":446},{"cta":442,"href":443,"title":444,"type":445},"Accéder à l'assessment gratuit →","/mes-ressources","Ressource gratuite : Engineering Maturity Self-Assessment","resource",[447],{"type":29,"tag":37,"props":448,"children":449},{},[450],{"type":35,"value":451},"30 questions pour évaluer votre maturité engineering sur 5 dimensions. Score automatique, positionnement sur les 5 niveaux, et les 3 actions prioritaires pour transformer votre engineering en avantage concurrentiel mesurable.",{"title":8,"searchDepth":453,"depth":453,"links":454},2,[455,456,462,463,464,465],{"id":72,"depth":453,"text":75},{"id":101,"depth":453,"text":104,"children":457},[458,460,461],{"id":108,"depth":459,"text":111},3,{"id":124,"depth":459,"text":127},{"id":140,"depth":459,"text":143},{"id":183,"depth":453,"text":186},{"id":247,"depth":453,"text":250},{"id":296,"depth":453,"text":299},{"id":366,"depth":453,"text":369},"markdown","content:fr:dette-technique:ingenierie-logicielle-avantage-concurrentiel.md","content","fr/dette-technique/ingenierie-logicielle-avantage-concurrentiel.md","fr/dette-technique/ingenierie-logicielle-avantage-concurrentiel","md",{"_path":473,"_dir":474,"_draft":7,"_partial":7,"_locale":8,"title":475,"description":476,"id":477,"date":478,"listed":13,"nocomments":7,"hidden":7,"categories":479,"tags":480,"--cover":485,"readingTime":486,"body":490,"_type":466,"_id":1255,"_source":468,"_file":1256,"_stem":1257,"_extension":471},"/fr/architecture-craft/database-per-service-microservices","architecture-craft","Database per Service : quand ça vaut vraiment la complexité","Le pattern Database per Service est présenté comme obligatoire en microservices. Il ne l'est pas. Le critère objectif pour décider — et les alternatives ignorées.",35,"2026-03-25",[474],[481,482,483,484],"Microservices","Database per Service","Architecture Distribuée","Base de Données","covers/articles/database-per-service-microservices.jpg",{"text":21,"minutes":487,"time":488,"words":489},7.61,456600,1522,{"type":26,"children":491,"toc":1246},[492,497,509,514,519,524,527,533,538,543,562,572,582,592,605,608,614,624,634,639,648,661,679,688,691,697,702,843,853,856,862,867,875,880,1020,1025,1033,1038,1046,1051,1054,1060,1068,1093,1103,1111,1114,1120,1125,1130,1153,1156,1162,1175,1188,1201,1214,1227,1230,1240],{"type":29,"tag":30,"props":493,"children":495},{"id":494},"database-per-service-quand-ça-vaut-vraiment-la-complexité",[496],{"type":35,"value":475},{"type":29,"tag":37,"props":498,"children":499},{},[500,502,507],{"type":35,"value":501},"J'ai accompagné un client dans le secteur du commerce en ligne qui avait adopté Database per Service dès le début, par principe, avant même d'avoir 5 développeurs. 18 mois plus tard, l'équipe de 6 développeurs backend passait ",{"type":29,"tag":55,"props":503,"children":504},{},[505],{"type":35,"value":506},"30% de son temps",{"type":35,"value":508}," à gérer l'infrastructure de 20 bases de données, les sagas qui échouaient partiellement, et les incohérences de données entre services.",{"type":29,"tag":37,"props":510,"children":511},{},[512],{"type":35,"value":513},"La décision que nous avons prise ensemble : migrer 15 des 20 services vers un schéma-per-service dans une base partagée. Seuls les 5 services critiques (ceux qui avaient vraiment des besoins différents de performance, d'isolation, ou de moteur) ont conservé leur base dédiée.",{"type":29,"tag":37,"props":515,"children":516},{},[517],{"type":35,"value":518},"Résultat : le temps passé à l'infrastructure est passé de 30% à 8%. L'équipe a pu réinvestir ces heures dans de la valeur produit.",{"type":29,"tag":37,"props":520,"children":521},{},[522],{"type":35,"value":523},"Database per Service n'est pas un impératif des microservices. C'est un trade-off. Et comme tout trade-off, il se décide selon le contexte, pas selon un dogme.",{"type":29,"tag":66,"props":525,"children":526},{},[],{"type":29,"tag":70,"props":528,"children":530},{"id":529},"le-problème-réel-que-database-per-service-résout",[531],{"type":35,"value":532},"Le problème réel que Database per Service résout",{"type":29,"tag":37,"props":534,"children":535},{},[536],{"type":35,"value":537},"Sam Newman dans \"Building Microservices\" (2014) a popularisé l'idée que chaque microservice devrait posséder ses données. L'intention était valide : éviter le couplage de base de données partagée qui crée des dépendances implicites entre services.",{"type":29,"tag":37,"props":539,"children":540},{},[541],{"type":35,"value":542},"Ces couplages sont réels :",{"type":29,"tag":37,"props":544,"children":545},{},[546,551,553,560],{"type":29,"tag":55,"props":547,"children":548},{},[549],{"type":35,"value":550},"Couplage de schéma :",{"type":35,"value":552}," si le service A modifie la table ",{"type":29,"tag":554,"props":555,"children":557},"code",{"className":556},[],[558],{"type":35,"value":559},"orders",{"type":35,"value":561},", le service B qui lit cette table peut casser sans que l'équipe A s'en rende compte.",{"type":29,"tag":37,"props":563,"children":564},{},[565,570],{"type":29,"tag":55,"props":566,"children":567},{},[568],{"type":35,"value":569},"Couplage de déploiement :",{"type":35,"value":571}," une migration de base de données doit être coordonnée avec tous les services qui lisent ou écrivent les tables concernées.",{"type":29,"tag":37,"props":573,"children":574},{},[575,580],{"type":29,"tag":55,"props":576,"children":577},{},[578],{"type":35,"value":579},"Couplage de performance :",{"type":35,"value":581}," une requête lente du service A consomme des ressources de connexion qui dégradent les performances du service B.",{"type":29,"tag":37,"props":583,"children":584},{},[585,590],{"type":29,"tag":55,"props":586,"children":587},{},[588],{"type":35,"value":589},"Couplage de technologie :",{"type":35,"value":591}," tous les services sont contraints d'utiliser le même moteur de base de données, même si certains auraient besoin d'un graph database et d'autres d'un document store.",{"type":29,"tag":37,"props":593,"children":594},{},[595,597,603],{"type":35,"value":596},"Ces couplages valent la peine d'être éliminés, mais la question est : à quel coût, et avec quelle alternative ? Et la décision de les éliminer (ou de les tolérer) mérite d'être consignée dans un ",{"type":29,"tag":43,"props":598,"children":600},{"href":599},"/fr/architecture-craft/adr-architecture-decision-record",[601],{"type":35,"value":602},"Architecture Decision Record",{"type":35,"value":604}," pour que le contexte reste accessible à toute l'équipe.",{"type":29,"tag":66,"props":606,"children":607},{},[],{"type":29,"tag":70,"props":609,"children":611},{"id":610},"le-coût-réel-de-database-per-service",[612],{"type":35,"value":613},"Le coût réel de Database per Service",{"type":29,"tag":37,"props":615,"children":616},{},[617,622],{"type":29,"tag":55,"props":618,"children":619},{},[620],{"type":35,"value":621},"Complexité opérationnelle :",{"type":35,"value":623}," 10 services = 10 bases de données à provisionner, monitorer, sauvegarder, mettre à jour, et maintenir en haute disponibilité. Sur AWS, 10 instances RDS PostgreSQL coûtent entre 500 et 2 000€ par mois selon la taille, avant les coûts d'ingénierie pour les gérer.",{"type":29,"tag":37,"props":625,"children":626},{},[627,632],{"type":29,"tag":55,"props":628,"children":629},{},[630],{"type":35,"value":631},"Transactions distribuées :",{"type":35,"value":633}," sans base de données partagée, une opération qui modifie des données dans plusieurs services (créer une commande ET décrémenter le stock ET enregistrer le paiement) ne peut plus être traitée dans une transaction ACID.",{"type":29,"tag":37,"props":635,"children":636},{},[637],{"type":35,"value":638},"Il faut implémenter le pattern Saga, décrit en détail par Vernon Vaughn dans \"Implementing Domain-Driven Design\" :",{"type":29,"tag":640,"props":641,"children":643},"pre",{"code":642},"Saga chorégraphie pour la création d'une commande :\nOrderService.createOrder() → publie OrderCreated\n→ InventoryService réserve le stock → publie InventoryReserved\n→ PaymentService charge le paiement → publie PaymentProcessed\n→ OrderService confirme la commande\n\nEn cas d'échec du paiement :\n→ PaymentService publie PaymentFailed\n→ InventoryService libère la réservation\n→ OrderService annule la commande\n",[644],{"type":29,"tag":554,"props":645,"children":646},{"__ignoreMap":8},[647],{"type":35,"value":642},{"type":29,"tag":37,"props":649,"children":650},{},[651,653,659],{"type":35,"value":652},"Chaque étape peut échouer, les messages peuvent être perdus ou dupliqués, et les états intermédiaires sont difficiles à debugger. Pour renforcer la robustesse de ces flux, les ",{"type":29,"tag":43,"props":654,"children":656},{"href":655},"/fr/architecture-craft/patterns-resilience-circuit-breaker-retry",[657],{"type":35,"value":658},"patterns de résilience : circuit breaker, retry, timeout",{"type":35,"value":660}," sont indispensables dès lors que les services communiquent de manière asynchrone.",{"type":29,"tag":37,"props":662,"children":663},{},[664,669,671,677],{"type":29,"tag":55,"props":665,"children":666},{},[667],{"type":35,"value":668},"Requêtes cross-services :",{"type":35,"value":670}," une requête qui joint des données de plusieurs services (liste des commandes avec le nom du client et le stock disponible) devient une API composition : plusieurs appels HTTP en séquence ou en parallèle, avec de la logique d'agrégation en mémoire. Cette communication asynchrone entre services introduit un ",{"type":29,"tag":43,"props":672,"children":674},{"href":673},"/fr/architecture-craft/couplage-temporel-code-asynchrone",[675],{"type":35,"value":676},"couplage temporel",{"type":35,"value":678}," qu'il faut gérer explicitement, notamment avec des garanties d'idempotence et d'ordre sur les événements.",{"type":29,"tag":166,"props":680,"children":682},{"cta":168,"href":169,"title":681,"type":171},"Vous migrez vers les microservices et vous hésitez sur la stratégie de base de données ?",[683],{"type":29,"tag":37,"props":684,"children":685},{},[686],{"type":35,"value":687},"Choisir la bonne stratégie de base de données pour une architecture distribuée dépend de nombreux facteurs contextuels que j'ai appris à évaluer sur le terrain, dans la finance, les médias, la logistique. En 30 minutes, on peut évaluer les trade-offs et définir l'approche adaptée à votre situation réelle.",{"type":29,"tag":66,"props":689,"children":690},{},[],{"type":29,"tag":70,"props":692,"children":694},{"id":693},"le-cadre-de-décision-objectif",[695],{"type":35,"value":696},"Le cadre de décision objectif",{"type":29,"tag":37,"props":698,"children":699},{},[700],{"type":35,"value":701},"La question n'est pas \"devrions-nous faire Database per Service ?\", c'est \"quel niveau de couplage de base de données est acceptable dans notre contexte ?\"",{"type":29,"tag":703,"props":704,"children":705},"table",{},[706,730],{"type":29,"tag":707,"props":708,"children":709},"thead",{},[710],{"type":29,"tag":711,"props":712,"children":713},"tr",{},[714,720,725],{"type":29,"tag":715,"props":716,"children":717},"th",{},[718],{"type":35,"value":719},"Critère",{"type":29,"tag":715,"props":721,"children":722},{},[723],{"type":35,"value":724},"Favorise Database per Service",{"type":29,"tag":715,"props":726,"children":727},{},[728],{"type":35,"value":729},"Favorise Base partagée",{"type":29,"tag":731,"props":732,"children":733},"tbody",{},[734,753,771,789,807,825],{"type":29,"tag":711,"props":735,"children":736},{},[737,743,748],{"type":29,"tag":738,"props":739,"children":740},"td",{},[741],{"type":35,"value":742},"Taille de l'équipe",{"type":29,"tag":738,"props":744,"children":745},{},[746],{"type":35,"value":747},"> 15 développeurs, équipes indépendantes",{"type":29,"tag":738,"props":749,"children":750},{},[751],{"type":35,"value":752},"\u003C 15 développeurs, une seule équipe",{"type":29,"tag":711,"props":754,"children":755},{},[756,761,766],{"type":29,"tag":738,"props":757,"children":758},{},[759],{"type":35,"value":760},"Fréquence de changement de schéma",{"type":29,"tag":738,"props":762,"children":763},{},[764],{"type":35,"value":765},"Fréquente (plusieurs fois par semaine)",{"type":29,"tag":738,"props":767,"children":768},{},[769],{"type":35,"value":770},"Rare (quelques fois par mois)",{"type":29,"tag":711,"props":772,"children":773},{},[774,779,784],{"type":29,"tag":738,"props":775,"children":776},{},[777],{"type":35,"value":778},"Exigences de performance",{"type":29,"tag":738,"props":780,"children":781},{},[782],{"type":35,"value":783},"Services avec des profils d'usage très différents",{"type":29,"tag":738,"props":785,"children":786},{},[787],{"type":35,"value":788},"Profils d'usage similaires",{"type":29,"tag":711,"props":790,"children":791},{},[792,797,802],{"type":29,"tag":738,"props":793,"children":794},{},[795],{"type":35,"value":796},"Exigences de disponibilité",{"type":29,"tag":738,"props":798,"children":799},{},[800],{"type":35,"value":801},"SLAs différents par service",{"type":29,"tag":738,"props":803,"children":804},{},[805],{"type":35,"value":806},"SLA uniforme",{"type":29,"tag":711,"props":808,"children":809},{},[810,815,820],{"type":29,"tag":738,"props":811,"children":812},{},[813],{"type":35,"value":814},"Transactions cross-services",{"type":29,"tag":738,"props":816,"children":817},{},[818],{"type":35,"value":819},"Rares",{"type":29,"tag":738,"props":821,"children":822},{},[823],{"type":35,"value":824},"Fréquentes et critiques",{"type":29,"tag":711,"props":826,"children":827},{},[828,833,838],{"type":29,"tag":738,"props":829,"children":830},{},[831],{"type":35,"value":832},"Maturité opérationnelle",{"type":29,"tag":738,"props":834,"children":835},{},[836],{"type":35,"value":837},"SRE dédié, infrastructure mature",{"type":29,"tag":738,"props":839,"children":840},{},[841],{"type":35,"value":842},"Pas d'équipe infra dédiée",{"type":29,"tag":37,"props":844,"children":845},{},[846,851],{"type":29,"tag":55,"props":847,"children":848},{},[849],{"type":35,"value":850},"La règle empirique :",{"type":35,"value":852}," si les équipes qui développent les services peuvent déployer indépendamment et que les transactions cross-services sont rares, Database per Service a du sens. Sinon, le coût dépasse la valeur.",{"type":29,"tag":66,"props":854,"children":855},{},[],{"type":29,"tag":70,"props":857,"children":859},{"id":858},"les-alternatives-ignorées",[860],{"type":35,"value":861},"Les alternatives ignorées",{"type":29,"tag":37,"props":863,"children":864},{},[865],{"type":35,"value":866},"Avant de sauter à \"une base de données par service\", il existe des options intermédiaires qui réduisent le couplage sans la complexité complète.",{"type":29,"tag":37,"props":868,"children":869},{},[870],{"type":29,"tag":55,"props":871,"children":872},{},[873],{"type":35,"value":874},"Option 1 : Schema per Service (dans la même base de données)",{"type":29,"tag":37,"props":876,"children":877},{},[878],{"type":35,"value":879},"Chaque service possède son schéma (namespace) dans une base de données partagée. Le service A ne peut accéder qu'aux tables du schéma A.",{"type":29,"tag":640,"props":881,"children":885},{"code":882,"language":883,"meta":8,"className":884,"style":8},"-- Service A n'accède qu'à son schéma\nSET search_path TO ordering;\nSELECT * FROM orders;  -- → ordering.orders\n\n-- Service B n'accède qu'à son schéma\nSET search_path TO inventory;\nSELECT * FROM products;  -- → inventory.products\n","sql","language-sql shiki shiki-themes catppuccin-frappe github-dark",[886],{"type":29,"tag":554,"props":887,"children":888},{"__ignoreMap":8},[889,901,926,955,964,973,994],{"type":29,"tag":890,"props":891,"children":894},"span",{"class":892,"line":893},"line",1,[895],{"type":29,"tag":890,"props":896,"children":898},{"style":897},"--shiki-default:#737994;--shiki-default-font-style:italic;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit",[899],{"type":35,"value":900},"-- Service A n'accède qu'à son schéma\n",{"type":29,"tag":890,"props":902,"children":903},{"class":892,"line":453},[904,910,916,921],{"type":29,"tag":890,"props":905,"children":907},{"style":906},"--shiki-default:#CA9EE6;--shiki-dark:#F97583",[908],{"type":35,"value":909},"SET",{"type":29,"tag":890,"props":911,"children":913},{"style":912},"--shiki-default:#C6D0F5;--shiki-dark:#E1E4E8",[914],{"type":35,"value":915}," search_path ",{"type":29,"tag":890,"props":917,"children":918},{"style":906},[919],{"type":35,"value":920},"TO",{"type":29,"tag":890,"props":922,"children":923},{"style":912},[924],{"type":35,"value":925}," ordering;\n",{"type":29,"tag":890,"props":927,"children":928},{"class":892,"line":459},[929,934,940,945,950],{"type":29,"tag":890,"props":930,"children":931},{"style":906},[932],{"type":35,"value":933},"SELECT",{"type":29,"tag":890,"props":935,"children":937},{"style":936},"--shiki-default:#81C8BE;--shiki-dark:#F97583",[938],{"type":35,"value":939}," *",{"type":29,"tag":890,"props":941,"children":942},{"style":906},[943],{"type":35,"value":944}," FROM",{"type":29,"tag":890,"props":946,"children":947},{"style":912},[948],{"type":35,"value":949}," orders;  ",{"type":29,"tag":890,"props":951,"children":952},{"style":897},[953],{"type":35,"value":954},"-- → ordering.orders\n",{"type":29,"tag":890,"props":956,"children":958},{"class":892,"line":957},4,[959],{"type":29,"tag":890,"props":960,"children":961},{"emptyLinePlaceholder":13},[962],{"type":35,"value":963},"\n",{"type":29,"tag":890,"props":965,"children":967},{"class":892,"line":966},5,[968],{"type":29,"tag":890,"props":969,"children":970},{"style":897},[971],{"type":35,"value":972},"-- Service B n'accède qu'à son schéma\n",{"type":29,"tag":890,"props":974,"children":976},{"class":892,"line":975},6,[977,981,985,989],{"type":29,"tag":890,"props":978,"children":979},{"style":906},[980],{"type":35,"value":909},{"type":29,"tag":890,"props":982,"children":983},{"style":912},[984],{"type":35,"value":915},{"type":29,"tag":890,"props":986,"children":987},{"style":906},[988],{"type":35,"value":920},{"type":29,"tag":890,"props":990,"children":991},{"style":912},[992],{"type":35,"value":993}," inventory;\n",{"type":29,"tag":890,"props":995,"children":997},{"class":892,"line":996},7,[998,1002,1006,1010,1015],{"type":29,"tag":890,"props":999,"children":1000},{"style":906},[1001],{"type":35,"value":933},{"type":29,"tag":890,"props":1003,"children":1004},{"style":936},[1005],{"type":35,"value":939},{"type":29,"tag":890,"props":1007,"children":1008},{"style":906},[1009],{"type":35,"value":944},{"type":29,"tag":890,"props":1011,"children":1012},{"style":912},[1013],{"type":35,"value":1014}," products;  ",{"type":29,"tag":890,"props":1016,"children":1017},{"style":897},[1018],{"type":35,"value":1019},"-- → inventory.products\n",{"type":29,"tag":37,"props":1021,"children":1022},{},[1023],{"type":35,"value":1024},"Avantages : les transactions ACID restent possibles si nécessaire. Complexité opérationnelle minimale (une seule base de données).",{"type":29,"tag":37,"props":1026,"children":1027},{},[1028],{"type":29,"tag":55,"props":1029,"children":1030},{},[1031],{"type":35,"value":1032},"Option 2 : Read replicas dédiées par service",{"type":29,"tag":37,"props":1034,"children":1035},{},[1036],{"type":35,"value":1037},"La base de données principale est partagée pour les écritures, mais chaque service lit depuis sa propre replica read-only synchronisée. Utile quand le problème principal est la contention de lecture.",{"type":29,"tag":37,"props":1039,"children":1040},{},[1041],{"type":29,"tag":55,"props":1042,"children":1043},{},[1044],{"type":35,"value":1045},"Option 3 : CQRS sans séparation de base",{"type":29,"tag":37,"props":1047,"children":1048},{},[1049],{"type":35,"value":1050},"Séparer les modèles de lecture et d'écriture sans nécessairement avoir des bases de données séparées. Les requêtes complexes lisent des vues matérialisées maintenues à jour par des événements.",{"type":29,"tag":66,"props":1052,"children":1053},{},[],{"type":29,"tag":70,"props":1055,"children":1057},{"id":1056},"quand-migrer-vers-database-per-service",[1058],{"type":35,"value":1059},"Quand migrer vers Database per Service",{"type":29,"tag":37,"props":1061,"children":1062},{},[1063],{"type":29,"tag":55,"props":1064,"children":1065},{},[1066],{"type":35,"value":1067},"Les signaux que la base partagée devient un problème :",{"type":29,"tag":1069,"props":1070,"children":1071},"ul",{},[1072,1078,1083,1088],{"type":29,"tag":1073,"props":1074,"children":1075},"li",{},[1076],{"type":35,"value":1077},"Les migrations de base de données nécessitent de coordonner 3 équipes ou plus",{"type":29,"tag":1073,"props":1079,"children":1080},{},[1081],{"type":35,"value":1082},"Un service lent dégrade régulièrement les performances des autres",{"type":29,"tag":1073,"props":1084,"children":1085},{},[1086],{"type":35,"value":1087},"Deux services ont des besoins contradictoires sur le schéma d'une table partagée",{"type":29,"tag":1073,"props":1089,"children":1090},{},[1091],{"type":35,"value":1092},"L'équipe veut utiliser un moteur de base de données différent pour un service spécifique",{"type":29,"tag":37,"props":1094,"children":1095},{},[1096,1101],{"type":29,"tag":55,"props":1097,"children":1098},{},[1099],{"type":35,"value":1100},"La migration progressive :",{"type":35,"value":1102}," commencer par les tables du service le plus indépendant. Migrer la table, mettre en place la synchronisation des données si nécessaire (CDC avec Debezium, événements de domaine), valider, puis passer à la table suivante.",{"type":29,"tag":640,"props":1104,"children":1106},{"code":1105},"Plan de migration en 4 phases :\nPhase 1 : service de notifications (aucune dépendance cross-service)\nPhase 2 : service de recherche (lecture seule, pas d'écriture cross-service)\nPhase 3 : service de catalogue produit (écriture rarement liée aux autres)\nPhase 4 : service de commandes (transactions complexes — laisser pour dernier)\n",[1107],{"type":29,"tag":554,"props":1108,"children":1109},{"__ignoreMap":8},[1110],{"type":35,"value":1105},{"type":29,"tag":66,"props":1112,"children":1113},{},[],{"type":29,"tag":70,"props":1115,"children":1117},{"id":1116},"le-cas-particulier-du-polyglot-persistence",[1118],{"type":35,"value":1119},"Le cas particulier du polyglot persistence",{"type":29,"tag":37,"props":1121,"children":1122},{},[1123],{"type":35,"value":1124},"Database per Service devient moins coûteux quand les services utilisent des bases de données managées (DynamoDB, MongoDB Atlas, Redis Cloud) avec une facturation à l'usage. Le coût opérationnel est absorbé par le fournisseur.",{"type":29,"tag":37,"props":1126,"children":1127},{},[1128],{"type":35,"value":1129},"Le pattern polyglot persistence (chaque service utilise le moteur adapté à ses besoins) ne vaut sa complexité que si les besoins sont vraiment distincts et que l'équipe a la maturité opérationnelle pour gérer plusieurs moteurs.",{"type":29,"tag":1069,"props":1131,"children":1132},{},[1133,1138,1143,1148],{"type":29,"tag":1073,"props":1134,"children":1135},{},[1136],{"type":35,"value":1137},"Service de recherche → Elasticsearch",{"type":29,"tag":1073,"props":1139,"children":1140},{},[1141],{"type":35,"value":1142},"Service de sessions → Redis",{"type":29,"tag":1073,"props":1144,"children":1145},{},[1146],{"type":35,"value":1147},"Service de catalogue → MongoDB (documents flexibles)",{"type":29,"tag":1073,"props":1149,"children":1150},{},[1151],{"type":35,"value":1152},"Service de commandes → PostgreSQL (transactions ACID)",{"type":29,"tag":66,"props":1154,"children":1155},{},[],{"type":29,"tag":70,"props":1157,"children":1159},{"id":1158},"faq-sur-database-per-service",[1160],{"type":35,"value":1161},"FAQ sur Database per Service",{"type":29,"tag":371,"props":1163,"children":1164},{},[1165,1170],{"type":29,"tag":375,"props":1166,"children":1167},{},[1168],{"type":35,"value":1169},"1. Comment gérer la cohérence des données entre services sans transactions distribuées ?",{"type":29,"tag":37,"props":1171,"children":1172},{},[1173],{"type":35,"value":1174},"Eventual consistency avec compensation. Accepter que les données ne soient pas instantanément cohérentes entre services, seulement éventuellement cohérentes. Pour les cas où une cohérence forte est nécessaire, utiliser le pattern Outbox : écrire l'événement dans la même transaction que la donnée, puis publier l'événement de façon asynchrone. Pour les cas d'échec, implémenter des compensating transactions explicites plutôt que des rollbacks automatiques.",{"type":29,"tag":371,"props":1176,"children":1177},{},[1178,1183],{"type":29,"tag":375,"props":1179,"children":1180},{},[1181],{"type":35,"value":1182},"2. Peut-on utiliser des transactions distribuées (2PC) à la place des Sagas ?",{"type":29,"tag":37,"props":1184,"children":1185},{},[1186],{"type":35,"value":1187},"Techniquement oui, mais déconseillé. Le Two-Phase Commit est lent (lock pendant la phase de préparation), fragile (coordinator failure = système bloqué), et complexe à implémenter correctement. Les Sagas sont plus complexes à concevoir mais plus robustes en production. La recommandation de Sam Newman et de l'industrie : éviter 2PC, préférer les Sagas ou revoir l'architecture pour réduire les transactions cross-services.",{"type":29,"tag":371,"props":1189,"children":1190},{},[1191,1196],{"type":29,"tag":375,"props":1192,"children":1193},{},[1194],{"type":35,"value":1195},"3. Comment gérer les reportings qui nécessitent des données de plusieurs services ?",{"type":29,"tag":37,"props":1197,"children":1198},{},[1199],{"type":35,"value":1200},"Data warehouse ou OLAP dédié. Chaque service publie ses événements vers un pipeline de données (Kafka → Spark/Flink → Data Warehouse). Les analyses et rapports lisent le data warehouse, pas les bases des services. C'est le principe CQRS à l'échelle de l'architecture : les services gèrent les écritures, le data warehouse gère les lectures analytiques complexes.",{"type":29,"tag":371,"props":1202,"children":1203},{},[1204,1209],{"type":29,"tag":375,"props":1205,"children":1206},{},[1207],{"type":35,"value":1208},"4. Quel outil utiliser pour la synchronisation de données entre services ?",{"type":29,"tag":37,"props":1210,"children":1211},{},[1212],{"type":35,"value":1213},"Change Data Capture (CDC) avec Debezium : il capture les changements PostgreSQL/MySQL en temps réel et les publie sur Kafka. Pour des cas plus simples : événements de domaine publiés sur une queue à chaque changement d'état. L'approche CDC est plus robuste (aucun changement applicatif requis) mais plus complexe à opérer. Les événements de domaine sont plus simples mais nécessitent une discipline applicative.",{"type":29,"tag":371,"props":1215,"children":1216},{},[1217,1222],{"type":29,"tag":375,"props":1218,"children":1219},{},[1220],{"type":35,"value":1221},"5. Database per Service est-il compatible avec les architectures serverless (Lambda, Cloud Functions) ?",{"type":29,"tag":37,"props":1223,"children":1224},{},[1225],{"type":35,"value":1226},"Oui, et c'est souvent plus simple. Les bases de données managées à l'usage (DynamoDB, Firestore, Aurora Serverless) s'adaptent naturellement au modèle serverless : pas de pool de connexions à gérer, facturation à la requête. Le principal défi est la gestion des connexions (Lambda peut créer des milliers de connexions simultanées), résolu par des proxy de connexions comme RDS Proxy pour PostgreSQL/MySQL.",{"type":29,"tag":66,"props":1228,"children":1229},{},[],{"type":29,"tag":166,"props":1231,"children":1234},{"cta":1232,"href":1233,"title":444,"type":445},"Faire mon auto-évaluation →","/ema",[1235],{"type":29,"tag":37,"props":1236,"children":1237},{},[1238],{"type":35,"value":1239},"L'Engineering Maturity Self-Assessment couvre le domaine Architecture Distribuée : évaluez votre maturité sur le découpage des services, la gestion des données, et la résilience. Score et plan d'action en 10 minutes.",{"type":29,"tag":1241,"props":1242,"children":1243},"style",{},[1244],{"type":35,"value":1245},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":8,"searchDepth":453,"depth":453,"links":1247},[1248,1249,1250,1251,1252,1253,1254],{"id":529,"depth":453,"text":532},{"id":610,"depth":453,"text":613},{"id":693,"depth":453,"text":696},{"id":858,"depth":453,"text":861},{"id":1056,"depth":453,"text":1059},{"id":1116,"depth":453,"text":1119},{"id":1158,"depth":453,"text":1161},"content:fr:architecture-craft:database-per-service-microservices.md","fr/architecture-craft/database-per-service-microservices.md","fr/architecture-craft/database-per-service-microservices",{"_path":1259,"_dir":1260,"_draft":7,"_partial":7,"_locale":8,"title":1261,"description":1262,"id":1263,"date":1264,"listed":13,"nocomments":7,"hidden":7,"categories":1265,"tags":1266,"--cover":1271,"readingTime":1272,"body":1276,"_type":466,"_id":2102,"_source":468,"_file":2103,"_stem":2104,"_extension":471},"/fr/management/delegation-technique-confiance","management","Délégation technique : la matrice par niveau de séniorité","La délégation technique ne se fait pas de la même façon selon le niveau du développeur. La matrice qui évite le micro-management et l'abandon — et comment construire la confiance progressivement.",34,"2026-03-23",[1260],[1267,1268,1269,1270],"Délégation","Management","Séniorité","Confiance","covers/articles/delegation-technique-confiance.jpg",{"text":21,"minutes":1273,"time":1274,"words":1275},7.99,479400,1598,{"type":26,"children":1277,"toc":2090},[1278,1283,1288,1293,1305,1308,1314,1324,1334,1344,1354,1364,1367,1373,1379,1510,1520,1523,1529,1655,1665,1674,1677,1683,1809,1819,1822,1828,1841,1849,1859,1869,1879,1889,1892,1898,1906,1929,1937,1960,1970,1973,1979,1984,1989,1992,1998,2019,2032,2045,2066,2079,2082],{"type":29,"tag":30,"props":1279,"children":1281},{"id":1280},"délégation-technique-la-matrice-par-niveau-de-séniorité",[1282],{"type":35,"value":1261},{"type":29,"tag":37,"props":1284,"children":1285},{},[1286],{"type":35,"value":1287},"J'ai fait les deux erreurs. Chez Crédit Agricole, j'ai micro-managé un développeur senior sur son domaine de compétence : je relisais ses PR ligne par ligne, je lui demandais de justifier chaque choix d'implémentation. Il est parti au bout de 8 mois. Son feedback d'adieu : \"Je me sentais traité comme un junior.\" Dans une autre organisation, j'ai délégué une décision d'architecture à un développeur junior sans filet de sécurité. Il a passé 3 semaines à tourner en rond sans oser dire qu'il était perdu. La feature a pris 6 semaines de retard.",{"type":29,"tag":37,"props":1289,"children":1290},{},[1291],{"type":35,"value":1292},"Le micro-management détruit les meilleurs. L'abandon détruit les moins expérimentés. La délégation efficace est la zone entre les deux, et elle se calibre par personne, par tâche, et par contexte.",{"type":29,"tag":37,"props":1294,"children":1295},{},[1296,1298,1303],{"type":35,"value":1297},"Hersey & Blanchard ont formalisé ce principe dans le modèle du Situational Leadership : le niveau d'autonomie accordé doit correspondre au niveau de compétence et de motivation du collaborateur ",{"type":29,"tag":55,"props":1299,"children":1300},{},[1301],{"type":35,"value":1302},"sur la tâche spécifique",{"type":35,"value":1304},". Pas sur la personne en général. Un développeur senior peut être en pleine autonomie sur l'architecture d'un service et avoir besoin d'accompagnement sur la facilitation d'un atelier. La délégation se calibre par tâche, pas par titre.",{"type":29,"tag":66,"props":1306,"children":1307},{},[],{"type":29,"tag":70,"props":1309,"children":1311},{"id":1310},"les-4-niveaux-de-délégation",[1312],{"type":35,"value":1313},"Les 4 niveaux de délégation",{"type":29,"tag":37,"props":1315,"children":1316},{},[1317,1322],{"type":29,"tag":55,"props":1318,"children":1319},{},[1320],{"type":35,"value":1321},"Niveau D1 : Direction :",{"type":35,"value":1323}," faible compétence, forte motivation. Le développeur est enthousiaste mais ne sait pas encore faire. Je décide et j'explique pourquoi.",{"type":29,"tag":37,"props":1325,"children":1326},{},[1327,1332],{"type":29,"tag":55,"props":1328,"children":1329},{},[1330],{"type":35,"value":1331},"Niveau D2 : Coaching :",{"type":35,"value":1333}," compétence croissante, motivation variable. Le développeur commence à maîtriser mais manque de confiance. Je décide après discussion, j'explique le raisonnement.",{"type":29,"tag":37,"props":1335,"children":1336},{},[1337,1342],{"type":29,"tag":55,"props":1338,"children":1339},{},[1340],{"type":35,"value":1341},"Niveau D3 : Support :",{"type":35,"value":1343}," compétence forte, motivation variable. Le développeur sait faire mais hésite à décider seul. Il propose, je valide ou je questionne.",{"type":29,"tag":37,"props":1345,"children":1346},{},[1347,1352],{"type":29,"tag":55,"props":1348,"children":1349},{},[1350],{"type":35,"value":1351},"Niveau D4 : Délégation complète :",{"type":35,"value":1353}," compétence forte, forte motivation. Le développeur sait faire et veut le faire. Il décide, je suis informé.",{"type":29,"tag":37,"props":1355,"children":1356},{},[1357,1362],{"type":29,"tag":55,"props":1358,"children":1359},{},[1360],{"type":35,"value":1361},"L'erreur que je vois le plus souvent :",{"type":35,"value":1363}," traiter une personne au même niveau sur toutes les dimensions. Un développeur senior peut être D4 sur son périmètre technique et D1 sur la conduite d'un entretien de recrutement. La matrice ne s'applique pas à la personne : elle s'applique à la combinaison personne + tâche.",{"type":29,"tag":66,"props":1365,"children":1366},{},[],{"type":29,"tag":70,"props":1368,"children":1370},{"id":1369},"la-matrice-de-délégation-par-domaine-et-séniorité",[1371],{"type":35,"value":1372},"La matrice de délégation par domaine et séniorité",{"type":29,"tag":106,"props":1374,"children":1376},{"id":1375},"développeur-junior-0-2-ans-dexpérience",[1377],{"type":35,"value":1378},"Développeur junior (0-2 ans d'expérience)",{"type":29,"tag":703,"props":1380,"children":1381},{},[1382,1403],{"type":29,"tag":707,"props":1383,"children":1384},{},[1385],{"type":29,"tag":711,"props":1386,"children":1387},{},[1388,1393,1398],{"type":29,"tag":715,"props":1389,"children":1390},{},[1391],{"type":35,"value":1392},"Domaine de décision",{"type":29,"tag":715,"props":1394,"children":1395},{},[1396],{"type":35,"value":1397},"Niveau de délégation",{"type":29,"tag":715,"props":1399,"children":1400},{},[1401],{"type":35,"value":1402},"Ce que ça signifie en pratique",{"type":29,"tag":731,"props":1404,"children":1405},{},[1406,1424,1442,1459,1476,1493],{"type":29,"tag":711,"props":1407,"children":1408},{},[1409,1414,1419],{"type":29,"tag":738,"props":1410,"children":1411},{},[1412],{"type":35,"value":1413},"Implémentation d'une story",{"type":29,"tag":738,"props":1415,"children":1416},{},[1417],{"type":35,"value":1418},"D2",{"type":29,"tag":738,"props":1420,"children":1421},{},[1422],{"type":35,"value":1423},"Le junior propose l'approche, validation avant de commencer",{"type":29,"tag":711,"props":1425,"children":1426},{},[1427,1432,1437],{"type":29,"tag":738,"props":1428,"children":1429},{},[1430],{"type":35,"value":1431},"Choix de librairie",{"type":29,"tag":738,"props":1433,"children":1434},{},[1435],{"type":35,"value":1436},"D1",{"type":29,"tag":738,"props":1438,"children":1439},{},[1440],{"type":35,"value":1441},"Je choisis avec explication",{"type":29,"tag":711,"props":1443,"children":1444},{},[1445,1450,1454],{"type":29,"tag":738,"props":1446,"children":1447},{},[1448],{"type":35,"value":1449},"Architecture d'un service",{"type":29,"tag":738,"props":1451,"children":1452},{},[1453],{"type":35,"value":1436},{"type":29,"tag":738,"props":1455,"children":1456},{},[1457],{"type":35,"value":1458},"Décision manager/senior, explication détaillée",{"type":29,"tag":711,"props":1460,"children":1461},{},[1462,1467,1471],{"type":29,"tag":738,"props":1463,"children":1464},{},[1465],{"type":35,"value":1466},"Refactoring local",{"type":29,"tag":738,"props":1468,"children":1469},{},[1470],{"type":35,"value":1418},{"type":29,"tag":738,"props":1472,"children":1473},{},[1474],{"type":35,"value":1475},"Proposition + validation avant merge",{"type":29,"tag":711,"props":1477,"children":1478},{},[1479,1484,1488],{"type":29,"tag":738,"props":1480,"children":1481},{},[1482],{"type":35,"value":1483},"Tests à écrire",{"type":29,"tag":738,"props":1485,"children":1486},{},[1487],{"type":35,"value":1418},{"type":29,"tag":738,"props":1489,"children":1490},{},[1491],{"type":35,"value":1492},"Proposition + review attentive",{"type":29,"tag":711,"props":1494,"children":1495},{},[1496,1501,1505],{"type":29,"tag":738,"props":1497,"children":1498},{},[1499],{"type":35,"value":1500},"Communication avec le PO",{"type":29,"tag":738,"props":1502,"children":1503},{},[1504],{"type":35,"value":1436},{"type":29,"tag":738,"props":1506,"children":1507},{},[1508],{"type":35,"value":1509},"Manager/senior présent ou brief avant",{"type":29,"tag":37,"props":1511,"children":1512},{},[1513,1518],{"type":29,"tag":55,"props":1514,"children":1515},{},[1516],{"type":35,"value":1517},"Ma règle pour le junior :",{"type":35,"value":1519}," jamais de décision irréversible sans validation. Les décisions réversibles (un commit sur une branche locale, une exploration technique) peuvent être prises en autonomie. Les décisions irréversibles (merge en production, modification de schéma de base de données) nécessitent une validation.",{"type":29,"tag":66,"props":1521,"children":1522},{},[],{"type":29,"tag":106,"props":1524,"children":1526},{"id":1525},"développeur-intermédiaire-2-5-ans-dexpérience",[1527],{"type":35,"value":1528},"Développeur intermédiaire (2-5 ans d'expérience)",{"type":29,"tag":703,"props":1530,"children":1531},{},[1532,1550],{"type":29,"tag":707,"props":1533,"children":1534},{},[1535],{"type":29,"tag":711,"props":1536,"children":1537},{},[1538,1542,1546],{"type":29,"tag":715,"props":1539,"children":1540},{},[1541],{"type":35,"value":1392},{"type":29,"tag":715,"props":1543,"children":1544},{},[1545],{"type":35,"value":1397},{"type":29,"tag":715,"props":1547,"children":1548},{},[1549],{"type":35,"value":1402},{"type":29,"tag":731,"props":1551,"children":1552},{},[1553,1570,1587,1604,1621,1638],{"type":29,"tag":711,"props":1554,"children":1555},{},[1556,1560,1565],{"type":29,"tag":738,"props":1557,"children":1558},{},[1559],{"type":35,"value":1413},{"type":29,"tag":738,"props":1561,"children":1562},{},[1563],{"type":35,"value":1564},"D3-D4",{"type":29,"tag":738,"props":1566,"children":1567},{},[1568],{"type":35,"value":1569},"Pleine autonomie sur l'implémentation",{"type":29,"tag":711,"props":1571,"children":1572},{},[1573,1577,1582],{"type":29,"tag":738,"props":1574,"children":1575},{},[1576],{"type":35,"value":1431},{"type":29,"tag":738,"props":1578,"children":1579},{},[1580],{"type":35,"value":1581},"D3",{"type":29,"tag":738,"props":1583,"children":1584},{},[1585],{"type":35,"value":1586},"Propose + justifie, validation légère",{"type":29,"tag":711,"props":1588,"children":1589},{},[1590,1594,1599],{"type":29,"tag":738,"props":1591,"children":1592},{},[1593],{"type":35,"value":1449},{"type":29,"tag":738,"props":1595,"children":1596},{},[1597],{"type":35,"value":1598},"D2-D3",{"type":29,"tag":738,"props":1600,"children":1601},{},[1602],{"type":35,"value":1603},"Co-construction avec le manager/senior",{"type":29,"tag":711,"props":1605,"children":1606},{},[1607,1612,1616],{"type":29,"tag":738,"props":1608,"children":1609},{},[1610],{"type":35,"value":1611},"Refactoring de périmètre moyen",{"type":29,"tag":738,"props":1613,"children":1614},{},[1615],{"type":35,"value":1581},{"type":29,"tag":738,"props":1617,"children":1618},{},[1619],{"type":35,"value":1620},"Autonomie avec point d'étape",{"type":29,"tag":711,"props":1622,"children":1623},{},[1624,1629,1633],{"type":29,"tag":738,"props":1625,"children":1626},{},[1627],{"type":35,"value":1628},"Découpage de stories",{"type":29,"tag":738,"props":1630,"children":1631},{},[1632],{"type":35,"value":1581},{"type":29,"tag":738,"props":1634,"children":1635},{},[1636],{"type":35,"value":1637},"Propose le découpage, validation PO/manager",{"type":29,"tag":711,"props":1639,"children":1640},{},[1641,1646,1650],{"type":29,"tag":738,"props":1642,"children":1643},{},[1644],{"type":35,"value":1645},"Mentoring d'un junior",{"type":29,"tag":738,"props":1647,"children":1648},{},[1649],{"type":35,"value":1418},{"type":29,"tag":738,"props":1651,"children":1652},{},[1653],{"type":35,"value":1654},"Encadré par le senior au début",{"type":29,"tag":37,"props":1656,"children":1657},{},[1658,1663],{"type":29,"tag":55,"props":1659,"children":1660},{},[1661],{"type":35,"value":1662},"Ma règle pour l'intermédiaire :",{"type":35,"value":1664}," autonomie sur l'exécution, validation sur les décisions d'impact moyen à fort. L'intermédiaire doit être challengé à prendre des décisions et à les justifier, pas protégé de toute décision. C'est dans cet espace inconfortable que la progression se fait.",{"type":29,"tag":166,"props":1666,"children":1668},{"cta":168,"href":169,"title":1667,"type":171},"Vous peinez à calibrer le bon niveau d'autonomie pour chaque membre de votre équipe ?",[1669],{"type":29,"tag":37,"props":1670,"children":1671},{},[1672],{"type":35,"value":1673},"Vous avez peut-être des seniors frustrés par trop de contrôle et des juniors perdus par trop de liberté, dans la même équipe. Construire un système de délégation progressive adapté nécessite un audit des compétences et des niveaux de confiance actuels. En 30 minutes, je peux définir avec vous la matrice de délégation adaptée à vos 3 à 4 profils clés.",{"type":29,"tag":66,"props":1675,"children":1676},{},[],{"type":29,"tag":106,"props":1678,"children":1680},{"id":1679},"développeur-senior-5-ans-dexpérience",[1681],{"type":35,"value":1682},"Développeur senior (5+ ans d'expérience)",{"type":29,"tag":703,"props":1684,"children":1685},{},[1686,1704],{"type":29,"tag":707,"props":1687,"children":1688},{},[1689],{"type":29,"tag":711,"props":1690,"children":1691},{},[1692,1696,1700],{"type":29,"tag":715,"props":1693,"children":1694},{},[1695],{"type":35,"value":1392},{"type":29,"tag":715,"props":1697,"children":1698},{},[1699],{"type":35,"value":1397},{"type":29,"tag":715,"props":1701,"children":1702},{},[1703],{"type":35,"value":1402},{"type":29,"tag":731,"props":1705,"children":1706},{},[1707,1723,1741,1758,1775,1792],{"type":29,"tag":711,"props":1708,"children":1709},{},[1710,1714,1718],{"type":29,"tag":738,"props":1711,"children":1712},{},[1713],{"type":35,"value":1449},{"type":29,"tag":738,"props":1715,"children":1716},{},[1717],{"type":35,"value":1564},{"type":29,"tag":738,"props":1719,"children":1720},{},[1721],{"type":35,"value":1722},"Décision senior, information manager",{"type":29,"tag":711,"props":1724,"children":1725},{},[1726,1731,1736],{"type":29,"tag":738,"props":1727,"children":1728},{},[1729],{"type":35,"value":1730},"Choix technologique d'impact limité",{"type":29,"tag":738,"props":1732,"children":1733},{},[1734],{"type":35,"value":1735},"D4",{"type":29,"tag":738,"props":1737,"children":1738},{},[1739],{"type":35,"value":1740},"Pleine autonomie",{"type":29,"tag":711,"props":1742,"children":1743},{},[1744,1749,1753],{"type":29,"tag":738,"props":1745,"children":1746},{},[1747],{"type":35,"value":1748},"Choix technologique d'impact fort",{"type":29,"tag":738,"props":1750,"children":1751},{},[1752],{"type":35,"value":1581},{"type":29,"tag":738,"props":1754,"children":1755},{},[1756],{"type":35,"value":1757},"Proposition structurée (ADR), validation manager/CTO",{"type":29,"tag":711,"props":1759,"children":1760},{},[1761,1766,1770],{"type":29,"tag":738,"props":1762,"children":1763},{},[1764],{"type":35,"value":1765},"Standards d'équipe",{"type":29,"tag":738,"props":1767,"children":1768},{},[1769],{"type":35,"value":1581},{"type":29,"tag":738,"props":1771,"children":1772},{},[1773],{"type":35,"value":1774},"Propose, présente à l'équipe, manager valide",{"type":29,"tag":711,"props":1776,"children":1777},{},[1778,1783,1787],{"type":29,"tag":738,"props":1779,"children":1780},{},[1781],{"type":35,"value":1782},"Recrutement technique",{"type":29,"tag":738,"props":1784,"children":1785},{},[1786],{"type":35,"value":1581},{"type":29,"tag":738,"props":1788,"children":1789},{},[1790],{"type":35,"value":1791},"Conduit les entretiens techniques, input sur la décision",{"type":29,"tag":711,"props":1793,"children":1794},{},[1795,1800,1804],{"type":29,"tag":738,"props":1796,"children":1797},{},[1798],{"type":35,"value":1799},"Architecture cross-services",{"type":29,"tag":738,"props":1801,"children":1802},{},[1803],{"type":35,"value":1598},{"type":29,"tag":738,"props":1805,"children":1806},{},[1807],{"type":35,"value":1808},"Co-construction avec le CTO",{"type":29,"tag":37,"props":1810,"children":1811},{},[1812,1817],{"type":29,"tag":55,"props":1813,"children":1814},{},[1815],{"type":35,"value":1816},"Ma règle pour le senior :",{"type":35,"value":1818}," autonomie forte sur son périmètre de compétence, co-construction sur les décisions d'impact organisationnel. Le micro-management d'un senior sur son domaine de compétence est la première cause de départ des profils techniques forts. J'ai appris ça de la pire façon.",{"type":29,"tag":66,"props":1820,"children":1821},{},[],{"type":29,"tag":70,"props":1823,"children":1825},{"id":1824},"comment-construire-la-confiance-pour-déléguer-davantage",[1826],{"type":35,"value":1827},"Comment construire la confiance pour déléguer davantage",{"type":29,"tag":37,"props":1829,"children":1830},{},[1831,1833,1839],{"type":35,"value":1832},"La délégation ne se donne pas avec l'ancienneté. Elle se construit dans les deux sens, elle repose sur la ",{"type":29,"tag":43,"props":1834,"children":1836},{"href":1835},"/fr/management/confiance-equipe-engineering",[1837],{"type":35,"value":1838},"confiance",{"type":35,"value":1840}," comme substrat indispensable : le développeur démontre qu'il peut gérer une décision, je délègue la suivante. Le cycle est symétrique.",{"type":29,"tag":37,"props":1842,"children":1843},{},[1844],{"type":29,"tag":55,"props":1845,"children":1846},{},[1847],{"type":35,"value":1848},"Les 4 étapes du cycle de délégation que j'utilise :",{"type":29,"tag":37,"props":1850,"children":1851},{},[1852,1857],{"type":29,"tag":55,"props":1853,"children":1854},{},[1855],{"type":35,"value":1856},"Étape 1 : Mission claire :",{"type":35,"value":1858}," je définis clairement le périmètre de la décision, les contraintes, et les critères de succès. Pas \"améliore les tests\" : \"augmente la couverture du service X de 40% à 70% en ciblant les fonctions critiques, budget : 3 jours.\"",{"type":29,"tag":37,"props":1860,"children":1861},{},[1862,1867],{"type":29,"tag":55,"props":1863,"children":1864},{},[1865],{"type":35,"value":1866},"Étape 2 : Filet de sécurité défini :",{"type":35,"value":1868}," je définit en avance ce qui déclencherait une escalade. \"Si tu rencontres des dépendances avec le service Y ou si l'implémentation prend plus de 5 jours, viens me voir avant de continuer.\" Le filet rassure le développeur et me protège.",{"type":29,"tag":37,"props":1870,"children":1871},{},[1872,1877],{"type":29,"tag":55,"props":1873,"children":1874},{},[1875],{"type":35,"value":1876},"Étape 3 : Autonomie réelle :",{"type":35,"value":1878}," entre le début et le filet de sécurité, le développeur décide seul. Je ne vérifie pas l'avancement quotidiennement, sauf si le développeur le demande.",{"type":29,"tag":37,"props":1880,"children":1881},{},[1882,1887],{"type":29,"tag":55,"props":1883,"children":1884},{},[1885],{"type":35,"value":1886},"Étape 4 : Débriefing :",{"type":35,"value":1888}," après la mission, un point sur les décisions prises. \"Qu'est-ce que tu ferais différemment ? Qu'est-ce que tu as appris ?\" Ce n'est pas un contrôle : c'est un apprentissage partagé.",{"type":29,"tag":66,"props":1890,"children":1891},{},[],{"type":29,"tag":70,"props":1893,"children":1895},{"id":1894},"les-signaux-dune-délégation-mal-calibrée",[1896],{"type":35,"value":1897},"Les signaux d'une délégation mal calibrée",{"type":29,"tag":37,"props":1899,"children":1900},{},[1901],{"type":29,"tag":55,"props":1902,"children":1903},{},[1904],{"type":35,"value":1905},"Signaux de sur-délégation (trop d'autonomie trop tôt) :",{"type":29,"tag":1069,"props":1907,"children":1908},{},[1909,1914,1919,1924],{"type":29,"tag":1073,"props":1910,"children":1911},{},[1912],{"type":35,"value":1913},"Le développeur pose des questions sur chaque micro-décision",{"type":29,"tag":1073,"props":1915,"children":1916},{},[1917],{"type":35,"value":1918},"Les délais glissent sans alerte de sa part",{"type":29,"tag":1073,"props":1920,"children":1921},{},[1922],{"type":35,"value":1923},"La qualité du travail est irrégulière",{"type":29,"tag":1073,"props":1925,"children":1926},{},[1927],{"type":35,"value":1928},"Il dit \"j'ai fait X\" mais ne peut pas expliquer pourquoi",{"type":29,"tag":37,"props":1930,"children":1931},{},[1932],{"type":29,"tag":55,"props":1933,"children":1934},{},[1935],{"type":35,"value":1936},"Signaux de sous-délégation (trop de contrôle) :",{"type":29,"tag":1069,"props":1938,"children":1939},{},[1940,1945,1950,1955],{"type":29,"tag":1073,"props":1941,"children":1942},{},[1943],{"type":35,"value":1944},"Le développeur \"fait valider\" des décisions triviales",{"type":29,"tag":1073,"props":1946,"children":1947},{},[1948],{"type":35,"value":1949},"Il n'apporte plus de propositions, il attend les instructions",{"type":29,"tag":1073,"props":1951,"children":1952},{},[1953],{"type":35,"value":1954},"Il exprime de la frustration sur son manque d'autonomie",{"type":29,"tag":1073,"props":1956,"children":1957},{},[1958],{"type":35,"value":1959},"Il perd en motivation visible sur plusieurs semaines",{"type":29,"tag":37,"props":1961,"children":1962},{},[1963,1968],{"type":29,"tag":55,"props":1964,"children":1965},{},[1966],{"type":35,"value":1967},"Le recalibrage :",{"type":35,"value":1969}," la délégation peut monter ou descendre selon l'évolution des compétences et de la confiance. Un développeur qui traverse une période difficile peut temporairement revenir à un niveau de délégation plus supporté, sans que ce soit perçu comme une rétrogradation, à condition d'expliquer pourquoi.",{"type":29,"tag":66,"props":1971,"children":1972},{},[],{"type":29,"tag":70,"props":1974,"children":1976},{"id":1975},"la-délégation-comme-outil-de-développement",[1977],{"type":35,"value":1978},"La délégation comme outil de développement",{"type":29,"tag":37,"props":1980,"children":1981},{},[1982],{"type":35,"value":1983},"La délégation progressive n'est pas seulement un outil de management : c'est un outil de développement. Vygotsky appelle ça la zone proximale de développement : déléguer légèrement au-delà de ce que le développeur sait faire aujourd'hui, avec un filet de sécurité, accélère son développement. Déléguer dans la zone de confort maintient le statu quo. Déléguer trop loin au-delà génère de l'anxiété et des erreurs.",{"type":29,"tag":37,"props":1985,"children":1986},{},[1987],{"type":35,"value":1988},"Dans un client dans l'édition logicielle (30 personnes), j'accompagnais un développeur intermédiaire qui se plaignait de manque d'autonomie. Son manager lui faisait valider toutes ses PRs, même les plus triviales. Après un audit de délégation et la mise en place de la matrice, le développeur a obtenu l'autonomie complète sur son périmètre (service de notifications) avec un seul filet de sécurité (escalader si impact sur d'autres services). En 3 mois, il avait redesigné l'architecture du service, documenté ses décisions, et formé un junior sur son périmètre. Ces trois choses étaient impossibles dans l'ancien mode de fonctionnement.",{"type":29,"tag":66,"props":1990,"children":1991},{},[],{"type":29,"tag":70,"props":1993,"children":1995},{"id":1994},"faq-sur-la-délégation-technique",[1996],{"type":35,"value":1997},"FAQ sur la délégation technique",{"type":29,"tag":371,"props":1999,"children":2000},{},[2001,2006],{"type":29,"tag":375,"props":2002,"children":2003},{},[2004],{"type":35,"value":2005},"Comment gérer la délégation quand un développeur senior refuse les responsabilités ?",{"type":29,"tag":37,"props":2007,"children":2008},{},[2009,2011,2017],{"type":35,"value":2010},"La résistance à la délégation est souvent une protection contre l'échec ou un manque de clarté sur les attentes. Je distingue les deux cas. Si c'est la peur de l'échec : je rends les filets de sécurité plus explicites et les conséquences de l'erreur moins sévères. Si c'est le manque de clarté : je redéfinis la mission avec des critères de succès très précis. Un senior qui refuse systématiquement les responsabilités sur un horizon de 6 mois a peut-être atteint son niveau de confort dans son rôle actuel : conversation honnête nécessaire lors de l'",{"type":29,"tag":43,"props":2012,"children":2014},{"href":2013},"/fr/management/entretien-annuel-developpeur-format",[2015],{"type":35,"value":2016},"entretien annuel",{"type":35,"value":2018}," sur les aspirations et les attentes mutuelles.",{"type":29,"tag":371,"props":2020,"children":2021},{},[2022,2027],{"type":29,"tag":375,"props":2023,"children":2024},{},[2025],{"type":35,"value":2026},"Comment documenter les niveaux de délégation pour éviter les ambiguïtés ?",{"type":29,"tag":37,"props":2028,"children":2029},{},[2030],{"type":35,"value":2031},"Un simple document partagé avec l'équipe qui liste les domaines de décision et le niveau de délégation pour chaque niveau de séniorité. Je le mets à jour lors des promotions ou changements de périmètre. L'important n'est pas la précision exhaustive : c'est que le développeur et moi ayons la même compréhension des zones d'autonomie. En cas d'ambiguïté, la règle par défaut est D3 (le développeur propose, je valide), ce qui laisse l'autonomie sur l'exécution et la validation sur les décisions.",{"type":29,"tag":371,"props":2033,"children":2034},{},[2035,2040],{"type":29,"tag":375,"props":2036,"children":2037},{},[2038],{"type":35,"value":2039},"Quelle est la différence entre délégation et abandon ?",{"type":29,"tag":37,"props":2041,"children":2042},{},[2043],{"type":35,"value":2044},"La délégation a trois éléments que l'abandon n'a pas : une mission claire (périmètre et critères de succès définis), un filet de sécurité (les conditions d'escalade sont définies en avance), et un débriefing (retour sur l'expérience). L'abandon, c'est \"débrouille-toi\" sans ces trois éléments. La délégation sans mission claire ressemble à de l'abandon, même si l'intention du manager est bonne.",{"type":29,"tag":371,"props":2046,"children":2047},{},[2048,2053],{"type":29,"tag":375,"props":2049,"children":2050},{},[2051],{"type":35,"value":2052},"Comment déléguer dans un contexte de forte dette technique où chaque décision a des conséquences importantes ?",{"type":29,"tag":37,"props":2054,"children":2055},{},[2056,2058,2064],{"type":35,"value":2057},"En rendant les filets de sécurité plus explicites et plus fréquents. Pas \"viens me voir si tu as un problème\", mais \"viens me voir après J+2 pour un point d'étape, et immédiatement si tu rencontres X ou Y.\" Dans un contexte de ",{"type":29,"tag":43,"props":2059,"children":2061},{"href":2060},"/fr/dette-technique/programme-refactoring-approuve-business",[2062],{"type":35,"value":2063},"forte dette technique",{"type":35,"value":2065},", la délégation est possible et nécessaire, mais avec des checkpoints plus fréquents pour détecter tôt les décisions qui pourraient avoir des effets de bord non anticipés.",{"type":29,"tag":371,"props":2067,"children":2068},{},[2069,2074],{"type":29,"tag":375,"props":2070,"children":2071},{},[2072],{"type":35,"value":2073},"Comment calibrer la délégation pour un nouveau membre de l'équipe, même senior ?",{"type":29,"tag":37,"props":2075,"children":2076},{},[2077],{"type":35,"value":2078},"Je commence à D2 pour les 30 premiers jours, quelle que soit la séniorité. Non pas parce que le développeur manque de compétence, mais parce qu'il manque de contexte sur le codebase, les décisions passées, et les normes de l'équipe. La montée en délégation est rapide (D2 → D4 en 4 à 6 semaines pour un senior compétent) mais elle doit partir de là. J'explique cette progression explicitement à l'onboarding pour éviter la frustration.",{"type":29,"tag":66,"props":2080,"children":2081},{},[],{"type":29,"tag":166,"props":2083,"children":2084},{"cta":1232,"href":1233,"title":444,"type":445},[2085],{"type":29,"tag":37,"props":2086,"children":2087},{},[2088],{"type":35,"value":2089},"L'Engineering Maturity Self-Assessment couvre le domaine Management Technique : évaluez votre niveau de maturité sur la délégation, le développement de l'autonomie, et les pratiques de feedback. Score et recommandations en 10 minutes.",{"title":8,"searchDepth":453,"depth":453,"links":2091},[2092,2093,2098,2099,2100,2101],{"id":1310,"depth":453,"text":1313},{"id":1369,"depth":453,"text":1372,"children":2094},[2095,2096,2097],{"id":1375,"depth":459,"text":1378},{"id":1525,"depth":459,"text":1528},{"id":1679,"depth":459,"text":1682},{"id":1824,"depth":453,"text":1827},{"id":1894,"depth":453,"text":1897},{"id":1975,"depth":453,"text":1978},{"id":1994,"depth":453,"text":1997},"content:fr:management:delegation-technique-confiance.md","fr/management/delegation-technique-confiance.md","fr/management/delegation-technique-confiance",{"_path":2106,"_dir":2107,"_draft":7,"_partial":7,"_locale":8,"title":2108,"description":2109,"id":2110,"date":2111,"listed":13,"nocomments":7,"hidden":7,"categories":2112,"tags":2113,"--cover":2118,"readingTime":2119,"body":2124,"_type":466,"_id":4092,"_source":468,"_file":4093,"_stem":4094,"_extension":471},"/fr/intelligence-artificielle/ia-code-review-retour-experience","intelligence-artificielle","IA en code review : retour d'expérience après 6 mois","Après 6 mois d'outils IA dans les code reviews : ce qu'ils trouvent bien, ce qu'ils ratent systématiquement, et comment les intégrer sans dégrader la culture de review.",37,"2026-03-20",[2107],[2114,2115,2116,2117],"Code Review","IA","Retour d'expérience","Qualité","covers/articles/ia-code-review-retour-experience.jpg",{"text":2120,"minutes":2121,"time":2122,"words":2123},"9 min read",8.765,525900,1753,{"type":26,"children":2125,"toc":4083},[2126,2131,2136,2141,2149,2152,2158,2163,2188,2290,2300,2310,2320,2323,2329,2334,2344,2354,2364,2374,2384,2393,2396,2402,2407,2417,2427,2437,2440,2446,2454,2459,2467,2480,2567,2575,2580,2588,2593,2596,2602,2612,2622,2632,2642,2645,2651,2661,2671,2681,2691,2696,2699,2705,2725,2738,4027,4040,4053,4066,4069,4079],{"type":29,"tag":30,"props":2127,"children":2129},{"id":2128},"ia-en-code-review-retour-dexpérience-après-6-mois",[2130],{"type":35,"value":2108},{"type":29,"tag":37,"props":2132,"children":2133},{},[2134],{"type":35,"value":2135},"En janvier 2026, j'ai accompagné un client (15 développeurs) dans l'adoption de CodeRabbit. Le CTO avait une attente simple : réduire le temps de review sans dégrader la qualité. Six semaines plus tard, le temps de review humaine avait baissé de 35% (de 45 minutes à 30 minutes par PR en moyenne). Le taux de faux positifs de l'IA était à 28% initialement, réduit à 15% après ajustement de la configuration avec les conventions de l'équipe. Les reviewers disaient \"je me concentre sur ce qui compte\".",{"type":29,"tag":37,"props":2137,"children":2138},{},[2139],{"type":35,"value":2140},"Mais dans une autre équipe, chez un éditeur de logiciels de 18 développeurs, l'adoption du même type d'outil avait produit l'effet inverse : une \"alert fatigue\" qui avait dégradé la culture de review. Les développeurs ignoraient les commentaires IA en masse, y compris les commentaires importants.",{"type":29,"tag":37,"props":2142,"children":2143},{},[2144],{"type":29,"tag":55,"props":2145,"children":2146},{},[2147],{"type":35,"value":2148},"La différence entre ces deux résultats n'était pas l'outil. C'était la méthode d'intégration.",{"type":29,"tag":66,"props":2150,"children":2151},{},[],{"type":29,"tag":70,"props":2153,"children":2155},{"id":2154},"ce-que-lia-trouve-bien",[2156],{"type":35,"value":2157},"Ce que l'IA trouve bien",{"type":29,"tag":37,"props":2159,"children":2160},{},[2161],{"type":35,"value":2162},"L'IA en code review excelle sur les patterns connus et répétables.",{"type":29,"tag":37,"props":2164,"children":2165},{},[2166,2171,2173,2179,2181,2186],{"type":29,"tag":55,"props":2167,"children":2168},{},[2169],{"type":35,"value":2170},"Problèmes de sécurité évidents :",{"type":35,"value":2172}," injections SQL, secrets hardcodés, XSS potentiels, dépendances avec CVE connus, des ",{"type":29,"tag":43,"props":2174,"children":2176},{"href":2175},"/fr/intelligence-artificielle/llm-securite-code-vulnerabilites",[2177],{"type":35,"value":2178},"vulnérabilités typiques du code LLM-généré",{"type":35,"value":2180},". L'IA les détecte mieux que la review humaine moyenne, non pas parce qu'elle est plus intelligente, mais parce qu'elle ne fatigue pas et applique systématiquement les patterns connus. Une étude de ",{"type":29,"tag":55,"props":2182,"children":2183},{},[2184],{"type":35,"value":2185},"Stanford (2023)",{"type":35,"value":2187}," documentait que 40% du code IA-généré contenait des vulnérabilités dans des contextes de sécurité spécifiques : l'IA en code review détecte précisément ces patterns.",{"type":29,"tag":640,"props":2189,"children":2193},{"className":2190,"code":2191,"language":2192,"meta":8,"style":8},"language-python shiki shiki-themes catppuccin-frappe github-dark","# L'IA détecte ce pattern immédiatement\nquery = f\"SELECT * FROM users WHERE email = '{email}'\"  # SQL injection\n# Et suggère\nquery = \"SELECT * FROM users WHERE email = %s\"\n","python",[2194],{"type":29,"tag":554,"props":2195,"children":2196},{"__ignoreMap":8},[2197,2205,2256,2264],{"type":29,"tag":890,"props":2198,"children":2199},{"class":892,"line":893},[2200],{"type":29,"tag":890,"props":2201,"children":2202},{"style":897},[2203],{"type":35,"value":2204},"# L'IA détecte ce pattern immédiatement\n",{"type":29,"tag":890,"props":2206,"children":2207},{"class":892,"line":453},[2208,2213,2218,2224,2230,2236,2241,2246,2251],{"type":29,"tag":890,"props":2209,"children":2210},{"style":912},[2211],{"type":35,"value":2212},"query ",{"type":29,"tag":890,"props":2214,"children":2215},{"style":936},[2216],{"type":35,"value":2217},"=",{"type":29,"tag":890,"props":2219,"children":2221},{"style":2220},"--shiki-default:#A6D189;--shiki-default-font-style:italic;--shiki-dark:#F97583;--shiki-dark-font-style:inherit",[2222],{"type":35,"value":2223}," f",{"type":29,"tag":890,"props":2225,"children":2227},{"style":2226},"--shiki-default:#A6D189;--shiki-dark:#9ECBFF",[2228],{"type":35,"value":2229},"\"SELECT * FROM users WHERE email = '",{"type":29,"tag":890,"props":2231,"children":2233},{"style":2232},"--shiki-default:#F4B8E4;--shiki-dark:#79B8FF",[2234],{"type":35,"value":2235},"{",{"type":29,"tag":890,"props":2237,"children":2238},{"style":912},[2239],{"type":35,"value":2240},"email",{"type":29,"tag":890,"props":2242,"children":2243},{"style":2232},[2244],{"type":35,"value":2245},"}",{"type":29,"tag":890,"props":2247,"children":2248},{"style":2226},[2249],{"type":35,"value":2250},"'\"",{"type":29,"tag":890,"props":2252,"children":2253},{"style":897},[2254],{"type":35,"value":2255},"  # SQL injection\n",{"type":29,"tag":890,"props":2257,"children":2258},{"class":892,"line":459},[2259],{"type":29,"tag":890,"props":2260,"children":2261},{"style":897},[2262],{"type":35,"value":2263},"# Et suggère\n",{"type":29,"tag":890,"props":2265,"children":2266},{"class":892,"line":957},[2267,2271,2275,2280,2285],{"type":29,"tag":890,"props":2268,"children":2269},{"style":912},[2270],{"type":35,"value":2212},{"type":29,"tag":890,"props":2272,"children":2273},{"style":936},[2274],{"type":35,"value":2217},{"type":29,"tag":890,"props":2276,"children":2277},{"style":2226},[2278],{"type":35,"value":2279}," \"SELECT * FROM users WHERE email = ",{"type":29,"tag":890,"props":2281,"children":2282},{"style":2232},[2283],{"type":35,"value":2284},"%s",{"type":29,"tag":890,"props":2286,"children":2287},{"style":2226},[2288],{"type":35,"value":2289},"\"\n",{"type":29,"tag":37,"props":2291,"children":2292},{},[2293,2298],{"type":29,"tag":55,"props":2294,"children":2295},{},[2296],{"type":35,"value":2297},"Problèmes de style et de conventions :",{"type":35,"value":2299}," nommage incohérent, fonctions trop longues, complexité cyclomatique élevée, code dupliqué détectable par pattern matching. L'IA commente ces points avec une régularité que les reviewers humains n'ont pas, car ils s'habituent aux patterns de l'équipe et les ignorent progressivement.",{"type":29,"tag":37,"props":2301,"children":2302},{},[2303,2308],{"type":29,"tag":55,"props":2304,"children":2305},{},[2306],{"type":35,"value":2307},"Documentation manquante :",{"type":35,"value":2309}," fonctions publiques sans docstring, paramètres non typés, valeurs de retour non documentées. L'IA les signale systématiquement et peut générer la documentation manquante en temps réel.",{"type":29,"tag":37,"props":2311,"children":2312},{},[2313,2318],{"type":29,"tag":55,"props":2314,"children":2315},{},[2316],{"type":35,"value":2317},"Tests manquants :",{"type":35,"value":2319}," branches de code non couvertes par les tests présents dans la PR. L'IA peut identifier \"ce bloc else n'est pas testé\" avec une précision correcte.",{"type":29,"tag":66,"props":2321,"children":2322},{},[],{"type":29,"tag":70,"props":2324,"children":2326},{"id":2325},"ce-que-lia-rate-systématiquement",[2327],{"type":35,"value":2328},"Ce que l'IA rate systématiquement",{"type":29,"tag":37,"props":2330,"children":2331},{},[2332],{"type":35,"value":2333},"Après 6 mois d'observation, j'ai identifié 5 angles morts récurrents.",{"type":29,"tag":37,"props":2335,"children":2336},{},[2337,2342],{"type":29,"tag":55,"props":2338,"children":2339},{},[2340],{"type":35,"value":2341},"La cohérence avec le reste du codebase :",{"type":35,"value":2343}," l'IA revoit la PR en isolation. Si la base de code utilise un pattern de gestion d'erreur spécifique, l'IA peut suggérer un pattern différent, techniquement correct mais incohérent avec le reste. Après 6 mois, c'est le problème numéro un des équipes : l'IA crée du bruit avec des suggestions valides techniquement mais inadaptées au contexte.",{"type":29,"tag":37,"props":2345,"children":2346},{},[2347,2352],{"type":29,"tag":55,"props":2348,"children":2349},{},[2350],{"type":35,"value":2351},"La logique métier incorrecte :",{"type":35,"value":2353}," une fonction qui calcule incorrectement une remise selon des règles business spécifiques : l'IA ne voit pas le problème si le code est techniquement correct. Ce bug ne sera trouvé que par un reviewer humain qui connaît les règles métier.",{"type":29,"tag":37,"props":2355,"children":2356},{},[2357,2362],{"type":29,"tag":55,"props":2358,"children":2359},{},[2360],{"type":35,"value":2361},"L'impact architectural :",{"type":35,"value":2363}," un changement qui passe tous les tests et respecte tous les patterns de style peut introduire un couplage architectural problématique à long terme. L'IA ne voit pas les implications systémiques d'un changement local.",{"type":29,"tag":37,"props":2365,"children":2366},{},[2367,2372],{"type":29,"tag":55,"props":2368,"children":2369},{},[2370],{"type":35,"value":2371},"La duplication de logique métier cross-services :",{"type":35,"value":2373}," deux services qui implémentent la même règle légèrement différemment. L'IA revoit un service à la fois, elle ne peut pas détecter la duplication sans contexte étendu.",{"type":29,"tag":37,"props":2375,"children":2376},{},[2377,2382],{"type":29,"tag":55,"props":2378,"children":2379},{},[2380],{"type":35,"value":2381},"L'intention du changement :",{"type":35,"value":2383}," une PR qui modifie une constante de configuration. L'IA commente sur le style. Elle ne peut pas dire \"cette constante avait été fixée à cette valeur pour contourner un bug du service X, la modifier va créer des problèmes en production.\"",{"type":29,"tag":166,"props":2385,"children":2387},{"cta":168,"href":169,"title":2386,"type":171},"Vous adoptez des outils IA dans votre workflow de review et vous voulez éviter les pièges ?",[2388],{"type":29,"tag":37,"props":2389,"children":2390},{},[2391],{"type":35,"value":2392},"Vous avez adopté ou envisagez d'adopter un outil IA en code review, mais vous ne savez pas comment l'intégrer sans dégrader la culture d'équipe. En 30 minutes, on définit les règles d'utilisation, les limites, et le processus adapté à votre contexte.",{"type":29,"tag":66,"props":2394,"children":2395},{},[],{"type":29,"tag":70,"props":2397,"children":2399},{"id":2398},"limpact-sur-la-culture-de-review",[2400],{"type":35,"value":2401},"L'impact sur la culture de review",{"type":29,"tag":37,"props":2403,"children":2404},{},[2405],{"type":35,"value":2406},"Ce que les équipes rapportent après 6 mois :",{"type":29,"tag":37,"props":2408,"children":2409},{},[2410,2415],{"type":29,"tag":55,"props":2411,"children":2412},{},[2413],{"type":35,"value":2414},"Ce qui s'améliore :",{"type":35,"value":2416}," les reviews humaines se concentrent plus sur le fond (logique métier, architecture, cohérence) et moins sur la forme (style, conventions). L'IA filtre le bruit. Les développeurs juniors reçoivent plus de feedback structuré et rapide, l'IA joue un rôle de \"premier reviewer\" qui leur permet d'améliorer leur code avant la review humaine.",{"type":29,"tag":37,"props":2418,"children":2419},{},[2420,2425],{"type":29,"tag":55,"props":2421,"children":2422},{},[2423],{"type":35,"value":2424},"Ce qui se dégrade si mal géré :",{"type":35,"value":2426}," dans plusieurs équipes, le volume de commentaires IA a créé une \"alert fatigue\". Les développeurs commencent à ignorer les commentaires IA en masse, y compris les commentaires importants. Une équipe a constaté une augmentation de 30% du nombre de commentaires de PR, avec une diminution de la qualité de l'engagement sur chacun.",{"type":29,"tag":37,"props":2428,"children":2429},{},[2430,2435],{"type":29,"tag":55,"props":2431,"children":2432},{},[2433],{"type":35,"value":2434},"Le risque principal :",{"type":35,"value":2436}," la délégation de responsabilité. \"L'IA a approuvé, donc ça doit être bon.\" Ce pattern crée une fausse sécurité dangereuse. Les reviewers humains réduisent l'intensité de leur review quand l'IA a déjà commenté. J'ai vu ce pattern se répéter dans chaque équipe qui n'avait pas défini explicitement la séparation des responsabilités.",{"type":29,"tag":66,"props":2438,"children":2439},{},[],{"type":29,"tag":70,"props":2441,"children":2443},{"id":2442},"les-règles-dintégration-qui-fonctionnent",[2444],{"type":35,"value":2445},"Les règles d'intégration qui fonctionnent",{"type":29,"tag":37,"props":2447,"children":2448},{},[2449],{"type":29,"tag":55,"props":2450,"children":2451},{},[2452],{"type":35,"value":2453},"Règle 1 : Séparer les commentaires IA des commentaires humains",{"type":29,"tag":37,"props":2455,"children":2456},{},[2457],{"type":35,"value":2458},"Les commentaires IA doivent être visuellement distincts. Le reviewer humain sait que l'IA a déjà reviewé les aspects de style/sécurité et peut se concentrer sur le fond. CodeRabbit et les intégrations GitHub Copilot le font nativement. Si vous utilisez une intégration personnalisée, utilisez un bot account dédié.",{"type":29,"tag":37,"props":2460,"children":2461},{},[2462],{"type":29,"tag":55,"props":2463,"children":2464},{},[2465],{"type":35,"value":2466},"Règle 2 : Définir ce que l'IA revoit, définir ce que l'humain revoit",{"type":29,"tag":37,"props":2468,"children":2469},{},[2470,2472,2478],{"type":35,"value":2471},"Complétez ce tableau avec la ",{"type":29,"tag":43,"props":2473,"children":2475},{"href":2474},"/fr/intelligence-artificielle/tester-code-genere-ia-checklist",[2476],{"type":35,"value":2477},"checklist de validation du code IA",{"type":35,"value":2479}," pour les PRs à fort contenu généré.",{"type":29,"tag":703,"props":2481,"children":2482},{},[2483,2499],{"type":29,"tag":707,"props":2484,"children":2485},{},[2486],{"type":29,"tag":711,"props":2487,"children":2488},{},[2489,2494],{"type":29,"tag":715,"props":2490,"children":2491},{},[2492],{"type":35,"value":2493},"L'IA revoit",{"type":29,"tag":715,"props":2495,"children":2496},{},[2497],{"type":35,"value":2498},"L'humain revoit",{"type":29,"tag":731,"props":2500,"children":2501},{},[2502,2515,2528,2541,2554],{"type":29,"tag":711,"props":2503,"children":2504},{},[2505,2510],{"type":29,"tag":738,"props":2506,"children":2507},{},[2508],{"type":35,"value":2509},"Sécurité (injections, secrets)",{"type":29,"tag":738,"props":2511,"children":2512},{},[2513],{"type":35,"value":2514},"Logique métier",{"type":29,"tag":711,"props":2516,"children":2517},{},[2518,2523],{"type":29,"tag":738,"props":2519,"children":2520},{},[2521],{"type":35,"value":2522},"Style et conventions",{"type":29,"tag":738,"props":2524,"children":2525},{},[2526],{"type":35,"value":2527},"Impact architectural",{"type":29,"tag":711,"props":2529,"children":2530},{},[2531,2536],{"type":29,"tag":738,"props":2532,"children":2533},{},[2534],{"type":35,"value":2535},"Tests manquants",{"type":29,"tag":738,"props":2537,"children":2538},{},[2539],{"type":35,"value":2540},"Cohérence avec le codebase",{"type":29,"tag":711,"props":2542,"children":2543},{},[2544,2549],{"type":29,"tag":738,"props":2545,"children":2546},{},[2547],{"type":35,"value":2548},"Complexité excessive",{"type":29,"tag":738,"props":2550,"children":2551},{},[2552],{"type":35,"value":2553},"Intention du changement",{"type":29,"tag":711,"props":2555,"children":2556},{},[2557,2562],{"type":29,"tag":738,"props":2558,"children":2559},{},[2560],{"type":35,"value":2561},"Documentation manquante",{"type":29,"tag":738,"props":2563,"children":2564},{},[2565],{"type":35,"value":2566},"Trade-offs de design",{"type":29,"tag":37,"props":2568,"children":2569},{},[2570],{"type":29,"tag":55,"props":2571,"children":2572},{},[2573],{"type":35,"value":2574},"Règle 3 : Ne pas rendre la review IA bloquante par défaut",{"type":29,"tag":37,"props":2576,"children":2577},{},[2578],{"type":35,"value":2579},"La review IA ne doit pas bloquer le merge de façon automatique sur les commentaires non-critiques. Seuls les commentaires de sécurité (injection, secrets, vulnérabilités connues) méritent un blocage automatique. Les autres sont des suggestions que l'auteur de la PR peut accepter ou rejeter explicitement.",{"type":29,"tag":37,"props":2581,"children":2582},{},[2583],{"type":29,"tag":55,"props":2584,"children":2585},{},[2586],{"type":35,"value":2587},"Règle 4 : Conserver la review humaine comme étape obligatoire",{"type":29,"tag":37,"props":2589,"children":2590},{},[2591],{"type":35,"value":2592},"Même avec un outil IA excellent, la review humaine reste obligatoire. La tentation de supprimer la review humaine pour les \"petites PR\" est dangereuse, car c'est souvent sur une \"petite PR\" que le bug critique est introduit.",{"type":29,"tag":66,"props":2594,"children":2595},{},[],{"type":29,"tag":70,"props":2597,"children":2599},{"id":2598},"les-métriques-de-suivi-à-6-mois",[2600],{"type":35,"value":2601},"Les métriques de suivi à 6 mois",{"type":29,"tag":37,"props":2603,"children":2604},{},[2605,2610],{"type":29,"tag":55,"props":2606,"children":2607},{},[2608],{"type":35,"value":2609},"Time to first review :",{"type":35,"value":2611}," le temps entre la création d'une PR et le premier commentaire. Avec un outil IA, ce metric descend à moins de 5 minutes (le bot review instantanément). C'est un gain réel pour les développeurs qui attendent un feedback.",{"type":29,"tag":37,"props":2613,"children":2614},{},[2615,2620],{"type":29,"tag":55,"props":2616,"children":2617},{},[2618],{"type":35,"value":2619},"Human review time :",{"type":35,"value":2621}," le temps que les développeurs humains passent sur les reviews. L'objectif est que ce temps reste stable ou diminue légèrement (l'IA a filtré le bruit) tout que la qualité augmente.",{"type":29,"tag":37,"props":2623,"children":2624},{},[2625,2630],{"type":29,"tag":55,"props":2626,"children":2627},{},[2628],{"type":35,"value":2629},"False positive rate de l'IA :",{"type":35,"value":2631}," le pourcentage de commentaires IA que l'auteur de la PR rejette comme non-pertinents. Un taux supérieur à 30% signifie que l'IA génère trop de bruit : ajustez la configuration ou le prompt système.",{"type":29,"tag":37,"props":2633,"children":2634},{},[2635,2640],{"type":29,"tag":55,"props":2636,"children":2637},{},[2638],{"type":35,"value":2639},"Bug escape rate :",{"type":35,"value":2641}," le nombre de bugs trouvés en production par rapport aux bugs trouvés en review. Si ce ratio s'améliore avec l'IA, l'outil fonctionne. S'il se dégrade, l'IA crée une fausse sécurité.",{"type":29,"tag":66,"props":2643,"children":2644},{},[],{"type":29,"tag":70,"props":2646,"children":2648},{"id":2647},"les-outils-et-leur-positionnement",[2649],{"type":35,"value":2650},"Les outils et leur positionnement",{"type":29,"tag":37,"props":2652,"children":2653},{},[2654,2659],{"type":29,"tag":55,"props":2655,"children":2656},{},[2657],{"type":35,"value":2658},"GitHub Copilot Code Review :",{"type":35,"value":2660}," intégration native dans GitHub, activée au niveau de la PR. Bon pour le style et les patterns de sécurité courants. Limite : connaissance du codebase limitée au diff de la PR.",{"type":29,"tag":37,"props":2662,"children":2663},{},[2664,2669],{"type":29,"tag":55,"props":2665,"children":2666},{},[2667],{"type":35,"value":2668},"CodeRabbit :",{"type":35,"value":2670}," outil spécialisé review avec contexte étendu du codebase. Meilleur pour la cohérence avec le codebase que Copilot. Configuration par règles yaml.",{"type":29,"tag":37,"props":2672,"children":2673},{},[2674,2679],{"type":29,"tag":55,"props":2675,"children":2676},{},[2677],{"type":35,"value":2678},"Claude / GPT-4 via API :",{"type":35,"value":2680}," intégration personnalisée avec contexte métier. Le plus flexible : vous pouvez injecter les conventions de l'équipe, les règles métier critiques, et l'architecture dans le prompt système. Le plus complexe à configurer.",{"type":29,"tag":37,"props":2682,"children":2683},{},[2684,2689],{"type":29,"tag":55,"props":2685,"children":2686},{},[2687],{"type":35,"value":2688},"Cursor :",{"type":35,"value":2690}," IDE avec review intégrée en cours d'écriture, pas seulement sur la PR. Utile pour les développeurs qui veulent le feedback avant même de créer la PR.",{"type":29,"tag":37,"props":2692,"children":2693},{},[2694],{"type":35,"value":2695},"L'IA en code review est un amplificateur, pas un remplacement. Elle amplifie la capacité de détection sur les patterns connus et libère le temps humain pour ce que l'IA ne peut pas faire. Les équipes qui sortiront gagnantes de cette transition ne seront pas celles qui délèguent le plus à l'IA. Ce seront celles qui comprennent précisément ce qu'elles lui délèguent.",{"type":29,"tag":66,"props":2697,"children":2698},{},[],{"type":29,"tag":70,"props":2700,"children":2702},{"id":2701},"faq-sur-lia-en-code-review",[2703],{"type":35,"value":2704},"FAQ sur l'IA en code review",{"type":29,"tag":371,"props":2706,"children":2707},{},[2708,2713],{"type":29,"tag":375,"props":2709,"children":2710},{},[2711],{"type":35,"value":2712},"1. Quelle est la différence entre un linter et un outil de review IA ?",{"type":29,"tag":37,"props":2714,"children":2715},{},[2716,2718,2723],{"type":35,"value":2717},"Un ",{"type":29,"tag":43,"props":2719,"children":2720},{"href":327},[2721],{"type":35,"value":2722},"linter",{"type":35,"value":2724}," applique des règles déterministes prédéfinies : syntaxe, style, patterns interdits. Il est rapide, sans faux positifs sur ce qu'il est configuré à détecter. Un outil IA applique un raisonnement contextuel sur le code : il peut détecter des problèmes que le linter ne peut pas formaliser en règles (ex : \"cette fonction fait trop de choses\"). La complémentarité est optimale : linter pour les règles déterministes, IA pour les jugements contextuels.",{"type":29,"tag":371,"props":2726,"children":2727},{},[2728,2733],{"type":29,"tag":375,"props":2729,"children":2730},{},[2731],{"type":35,"value":2732},"2. L'IA peut-elle reviewer du code dans des langages peu courants ou des DSLs internes ?",{"type":29,"tag":37,"props":2734,"children":2735},{},[2736],{"type":35,"value":2737},"Les LLMs sont entraînés principalement sur les langages populaires (Python, JavaScript, Java, Go, TypeScript). Pour les langages peu courants ou les DSLs internes, la qualité du review IA est dégradée. Dans ce cas, utilisez l'IA uniquement pour les aspects génériques (sécurité, documentation) et laissez les aspects spécifiques au langage aux reviewers humains.",{"type":29,"tag":371,"props":2739,"children":2740},{},[2741,2746],{"type":29,"tag":375,"props":2742,"children":2743},{},[2744],{"type":35,"value":2745},"3. Comment gérer le coût des reviews IA sur un grand nombre de PRs ?",{"type":29,"tag":37,"props":2747,"children":2748},{},[2749,2751,3491,3493,4025],{"type":35,"value":2750},"Les coûts varient selon l'outil. GitHub Copilot Code Review est inclus dans l'abonnement Copilot (19",{"type":29,"tag":890,"props":2752,"children":2755},{"className":2753},[2754],"katex",[2756,3090],{"type":29,"tag":890,"props":2757,"children":2760},{"className":2758},[2759],"katex-mathml",[2761],{"type":29,"tag":2762,"props":2763,"children":2765},"math",{"xmlns":2764},"http://www.w3.org/1998/Math/MathML",[2766],{"type":29,"tag":2767,"props":2768,"children":2769},"semantics",{},[2770,3083],{"type":29,"tag":2771,"props":2772,"children":2773},"mrow",{},[2774,2781,2786,2791,2796,2801,2805,2810,2826,2831,2835,2840,2844,2848,2852,2856,2861,2866,2872,2876,2881,2885,2889,2893,2898,2902,2907,2911,2915,2920,2924,2928,2933,2937,2941,2945,2949,2954,2958,2962,2966,2970,2974,2978,2982,2986,2990,2994,2998,3009,3013,3017,3021,3025,3029,3033,3037,3041,3045,3049,3054,3058,3062,3066,3071,3077],{"type":29,"tag":2775,"props":2776,"children":2778},"mi",{"mathvariant":2777},"normal",[2779],{"type":35,"value":2780},"/",{"type":29,"tag":2775,"props":2782,"children":2783},{},[2784],{"type":35,"value":2785},"m",{"type":29,"tag":2775,"props":2787,"children":2788},{},[2789],{"type":35,"value":2790},"o",{"type":29,"tag":2775,"props":2792,"children":2793},{},[2794],{"type":35,"value":2795},"i",{"type":29,"tag":2775,"props":2797,"children":2798},{},[2799],{"type":35,"value":2800},"s",{"type":29,"tag":2775,"props":2802,"children":2803},{"mathvariant":2777},[2804],{"type":35,"value":2780},{"type":29,"tag":2775,"props":2806,"children":2807},{},[2808],{"type":35,"value":2809},"d",{"type":29,"tag":2811,"props":2812,"children":2814},"mover",{"accent":2813},"true",[2815,2820],{"type":29,"tag":2775,"props":2816,"children":2817},{},[2818],{"type":35,"value":2819},"e",{"type":29,"tag":2821,"props":2822,"children":2823},"mo",{},[2824],{"type":35,"value":2825},"ˊ",{"type":29,"tag":2775,"props":2827,"children":2828},{},[2829],{"type":35,"value":2830},"v",{"type":29,"tag":2775,"props":2832,"children":2833},{},[2834],{"type":35,"value":2819},{"type":29,"tag":2775,"props":2836,"children":2837},{},[2838],{"type":35,"value":2839},"l",{"type":29,"tag":2775,"props":2841,"children":2842},{},[2843],{"type":35,"value":2790},{"type":29,"tag":2775,"props":2845,"children":2846},{},[2847],{"type":35,"value":37},{"type":29,"tag":2775,"props":2849,"children":2850},{},[2851],{"type":35,"value":37},{"type":29,"tag":2775,"props":2853,"children":2854},{},[2855],{"type":35,"value":2819},{"type":29,"tag":2775,"props":2857,"children":2858},{},[2859],{"type":35,"value":2860},"u",{"type":29,"tag":2775,"props":2862,"children":2863},{},[2864],{"type":35,"value":2865},"r",{"type":29,"tag":2821,"props":2867,"children":2869},{"stretchy":2868},"false",[2870],{"type":35,"value":2871},")",{"type":29,"tag":2775,"props":2873,"children":2874},{"mathvariant":2777},[2875],{"type":35,"value":332},{"type":29,"tag":2775,"props":2877,"children":2878},{},[2879],{"type":35,"value":2880},"C",{"type":29,"tag":2775,"props":2882,"children":2883},{},[2884],{"type":35,"value":2790},{"type":29,"tag":2775,"props":2886,"children":2887},{},[2888],{"type":35,"value":2809},{"type":29,"tag":2775,"props":2890,"children":2891},{},[2892],{"type":35,"value":2819},{"type":29,"tag":2775,"props":2894,"children":2895},{},[2896],{"type":35,"value":2897},"R",{"type":29,"tag":2775,"props":2899,"children":2900},{},[2901],{"type":35,"value":43},{"type":29,"tag":2775,"props":2903,"children":2904},{},[2905],{"type":35,"value":2906},"b",{"type":29,"tag":2775,"props":2908,"children":2909},{},[2910],{"type":35,"value":2906},{"type":29,"tag":2775,"props":2912,"children":2913},{},[2914],{"type":35,"value":2795},{"type":29,"tag":2775,"props":2916,"children":2917},{},[2918],{"type":35,"value":2919},"t",{"type":29,"tag":2775,"props":2921,"children":2922},{},[2923],{"type":35,"value":43},{"type":29,"tag":2775,"props":2925,"children":2926},{},[2927],{"type":35,"value":2860},{"type":29,"tag":2775,"props":2929,"children":2930},{},[2931],{"type":35,"value":2932},"n",{"type":29,"tag":2775,"props":2934,"children":2935},{},[2936],{"type":35,"value":2919},{"type":29,"tag":2775,"props":2938,"children":2939},{},[2940],{"type":35,"value":2795},{"type":29,"tag":2775,"props":2942,"children":2943},{},[2944],{"type":35,"value":2819},{"type":29,"tag":2775,"props":2946,"children":2947},{},[2948],{"type":35,"value":2865},{"type":29,"tag":2775,"props":2950,"children":2951},{},[2952],{"type":35,"value":2953},"g",{"type":29,"tag":2775,"props":2955,"children":2956},{},[2957],{"type":35,"value":2865},{"type":29,"tag":2775,"props":2959,"children":2960},{},[2961],{"type":35,"value":43},{"type":29,"tag":2775,"props":2963,"children":2964},{},[2965],{"type":35,"value":2919},{"type":29,"tag":2775,"props":2967,"children":2968},{},[2969],{"type":35,"value":2860},{"type":29,"tag":2775,"props":2971,"children":2972},{},[2973],{"type":35,"value":2795},{"type":29,"tag":2775,"props":2975,"children":2976},{},[2977],{"type":35,"value":2919},{"type":29,"tag":2775,"props":2979,"children":2980},{},[2981],{"type":35,"value":2839},{"type":29,"tag":2775,"props":2983,"children":2984},{},[2985],{"type":35,"value":2795},{"type":29,"tag":2775,"props":2987,"children":2988},{},[2989],{"type":35,"value":2785},{"type":29,"tag":2775,"props":2991,"children":2992},{},[2993],{"type":35,"value":2795},{"type":29,"tag":2775,"props":2995,"children":2996},{},[2997],{"type":35,"value":2919},{"type":29,"tag":2811,"props":2999,"children":3000},{"accent":2813},[3001,3005],{"type":29,"tag":2775,"props":3002,"children":3003},{},[3004],{"type":35,"value":2819},{"type":29,"tag":2821,"props":3006,"children":3007},{},[3008],{"type":35,"value":2825},{"type":29,"tag":2775,"props":3010,"children":3011},{},[3012],{"type":35,"value":2819},{"type":29,"tag":2775,"props":3014,"children":3015},{},[3016],{"type":35,"value":2919},{"type":29,"tag":2775,"props":3018,"children":3019},{},[3020],{"type":35,"value":2860},{"type":29,"tag":2775,"props":3022,"children":3023},{},[3024],{"type":35,"value":2932},{"type":29,"tag":2775,"props":3026,"children":3027},{},[3028],{"type":35,"value":2919},{"type":29,"tag":2775,"props":3030,"children":3031},{},[3032],{"type":35,"value":2795},{"type":29,"tag":2775,"props":3034,"children":3035},{},[3036],{"type":35,"value":2819},{"type":29,"tag":2775,"props":3038,"children":3039},{},[3040],{"type":35,"value":2865},{"type":29,"tag":2775,"props":3042,"children":3043},{},[3044],{"type":35,"value":37},{"type":29,"tag":2775,"props":3046,"children":3047},{},[3048],{"type":35,"value":43},{"type":29,"tag":2775,"props":3050,"children":3051},{},[3052],{"type":35,"value":3053},"y",{"type":29,"tag":2775,"props":3055,"children":3056},{},[3057],{"type":35,"value":43},{"type":29,"tag":2775,"props":3059,"children":3060},{},[3061],{"type":35,"value":2932},{"type":29,"tag":2775,"props":3063,"children":3064},{},[3065],{"type":35,"value":2919},{"type":29,"tag":2821,"props":3067,"children":3068},{"stretchy":2868},[3069],{"type":35,"value":3070},"(",{"type":29,"tag":3072,"props":3073,"children":3074},"mtext",{},[3075],{"type":35,"value":3076}," ",{"type":29,"tag":3078,"props":3079,"children":3080},"mn",{},[3081],{"type":35,"value":3082},"19",{"type":29,"tag":3084,"props":3085,"children":3087},"annotation",{"encoding":3086},"application/x-tex",[3088],{"type":35,"value":3089},"/mois/développeur). CodeRabbit a un tier gratuit limité et un tier payant (~19",{"type":29,"tag":890,"props":3091,"children":3094},{"className":3092,"ariaHidden":2813},[3093],"katex-html",[3095],{"type":29,"tag":890,"props":3096,"children":3099},{"className":3097},[3098],"base",[3100,3106,3112,3118,3123,3128,3133,3138,3143,3197,3203,3208,3214,3219,3225,3230,3235,3241,3247,3252,3258,3263,3268,3273,3279,3285,3290,3295,3300,3305,3310,3315,3321,3326,3331,3336,3341,3346,3351,3357,3363,3368,3412,3417,3422,3427,3432,3437,3442,3447,3452,3457,3462,3468,3473,3479,3486],{"type":29,"tag":890,"props":3101,"children":3105},{"className":3102,"style":3104},[3103],"strut","height:1em;vertical-align:-0.25em;",[],{"type":29,"tag":890,"props":3107,"children":3110},{"className":3108},[3109],"mord",[3111],{"type":35,"value":2780},{"type":29,"tag":890,"props":3113,"children":3116},{"className":3114},[3109,3115],"mathnormal",[3117],{"type":35,"value":2785},{"type":29,"tag":890,"props":3119,"children":3121},{"className":3120},[3109,3115],[3122],{"type":35,"value":2790},{"type":29,"tag":890,"props":3124,"children":3126},{"className":3125},[3109,3115],[3127],{"type":35,"value":2795},{"type":29,"tag":890,"props":3129,"children":3131},{"className":3130},[3109,3115],[3132],{"type":35,"value":2800},{"type":29,"tag":890,"props":3134,"children":3136},{"className":3135},[3109],[3137],{"type":35,"value":2780},{"type":29,"tag":890,"props":3139,"children":3141},{"className":3140},[3109,3115],[3142],{"type":35,"value":2809},{"type":29,"tag":890,"props":3144,"children":3147},{"className":3145},[3109,3146],"accent",[3148],{"type":29,"tag":890,"props":3149,"children":3152},{"className":3150},[3151],"vlist-t",[3153],{"type":29,"tag":890,"props":3154,"children":3157},{"className":3155},[3156],"vlist-r",[3158],{"type":29,"tag":890,"props":3159,"children":3163},{"className":3160,"style":3162},[3161],"vlist","height:0.6944em;",[3164,3179],{"type":29,"tag":890,"props":3165,"children":3167},{"style":3166},"top:-3em;",[3168,3174],{"type":29,"tag":890,"props":3169,"children":3173},{"className":3170,"style":3172},[3171],"pstrut","height:3em;",[],{"type":29,"tag":890,"props":3175,"children":3177},{"className":3176},[3109,3115],[3178],{"type":35,"value":2819},{"type":29,"tag":890,"props":3180,"children":3181},{"style":3166},[3182,3186],{"type":29,"tag":890,"props":3183,"children":3185},{"className":3184,"style":3172},[3171],[],{"type":29,"tag":890,"props":3187,"children":3191},{"className":3188,"style":3190},[3189],"accent-body","left:-0.1944em;",[3192],{"type":29,"tag":890,"props":3193,"children":3195},{"className":3194},[3109],[3196],{"type":35,"value":2825},{"type":29,"tag":890,"props":3198,"children":3201},{"className":3199,"style":3200},[3109,3115],"margin-right:0.03588em;",[3202],{"type":35,"value":2830},{"type":29,"tag":890,"props":3204,"children":3206},{"className":3205},[3109,3115],[3207],{"type":35,"value":2819},{"type":29,"tag":890,"props":3209,"children":3212},{"className":3210,"style":3211},[3109,3115],"margin-right:0.01968em;",[3213],{"type":35,"value":2839},{"type":29,"tag":890,"props":3215,"children":3217},{"className":3216},[3109,3115],[3218],{"type":35,"value":2790},{"type":29,"tag":890,"props":3220,"children":3222},{"className":3221},[3109,3115],[3223],{"type":35,"value":3224},"pp",{"type":29,"tag":890,"props":3226,"children":3228},{"className":3227},[3109,3115],[3229],{"type":35,"value":2819},{"type":29,"tag":890,"props":3231,"children":3233},{"className":3232},[3109,3115],[3234],{"type":35,"value":2860},{"type":29,"tag":890,"props":3236,"children":3239},{"className":3237,"style":3238},[3109,3115],"margin-right:0.02778em;",[3240],{"type":35,"value":2865},{"type":29,"tag":890,"props":3242,"children":3245},{"className":3243},[3244],"mclose",[3246],{"type":35,"value":2871},{"type":29,"tag":890,"props":3248,"children":3250},{"className":3249},[3109],[3251],{"type":35,"value":332},{"type":29,"tag":890,"props":3253,"children":3256},{"className":3254,"style":3255},[3109,3115],"margin-right:0.07153em;",[3257],{"type":35,"value":2880},{"type":29,"tag":890,"props":3259,"children":3261},{"className":3260},[3109,3115],[3262],{"type":35,"value":2790},{"type":29,"tag":890,"props":3264,"children":3266},{"className":3265},[3109,3115],[3267],{"type":35,"value":2809},{"type":29,"tag":890,"props":3269,"children":3271},{"className":3270},[3109,3115],[3272],{"type":35,"value":2819},{"type":29,"tag":890,"props":3274,"children":3277},{"className":3275,"style":3276},[3109,3115],"margin-right:0.00773em;",[3278],{"type":35,"value":2897},{"type":29,"tag":890,"props":3280,"children":3282},{"className":3281},[3109,3115],[3283],{"type":35,"value":3284},"abbi",{"type":29,"tag":890,"props":3286,"children":3288},{"className":3287},[3109,3115],[3289],{"type":35,"value":2919},{"type":29,"tag":890,"props":3291,"children":3293},{"className":3292},[3109,3115],[3294],{"type":35,"value":43},{"type":29,"tag":890,"props":3296,"children":3298},{"className":3297},[3109,3115],[3299],{"type":35,"value":2860},{"type":29,"tag":890,"props":3301,"children":3303},{"className":3302},[3109,3115],[3304],{"type":35,"value":2932},{"type":29,"tag":890,"props":3306,"children":3308},{"className":3307},[3109,3115],[3309],{"type":35,"value":2919},{"type":29,"tag":890,"props":3311,"children":3313},{"className":3312},[3109,3115],[3314],{"type":35,"value":2795},{"type":29,"tag":890,"props":3316,"children":3318},{"className":3317,"style":3238},[3109,3115],[3319],{"type":35,"value":3320},"er",{"type":29,"tag":890,"props":3322,"children":3324},{"className":3323,"style":3200},[3109,3115],[3325],{"type":35,"value":2953},{"type":29,"tag":890,"props":3327,"children":3329},{"className":3328,"style":3238},[3109,3115],[3330],{"type":35,"value":2865},{"type":29,"tag":890,"props":3332,"children":3334},{"className":3333},[3109,3115],[3335],{"type":35,"value":43},{"type":29,"tag":890,"props":3337,"children":3339},{"className":3338},[3109,3115],[3340],{"type":35,"value":2919},{"type":29,"tag":890,"props":3342,"children":3344},{"className":3343},[3109,3115],[3345],{"type":35,"value":2860},{"type":29,"tag":890,"props":3347,"children":3349},{"className":3348},[3109,3115],[3350],{"type":35,"value":2795},{"type":29,"tag":890,"props":3352,"children":3354},{"className":3353,"style":3211},[3109,3115],[3355],{"type":35,"value":3356},"tl",{"type":29,"tag":890,"props":3358,"children":3360},{"className":3359},[3109,3115],[3361],{"type":35,"value":3362},"imi",{"type":29,"tag":890,"props":3364,"children":3366},{"className":3365},[3109,3115],[3367],{"type":35,"value":2919},{"type":29,"tag":890,"props":3369,"children":3371},{"className":3370},[3109,3146],[3372],{"type":29,"tag":890,"props":3373,"children":3375},{"className":3374},[3151],[3376],{"type":29,"tag":890,"props":3377,"children":3379},{"className":3378},[3156],[3380],{"type":29,"tag":890,"props":3381,"children":3383},{"className":3382,"style":3162},[3161],[3384,3396],{"type":29,"tag":890,"props":3385,"children":3386},{"style":3166},[3387,3391],{"type":29,"tag":890,"props":3388,"children":3390},{"className":3389,"style":3172},[3171],[],{"type":29,"tag":890,"props":3392,"children":3394},{"className":3393},[3109,3115],[3395],{"type":35,"value":2819},{"type":29,"tag":890,"props":3397,"children":3398},{"style":3166},[3399,3403],{"type":29,"tag":890,"props":3400,"children":3402},{"className":3401,"style":3172},[3171],[],{"type":29,"tag":890,"props":3404,"children":3406},{"className":3405,"style":3190},[3189],[3407],{"type":29,"tag":890,"props":3408,"children":3410},{"className":3409},[3109],[3411],{"type":35,"value":2825},{"type":29,"tag":890,"props":3413,"children":3415},{"className":3414},[3109,3115],[3416],{"type":35,"value":2819},{"type":29,"tag":890,"props":3418,"children":3420},{"className":3419},[3109,3115],[3421],{"type":35,"value":2919},{"type":29,"tag":890,"props":3423,"children":3425},{"className":3424},[3109,3115],[3426],{"type":35,"value":2860},{"type":29,"tag":890,"props":3428,"children":3430},{"className":3429},[3109,3115],[3431],{"type":35,"value":2932},{"type":29,"tag":890,"props":3433,"children":3435},{"className":3434},[3109,3115],[3436],{"type":35,"value":2919},{"type":29,"tag":890,"props":3438,"children":3440},{"className":3439},[3109,3115],[3441],{"type":35,"value":2795},{"type":29,"tag":890,"props":3443,"children":3445},{"className":3444,"style":3238},[3109,3115],[3446],{"type":35,"value":3320},{"type":29,"tag":890,"props":3448,"children":3450},{"className":3449},[3109,3115],[3451],{"type":35,"value":37},{"type":29,"tag":890,"props":3453,"children":3455},{"className":3454},[3109,3115],[3456],{"type":35,"value":43},{"type":29,"tag":890,"props":3458,"children":3460},{"className":3459,"style":3200},[3109,3115],[3461],{"type":35,"value":3053},{"type":29,"tag":890,"props":3463,"children":3465},{"className":3464},[3109,3115],[3466],{"type":35,"value":3467},"an",{"type":29,"tag":890,"props":3469,"children":3471},{"className":3470},[3109,3115],[3472],{"type":35,"value":2919},{"type":29,"tag":890,"props":3474,"children":3477},{"className":3475},[3476],"mopen",[3478],{"type":35,"value":3070},{"type":29,"tag":890,"props":3480,"children":3484},{"className":3481},[3482,3483],"mspace","nobreak",[3485],{"type":35,"value":3076},{"type":29,"tag":890,"props":3487,"children":3489},{"className":3488},[3109],[3490],{"type":35,"value":3082},{"type":35,"value":3492},"/mois/utilisateur). Une intégration API directe coûte environ 0,5 à 2",{"type":29,"tag":890,"props":3494,"children":3496},{"className":3495},[2754],[3497,3734],{"type":29,"tag":890,"props":3498,"children":3500},{"className":3499},[2759],[3501],{"type":29,"tag":2762,"props":3502,"children":3503},{"xmlns":2764},[3504],{"type":29,"tag":2767,"props":3505,"children":3506},{},[3507,3729],{"type":29,"tag":2771,"props":3508,"children":3509},{},[3510,3514,3518,3522,3527,3531,3535,3539,3543,3547,3551,3555,3559,3563,3567,3571,3575,3579,3583,3587,3592,3596,3600,3605,3609,3613,3617,3621,3625,3629,3633,3637,3641,3645,3649,3654,3658,3662,3667,3671,3683,3687,3691,3695,3699,3703,3707,3712,3724],{"type":29,"tag":2775,"props":3511,"children":3512},{},[3513],{"type":35,"value":37},{"type":29,"tag":2775,"props":3515,"children":3516},{},[3517],{"type":35,"value":43},{"type":29,"tag":2775,"props":3519,"children":3520},{},[3521],{"type":35,"value":2865},{"type":29,"tag":2775,"props":3523,"children":3524},{},[3525],{"type":35,"value":3526},"P",{"type":29,"tag":2775,"props":3528,"children":3529},{},[3530],{"type":35,"value":2897},{"type":29,"tag":2775,"props":3532,"children":3533},{},[3534],{"type":35,"value":2800},{"type":29,"tag":2775,"props":3536,"children":3537},{},[3538],{"type":35,"value":2819},{"type":29,"tag":2775,"props":3540,"children":3541},{},[3542],{"type":35,"value":2839},{"type":29,"tag":2775,"props":3544,"children":3545},{},[3546],{"type":35,"value":2790},{"type":29,"tag":2775,"props":3548,"children":3549},{},[3550],{"type":35,"value":2932},{"type":29,"tag":2775,"props":3552,"children":3553},{},[3554],{"type":35,"value":2839},{"type":29,"tag":2775,"props":3556,"children":3557},{},[3558],{"type":35,"value":43},{"type":29,"tag":2775,"props":3560,"children":3561},{},[3562],{"type":35,"value":2919},{"type":29,"tag":2775,"props":3564,"children":3565},{},[3566],{"type":35,"value":43},{"type":29,"tag":2775,"props":3568,"children":3569},{},[3570],{"type":35,"value":2795},{"type":29,"tag":2775,"props":3572,"children":3573},{},[3574],{"type":35,"value":2839},{"type":29,"tag":2775,"props":3576,"children":3577},{},[3578],{"type":35,"value":2839},{"type":29,"tag":2775,"props":3580,"children":3581},{},[3582],{"type":35,"value":2819},{"type":29,"tag":2775,"props":3584,"children":3585},{"mathvariant":2777},[3586],{"type":35,"value":332},{"type":29,"tag":2775,"props":3588,"children":3589},{},[3590],{"type":35,"value":3591},"S",{"type":29,"tag":2775,"props":3593,"children":3594},{},[3595],{"type":35,"value":2860},{"type":29,"tag":2775,"props":3597,"children":3598},{},[3599],{"type":35,"value":2865},{"type":29,"tag":3078,"props":3601,"children":3602},{},[3603],{"type":35,"value":3604},"50",{"type":29,"tag":2775,"props":3606,"children":3607},{},[3608],{"type":35,"value":3526},{"type":29,"tag":2775,"props":3610,"children":3611},{},[3612],{"type":35,"value":2897},{"type":29,"tag":2775,"props":3614,"children":3615},{},[3616],{"type":35,"value":2800},{"type":29,"tag":2775,"props":3618,"children":3619},{"mathvariant":2777},[3620],{"type":35,"value":2780},{"type":29,"tag":2775,"props":3622,"children":3623},{},[3624],{"type":35,"value":2800},{"type":29,"tag":2775,"props":3626,"children":3627},{},[3628],{"type":35,"value":2819},{"type":29,"tag":2775,"props":3630,"children":3631},{},[3632],{"type":35,"value":2785},{"type":29,"tag":2775,"props":3634,"children":3635},{},[3636],{"type":35,"value":43},{"type":29,"tag":2775,"props":3638,"children":3639},{},[3640],{"type":35,"value":2795},{"type":29,"tag":2775,"props":3642,"children":3643},{},[3644],{"type":35,"value":2932},{"type":29,"tag":2775,"props":3646,"children":3647},{},[3648],{"type":35,"value":2819},{"type":29,"tag":2821,"props":3650,"children":3651},{"separator":2813},[3652],{"type":35,"value":3653},",",{"type":29,"tag":2775,"props":3655,"children":3656},{},[3657],{"type":35,"value":2839},{"type":29,"tag":2775,"props":3659,"children":3660},{},[3661],{"type":35,"value":2819},{"type":29,"tag":2775,"props":3663,"children":3664},{},[3665],{"type":35,"value":3666},"c",{"type":29,"tag":2775,"props":3668,"children":3669},{},[3670],{"type":35,"value":2790},{"type":29,"tag":2811,"props":3672,"children":3673},{"accent":2813},[3674,3678],{"type":29,"tag":2775,"props":3675,"children":3676},{},[3677],{"type":35,"value":2860},{"type":29,"tag":2821,"props":3679,"children":3680},{},[3681],{"type":35,"value":3682},"^",{"type":29,"tag":2775,"props":3684,"children":3685},{},[3686],{"type":35,"value":2919},{"type":29,"tag":2775,"props":3688,"children":3689},{},[3690],{"type":35,"value":2819},{"type":29,"tag":2775,"props":3692,"children":3693},{},[3694],{"type":35,"value":2800},{"type":29,"tag":2775,"props":3696,"children":3697},{},[3698],{"type":35,"value":2919},{"type":29,"tag":2775,"props":3700,"children":3701},{},[3702],{"type":35,"value":2809},{"type":29,"tag":2775,"props":3704,"children":3705},{},[3706],{"type":35,"value":2819},{"type":29,"tag":3078,"props":3708,"children":3709},{},[3710],{"type":35,"value":3711},"25",{"type":29,"tag":2811,"props":3713,"children":3714},{"accent":2813},[3715,3719],{"type":29,"tag":2775,"props":3716,"children":3717},{},[3718],{"type":35,"value":43},{"type":29,"tag":2821,"props":3720,"children":3721},{},[3722],{"type":35,"value":3723},"ˋ",{"type":29,"tag":3078,"props":3725,"children":3726},{},[3727],{"type":35,"value":3728},"100",{"type":29,"tag":3084,"props":3730,"children":3731},{"encoding":3086},[3732],{"type":35,"value":3733}," par PR selon la taille. Sur 50 PRs/semaine, le coût est de 25 à 100",{"type":29,"tag":890,"props":3735,"children":3737},{"className":3736,"ariaHidden":2813},[3093],[3738],{"type":29,"tag":890,"props":3739,"children":3741},{"className":3740},[3098],[3742,3746,3751,3756,3761,3767,3773,3778,3783,3788,3793,3798,3803,3809,3815,3820,3825,3831,3836,3841,3846,3851,3856,3861,3866,3872,3877,3883,3888,3893,3899,3944,3949,3955,3960,3965,3970,3975,4020],{"type":29,"tag":890,"props":3743,"children":3745},{"className":3744,"style":3104},[3103],[],{"type":29,"tag":890,"props":3747,"children":3749},{"className":3748},[3109,3115],[3750],{"type":35,"value":37},{"type":29,"tag":890,"props":3752,"children":3754},{"className":3753},[3109,3115],[3755],{"type":35,"value":43},{"type":29,"tag":890,"props":3757,"children":3759},{"className":3758,"style":3238},[3109,3115],[3760],{"type":35,"value":2865},{"type":29,"tag":890,"props":3762,"children":3764},{"className":3763,"style":3276},[3109,3115],[3765],{"type":35,"value":3766},"PR",{"type":29,"tag":890,"props":3768,"children":3770},{"className":3769},[3109,3115],[3771],{"type":35,"value":3772},"se",{"type":29,"tag":890,"props":3774,"children":3776},{"className":3775,"style":3211},[3109,3115],[3777],{"type":35,"value":2839},{"type":29,"tag":890,"props":3779,"children":3781},{"className":3780},[3109,3115],[3782],{"type":35,"value":2790},{"type":29,"tag":890,"props":3784,"children":3786},{"className":3785},[3109,3115],[3787],{"type":35,"value":2932},{"type":29,"tag":890,"props":3789,"children":3791},{"className":3790,"style":3211},[3109,3115],[3792],{"type":35,"value":2839},{"type":29,"tag":890,"props":3794,"children":3796},{"className":3795},[3109,3115],[3797],{"type":35,"value":43},{"type":29,"tag":890,"props":3799,"children":3801},{"className":3800},[3109,3115],[3802],{"type":35,"value":2919},{"type":29,"tag":890,"props":3804,"children":3806},{"className":3805},[3109,3115],[3807],{"type":35,"value":3808},"ai",{"type":29,"tag":890,"props":3810,"children":3812},{"className":3811,"style":3211},[3109,3115],[3813],{"type":35,"value":3814},"ll",{"type":29,"tag":890,"props":3816,"children":3818},{"className":3817},[3109,3115],[3819],{"type":35,"value":2819},{"type":29,"tag":890,"props":3821,"children":3823},{"className":3822},[3109],[3824],{"type":35,"value":332},{"type":29,"tag":890,"props":3826,"children":3829},{"className":3827,"style":3828},[3109,3115],"margin-right:0.05764em;",[3830],{"type":35,"value":3591},{"type":29,"tag":890,"props":3832,"children":3834},{"className":3833},[3109,3115],[3835],{"type":35,"value":2860},{"type":29,"tag":890,"props":3837,"children":3839},{"className":3838,"style":3238},[3109,3115],[3840],{"type":35,"value":2865},{"type":29,"tag":890,"props":3842,"children":3844},{"className":3843},[3109],[3845],{"type":35,"value":3604},{"type":29,"tag":890,"props":3847,"children":3849},{"className":3848,"style":3276},[3109,3115],[3850],{"type":35,"value":3766},{"type":29,"tag":890,"props":3852,"children":3854},{"className":3853},[3109,3115],[3855],{"type":35,"value":2800},{"type":29,"tag":890,"props":3857,"children":3859},{"className":3858},[3109],[3860],{"type":35,"value":2780},{"type":29,"tag":890,"props":3862,"children":3864},{"className":3863},[3109,3115],[3865],{"type":35,"value":3772},{"type":29,"tag":890,"props":3867,"children":3869},{"className":3868},[3109,3115],[3870],{"type":35,"value":3871},"main",{"type":29,"tag":890,"props":3873,"children":3875},{"className":3874},[3109,3115],[3876],{"type":35,"value":2819},{"type":29,"tag":890,"props":3878,"children":3881},{"className":3879},[3880],"mpunct",[3882],{"type":35,"value":3653},{"type":29,"tag":890,"props":3884,"children":3887},{"className":3885,"style":3886},[3482],"margin-right:0.1667em;",[],{"type":29,"tag":890,"props":3889,"children":3891},{"className":3890,"style":3211},[3109,3115],[3892],{"type":35,"value":2839},{"type":29,"tag":890,"props":3894,"children":3896},{"className":3895},[3109,3115],[3897],{"type":35,"value":3898},"eco",{"type":29,"tag":890,"props":3900,"children":3902},{"className":3901},[3109,3146],[3903],{"type":29,"tag":890,"props":3904,"children":3906},{"className":3905},[3151],[3907],{"type":29,"tag":890,"props":3908,"children":3910},{"className":3909},[3156],[3911],{"type":29,"tag":890,"props":3912,"children":3914},{"className":3913,"style":3162},[3161],[3915,3927],{"type":29,"tag":890,"props":3916,"children":3917},{"style":3166},[3918,3922],{"type":29,"tag":890,"props":3919,"children":3921},{"className":3920,"style":3172},[3171],[],{"type":29,"tag":890,"props":3923,"children":3925},{"className":3924},[3109,3115],[3926],{"type":35,"value":2860},{"type":29,"tag":890,"props":3928,"children":3929},{"style":3166},[3930,3934],{"type":29,"tag":890,"props":3931,"children":3933},{"className":3932,"style":3172},[3171],[],{"type":29,"tag":890,"props":3935,"children":3938},{"className":3936,"style":3937},[3189],"left:-0.2222em;",[3939],{"type":29,"tag":890,"props":3940,"children":3942},{"className":3941},[3109],[3943],{"type":35,"value":3682},{"type":29,"tag":890,"props":3945,"children":3947},{"className":3946},[3109,3115],[3948],{"type":35,"value":2919},{"type":29,"tag":890,"props":3950,"children":3952},{"className":3951},[3109,3115],[3953],{"type":35,"value":3954},"es",{"type":29,"tag":890,"props":3956,"children":3958},{"className":3957},[3109,3115],[3959],{"type":35,"value":2919},{"type":29,"tag":890,"props":3961,"children":3963},{"className":3962},[3109,3115],[3964],{"type":35,"value":2809},{"type":29,"tag":890,"props":3966,"children":3968},{"className":3967},[3109,3115],[3969],{"type":35,"value":2819},{"type":29,"tag":890,"props":3971,"children":3973},{"className":3972},[3109],[3974],{"type":35,"value":3711},{"type":29,"tag":890,"props":3976,"children":3978},{"className":3977},[3109,3146],[3979],{"type":29,"tag":890,"props":3980,"children":3982},{"className":3981},[3151],[3983],{"type":29,"tag":890,"props":3984,"children":3986},{"className":3985},[3156],[3987],{"type":29,"tag":890,"props":3988,"children":3990},{"className":3989,"style":3162},[3161],[3991,4003],{"type":29,"tag":890,"props":3992,"children":3993},{"style":3166},[3994,3998],{"type":29,"tag":890,"props":3995,"children":3997},{"className":3996,"style":3172},[3171],[],{"type":29,"tag":890,"props":3999,"children":4001},{"className":4000},[3109,3115],[4002],{"type":35,"value":43},{"type":29,"tag":890,"props":4004,"children":4005},{"style":3166},[4006,4010],{"type":29,"tag":890,"props":4007,"children":4009},{"className":4008,"style":3172},[3171],[],{"type":29,"tag":890,"props":4011,"children":4014},{"className":4012,"style":4013},[3189],"left:-0.25em;",[4015],{"type":29,"tag":890,"props":4016,"children":4018},{"className":4017},[3109],[4019],{"type":35,"value":3723},{"type":29,"tag":890,"props":4021,"children":4023},{"className":4022},[3109],[4024],{"type":35,"value":3728},{"type":35,"value":4026},"/semaine, marginal par rapport au coût d'un développeur. Le ROI est positif dès qu'une review IA prévient un seul bug en production.",{"type":29,"tag":371,"props":4028,"children":4029},{},[4030,4035],{"type":29,"tag":375,"props":4031,"children":4032},{},[4033],{"type":35,"value":4034},"4. Comment éviter que les développeurs seniors rejettent l'IA en code review ?",{"type":29,"tag":37,"props":4036,"children":4037},{},[4038],{"type":35,"value":4039},"En les impliquant dans la configuration. Les seniors qui configurent les règles de l'outil (quels patterns l'IA doit signaler, quels patterns ignorer) deviennent propriétaires de l'outil plutôt que sujets. Leur expertise améliore la qualité de l'IA, et leur résistance diminue quand ils voient leurs propres standards appliqués automatiquement.",{"type":29,"tag":371,"props":4041,"children":4042},{},[4043,4048],{"type":29,"tag":375,"props":4044,"children":4045},{},[4046],{"type":35,"value":4047},"5. L'IA en code review peut-elle nuire à l'apprentissage des développeurs juniors ?",{"type":29,"tag":37,"props":4049,"children":4050},{},[4051],{"type":35,"value":4052},"Risque réel si mal géré. Un junior qui reçoit du feedback uniquement de l'IA apprend les patterns que l'IA connaît, mais pas les jugements contextuels que les seniors auraient partagés. La règle : l'IA est le premier reviewer pour les juniors (feedback immédiat sur style et sécurité), mais la review humaine d'un senior reste obligatoire. Le senior peut commenter sur \"pourquoi cette architecture plutôt qu'une autre\", ce que l'IA ne peut pas faire.",{"type":29,"tag":371,"props":4054,"children":4055},{},[4056,4061],{"type":29,"tag":375,"props":4057,"children":4058},{},[4059],{"type":35,"value":4060},"6. Comment mesurer si l'IA améliore réellement la qualité du code sur 6 mois ?",{"type":29,"tag":37,"props":4062,"children":4063},{},[4064],{"type":35,"value":4065},"Deux métriques combinées : le bug escape rate (bugs détectés en production / bugs détectés en review) et la densité de défauts par KLOC sur le code produit depuis l'adoption. Si le bug escape rate diminue et que la densité de défauts diminue, l'IA améliore la qualité. Si seulement le bug escape rate diminue, l'IA détecte mieux mais ne change pas les pratiques de développement : il faut renforcer la formation.",{"type":29,"tag":66,"props":4067,"children":4068},{},[],{"type":29,"tag":166,"props":4070,"children":4073},{"cta":4071,"href":443,"title":4072,"type":445},"Testez la readiness IA de votre équipe →","Ressource gratuite : AI-Ready Engineering Team Checklist",[4074],{"type":29,"tag":37,"props":4075,"children":4076},{},[4077],{"type":35,"value":4078},"La checklist AI-Ready inclut une section dédiée à l'adoption des outils IA en code review : critères de sélection d'outil, règles d'intégration, et métriques de suivi à 30 et 90 jours.",{"type":29,"tag":1241,"props":4080,"children":4081},{},[4082],{"type":35,"value":1245},{"title":8,"searchDepth":453,"depth":453,"links":4084},[4085,4086,4087,4088,4089,4090,4091],{"id":2154,"depth":453,"text":2157},{"id":2325,"depth":453,"text":2328},{"id":2398,"depth":453,"text":2401},{"id":2442,"depth":453,"text":2445},{"id":2598,"depth":453,"text":2601},{"id":2647,"depth":453,"text":2650},{"id":2701,"depth":453,"text":2704},"content:fr:intelligence-artificielle:ia-code-review-retour-experience.md","fr/intelligence-artificielle/ia-code-review-retour-experience.md","fr/intelligence-artificielle/ia-code-review-retour-experience",{"_path":45,"_dir":4096,"_draft":7,"_partial":7,"_locale":8,"title":4097,"description":4098,"id":4099,"date":4100,"listed":13,"nocomments":7,"hidden":7,"categories":4101,"tags":4102,"--cover":4107,"readingTime":4108,"body":4112,"_type":466,"_id":4557,"_source":468,"_file":4558,"_stem":4559,"_extension":471},"pratiques-agiles","Limiter le Work In Progress : le levier le plus sous-estimé","La loi de Little appliquée à l'engineering : réduire le WIP est plus efficace que d'accélérer les développeurs. La démonstration et le protocole de mise en œuvre.",32,"2026-03-18",[4096],[4103,4104,4105,4106],"Work In Progress","WIP","Kanban","Flow","covers/articles/reduire-work-in-progress.jpg",{"text":2120,"minutes":4109,"time":4110,"words":4111},8.105,486300,1621,{"type":26,"children":4113,"toc":4549},[4114,4119,4124,4129,4134,4139,4144,4147,4153,4158,4166,4171,4176,4192,4209,4226,4231,4234,4240,4245,4255,4265,4275,4300,4309,4312,4318,4328,4338,4343,4361,4371,4381,4391,4394,4400,4410,4428,4438,4441,4447,4452,4457,4462,4465,4471,4484,4497,4510,4523,4536,4539],{"type":29,"tag":30,"props":4115,"children":4117},{"id":4116},"limiter-le-work-in-progress-le-levier-le-plus-sous-estimé",[4118],{"type":35,"value":4097},{"type":29,"tag":37,"props":4120,"children":4121},{},[4122],{"type":35,"value":4123},"J'accompagnais une équipe produit de 8 développeurs chez un client dans le secteur financier. Ils me demandaient comment livrer plus vite. Je leur ai demandé de compter le nombre de stories \"In Progress\" sur leur board.",{"type":29,"tag":37,"props":4125,"children":4126},{},[4127],{"type":35,"value":4128},"Il y en avait 22.",{"type":29,"tag":37,"props":4130,"children":4131},{},[4132],{"type":35,"value":4133},"22 stories pour 8 développeurs. Chaque développeur avait en moyenne 2,75 sujets en cours simultanément. Certains jonglaient entre 4 contextes différents dans la même journée.",{"type":29,"tag":37,"props":4135,"children":4136},{},[4137],{"type":35,"value":4138},"J'ai posé la question suivante : \"Quelle est la dernière fois qu'une story est allée de 'To Do' à 'Done' en moins de 3 jours ?\" Silence. L'un d'eux a vérifié Jira. La réponse était : 6 semaines auparavant.",{"type":29,"tag":37,"props":4140,"children":4141},{},[4142],{"type":35,"value":4143},"La solution que je leur ai proposée n'était pas d'embaucher, ni de changer de framework, ni d'adopter une nouvelle méthodologie. C'était de réduire le nombre de choses en cours simultanément. Ça semblait trop simple. C'était la bonne réponse.",{"type":29,"tag":66,"props":4145,"children":4146},{},[],{"type":29,"tag":70,"props":4148,"children":4150},{"id":4149},"la-loi-de-little-la-démonstration-mathématique",[4151],{"type":35,"value":4152},"La loi de Little : la démonstration mathématique",{"type":29,"tag":37,"props":4154,"children":4155},{},[4156],{"type":35,"value":4157},"La loi de Little, formulée par le mathématicien John Dutton Converse Little en 1961, s'applique à tout système de flux (file d'attente bancaire, réseau logistique, ou équipe de développement logiciel).",{"type":29,"tag":37,"props":4159,"children":4160},{},[4161],{"type":29,"tag":55,"props":4162,"children":4163},{},[4164],{"type":35,"value":4165},"Lead Time = Work In Progress / Throughput",{"type":29,"tag":37,"props":4167,"children":4168},{},[4169],{"type":35,"value":4170},"Traduction pour l'engineering : si votre équipe livre 10 stories par semaine (throughput) et a 30 stories en cours simultanément (WIP), le lead time moyen est de 3 semaines. Pour réduire le lead time à 1 semaine sans changer le throughput : réduire le WIP à 10 stories.",{"type":29,"tag":37,"props":4172,"children":4173},{},[4174],{"type":35,"value":4175},"La démonstration chiffrée est implacable.",{"type":29,"tag":37,"props":4177,"children":4178},{},[4179,4184,4186,4191],{"type":29,"tag":55,"props":4180,"children":4181},{},[4182],{"type":35,"value":4183},"Scénario A : WIP illimité",{"type":35,"value":4185}," : équipe de 5 développeurs, 15 stories en cours (3 par développeur), throughput de 10 stories par semaine. Lead Time moyen : 15 / 10 = ",{"type":29,"tag":55,"props":4187,"children":4188},{},[4189],{"type":35,"value":4190},"1,5 semaine",{"type":35,"value":332},{"type":29,"tag":37,"props":4193,"children":4194},{},[4195,4200,4202,4207],{"type":29,"tag":55,"props":4196,"children":4197},{},[4198],{"type":35,"value":4199},"Scénario B : WIP limité à 8",{"type":35,"value":4201}," : même équipe, même throughput, 8 stories en cours. Lead Time moyen : 8 / 10 = ",{"type":29,"tag":55,"props":4203,"children":4204},{},[4205],{"type":35,"value":4206},"0,8 semaine",{"type":35,"value":4208}," (−47%).",{"type":29,"tag":37,"props":4210,"children":4211},{},[4212,4217,4219,4224],{"type":29,"tag":55,"props":4213,"children":4214},{},[4215],{"type":35,"value":4216},"Scénario C : WIP limité à 5",{"type":35,"value":4218}," : 5 stories en cours (1 par développeur). Lead Time moyen : 5 / 10 = ",{"type":29,"tag":55,"props":4220,"children":4221},{},[4222],{"type":35,"value":4223},"0,5 semaine",{"type":35,"value":4225}," (−67%).",{"type":29,"tag":37,"props":4227,"children":4228},{},[4229],{"type":35,"value":4230},"En réduisant le WIP de 15 à 5, le lead time est divisé par 3, sans changer une ligne de code, sans recruter, sans changer de framework. C'est contre-intuitif dans une culture qui valorise l'occupation maximale. C'est pourtant ce que la théorie des contraintes de Goldratt et les principes Kanban enseignent depuis des décennies.",{"type":29,"tag":66,"props":4232,"children":4233},{},[],{"type":29,"tag":70,"props":4235,"children":4237},{"id":4236},"pourquoi-le-wip-augmente-naturellement",[4238],{"type":35,"value":4239},"Pourquoi le WIP augmente naturellement",{"type":29,"tag":37,"props":4241,"children":4242},{},[4243],{"type":35,"value":4244},"Dans la plupart des équipes, le WIP augmente sans décision consciente. Les mécanismes sont structurels.",{"type":29,"tag":37,"props":4246,"children":4247},{},[4248,4253],{"type":29,"tag":55,"props":4249,"children":4250},{},[4251],{"type":35,"value":4252},"Le multitâche comme norme.",{"type":35,"value":4254}," Un développeur bloqué sur une story en attend le feedback, démarre une deuxième story, est interrompu pour une troisième urgence. Sans règle explicite, 3 stories en parallèle par développeur devient la norme, et personne ne la remet en question.",{"type":29,"tag":37,"props":4256,"children":4257},{},[4258,4263],{"type":29,"tag":55,"props":4259,"children":4260},{},[4261],{"type":35,"value":4262},"La peur du \"slack\".",{"type":35,"value":4264}," Un développeur qui n'a rien en cours est perçu comme improductif. Résultat : chacun s'assigne une nouvelle story plutôt que d'aider un collègue à terminer. Le système optimise l'occupation individuelle au détriment du flux collectif.",{"type":29,"tag":37,"props":4266,"children":4267},{},[4268,4273],{"type":29,"tag":55,"props":4269,"children":4270},{},[4271],{"type":35,"value":4272},"Les dépendances non résolues.",{"type":35,"value":4274}," Une story en attente d'une décision produit, d'une clarification métier, ou d'une PR de review contribue au WIP sans avancer. Elle bloque la colonne sans produire de valeur.",{"type":29,"tag":37,"props":4276,"children":4277},{},[4278,4290,4292,4298],{"type":29,"tag":55,"props":4279,"children":4280},{},[4281,4283,4289],{"type":35,"value":4282},"Le ",{"type":29,"tag":43,"props":4284,"children":4286},{"href":4285},"/fr/pratiques-agiles/anti-patterns-backlog",[4287],{"type":35,"value":4288},"backlog infini",{"type":35,"value":332},{"type":35,"value":4291}," Si le backlog a 200 stories priorisées et qu'il n'y a pas de limite explicite, l'équipe accepte plus qu'elle ne peut faire. C'est le ",{"type":29,"tag":43,"props":4293,"children":4295},{"href":4294},"/fr/pratiques-agiles/sprint-planning-efficace",[4296],{"type":35,"value":4297},"sprint planning",{"type":35,"value":4299}," qui génère du WIP excessif.",{"type":29,"tag":166,"props":4301,"children":4303},{"cta":168,"href":169,"title":4302,"type":171},"Votre lead time dépasse 3 semaines et vous cherchez les bons leviers pour le réduire ?",[4304],{"type":29,"tag":37,"props":4305,"children":4306},{},[4307],{"type":35,"value":4308},"Identifier les bonnes limites de WIP pour votre équipe nécessite une analyse du flux actuel. En 30 minutes, je calcule votre lead time théorique, j'identifie les goulots d'étranglement, et je définis avec vous les limites de WIP adaptées à votre contexte.",{"type":29,"tag":66,"props":4310,"children":4311},{},[],{"type":29,"tag":70,"props":4313,"children":4315},{"id":4314},"le-protocole-dimplémentation-en-5-étapes",[4316],{"type":35,"value":4317},"Le protocole d'implémentation en 5 étapes",{"type":29,"tag":37,"props":4319,"children":4320},{},[4321,4326],{"type":29,"tag":55,"props":4322,"children":4323},{},[4324],{"type":35,"value":4325},"Étape 1 : Mesurer le WIP actuel.",{"type":35,"value":4327}," Avant d'imposer une limite, mesurer l'état réel. Pendant 2 semaines, poser ces questions en daily standup : combien de stories chaque développeur a-t-il en cours aujourd'hui ? Combien de stories sont en cours depuis plus de 5 jours ? Quel est le nombre total de stories \"In Progress\" sur le board ? Calculer la moyenne. C'est le WIP de départ.",{"type":29,"tag":37,"props":4329,"children":4330},{},[4331,4336],{"type":29,"tag":55,"props":4332,"children":4333},{},[4334],{"type":35,"value":4335},"Étape 2 : Définir les limites initiales.",{"type":35,"value":4337}," Règle pratique de départ : limite WIP = nombre de développeurs × 1,5. Pour une équipe de 6 : limite WIP = 9. C'est plus restrictif que l'état naturel (souvent 2 à 3 fois le nombre de développeurs) mais pas encore au niveau optimal.",{"type":29,"tag":37,"props":4339,"children":4340},{},[4341],{"type":35,"value":4342},"La limite s'applique par colonne du board Kanban, pas au total :",{"type":29,"tag":1069,"props":4344,"children":4345},{},[4346,4351,4356],{"type":29,"tag":1073,"props":4347,"children":4348},{},[4349],{"type":35,"value":4350},"\"In Progress\" : limite = N développeurs",{"type":29,"tag":1073,"props":4352,"children":4353},{},[4354],{"type":35,"value":4355},"\"In Review\" : limite = N/2",{"type":29,"tag":1073,"props":4357,"children":4358},{},[4359],{"type":35,"value":4360},"\"In Testing\" : limite = N/3",{"type":29,"tag":37,"props":4362,"children":4363},{},[4364,4369],{"type":29,"tag":55,"props":4365,"children":4366},{},[4367],{"type":35,"value":4368},"Étape 3 : Rendre la limite visible et automatique.",{"type":35,"value":4370}," Sur Jira, configurer le \"Work In Progress Limit\" sur chaque colonne du board. Jira affiche une alerte visuelle (colonne en rouge) quand la limite est atteinte. La règle doit être visible passivement, pas nécessiter une vérification active.",{"type":29,"tag":37,"props":4372,"children":4373},{},[4374,4379],{"type":29,"tag":55,"props":4375,"children":4376},{},[4377],{"type":35,"value":4378},"Étape 4 : Créer la règle \"finir avant de commencer\".",{"type":35,"value":4380}," Quand la limite WIP est atteinte, avant d'ouvrir une nouvelle story : fermer une story en cours. Ce qui implique concrètement d'aider un collègue à débloquer sa story, de prioriser les code reviews en attente (qui bloquent les stories en review), ou de diviser une grande story bloquée en sous-stories terminables.",{"type":29,"tag":37,"props":4382,"children":4383},{},[4384,4389],{"type":29,"tag":55,"props":4385,"children":4386},{},[4387],{"type":35,"value":4388},"Étape 5 : Ajuster la limite après 4 sprints.",{"type":35,"value":4390}," La limite initiale n'est pas la limite optimale. Si le board n'atteint jamais la limite : trop haute, la réduire de 20%. Si la limite bloque constamment le flux : peut-être trop basse, ou signal d'un goulot d'étranglement à résoudre autrement.",{"type":29,"tag":66,"props":4392,"children":4393},{},[],{"type":29,"tag":70,"props":4395,"children":4397},{"id":4396},"les-résistances-et-comment-les-adresser",[4398],{"type":35,"value":4399},"Les résistances et comment les adresser",{"type":29,"tag":37,"props":4401,"children":4402},{},[4403,4408],{"type":29,"tag":55,"props":4404,"children":4405},{},[4406],{"type":35,"value":4407},"\"Je suis bloqué, je dois bien commencer autre chose.\"",{"type":35,"value":4409}," Cette résistance est légitime. Ma réponse : le blocage est l'information importante, pas le contournement. Un développeur bloqué doit d'abord chercher à débloquer : escalader la dépendance, poser la question dans Slack, demander de l'aide. Ce n'est qu'après 2 heures de blocage sans perspective de résolution que commencer une autre story est acceptable. Et ce dépassement doit être visible sur le board.",{"type":29,"tag":37,"props":4411,"children":4412},{},[4413,4418,4420,4426],{"type":29,"tag":55,"props":4414,"children":4415},{},[4416],{"type":35,"value":4417},"\"Le business veut des estimations et une limite WIP les rend impossibles.\"",{"type":35,"value":4419}," Faux. Avec une limite WIP et la loi de Little, les prédictions sont plus précises, pas moins. \"Nous avons X stories en cours et Y en backlog. Avec notre ",{"type":29,"tag":43,"props":4421,"children":4423},{"href":4422},"/fr/pratiques-agiles/story-points-estimation-agile-alternative",[4424],{"type":35,"value":4425},"throughput",{"type":35,"value":4427}," de 10 stories par semaine et une limite WIP de 8, la feature Z sera livrée dans cet intervalle de confiance.\" C'est plus précis qu'une vélocité en story points qui dérive avec le temps.",{"type":29,"tag":37,"props":4429,"children":4430},{},[4431,4436],{"type":29,"tag":55,"props":4432,"children":4433},{},[4434],{"type":35,"value":4435},"\"Mes développeurs vont s'ennuyer en attendant.\"",{"type":35,"value":4437}," Les développeurs ne s'ennuient jamais : ils ont du backlog et de la dette technique. La vraie question est : qu'est-ce qui est plus précieux, commencer une nouvelle story ou aider à terminer les stories en cours ? La réponse est presque toujours la deuxième option. Finir une story livrée au client vaut plus que démarrer une story qui attendra 3 semaines dans la file.",{"type":29,"tag":66,"props":4439,"children":4440},{},[],{"type":29,"tag":70,"props":4442,"children":4444},{"id":4443},"ce-que-ça-a-changé",[4445],{"type":35,"value":4446},"Ce que ça a changé",{"type":29,"tag":37,"props":4448,"children":4449},{},[4450],{"type":35,"value":4451},"Dans l'équipe de 8 développeurs mentionnée en introduction, le WIP moyen était de 22 stories simultanées. Après implémentation des limites WIP à 10 et de la règle \"finir avant de commencer\", le WIP a baissé à 9 en 6 semaines. Le lead time moyen est passé de 18 jours à 7 jours. Le nombre de stories livrées par sprint n'a pas changé, mais leur délai de livraison a été divisé par 2,5.",{"type":29,"tag":37,"props":4453,"children":4454},{},[4455],{"type":35,"value":4456},"Les métriques à suivre pour mesurer l'impact : WIP moyen hebdomadaire (la tendance doit baisser), age du WIP en jours (les stories vieilles de plus de 2 sprints sont des signaux d'alerte), et distribution du lead time par story (une distribution qui se resserre indique un flux qui se normalise).",{"type":29,"tag":37,"props":4458,"children":4459},{},[4460],{"type":35,"value":4461},"Ce n'était jamais un problème de personnes. C'était un problème de système, et le système a changé quand les règles ont changé.",{"type":29,"tag":66,"props":4463,"children":4464},{},[],{"type":29,"tag":70,"props":4466,"children":4468},{"id":4467},"faq-sur-les-limites-de-wip",[4469],{"type":35,"value":4470},"FAQ sur les limites de WIP",{"type":29,"tag":371,"props":4472,"children":4473},{},[4474,4479],{"type":29,"tag":375,"props":4475,"children":4476},{},[4477],{"type":35,"value":4478},"1. Les limites de WIP s'appliquent-elles en Scrum comme en Kanban ?",{"type":29,"tag":37,"props":4480,"children":4481},{},[4482],{"type":35,"value":4483},"Oui. En Kanban, les limites WIP sont un principe fondamental. En Scrum, elles s'appliquent au niveau du sprint board. La différence est que Scrum permet de remplir le sprint à 100% de la capacité théorique, ce qui crée du WIP élevé. En ajoutant une limite explicite (ex: max 2 stories par développeur simultanément), l'équipe Scrum bénéficie des mêmes avantages de flux que Kanban.",{"type":29,"tag":371,"props":4485,"children":4486},{},[4487,4492],{"type":29,"tag":375,"props":4488,"children":4489},{},[4490],{"type":35,"value":4491},"2. Comment gérer les urgences qui obligent à dépasser la limite WIP ?",{"type":29,"tag":37,"props":4493,"children":4494},{},[4495],{"type":35,"value":4496},"Les urgences existent et peuvent justifier de dépasser temporairement la limite. La règle : chaque dépassement est une décision consciente et visible, la colonne du board vire au rouge. Après chaque urgence, analyser en rétro : était-ce vraiment une urgence ? Aurait-on pu l'anticiper ? Les équipes qui dépassent la limite pour urgence chaque semaine ont un problème de priorisation, pas de WIP.",{"type":29,"tag":371,"props":4498,"children":4499},{},[4500,4505],{"type":29,"tag":375,"props":4501,"children":4502},{},[4503],{"type":35,"value":4504},"3. Quelle est la limite WIP optimale ?",{"type":29,"tag":37,"props":4506,"children":4507},{},[4508],{"type":35,"value":4509},"Il n'y a pas de réponse universelle : elle dépend de la taille d'équipe, de la complexité des stories, et du niveau d'interdépendances. La règle empirique est de commencer à 1,5 fois le nombre de développeurs et d'ajuster vers le bas jusqu'à trouver la valeur où le lead time se stabilise sans créer de goulot d'étranglement. En pratique, la plupart des équipes trouvent leur optimum entre 1 et 2 fois le nombre de développeurs.",{"type":29,"tag":371,"props":4511,"children":4512},{},[4513,4518],{"type":29,"tag":375,"props":4514,"children":4515},{},[4516],{"type":35,"value":4517},"4. Comment les limites WIP interagissent-elles avec les bugs urgents ?",{"type":29,"tag":37,"props":4519,"children":4520},{},[4521],{"type":35,"value":4522},"Les bugs urgents (P1/P0) sont traités comme des interruptions explicites. Un bug P1 peut entrer en cours sans respecter la limite WIP, mais il doit être la priorité absolue jusqu'à sa résolution. Le développeur qui prend un bug P1 stationne sa story en cours dans une colonne \"On Hold\". Le WIP réel ne dépasse pas la limite : il y a une substitution consciente et visible.",{"type":29,"tag":371,"props":4524,"children":4525},{},[4526,4531],{"type":29,"tag":375,"props":4527,"children":4528},{},[4529],{"type":35,"value":4530},"5. Comment convaincre le management que moins de WIP n'est pas moins de travail ?",{"type":29,"tag":37,"props":4532,"children":4533},{},[4534],{"type":35,"value":4535},"Par la démonstration chiffrée de la loi de Little. Montrer le calcul : avec un WIP de 20 et un throughput de 10 stories par semaine, le lead time est de 2 semaines. Avec un WIP de 10, le lead time est de 1 semaine. Même throughput, deux fois plus de réactivité pour le business. Le business valorise la rapidité de livraison : les limites WIP la produisent sans recruter.",{"type":29,"tag":66,"props":4537,"children":4538},{},[],{"type":29,"tag":166,"props":4540,"children":4543},{"cta":4541,"href":443,"title":4542,"type":445},"Télécharger le guide gratuit →","Ressource gratuite : Guide Lead Time -50% en 90 jours",[4544],{"type":29,"tag":37,"props":4545,"children":4546},{},[4547],{"type":35,"value":4548},"Le guide complet pour réduire votre lead time en 90 jours inclut un chapitre détaillé sur l'implémentation des limites WIP, les métriques de suivi, et les benchmarks par taille d'équipe, avec les données issues de mes accompagnements terrain.",{"title":8,"searchDepth":453,"depth":453,"links":4550},[4551,4552,4553,4554,4555,4556],{"id":4149,"depth":453,"text":4152},{"id":4236,"depth":453,"text":4239},{"id":4314,"depth":453,"text":4317},{"id":4396,"depth":453,"text":4399},{"id":4443,"depth":453,"text":4446},{"id":4467,"depth":453,"text":4470},"content:fr:pratiques-agiles:reduire-work-in-progress-velocite.md","fr/pratiques-agiles/reduire-work-in-progress-velocite.md","fr/pratiques-agiles/reduire-work-in-progress-velocite",{"_path":345,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":4561,"description":4562,"id":4563,"date":4564,"listed":13,"nocomments":7,"hidden":7,"categories":4565,"tags":4566,"--cover":4570,"readingTime":4571,"body":4575,"_type":466,"_id":5094,"_source":468,"_file":5095,"_stem":5096,"_extension":471},"Pair programming : ROI réel et conditions de succès","Les études montrent un ROI de 15% sur la qualité à long terme — mais seulement dans certaines conditions. Ce que la recherche dit vraiment sur le pair programming.",31,"2026-03-16",[6],[4567,4568,4569],"Pair Programming","ROI","Pratiques Engineering","covers/articles/pair-programming-roi.jpg",{"text":21,"minutes":4572,"time":4573,"words":4574},7.3,438000,1460,{"type":26,"children":4576,"toc":5081},[4577,4582,4587,4595,4600,4603,4609,4628,4633,4652,4662,4665,4671,4676,4686,4696,4706,4716,4719,4728,4731,4737,4743,4748,4771,4776,4794,4800,4805,4810,4816,4849,4855,4860,4863,4869,4879,4889,4899,4902,4908,4918,4928,4946,4963,4966,4972,4985,4998,5011,5031,5044,5047,5055,5058,5066,5071],{"type":29,"tag":30,"props":4578,"children":4580},{"id":4579},"pair-programming-roi-réel-et-conditions-de-succès",[4581],{"type":35,"value":4561},{"type":29,"tag":37,"props":4583,"children":4584},{},[4585],{"type":35,"value":4586},"J'accompagnais une équipe dans une banque d'investissement parisienne : 18 développeurs, une culture tech solide. Trois nouveaux développeurs venaient de rejoindre l'équipe. Habituellement, leur montée en compétence prenait 8 semaines avant d'être autonomes sur les modules critiques. J'ai proposé d'introduire le pair programming exclusivement sur leur onboarding : chaque nouveau développeur pairait systématiquement avec un senior sur ses premières stories complexes. Le résultat, mesuré 6 semaines plus tard : les trois nouvelles recrues étaient autonomes en 4 semaines au lieu de 8. Et sans qu'on le planifie, les seniors avaient commencé à se pairer entre eux sur les stories de refactoring difficiles.",{"type":29,"tag":37,"props":4588,"children":4589},{},[4590],{"type":29,"tag":55,"props":4591,"children":4592},{},[4593],{"type":35,"value":4594},"Le pair programming est soit adulé par les équipes XP, soit rejeté par les managers qui voient \"deux personnes sur un seul clavier\". Rarement évalué objectivement. Or les données sont là, et elles sont plus nuancées que ce que les deux camps affirment.",{"type":29,"tag":37,"props":4596,"children":4597},{},[4598],{"type":35,"value":4599},"J'ai introduit le pair programming dans une dizaine d'équipes au cours des 10 dernières années, dans la finance, les médias, les télécoms. Certaines fois, ça a transformé la culture et la qualité. D'autres fois, ça a créé des tensions et été abandonné en 3 semaines. La différence ne tenait pas à la pratique, mais aux conditions d'introduction.",{"type":29,"tag":66,"props":4601,"children":4602},{},[],{"type":29,"tag":70,"props":4604,"children":4606},{"id":4605},"ce-que-la-recherche-dit-vraiment",[4607],{"type":35,"value":4608},"Ce que la recherche dit vraiment",{"type":29,"tag":37,"props":4610,"children":4611},{},[4612,4614,4619,4621,4626],{"type":35,"value":4613},"L'étude de référence est celle de Laurie Williams et Robert Kessler (2000, University of Utah) : sur un projet de développement logiciel, le pair programming produit un code avec ",{"type":29,"tag":55,"props":4615,"children":4616},{},[4617],{"type":35,"value":4618},"15% moins de défauts",{"type":35,"value":4620}," que le développement solo, mais avec ",{"type":29,"tag":55,"props":4622,"children":4623},{},[4624],{"type":35,"value":4625},"15% de temps supplémentaire",{"type":35,"value":4627}," à court terme.",{"type":29,"tag":37,"props":4629,"children":4630},{},[4631],{"type":35,"value":4632},"Le ROI net sur le long terme est positif pour une raison simple : le coût d'un défaut en production est 10 à 100 fois supérieur au coût de le détecter pendant le développement. 15% de temps en plus pour 15% de défauts en moins, c'est rentable dès que les défauts ont un coût significatif.",{"type":29,"tag":37,"props":4634,"children":4635},{},[4636,4638,4643,4645,4650],{"type":35,"value":4637},"Une méta-analyse de 2007 (Hannay et al., 18 études) nuance cependant les résultats : le bénéfice du pair programming est plus élevé pour les ",{"type":29,"tag":55,"props":4639,"children":4640},{},[4641],{"type":35,"value":4642},"tâches complexes",{"type":35,"value":4644}," et ",{"type":29,"tag":55,"props":4646,"children":4647},{},[4648],{"type":35,"value":4649},"les juniors qui travaillent avec des seniors",{"type":35,"value":4651},". Sur des tâches simples ou répétitives, l'overhead est présent sans le bénéfice proportionnel.",{"type":29,"tag":37,"props":4653,"children":4654},{},[4655,4660],{"type":29,"tag":55,"props":4656,"children":4657},{},[4658],{"type":35,"value":4659},"Ce que ça signifie concrètement",{"type":35,"value":4661}," : le pair programming n'est pas une pratique à appliquer uniformément. C'est une pratique à utiliser sur les bonnes tâches, dans les bonnes conditions.",{"type":29,"tag":66,"props":4663,"children":4664},{},[],{"type":29,"tag":70,"props":4666,"children":4668},{"id":4667},"quand-le-pair-programming-dégrade-la-productivité",[4669],{"type":35,"value":4670},"Quand le pair programming dégrade la productivité",{"type":29,"tag":37,"props":4672,"children":4673},{},[4674],{"type":35,"value":4675},"Avant les conditions de succès, les conditions d'échec, parce qu'elles sont plus fréquentes.",{"type":29,"tag":37,"props":4677,"children":4678},{},[4679,4684],{"type":29,"tag":55,"props":4680,"children":4681},{},[4682],{"type":35,"value":4683},"Tâches trop simples",{"type":35,"value":4685}," : un bug trivial, une modification de configuration, une story de 1 point. L'overhead cognitif de coordonner deux personnes dépasse le bénéfice. Résultat : frustration et sentiment de temps perdu.",{"type":29,"tag":37,"props":4687,"children":4688},{},[4689,4694],{"type":29,"tag":55,"props":4690,"children":4691},{},[4692],{"type":35,"value":4693},"Parité trop déséquilibrée sans intention pédagogique",{"type":35,"value":4695}," : un senior qui \"dicte\" pendant qu'un junior \"exécute\" n'est pas du pair programming, c'est de la supervision déguisée. C'est épuisant pour les deux et n'apporte pas les bénéfices de qualité attendus.",{"type":29,"tag":37,"props":4697,"children":4698},{},[4699,4704],{"type":29,"tag":55,"props":4700,"children":4701},{},[4702],{"type":35,"value":4703},"Sessions trop longues sans rotation",{"type":35,"value":4705}," : après 90 minutes de pair programming intensif, la fatigue cognitive s'accumule. Des sessions de plus de 2 heures sans pause produisent des erreurs que des sessions de 90 minutes n'auraient pas produites.",{"type":29,"tag":37,"props":4707,"children":4708},{},[4709,4714],{"type":29,"tag":55,"props":4710,"children":4711},{},[4712],{"type":35,"value":4713},"Introduction imposée sans explication",{"type":35,"value":4715}," : \"Désormais, toutes les stories se font en pair programming.\" Sans comprendre pourquoi, les développeurs perçoivent la pratique comme un manque de confiance. La résistance est immédiate et dure.",{"type":29,"tag":66,"props":4717,"children":4718},{},[],{"type":29,"tag":166,"props":4720,"children":4722},{"cta":168,"href":169,"title":4721,"type":171},"Vous voulez introduire le pair programming mais vous ne savez pas comment éviter la résistance ?",[4723],{"type":29,"tag":37,"props":4724,"children":4725},{},[4726],{"type":35,"value":4727},"Vous avez tenté de lancer le pair programming et ça n'a pas pris, ou vous voulez bien faire du premier coup pour ne pas brûler le capital de confiance de l'équipe. L'introduction réussie dépend de la communication des objectifs, du choix des premières tâches, et du format adapté à votre contexte. En 30 minutes, on définit la stratégie adaptée.",{"type":29,"tag":66,"props":4729,"children":4730},{},[],{"type":29,"tag":70,"props":4732,"children":4734},{"id":4733},"les-4-conditions-de-succès",[4735],{"type":35,"value":4736},"Les 4 conditions de succès",{"type":29,"tag":106,"props":4738,"children":4740},{"id":4739},"condition-1-le-bon-contexte-de-tâche",[4741],{"type":35,"value":4742},"Condition 1 : Le bon contexte de tâche",{"type":29,"tag":37,"props":4744,"children":4745},{},[4746],{"type":35,"value":4747},"Le pair programming apporte le plus de valeur sur :",{"type":29,"tag":1069,"props":4749,"children":4750},{},[4751,4756,4761,4766],{"type":29,"tag":1073,"props":4752,"children":4753},{},[4754],{"type":35,"value":4755},"Les tâches complexes avec des contraintes non-triviales",{"type":29,"tag":1073,"props":4757,"children":4758},{},[4759],{"type":35,"value":4760},"Les tâches dans des zones de code peu connues ou à haut risque",{"type":29,"tag":1073,"props":4762,"children":4763},{},[4764],{"type":35,"value":4765},"Les tâches d'architecture ou de design",{"type":29,"tag":1073,"props":4767,"children":4768},{},[4769],{"type":35,"value":4770},"L'onboarding d'un nouveau développeur sur un module spécifique",{"type":29,"tag":37,"props":4772,"children":4773},{},[4774],{"type":35,"value":4775},"Il apporte peu de valeur sur :",{"type":29,"tag":1069,"props":4777,"children":4778},{},[4779,4784,4789],{"type":29,"tag":1073,"props":4780,"children":4781},{},[4782],{"type":35,"value":4783},"Les tâches répétitives et bien définies",{"type":29,"tag":1073,"props":4785,"children":4786},{},[4787],{"type":35,"value":4788},"Les investigations longues et exploratoires (pair review après, pas pair programming pendant)",{"type":29,"tag":1073,"props":4790,"children":4791},{},[4792],{"type":35,"value":4793},"Les optimisations de performance nécessitant du profiling individuel",{"type":29,"tag":106,"props":4795,"children":4797},{"id":4796},"condition-2-la-rotation-du-rôle-drivernavigator",[4798],{"type":35,"value":4799},"Condition 2 : La rotation du rôle driver/navigator",{"type":29,"tag":37,"props":4801,"children":4802},{},[4803],{"type":35,"value":4804},"Le format classique est driver/navigator : le driver écrit le code, le navigator réfléchit à la direction et détecte les erreurs. La rotation doit être explicite et fréquente, toutes les 25 à 30 minutes (technique Pomodoro adaptée).",{"type":29,"tag":37,"props":4806,"children":4807},{},[4808],{"type":35,"value":4809},"Sans rotation, l'un des deux s'ennuie ou se décroche. Avec rotation, les deux restent engagés et le code bénéficie de deux perspectives actives.",{"type":29,"tag":106,"props":4811,"children":4813},{"id":4812},"condition-3-la-parité-ajustée-à-lobjectif",[4814],{"type":35,"value":4815},"Condition 3 : La parité ajustée à l'objectif",{"type":29,"tag":1069,"props":4817,"children":4818},{},[4819,4829,4839],{"type":29,"tag":1073,"props":4820,"children":4821},{},[4822,4827],{"type":29,"tag":55,"props":4823,"children":4824},{},[4825],{"type":35,"value":4826},"Objectif qualité",{"type":35,"value":4828}," : deux développeurs de niveau similaire, l'un challenge l'autre, la qualité est le produit des deux regards",{"type":29,"tag":1073,"props":4830,"children":4831},{},[4832,4837],{"type":29,"tag":55,"props":4833,"children":4834},{},[4835],{"type":35,"value":4836},"Objectif formation",{"type":35,"value":4838}," : un senior + un junior avec intention pédagogique explicite, le senior explique ses raisonnements, le junior pose des questions sans être jugé",{"type":29,"tag":1073,"props":4840,"children":4841},{},[4842,4847],{"type":29,"tag":55,"props":4843,"children":4844},{},[4845],{"type":35,"value":4846},"Objectif connaissance métier",{"type":35,"value":4848}," : un développeur qui connaît le code + un développeur qui connaît le métier, le knowledge sharing est bidirectionnel",{"type":29,"tag":106,"props":4850,"children":4852},{"id":4851},"condition-4-la-durée-et-le-rythme",[4853],{"type":35,"value":4854},"Condition 4 : La durée et le rythme",{"type":29,"tag":37,"props":4856,"children":4857},{},[4858],{"type":35,"value":4859},"Sessions recommandées : 90 à 120 minutes maximum par bloc, avec une pause de 15 minutes. Maximum 4 heures de pair programming par jour pour une personne. Au-delà, la qualité baisse et la fatigue s'accumule.",{"type":29,"tag":66,"props":4861,"children":4862},{},[],{"type":29,"tag":70,"props":4864,"children":4866},{"id":4865},"les-3-formats",[4867],{"type":35,"value":4868},"Les 3 formats",{"type":29,"tag":37,"props":4870,"children":4871},{},[4872,4877],{"type":29,"tag":55,"props":4873,"children":4874},{},[4875],{"type":35,"value":4876},"Driver/Navigator (classique)",{"type":35,"value":4878}," : un développeur code, l'autre navigue. Rotation toutes les 25-30 minutes. Format le plus connu, le plus polyvalent.",{"type":29,"tag":37,"props":4880,"children":4881},{},[4882,4887],{"type":29,"tag":55,"props":4883,"children":4884},{},[4885],{"type":35,"value":4886},"Ping-Pong (TDD)",{"type":35,"value":4888}," : développeur A écrit un test qui échoue, développeur B écrit le code minimum pour le faire passer, développeur A écrit le prochain test. Particulièrement efficace pour ancrer le TDD dans les habitudes de l'équipe, et pour rendre le TDD moins aride pour les développeurs qui résistent à l'écriture de tests.",{"type":29,"tag":37,"props":4890,"children":4891},{},[4892,4897],{"type":29,"tag":55,"props":4893,"children":4894},{},[4895],{"type":35,"value":4896},"Mob programming (Ensemble)",{"type":35,"value":4898}," : l'équipe entière (3 à 6 personnes) travaille sur le même problème avec un seul clavier. Un driver, le reste navigue. Rotation toutes les 7-15 minutes. Très efficace pour les décisions d'architecture et l'onboarding accéléré, coûteux en temps d'équipe.",{"type":29,"tag":66,"props":4900,"children":4901},{},[],{"type":29,"tag":70,"props":4903,"children":4905},{"id":4904},"comment-lintroduire-progressivement-sans-résistance",[4906],{"type":35,"value":4907},"Comment l'introduire progressivement sans résistance",{"type":29,"tag":37,"props":4909,"children":4910},{},[4911,4916],{"type":29,"tag":55,"props":4912,"children":4913},{},[4914],{"type":35,"value":4915},"Semaine 1-2",{"type":35,"value":4917}," : proposition volontaire. \"Si quelqu'un veut essayer le pair programming sur sa prochaine story complexe, voilà comment ça fonctionne.\" Trouver 2 volontaires enthousiastes.",{"type":29,"tag":37,"props":4919,"children":4920},{},[4921,4926],{"type":29,"tag":55,"props":4922,"children":4923},{},[4924],{"type":35,"value":4925},"Semaine 3-4",{"type":35,"value":4927}," : débrief public. Partager les retours des premiers pairs en rétrospective. Ne pas idéaliser, partager les difficultés aussi.",{"type":29,"tag":37,"props":4929,"children":4930},{},[4931,4936,4938,4944],{"type":29,"tag":55,"props":4932,"children":4933},{},[4934],{"type":35,"value":4935},"Mois 2",{"type":35,"value":4937}," : intégrer dans la ",{"type":29,"tag":43,"props":4939,"children":4941},{"href":4940},"/fr/dette-technique/definition-of-done-qualite",[4942],{"type":35,"value":4943},"DoD",{"type":35,"value":4945}," pour les stories complexes (score > M en sizing). Pas pour toutes les stories.",{"type":29,"tag":37,"props":4947,"children":4948},{},[4949,4954,4956,4962],{"type":29,"tag":55,"props":4950,"children":4951},{},[4952],{"type":35,"value":4953},"Mois 3+",{"type":35,"value":4955}," : laisser l'équipe définir ses propres règles sur quand pairer. Les équipes qui ont le contrôle sur leur pratique l'adoptent plus durablement que celles qui la subissent. Le pair programming s'intègre naturellement dans les ",{"type":29,"tag":43,"props":4957,"children":4959},{"href":4958},"/fr/management/engineering-culture-rituels",[4960],{"type":35,"value":4961},"rituels de culture engineering",{"type":35,"value":332},{"type":29,"tag":66,"props":4964,"children":4965},{},[],{"type":29,"tag":70,"props":4967,"children":4969},{"id":4968},"faq-sur-le-pair-programming",[4970],{"type":35,"value":4971},"FAQ sur le pair programming",{"type":29,"tag":371,"props":4973,"children":4974},{},[4975,4980],{"type":29,"tag":375,"props":4976,"children":4977},{},[4978],{"type":35,"value":4979},"1. Le pair programming est-il compatible avec le télétravail ?",{"type":29,"tag":37,"props":4981,"children":4982},{},[4983],{"type":35,"value":4984},"Oui, avec les bons outils. VS Code Live Share, JetBrains Code With Me, et Tuple sont conçus pour le pair programming à distance. La qualité est légèrement inférieure à l'in-person (plus de latence dans la communication) mais tout à fait viable. La règle : pas de pair programming à distance sur des connexions \u003C 10 Mbps ou avec des outils de visioconférence trop lourds.",{"type":29,"tag":371,"props":4986,"children":4987},{},[4988,4993],{"type":29,"tag":375,"props":4989,"children":4990},{},[4991],{"type":35,"value":4992},"2. Comment gérer le pair programming avec des développeurs introvertis ?",{"type":29,"tag":37,"props":4994,"children":4995},{},[4996],{"type":35,"value":4997},"Le pair programming intense et continu est épuisant pour les introvertis. Solution : sessions de 90 minutes maximum, avec des blocs de travail solo entre les sessions. Le format ping-pong TDD fonctionne souvent mieux que le driver/navigator pour les introvertis : les rôles sont clairs, alternés, et le focus est sur le code, pas sur la conversation.",{"type":29,"tag":371,"props":4999,"children":5000},{},[5001,5006],{"type":29,"tag":375,"props":5002,"children":5003},{},[5004],{"type":35,"value":5005},"3. Faut-il mesurer le ROI du pair programming dans notre équipe ?",{"type":29,"tag":37,"props":5007,"children":5008},{},[5009],{"type":35,"value":5010},"Oui, et c'est simple. Mesurer sur 2 mois : le taux de bugs sur les stories développées en pair vs solo, et le cycle time des stories complexes. Si le taux de bugs baisse significativement (> 15%), le ROI est positif même avec un overhead de temps modéré. Sur l'équipe bancaire que j'ai mentionnée, la réduction du temps d'onboarding de 8 à 4 semaines représentait seule 20 000€ d'économie par recrue.",{"type":29,"tag":371,"props":5012,"children":5013},{},[5014,5019],{"type":29,"tag":375,"props":5015,"children":5016},{},[5017],{"type":35,"value":5018},"4. Le pair programming remplace-t-il la code review ?",{"type":29,"tag":37,"props":5020,"children":5021},{},[5022,5024,5029],{"type":35,"value":5023},"Non. Le pair programming réduit le besoin de review approfondie (le code a déjà eu un second regard) mais ne la remplace pas. Une ",{"type":29,"tag":43,"props":5025,"children":5026},{"href":2106},[5027],{"type":35,"value":5028},"code review",{"type":35,"value":5030}," asynchrone reste nécessaire pour : la cohérence avec les standards de l'équipe, les aspects de sécurité, et le regard externe d'un développeur non impliqué dans la session.",{"type":29,"tag":371,"props":5032,"children":5033},{},[5034,5039],{"type":29,"tag":375,"props":5035,"children":5036},{},[5037],{"type":35,"value":5038},"5. Comment justifier le pair programming au management qui voit \"deux développeurs sur un seul clavier\" ?",{"type":29,"tag":37,"props":5040,"children":5041},{},[5042],{"type":35,"value":5043},"Le même argument que pour les tests : le coût de corriger un bug en production est 10 à 100 fois le coût de le détecter pendant le développement. 15% de temps en plus pendant le développement pour 15% de défauts en moins, c'est un ROI positif sur la durée. Je propose un pilote de 6 semaines avec mesure des métriques de qualité avant/après : les chiffres parlent d'eux-mêmes.",{"type":29,"tag":66,"props":5045,"children":5046},{},[],{"type":29,"tag":166,"props":5048,"children":5049},{"cta":442,"href":443,"title":444,"type":445},[5050],{"type":29,"tag":37,"props":5051,"children":5052},{},[5053],{"type":35,"value":5054},"L'assessment évalue vos pratiques de collaboration et de qualité, incluant les revues de code et les pratiques de développement collaboratif. Score de maturité et plan d'action sur 90 jours.",{"type":29,"tag":66,"props":5056,"children":5057},{},[],{"type":29,"tag":37,"props":5059,"children":5060},{},[5061],{"type":29,"tag":55,"props":5062,"children":5063},{},[5064],{"type":35,"value":5065},"Vous voulez savoir où en est vraiment votre équipe ?",{"type":29,"tag":37,"props":5067,"children":5068},{},[5069],{"type":35,"value":5070},"Téléchargez le template d'audit Engineering Health Report — un outil structuré pour diagnostiquer la qualité de votre code, votre couverture de tests et votre niveau de dette technique en moins d'une heure.",{"type":29,"tag":37,"props":5072,"children":5073},{},[5074,5076],{"type":35,"value":5075},"→ ",{"type":29,"tag":55,"props":5077,"children":5078},{},[5079],{"type":35,"value":5080},"Téléchargez le template d'audit",{"title":8,"searchDepth":453,"depth":453,"links":5082},[5083,5084,5085,5091,5092,5093],{"id":4605,"depth":453,"text":4608},{"id":4667,"depth":453,"text":4670},{"id":4733,"depth":453,"text":4736,"children":5086},[5087,5088,5089,5090],{"id":4739,"depth":459,"text":4742},{"id":4796,"depth":459,"text":4799},{"id":4812,"depth":459,"text":4815},{"id":4851,"depth":459,"text":4854},{"id":4865,"depth":453,"text":4868},{"id":4904,"depth":453,"text":4907},{"id":4968,"depth":453,"text":4971},"content:fr:dette-technique:pair-programming-roi-conditions.md","fr/dette-technique/pair-programming-roi-conditions.md","fr/dette-technique/pair-programming-roi-conditions",{"_path":5098,"_dir":474,"_draft":7,"_partial":7,"_locale":8,"title":5099,"description":5100,"id":5101,"date":5102,"listed":13,"nocomments":7,"hidden":7,"categories":5103,"tags":5104,"--cover":5109,"readingTime":5110,"body":5114,"_type":466,"_id":9917,"_source":468,"_file":9918,"_stem":9919,"_extension":471},"/fr/architecture-craft/dependency-inversion-pratique","Dependency Inversion Principle : 3 exemples concrets","Le DIP est le principe SOLID le plus mal compris. Pas un pattern de conception — une règle sur la direction des dépendances. Trois implémentations dans trois langages.",30,"2026-03-13",[474],[5105,5106,5107,5108],"SOLID","Dependency Inversion","Architecture","Clean Code","covers/articles/dependency-inversion-principe.jpg",{"text":21,"minutes":5111,"time":5112,"words":5113},7.155,429300,1431,{"type":26,"children":5115,"toc":9908},[5116,5121,5126,5131,5136,5139,5145,5158,5163,5534,5542,5588,5591,5597,5641,5649,5654,5657,5663,6736,6744,7237,7246,7249,7255,8746,8756,8759,8765,9690,9708,9711,9717,9725,9743,9751,9769,9787,9790,9796,9809,9822,9835,9856,9893,9896,9904],{"type":29,"tag":30,"props":5117,"children":5119},{"id":5118},"dependency-inversion-principle-3-exemples-concrets",[5120],{"type":35,"value":5099},{"type":29,"tag":37,"props":5122,"children":5123},{},[5124],{"type":35,"value":5125},"Chez un client dans le secteur du retail en ligne que j'accompagnais (20 développeurs, 8 services backend), la suite de tests prenait 18 minutes à s'exécuter. Pas parce que les tests étaient lents. Parce que chaque test unitaire démarrait une vraie base de données PostgreSQL, un vrai serveur Redis, et appelait le vrai Sendgrid.",{"type":29,"tag":37,"props":5127,"children":5128},{},[5129],{"type":35,"value":5130},"Ce n'était pas un problème de tests. C'était un problème d'architecture : les modules métier dépendaient directement des implémentations concrètes d'infrastructure.",{"type":29,"tag":37,"props":5132,"children":5133},{},[5134],{"type":35,"value":5135},"Après avoir introduit le Dependency Inversion Principle sur les 8 services les plus critiques, la suite de tests est passée à 3 minutes. La couverture de tests a augmenté de 35% à 72% en 3 mois. Pas parce que les développeurs avaient soudain envie d'écrire des tests, mais parce que les tests étaient devenus faciles à écrire.",{"type":29,"tag":66,"props":5137,"children":5138},{},[],{"type":29,"tag":70,"props":5140,"children":5142},{"id":5141},"le-problème-la-dépendance-directe",[5143],{"type":35,"value":5144},"Le problème : la dépendance directe",{"type":29,"tag":37,"props":5146,"children":5147},{},[5148,5150,5156],{"type":35,"value":5149},"Robert C. Martin (Uncle Bob) a formulé le DIP en 1996 dans ses travaux sur les principes SOLID : \"Les modules de haut niveau ne doivent pas dépendre des modules de bas niveau. Les deux doivent dépendre d'abstractions.\" C'est la règle de dépendance au cœur de la ",{"type":29,"tag":43,"props":5151,"children":5153},{"href":5152},"/fr/architecture-craft/clean-architecture-3-regles",[5154],{"type":35,"value":5155},"Clean Architecture",{"type":35,"value":5157}," : les flèches de dépendance doivent toujours pointer vers l'intérieur, vers le domaine métier.",{"type":29,"tag":37,"props":5159,"children":5160},{},[5161],{"type":35,"value":5162},"En pratique, la quasi-totalité des codebases sans discipline architecturale viole ce principe :",{"type":29,"tag":640,"props":5164,"children":5166},{"code":5165,"language":2192,"meta":8,"className":2190,"style":8},"# Violation du DIP — le module de haut niveau dépend du module de bas niveau\n\nclass OrderService:\n    def __init__(self):\n        self.db = PostgreSQLDatabase(host=\"localhost\", port=5432)  # dépendance directe\n        self.email = SendgridEmailClient(api_key=\"...\")              # dépendance directe\n\n    def create_order(self, order_data):\n        order_id = self.db.save(order_data)\n        self.email.send_confirmation(order_data[\"email\"], order_id)\n        return order_id\n",[5167],{"type":29,"tag":554,"props":5168,"children":5169},{"__ignoreMap":8},[5170,5178,5185,5205,5234,5309,5361,5368,5404,5454,5520],{"type":29,"tag":890,"props":5171,"children":5172},{"class":892,"line":893},[5173],{"type":29,"tag":890,"props":5174,"children":5175},{"style":897},[5176],{"type":35,"value":5177},"# Violation du DIP — le module de haut niveau dépend du module de bas niveau\n",{"type":29,"tag":890,"props":5179,"children":5180},{"class":892,"line":453},[5181],{"type":29,"tag":890,"props":5182,"children":5183},{"emptyLinePlaceholder":13},[5184],{"type":35,"value":963},{"type":29,"tag":890,"props":5186,"children":5187},{"class":892,"line":459},[5188,5193,5199],{"type":29,"tag":890,"props":5189,"children":5190},{"style":906},[5191],{"type":35,"value":5192},"class",{"type":29,"tag":890,"props":5194,"children":5196},{"style":5195},"--shiki-default:#E5C890;--shiki-default-font-style:italic;--shiki-dark:#B392F0;--shiki-dark-font-style:inherit",[5197],{"type":35,"value":5198}," OrderService",{"type":29,"tag":890,"props":5200,"children":5202},{"style":5201},"--shiki-default:#949CBB;--shiki-dark:#E1E4E8",[5203],{"type":35,"value":5204},":\n",{"type":29,"tag":890,"props":5206,"children":5207},{"class":892,"line":957},[5208,5213,5219,5223,5229],{"type":29,"tag":890,"props":5209,"children":5210},{"style":906},[5211],{"type":35,"value":5212},"    def",{"type":29,"tag":890,"props":5214,"children":5216},{"style":5215},"--shiki-default:#99D1DB;--shiki-default-font-style:italic;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit",[5217],{"type":35,"value":5218}," __init__",{"type":29,"tag":890,"props":5220,"children":5221},{"style":5201},[5222],{"type":35,"value":3070},{"type":29,"tag":890,"props":5224,"children":5226},{"style":5225},"--shiki-default:#E78284;--shiki-default-font-style:italic;--shiki-dark:#E1E4E8;--shiki-dark-font-style:inherit",[5227],{"type":35,"value":5228},"self",{"type":29,"tag":890,"props":5230,"children":5231},{"style":5201},[5232],{"type":35,"value":5233},"):\n",{"type":29,"tag":890,"props":5235,"children":5236},{"class":892,"line":966},[5237,5243,5247,5252,5256,5262,5266,5272,5276,5281,5285,5290,5294,5300,5304],{"type":29,"tag":890,"props":5238,"children":5240},{"style":5239},"--shiki-default:#E78284;--shiki-default-font-style:italic;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit",[5241],{"type":35,"value":5242},"        self",{"type":29,"tag":890,"props":5244,"children":5245},{"style":5201},[5246],{"type":35,"value":332},{"type":29,"tag":890,"props":5248,"children":5249},{"style":912},[5250],{"type":35,"value":5251},"db ",{"type":29,"tag":890,"props":5253,"children":5254},{"style":936},[5255],{"type":35,"value":2217},{"type":29,"tag":890,"props":5257,"children":5259},{"style":5258},"--shiki-default:#8CAAEE;--shiki-dark:#E1E4E8",[5260],{"type":35,"value":5261}," PostgreSQLDatabase",{"type":29,"tag":890,"props":5263,"children":5264},{"style":5201},[5265],{"type":35,"value":3070},{"type":29,"tag":890,"props":5267,"children":5269},{"style":5268},"--shiki-default:#EA999C;--shiki-default-font-style:italic;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit",[5270],{"type":35,"value":5271},"host",{"type":29,"tag":890,"props":5273,"children":5274},{"style":936},[5275],{"type":35,"value":2217},{"type":29,"tag":890,"props":5277,"children":5278},{"style":2226},[5279],{"type":35,"value":5280},"\"localhost\"",{"type":29,"tag":890,"props":5282,"children":5283},{"style":5201},[5284],{"type":35,"value":3653},{"type":29,"tag":890,"props":5286,"children":5287},{"style":5268},[5288],{"type":35,"value":5289}," port",{"type":29,"tag":890,"props":5291,"children":5292},{"style":936},[5293],{"type":35,"value":2217},{"type":29,"tag":890,"props":5295,"children":5297},{"style":5296},"--shiki-default:#EF9F76;--shiki-dark:#79B8FF",[5298],{"type":35,"value":5299},"5432",{"type":29,"tag":890,"props":5301,"children":5302},{"style":5201},[5303],{"type":35,"value":2871},{"type":29,"tag":890,"props":5305,"children":5306},{"style":897},[5307],{"type":35,"value":5308},"  # dépendance directe\n",{"type":29,"tag":890,"props":5310,"children":5311},{"class":892,"line":975},[5312,5316,5320,5325,5329,5334,5338,5343,5347,5352,5356],{"type":29,"tag":890,"props":5313,"children":5314},{"style":5239},[5315],{"type":35,"value":5242},{"type":29,"tag":890,"props":5317,"children":5318},{"style":5201},[5319],{"type":35,"value":332},{"type":29,"tag":890,"props":5321,"children":5322},{"style":912},[5323],{"type":35,"value":5324},"email ",{"type":29,"tag":890,"props":5326,"children":5327},{"style":936},[5328],{"type":35,"value":2217},{"type":29,"tag":890,"props":5330,"children":5331},{"style":5258},[5332],{"type":35,"value":5333}," SendgridEmailClient",{"type":29,"tag":890,"props":5335,"children":5336},{"style":5201},[5337],{"type":35,"value":3070},{"type":29,"tag":890,"props":5339,"children":5340},{"style":5268},[5341],{"type":35,"value":5342},"api_key",{"type":29,"tag":890,"props":5344,"children":5345},{"style":936},[5346],{"type":35,"value":2217},{"type":29,"tag":890,"props":5348,"children":5349},{"style":2226},[5350],{"type":35,"value":5351},"\"...\"",{"type":29,"tag":890,"props":5353,"children":5354},{"style":5201},[5355],{"type":35,"value":2871},{"type":29,"tag":890,"props":5357,"children":5358},{"style":897},[5359],{"type":35,"value":5360},"              # dépendance directe\n",{"type":29,"tag":890,"props":5362,"children":5363},{"class":892,"line":996},[5364],{"type":29,"tag":890,"props":5365,"children":5366},{"emptyLinePlaceholder":13},[5367],{"type":35,"value":963},{"type":29,"tag":890,"props":5369,"children":5371},{"class":892,"line":5370},8,[5372,5376,5382,5386,5390,5394,5400],{"type":29,"tag":890,"props":5373,"children":5374},{"style":906},[5375],{"type":35,"value":5212},{"type":29,"tag":890,"props":5377,"children":5379},{"style":5378},"--shiki-default:#8CAAEE;--shiki-default-font-style:italic;--shiki-dark:#B392F0;--shiki-dark-font-style:inherit",[5380],{"type":35,"value":5381}," create_order",{"type":29,"tag":890,"props":5383,"children":5384},{"style":5201},[5385],{"type":35,"value":3070},{"type":29,"tag":890,"props":5387,"children":5388},{"style":5225},[5389],{"type":35,"value":5228},{"type":29,"tag":890,"props":5391,"children":5392},{"style":5201},[5393],{"type":35,"value":3653},{"type":29,"tag":890,"props":5395,"children":5397},{"style":5396},"--shiki-default:#EA999C;--shiki-default-font-style:italic;--shiki-dark:#E1E4E8;--shiki-dark-font-style:inherit",[5398],{"type":35,"value":5399}," order_data",{"type":29,"tag":890,"props":5401,"children":5402},{"style":5201},[5403],{"type":35,"value":5233},{"type":29,"tag":890,"props":5405,"children":5407},{"class":892,"line":5406},9,[5408,5413,5417,5422,5426,5431,5435,5440,5444,5449],{"type":29,"tag":890,"props":5409,"children":5410},{"style":912},[5411],{"type":35,"value":5412},"        order_id ",{"type":29,"tag":890,"props":5414,"children":5415},{"style":936},[5416],{"type":35,"value":2217},{"type":29,"tag":890,"props":5418,"children":5419},{"style":5239},[5420],{"type":35,"value":5421}," self",{"type":29,"tag":890,"props":5423,"children":5424},{"style":5201},[5425],{"type":35,"value":332},{"type":29,"tag":890,"props":5427,"children":5428},{"style":912},[5429],{"type":35,"value":5430},"db",{"type":29,"tag":890,"props":5432,"children":5433},{"style":5201},[5434],{"type":35,"value":332},{"type":29,"tag":890,"props":5436,"children":5437},{"style":5258},[5438],{"type":35,"value":5439},"save",{"type":29,"tag":890,"props":5441,"children":5442},{"style":5201},[5443],{"type":35,"value":3070},{"type":29,"tag":890,"props":5445,"children":5446},{"style":912},[5447],{"type":35,"value":5448},"order_data",{"type":29,"tag":890,"props":5450,"children":5451},{"style":5201},[5452],{"type":35,"value":5453},")\n",{"type":29,"tag":890,"props":5455,"children":5457},{"class":892,"line":5456},10,[5458,5462,5466,5470,5474,5479,5483,5487,5492,5497,5502,5506,5511,5516],{"type":29,"tag":890,"props":5459,"children":5460},{"style":5239},[5461],{"type":35,"value":5242},{"type":29,"tag":890,"props":5463,"children":5464},{"style":5201},[5465],{"type":35,"value":332},{"type":29,"tag":890,"props":5467,"children":5468},{"style":912},[5469],{"type":35,"value":2240},{"type":29,"tag":890,"props":5471,"children":5472},{"style":5201},[5473],{"type":35,"value":332},{"type":29,"tag":890,"props":5475,"children":5476},{"style":5258},[5477],{"type":35,"value":5478},"send_confirmation",{"type":29,"tag":890,"props":5480,"children":5481},{"style":5201},[5482],{"type":35,"value":3070},{"type":29,"tag":890,"props":5484,"children":5485},{"style":5396},[5486],{"type":35,"value":5448},{"type":29,"tag":890,"props":5488,"children":5489},{"style":5201},[5490],{"type":35,"value":5491},"[",{"type":29,"tag":890,"props":5493,"children":5494},{"style":2226},[5495],{"type":35,"value":5496},"\"",{"type":29,"tag":890,"props":5498,"children":5500},{"style":5499},"--shiki-default:#A6D189;--shiki-default-font-style:italic;--shiki-dark:#9ECBFF;--shiki-dark-font-style:inherit",[5501],{"type":35,"value":2240},{"type":29,"tag":890,"props":5503,"children":5504},{"style":2226},[5505],{"type":35,"value":5496},{"type":29,"tag":890,"props":5507,"children":5508},{"style":5201},[5509],{"type":35,"value":5510},"],",{"type":29,"tag":890,"props":5512,"children":5513},{"style":912},[5514],{"type":35,"value":5515}," order_id",{"type":29,"tag":890,"props":5517,"children":5518},{"style":5201},[5519],{"type":35,"value":5453},{"type":29,"tag":890,"props":5521,"children":5523},{"class":892,"line":5522},11,[5524,5529],{"type":29,"tag":890,"props":5525,"children":5526},{"style":906},[5527],{"type":35,"value":5528},"        return",{"type":29,"tag":890,"props":5530,"children":5531},{"style":912},[5532],{"type":35,"value":5533}," order_id\n",{"type":29,"tag":37,"props":5535,"children":5536},{},[5537],{"type":29,"tag":55,"props":5538,"children":5539},{},[5540],{"type":35,"value":5541},"Ce que ça coûte concrètement :",{"type":29,"tag":1069,"props":5543,"children":5544},{},[5545,5558,5568,5578],{"type":29,"tag":1073,"props":5546,"children":5547},{},[5548,5550,5556],{"type":35,"value":5549},"Impossible de tester ",{"type":29,"tag":554,"props":5551,"children":5553},{"className":5552},[],[5554],{"type":35,"value":5555},"OrderService",{"type":35,"value":5557}," sans une vraie base de données PostgreSQL et un compte Sendgrid",{"type":29,"tag":1073,"props":5559,"children":5560},{},[5561,5563],{"type":35,"value":5562},"Changer de base de données oblige à modifier ",{"type":29,"tag":554,"props":5564,"children":5566},{"className":5565},[],[5567],{"type":35,"value":5555},{"type":29,"tag":1073,"props":5569,"children":5570},{},[5571,5573],{"type":35,"value":5572},"Changer d'email provider oblige à modifier ",{"type":29,"tag":554,"props":5574,"children":5576},{"className":5575},[],[5577],{"type":35,"value":5555},{"type":29,"tag":1073,"props":5579,"children":5580},{},[5581,5586],{"type":29,"tag":554,"props":5582,"children":5584},{"className":5583},[],[5585],{"type":35,"value":5555},{"type":35,"value":5587}," connaît des détails d'implémentation (host, port, api_key) qui n'ont rien à voir avec la logique métier de commande",{"type":29,"tag":66,"props":5589,"children":5590},{},[],{"type":29,"tag":70,"props":5592,"children":5594},{"id":5593},"le-principe-inverser-la-direction-des-dépendances",[5595],{"type":35,"value":5596},"Le principe : inverser la direction des dépendances",{"type":29,"tag":37,"props":5598,"children":5599},{},[5600,5602,5607,5609,5615,5617,5623,5625,5631,5633,5639],{"type":35,"value":5601},"La solution DIP : ",{"type":29,"tag":554,"props":5603,"children":5605},{"className":5604},[],[5606],{"type":35,"value":5555},{"type":35,"value":5608}," ne dépend pas de ",{"type":29,"tag":554,"props":5610,"children":5612},{"className":5611},[],[5613],{"type":35,"value":5614},"PostgreSQLDatabase",{"type":35,"value":5616}," ni de ",{"type":29,"tag":554,"props":5618,"children":5620},{"className":5619},[],[5621],{"type":35,"value":5622},"SendgridEmailClient",{"type":35,"value":5624},". Il dépend d'abstractions (",{"type":29,"tag":554,"props":5626,"children":5628},{"className":5627},[],[5629],{"type":35,"value":5630},"OrderRepository",{"type":35,"value":5632},", ",{"type":29,"tag":554,"props":5634,"children":5636},{"className":5635},[],[5637],{"type":35,"value":5638},"EmailNotifier",{"type":35,"value":5640},") que les implémentations concrètes respectent.",{"type":29,"tag":640,"props":5642,"children":5644},{"code":5643},"Sans DIP :\nOrderService → PostgreSQLDatabase\nOrderService → SendgridEmailClient\n\nAvec DIP :\nOrderService → OrderRepository (abstraction) ← PostgreSQLOrderRepository (implémentation)\nOrderService → EmailNotifier (abstraction)   ← SendgridEmailNotifier (implémentation)\n",[5645],{"type":29,"tag":554,"props":5646,"children":5647},{"__ignoreMap":8},[5648],{"type":35,"value":5643},{"type":29,"tag":37,"props":5650,"children":5651},{},[5652],{"type":35,"value":5653},"La flèche s'inverse : l'implémentation concrète dépend de l'abstraction, pas l'inverse.",{"type":29,"tag":66,"props":5655,"children":5656},{},[],{"type":29,"tag":70,"props":5658,"children":5660},{"id":5659},"exemple-1-python-injection-par-constructeur",[5661],{"type":35,"value":5662},"Exemple 1 : Python, injection par constructeur",{"type":29,"tag":640,"props":5664,"children":5666},{"code":5665,"language":2192,"meta":8,"className":2190,"style":8},"from abc import ABC, abstractmethod\n\nclass OrderRepository(ABC):\n    @abstractmethod\n    def save(self, order_data: dict) -> str:\n        pass\n\nclass EmailNotifier(ABC):\n    @abstractmethod\n    def send_confirmation(self, email: str, order_id: str) -> None:\n        pass\n\n# Le module de haut niveau — dépend uniquement des abstractions\nclass OrderService:\n    def __init__(self, repository: OrderRepository, notifier: EmailNotifier):\n        self.repository = repository\n        self.notifier = notifier\n\n    def create_order(self, order_data: dict) -> str:\n        order_id = self.repository.save(order_data)\n        self.notifier.send_confirmation(order_data[\"email\"], order_id)\n        return order_id\n\n# Les implémentations concrètes\nclass PostgreSQLOrderRepository(OrderRepository):\n    def save(self, order_data: dict) -> str:\n        return self.db.execute(\"INSERT INTO orders ...\", order_data)\n\nclass SendgridEmailNotifier(EmailNotifier):\n    def send_confirmation(self, email: str, order_id: str) -> None:\n        self.client.send(to=email, template=\"order_confirmation\", data={\"order_id\": order_id})\n\n# Composition à la racine de l'application\ndef create_order_service():\n    repository = PostgreSQLOrderRepository(db)\n    notifier = SendgridEmailNotifier(api_key=os.getenv(\"SENDGRID_KEY\"))\n    return OrderService(repository, notifier)\n",[5667],{"type":29,"tag":554,"props":5668,"children":5669},{"__ignoreMap":8},[5670,5703,5710,5735,5744,5801,5809,5816,5840,5847,5918,5925,5933,5942,5958,6017,6043,6069,6077,6129,6174,6235,6247,6255,6264,6289,6341,6391,6399,6424,6491,6586,6593,6602,6620,6648,6704],{"type":29,"tag":890,"props":5671,"children":5672},{"class":892,"line":893},[5673,5678,5683,5688,5694,5698],{"type":29,"tag":890,"props":5674,"children":5675},{"style":906},[5676],{"type":35,"value":5677},"from",{"type":29,"tag":890,"props":5679,"children":5680},{"style":912},[5681],{"type":35,"value":5682}," abc ",{"type":29,"tag":890,"props":5684,"children":5685},{"style":906},[5686],{"type":35,"value":5687},"import",{"type":29,"tag":890,"props":5689,"children":5691},{"style":5690},"--shiki-default:#C6D0F5;--shiki-dark:#79B8FF",[5692],{"type":35,"value":5693}," ABC",{"type":29,"tag":890,"props":5695,"children":5696},{"style":5201},[5697],{"type":35,"value":3653},{"type":29,"tag":890,"props":5699,"children":5700},{"style":912},[5701],{"type":35,"value":5702}," abstractmethod\n",{"type":29,"tag":890,"props":5704,"children":5705},{"class":892,"line":453},[5706],{"type":29,"tag":890,"props":5707,"children":5708},{"emptyLinePlaceholder":13},[5709],{"type":35,"value":963},{"type":29,"tag":890,"props":5711,"children":5712},{"class":892,"line":459},[5713,5717,5722,5726,5731],{"type":29,"tag":890,"props":5714,"children":5715},{"style":906},[5716],{"type":35,"value":5192},{"type":29,"tag":890,"props":5718,"children":5719},{"style":5195},[5720],{"type":35,"value":5721}," OrderRepository",{"type":29,"tag":890,"props":5723,"children":5724},{"style":5201},[5725],{"type":35,"value":3070},{"type":29,"tag":890,"props":5727,"children":5728},{"style":5690},[5729],{"type":35,"value":5730},"ABC",{"type":29,"tag":890,"props":5732,"children":5733},{"style":5201},[5734],{"type":35,"value":5233},{"type":29,"tag":890,"props":5736,"children":5737},{"class":892,"line":957},[5738],{"type":29,"tag":890,"props":5739,"children":5741},{"style":5740},"--shiki-default:#EF9F76;--shiki-default-font-style:italic;--shiki-dark:#B392F0;--shiki-dark-font-style:inherit",[5742],{"type":35,"value":5743},"    @abstractmethod\n",{"type":29,"tag":890,"props":5745,"children":5746},{"class":892,"line":966},[5747,5751,5756,5760,5764,5768,5772,5777,5783,5787,5792,5797],{"type":29,"tag":890,"props":5748,"children":5749},{"style":906},[5750],{"type":35,"value":5212},{"type":29,"tag":890,"props":5752,"children":5753},{"style":5378},[5754],{"type":35,"value":5755}," save",{"type":29,"tag":890,"props":5757,"children":5758},{"style":5201},[5759],{"type":35,"value":3070},{"type":29,"tag":890,"props":5761,"children":5762},{"style":5225},[5763],{"type":35,"value":5228},{"type":29,"tag":890,"props":5765,"children":5766},{"style":5201},[5767],{"type":35,"value":3653},{"type":29,"tag":890,"props":5769,"children":5770},{"style":5396},[5771],{"type":35,"value":5399},{"type":29,"tag":890,"props":5773,"children":5774},{"style":5201},[5775],{"type":35,"value":5776},":",{"type":29,"tag":890,"props":5778,"children":5780},{"style":5779},"--shiki-default:#EF9F76;--shiki-default-font-style:italic;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit",[5781],{"type":35,"value":5782}," dict",{"type":29,"tag":890,"props":5784,"children":5785},{"style":5201},[5786],{"type":35,"value":2871},{"type":29,"tag":890,"props":5788,"children":5789},{"style":5201},[5790],{"type":35,"value":5791}," ->",{"type":29,"tag":890,"props":5793,"children":5794},{"style":5779},[5795],{"type":35,"value":5796}," str",{"type":29,"tag":890,"props":5798,"children":5799},{"style":5201},[5800],{"type":35,"value":5204},{"type":29,"tag":890,"props":5802,"children":5803},{"class":892,"line":975},[5804],{"type":29,"tag":890,"props":5805,"children":5806},{"style":906},[5807],{"type":35,"value":5808},"        pass\n",{"type":29,"tag":890,"props":5810,"children":5811},{"class":892,"line":996},[5812],{"type":29,"tag":890,"props":5813,"children":5814},{"emptyLinePlaceholder":13},[5815],{"type":35,"value":963},{"type":29,"tag":890,"props":5817,"children":5818},{"class":892,"line":5370},[5819,5823,5828,5832,5836],{"type":29,"tag":890,"props":5820,"children":5821},{"style":906},[5822],{"type":35,"value":5192},{"type":29,"tag":890,"props":5824,"children":5825},{"style":5195},[5826],{"type":35,"value":5827}," EmailNotifier",{"type":29,"tag":890,"props":5829,"children":5830},{"style":5201},[5831],{"type":35,"value":3070},{"type":29,"tag":890,"props":5833,"children":5834},{"style":5690},[5835],{"type":35,"value":5730},{"type":29,"tag":890,"props":5837,"children":5838},{"style":5201},[5839],{"type":35,"value":5233},{"type":29,"tag":890,"props":5841,"children":5842},{"class":892,"line":5406},[5843],{"type":29,"tag":890,"props":5844,"children":5845},{"style":5740},[5846],{"type":35,"value":5743},{"type":29,"tag":890,"props":5848,"children":5849},{"class":892,"line":5456},[5850,5854,5859,5863,5867,5871,5876,5880,5884,5888,5892,5896,5900,5904,5908,5914],{"type":29,"tag":890,"props":5851,"children":5852},{"style":906},[5853],{"type":35,"value":5212},{"type":29,"tag":890,"props":5855,"children":5856},{"style":5378},[5857],{"type":35,"value":5858}," send_confirmation",{"type":29,"tag":890,"props":5860,"children":5861},{"style":5201},[5862],{"type":35,"value":3070},{"type":29,"tag":890,"props":5864,"children":5865},{"style":5225},[5866],{"type":35,"value":5228},{"type":29,"tag":890,"props":5868,"children":5869},{"style":5201},[5870],{"type":35,"value":3653},{"type":29,"tag":890,"props":5872,"children":5873},{"style":5396},[5874],{"type":35,"value":5875}," email",{"type":29,"tag":890,"props":5877,"children":5878},{"style":5201},[5879],{"type":35,"value":5776},{"type":29,"tag":890,"props":5881,"children":5882},{"style":5779},[5883],{"type":35,"value":5796},{"type":29,"tag":890,"props":5885,"children":5886},{"style":5201},[5887],{"type":35,"value":3653},{"type":29,"tag":890,"props":5889,"children":5890},{"style":5396},[5891],{"type":35,"value":5515},{"type":29,"tag":890,"props":5893,"children":5894},{"style":5201},[5895],{"type":35,"value":5776},{"type":29,"tag":890,"props":5897,"children":5898},{"style":5779},[5899],{"type":35,"value":5796},{"type":29,"tag":890,"props":5901,"children":5902},{"style":5201},[5903],{"type":35,"value":2871},{"type":29,"tag":890,"props":5905,"children":5906},{"style":5201},[5907],{"type":35,"value":5791},{"type":29,"tag":890,"props":5909,"children":5911},{"style":5910},"--shiki-default:#CA9EE6;--shiki-dark:#79B8FF",[5912],{"type":35,"value":5913}," None",{"type":29,"tag":890,"props":5915,"children":5916},{"style":5201},[5917],{"type":35,"value":5204},{"type":29,"tag":890,"props":5919,"children":5920},{"class":892,"line":5522},[5921],{"type":29,"tag":890,"props":5922,"children":5923},{"style":906},[5924],{"type":35,"value":5808},{"type":29,"tag":890,"props":5926,"children":5928},{"class":892,"line":5927},12,[5929],{"type":29,"tag":890,"props":5930,"children":5931},{"emptyLinePlaceholder":13},[5932],{"type":35,"value":963},{"type":29,"tag":890,"props":5934,"children":5936},{"class":892,"line":5935},13,[5937],{"type":29,"tag":890,"props":5938,"children":5939},{"style":897},[5940],{"type":35,"value":5941},"# Le module de haut niveau — dépend uniquement des abstractions\n",{"type":29,"tag":890,"props":5943,"children":5945},{"class":892,"line":5944},14,[5946,5950,5954],{"type":29,"tag":890,"props":5947,"children":5948},{"style":906},[5949],{"type":35,"value":5192},{"type":29,"tag":890,"props":5951,"children":5952},{"style":5195},[5953],{"type":35,"value":5198},{"type":29,"tag":890,"props":5955,"children":5956},{"style":5201},[5957],{"type":35,"value":5204},{"type":29,"tag":890,"props":5959,"children":5961},{"class":892,"line":5960},15,[5962,5966,5970,5974,5978,5982,5987,5991,5996,6000,6005,6009,6013],{"type":29,"tag":890,"props":5963,"children":5964},{"style":906},[5965],{"type":35,"value":5212},{"type":29,"tag":890,"props":5967,"children":5968},{"style":5215},[5969],{"type":35,"value":5218},{"type":29,"tag":890,"props":5971,"children":5972},{"style":5201},[5973],{"type":35,"value":3070},{"type":29,"tag":890,"props":5975,"children":5976},{"style":5225},[5977],{"type":35,"value":5228},{"type":29,"tag":890,"props":5979,"children":5980},{"style":5201},[5981],{"type":35,"value":3653},{"type":29,"tag":890,"props":5983,"children":5984},{"style":5396},[5985],{"type":35,"value":5986}," repository",{"type":29,"tag":890,"props":5988,"children":5989},{"style":5201},[5990],{"type":35,"value":5776},{"type":29,"tag":890,"props":5992,"children":5994},{"style":5993},"--shiki-default:#EA999C;--shiki-dark:#E1E4E8",[5995],{"type":35,"value":5721},{"type":29,"tag":890,"props":5997,"children":5998},{"style":5201},[5999],{"type":35,"value":3653},{"type":29,"tag":890,"props":6001,"children":6002},{"style":5396},[6003],{"type":35,"value":6004}," notifier",{"type":29,"tag":890,"props":6006,"children":6007},{"style":5201},[6008],{"type":35,"value":5776},{"type":29,"tag":890,"props":6010,"children":6011},{"style":5993},[6012],{"type":35,"value":5827},{"type":29,"tag":890,"props":6014,"children":6015},{"style":5201},[6016],{"type":35,"value":5233},{"type":29,"tag":890,"props":6018,"children":6020},{"class":892,"line":6019},16,[6021,6025,6029,6034,6038],{"type":29,"tag":890,"props":6022,"children":6023},{"style":5239},[6024],{"type":35,"value":5242},{"type":29,"tag":890,"props":6026,"children":6027},{"style":5201},[6028],{"type":35,"value":332},{"type":29,"tag":890,"props":6030,"children":6031},{"style":912},[6032],{"type":35,"value":6033},"repository ",{"type":29,"tag":890,"props":6035,"children":6036},{"style":936},[6037],{"type":35,"value":2217},{"type":29,"tag":890,"props":6039,"children":6040},{"style":912},[6041],{"type":35,"value":6042}," repository\n",{"type":29,"tag":890,"props":6044,"children":6046},{"class":892,"line":6045},17,[6047,6051,6055,6060,6064],{"type":29,"tag":890,"props":6048,"children":6049},{"style":5239},[6050],{"type":35,"value":5242},{"type":29,"tag":890,"props":6052,"children":6053},{"style":5201},[6054],{"type":35,"value":332},{"type":29,"tag":890,"props":6056,"children":6057},{"style":912},[6058],{"type":35,"value":6059},"notifier ",{"type":29,"tag":890,"props":6061,"children":6062},{"style":936},[6063],{"type":35,"value":2217},{"type":29,"tag":890,"props":6065,"children":6066},{"style":912},[6067],{"type":35,"value":6068}," notifier\n",{"type":29,"tag":890,"props":6070,"children":6072},{"class":892,"line":6071},18,[6073],{"type":29,"tag":890,"props":6074,"children":6075},{"emptyLinePlaceholder":13},[6076],{"type":35,"value":963},{"type":29,"tag":890,"props":6078,"children":6080},{"class":892,"line":6079},19,[6081,6085,6089,6093,6097,6101,6105,6109,6113,6117,6121,6125],{"type":29,"tag":890,"props":6082,"children":6083},{"style":906},[6084],{"type":35,"value":5212},{"type":29,"tag":890,"props":6086,"children":6087},{"style":5378},[6088],{"type":35,"value":5381},{"type":29,"tag":890,"props":6090,"children":6091},{"style":5201},[6092],{"type":35,"value":3070},{"type":29,"tag":890,"props":6094,"children":6095},{"style":5225},[6096],{"type":35,"value":5228},{"type":29,"tag":890,"props":6098,"children":6099},{"style":5201},[6100],{"type":35,"value":3653},{"type":29,"tag":890,"props":6102,"children":6103},{"style":5396},[6104],{"type":35,"value":5399},{"type":29,"tag":890,"props":6106,"children":6107},{"style":5201},[6108],{"type":35,"value":5776},{"type":29,"tag":890,"props":6110,"children":6111},{"style":5779},[6112],{"type":35,"value":5782},{"type":29,"tag":890,"props":6114,"children":6115},{"style":5201},[6116],{"type":35,"value":2871},{"type":29,"tag":890,"props":6118,"children":6119},{"style":5201},[6120],{"type":35,"value":5791},{"type":29,"tag":890,"props":6122,"children":6123},{"style":5779},[6124],{"type":35,"value":5796},{"type":29,"tag":890,"props":6126,"children":6127},{"style":5201},[6128],{"type":35,"value":5204},{"type":29,"tag":890,"props":6130,"children":6132},{"class":892,"line":6131},20,[6133,6137,6141,6145,6149,6154,6158,6162,6166,6170],{"type":29,"tag":890,"props":6134,"children":6135},{"style":912},[6136],{"type":35,"value":5412},{"type":29,"tag":890,"props":6138,"children":6139},{"style":936},[6140],{"type":35,"value":2217},{"type":29,"tag":890,"props":6142,"children":6143},{"style":5239},[6144],{"type":35,"value":5421},{"type":29,"tag":890,"props":6146,"children":6147},{"style":5201},[6148],{"type":35,"value":332},{"type":29,"tag":890,"props":6150,"children":6151},{"style":912},[6152],{"type":35,"value":6153},"repository",{"type":29,"tag":890,"props":6155,"children":6156},{"style":5201},[6157],{"type":35,"value":332},{"type":29,"tag":890,"props":6159,"children":6160},{"style":5258},[6161],{"type":35,"value":5439},{"type":29,"tag":890,"props":6163,"children":6164},{"style":5201},[6165],{"type":35,"value":3070},{"type":29,"tag":890,"props":6167,"children":6168},{"style":912},[6169],{"type":35,"value":5448},{"type":29,"tag":890,"props":6171,"children":6172},{"style":5201},[6173],{"type":35,"value":5453},{"type":29,"tag":890,"props":6175,"children":6177},{"class":892,"line":6176},21,[6178,6182,6186,6191,6195,6199,6203,6207,6211,6215,6219,6223,6227,6231],{"type":29,"tag":890,"props":6179,"children":6180},{"style":5239},[6181],{"type":35,"value":5242},{"type":29,"tag":890,"props":6183,"children":6184},{"style":5201},[6185],{"type":35,"value":332},{"type":29,"tag":890,"props":6187,"children":6188},{"style":912},[6189],{"type":35,"value":6190},"notifier",{"type":29,"tag":890,"props":6192,"children":6193},{"style":5201},[6194],{"type":35,"value":332},{"type":29,"tag":890,"props":6196,"children":6197},{"style":5258},[6198],{"type":35,"value":5478},{"type":29,"tag":890,"props":6200,"children":6201},{"style":5201},[6202],{"type":35,"value":3070},{"type":29,"tag":890,"props":6204,"children":6205},{"style":5396},[6206],{"type":35,"value":5448},{"type":29,"tag":890,"props":6208,"children":6209},{"style":5201},[6210],{"type":35,"value":5491},{"type":29,"tag":890,"props":6212,"children":6213},{"style":2226},[6214],{"type":35,"value":5496},{"type":29,"tag":890,"props":6216,"children":6217},{"style":5499},[6218],{"type":35,"value":2240},{"type":29,"tag":890,"props":6220,"children":6221},{"style":2226},[6222],{"type":35,"value":5496},{"type":29,"tag":890,"props":6224,"children":6225},{"style":5201},[6226],{"type":35,"value":5510},{"type":29,"tag":890,"props":6228,"children":6229},{"style":912},[6230],{"type":35,"value":5515},{"type":29,"tag":890,"props":6232,"children":6233},{"style":5201},[6234],{"type":35,"value":5453},{"type":29,"tag":890,"props":6236,"children":6238},{"class":892,"line":6237},22,[6239,6243],{"type":29,"tag":890,"props":6240,"children":6241},{"style":906},[6242],{"type":35,"value":5528},{"type":29,"tag":890,"props":6244,"children":6245},{"style":912},[6246],{"type":35,"value":5533},{"type":29,"tag":890,"props":6248,"children":6250},{"class":892,"line":6249},23,[6251],{"type":29,"tag":890,"props":6252,"children":6253},{"emptyLinePlaceholder":13},[6254],{"type":35,"value":963},{"type":29,"tag":890,"props":6256,"children":6258},{"class":892,"line":6257},24,[6259],{"type":29,"tag":890,"props":6260,"children":6261},{"style":897},[6262],{"type":35,"value":6263},"# Les implémentations concrètes\n",{"type":29,"tag":890,"props":6265,"children":6267},{"class":892,"line":6266},25,[6268,6272,6277,6281,6285],{"type":29,"tag":890,"props":6269,"children":6270},{"style":906},[6271],{"type":35,"value":5192},{"type":29,"tag":890,"props":6273,"children":6274},{"style":5195},[6275],{"type":35,"value":6276}," PostgreSQLOrderRepository",{"type":29,"tag":890,"props":6278,"children":6279},{"style":5201},[6280],{"type":35,"value":3070},{"type":29,"tag":890,"props":6282,"children":6283},{"style":5195},[6284],{"type":35,"value":5630},{"type":29,"tag":890,"props":6286,"children":6287},{"style":5201},[6288],{"type":35,"value":5233},{"type":29,"tag":890,"props":6290,"children":6292},{"class":892,"line":6291},26,[6293,6297,6301,6305,6309,6313,6317,6321,6325,6329,6333,6337],{"type":29,"tag":890,"props":6294,"children":6295},{"style":906},[6296],{"type":35,"value":5212},{"type":29,"tag":890,"props":6298,"children":6299},{"style":5378},[6300],{"type":35,"value":5755},{"type":29,"tag":890,"props":6302,"children":6303},{"style":5201},[6304],{"type":35,"value":3070},{"type":29,"tag":890,"props":6306,"children":6307},{"style":5225},[6308],{"type":35,"value":5228},{"type":29,"tag":890,"props":6310,"children":6311},{"style":5201},[6312],{"type":35,"value":3653},{"type":29,"tag":890,"props":6314,"children":6315},{"style":5396},[6316],{"type":35,"value":5399},{"type":29,"tag":890,"props":6318,"children":6319},{"style":5201},[6320],{"type":35,"value":5776},{"type":29,"tag":890,"props":6322,"children":6323},{"style":5779},[6324],{"type":35,"value":5782},{"type":29,"tag":890,"props":6326,"children":6327},{"style":5201},[6328],{"type":35,"value":2871},{"type":29,"tag":890,"props":6330,"children":6331},{"style":5201},[6332],{"type":35,"value":5791},{"type":29,"tag":890,"props":6334,"children":6335},{"style":5779},[6336],{"type":35,"value":5796},{"type":29,"tag":890,"props":6338,"children":6339},{"style":5201},[6340],{"type":35,"value":5204},{"type":29,"tag":890,"props":6342,"children":6344},{"class":892,"line":6343},27,[6345,6349,6353,6357,6361,6365,6370,6374,6379,6383,6387],{"type":29,"tag":890,"props":6346,"children":6347},{"style":906},[6348],{"type":35,"value":5528},{"type":29,"tag":890,"props":6350,"children":6351},{"style":5239},[6352],{"type":35,"value":5421},{"type":29,"tag":890,"props":6354,"children":6355},{"style":5201},[6356],{"type":35,"value":332},{"type":29,"tag":890,"props":6358,"children":6359},{"style":912},[6360],{"type":35,"value":5430},{"type":29,"tag":890,"props":6362,"children":6363},{"style":5201},[6364],{"type":35,"value":332},{"type":29,"tag":890,"props":6366,"children":6367},{"style":5258},[6368],{"type":35,"value":6369},"execute",{"type":29,"tag":890,"props":6371,"children":6372},{"style":5201},[6373],{"type":35,"value":3070},{"type":29,"tag":890,"props":6375,"children":6376},{"style":2226},[6377],{"type":35,"value":6378},"\"INSERT INTO orders ...\"",{"type":29,"tag":890,"props":6380,"children":6381},{"style":5201},[6382],{"type":35,"value":3653},{"type":29,"tag":890,"props":6384,"children":6385},{"style":912},[6386],{"type":35,"value":5399},{"type":29,"tag":890,"props":6388,"children":6389},{"style":5201},[6390],{"type":35,"value":5453},{"type":29,"tag":890,"props":6392,"children":6394},{"class":892,"line":6393},28,[6395],{"type":29,"tag":890,"props":6396,"children":6397},{"emptyLinePlaceholder":13},[6398],{"type":35,"value":963},{"type":29,"tag":890,"props":6400,"children":6402},{"class":892,"line":6401},29,[6403,6407,6412,6416,6420],{"type":29,"tag":890,"props":6404,"children":6405},{"style":906},[6406],{"type":35,"value":5192},{"type":29,"tag":890,"props":6408,"children":6409},{"style":5195},[6410],{"type":35,"value":6411}," SendgridEmailNotifier",{"type":29,"tag":890,"props":6413,"children":6414},{"style":5201},[6415],{"type":35,"value":3070},{"type":29,"tag":890,"props":6417,"children":6418},{"style":5195},[6419],{"type":35,"value":5638},{"type":29,"tag":890,"props":6421,"children":6422},{"style":5201},[6423],{"type":35,"value":5233},{"type":29,"tag":890,"props":6425,"children":6426},{"class":892,"line":5101},[6427,6431,6435,6439,6443,6447,6451,6455,6459,6463,6467,6471,6475,6479,6483,6487],{"type":29,"tag":890,"props":6428,"children":6429},{"style":906},[6430],{"type":35,"value":5212},{"type":29,"tag":890,"props":6432,"children":6433},{"style":5378},[6434],{"type":35,"value":5858},{"type":29,"tag":890,"props":6436,"children":6437},{"style":5201},[6438],{"type":35,"value":3070},{"type":29,"tag":890,"props":6440,"children":6441},{"style":5225},[6442],{"type":35,"value":5228},{"type":29,"tag":890,"props":6444,"children":6445},{"style":5201},[6446],{"type":35,"value":3653},{"type":29,"tag":890,"props":6448,"children":6449},{"style":5396},[6450],{"type":35,"value":5875},{"type":29,"tag":890,"props":6452,"children":6453},{"style":5201},[6454],{"type":35,"value":5776},{"type":29,"tag":890,"props":6456,"children":6457},{"style":5779},[6458],{"type":35,"value":5796},{"type":29,"tag":890,"props":6460,"children":6461},{"style":5201},[6462],{"type":35,"value":3653},{"type":29,"tag":890,"props":6464,"children":6465},{"style":5396},[6466],{"type":35,"value":5515},{"type":29,"tag":890,"props":6468,"children":6469},{"style":5201},[6470],{"type":35,"value":5776},{"type":29,"tag":890,"props":6472,"children":6473},{"style":5779},[6474],{"type":35,"value":5796},{"type":29,"tag":890,"props":6476,"children":6477},{"style":5201},[6478],{"type":35,"value":2871},{"type":29,"tag":890,"props":6480,"children":6481},{"style":5201},[6482],{"type":35,"value":5791},{"type":29,"tag":890,"props":6484,"children":6485},{"style":5910},[6486],{"type":35,"value":5913},{"type":29,"tag":890,"props":6488,"children":6489},{"style":5201},[6490],{"type":35,"value":5204},{"type":29,"tag":890,"props":6492,"children":6493},{"class":892,"line":4563},[6494,6498,6502,6507,6511,6516,6520,6525,6529,6533,6537,6542,6546,6551,6555,6560,6564,6568,6573,6577,6581],{"type":29,"tag":890,"props":6495,"children":6496},{"style":5239},[6497],{"type":35,"value":5242},{"type":29,"tag":890,"props":6499,"children":6500},{"style":5201},[6501],{"type":35,"value":332},{"type":29,"tag":890,"props":6503,"children":6504},{"style":912},[6505],{"type":35,"value":6506},"client",{"type":29,"tag":890,"props":6508,"children":6509},{"style":5201},[6510],{"type":35,"value":332},{"type":29,"tag":890,"props":6512,"children":6513},{"style":5258},[6514],{"type":35,"value":6515},"send",{"type":29,"tag":890,"props":6517,"children":6518},{"style":5201},[6519],{"type":35,"value":3070},{"type":29,"tag":890,"props":6521,"children":6522},{"style":5268},[6523],{"type":35,"value":6524},"to",{"type":29,"tag":890,"props":6526,"children":6527},{"style":936},[6528],{"type":35,"value":2217},{"type":29,"tag":890,"props":6530,"children":6531},{"style":912},[6532],{"type":35,"value":2240},{"type":29,"tag":890,"props":6534,"children":6535},{"style":5201},[6536],{"type":35,"value":3653},{"type":29,"tag":890,"props":6538,"children":6539},{"style":5268},[6540],{"type":35,"value":6541}," template",{"type":29,"tag":890,"props":6543,"children":6544},{"style":936},[6545],{"type":35,"value":2217},{"type":29,"tag":890,"props":6547,"children":6548},{"style":2226},[6549],{"type":35,"value":6550},"\"order_confirmation\"",{"type":29,"tag":890,"props":6552,"children":6553},{"style":5201},[6554],{"type":35,"value":3653},{"type":29,"tag":890,"props":6556,"children":6557},{"style":5268},[6558],{"type":35,"value":6559}," data",{"type":29,"tag":890,"props":6561,"children":6562},{"style":936},[6563],{"type":35,"value":2217},{"type":29,"tag":890,"props":6565,"children":6566},{"style":5201},[6567],{"type":35,"value":2235},{"type":29,"tag":890,"props":6569,"children":6570},{"style":2226},[6571],{"type":35,"value":6572},"\"order_id\"",{"type":29,"tag":890,"props":6574,"children":6575},{"style":5201},[6576],{"type":35,"value":5776},{"type":29,"tag":890,"props":6578,"children":6579},{"style":912},[6580],{"type":35,"value":5515},{"type":29,"tag":890,"props":6582,"children":6583},{"style":5201},[6584],{"type":35,"value":6585},"})\n",{"type":29,"tag":890,"props":6587,"children":6588},{"class":892,"line":4099},[6589],{"type":29,"tag":890,"props":6590,"children":6591},{"emptyLinePlaceholder":13},[6592],{"type":35,"value":963},{"type":29,"tag":890,"props":6594,"children":6596},{"class":892,"line":6595},33,[6597],{"type":29,"tag":890,"props":6598,"children":6599},{"style":897},[6600],{"type":35,"value":6601},"# Composition à la racine de l'application\n",{"type":29,"tag":890,"props":6603,"children":6604},{"class":892,"line":1263},[6605,6610,6615],{"type":29,"tag":890,"props":6606,"children":6607},{"style":906},[6608],{"type":35,"value":6609},"def",{"type":29,"tag":890,"props":6611,"children":6612},{"style":5378},[6613],{"type":35,"value":6614}," create_order_service",{"type":29,"tag":890,"props":6616,"children":6617},{"style":5201},[6618],{"type":35,"value":6619},"():\n",{"type":29,"tag":890,"props":6621,"children":6622},{"class":892,"line":477},[6623,6628,6632,6636,6640,6644],{"type":29,"tag":890,"props":6624,"children":6625},{"style":912},[6626],{"type":35,"value":6627},"    repository ",{"type":29,"tag":890,"props":6629,"children":6630},{"style":936},[6631],{"type":35,"value":2217},{"type":29,"tag":890,"props":6633,"children":6634},{"style":5258},[6635],{"type":35,"value":6276},{"type":29,"tag":890,"props":6637,"children":6638},{"style":5201},[6639],{"type":35,"value":3070},{"type":29,"tag":890,"props":6641,"children":6642},{"style":912},[6643],{"type":35,"value":5430},{"type":29,"tag":890,"props":6645,"children":6646},{"style":5201},[6647],{"type":35,"value":5453},{"type":29,"tag":890,"props":6649,"children":6650},{"class":892,"line":11},[6651,6656,6660,6664,6668,6672,6676,6681,6685,6690,6694,6699],{"type":29,"tag":890,"props":6652,"children":6653},{"style":912},[6654],{"type":35,"value":6655},"    notifier ",{"type":29,"tag":890,"props":6657,"children":6658},{"style":936},[6659],{"type":35,"value":2217},{"type":29,"tag":890,"props":6661,"children":6662},{"style":5258},[6663],{"type":35,"value":6411},{"type":29,"tag":890,"props":6665,"children":6666},{"style":5201},[6667],{"type":35,"value":3070},{"type":29,"tag":890,"props":6669,"children":6670},{"style":5268},[6671],{"type":35,"value":5342},{"type":29,"tag":890,"props":6673,"children":6674},{"style":936},[6675],{"type":35,"value":2217},{"type":29,"tag":890,"props":6677,"children":6678},{"style":912},[6679],{"type":35,"value":6680},"os",{"type":29,"tag":890,"props":6682,"children":6683},{"style":5201},[6684],{"type":35,"value":332},{"type":29,"tag":890,"props":6686,"children":6687},{"style":5258},[6688],{"type":35,"value":6689},"getenv",{"type":29,"tag":890,"props":6691,"children":6692},{"style":5201},[6693],{"type":35,"value":3070},{"type":29,"tag":890,"props":6695,"children":6696},{"style":2226},[6697],{"type":35,"value":6698},"\"SENDGRID_KEY\"",{"type":29,"tag":890,"props":6700,"children":6701},{"style":5201},[6702],{"type":35,"value":6703},"))\n",{"type":29,"tag":890,"props":6705,"children":6706},{"class":892,"line":2110},[6707,6712,6716,6720,6724,6728,6732],{"type":29,"tag":890,"props":6708,"children":6709},{"style":906},[6710],{"type":35,"value":6711},"    return",{"type":29,"tag":890,"props":6713,"children":6714},{"style":5258},[6715],{"type":35,"value":5198},{"type":29,"tag":890,"props":6717,"children":6718},{"style":5201},[6719],{"type":35,"value":3070},{"type":29,"tag":890,"props":6721,"children":6722},{"style":912},[6723],{"type":35,"value":6153},{"type":29,"tag":890,"props":6725,"children":6726},{"style":5201},[6727],{"type":35,"value":3653},{"type":29,"tag":890,"props":6729,"children":6730},{"style":912},[6731],{"type":35,"value":6004},{"type":29,"tag":890,"props":6733,"children":6734},{"style":5201},[6735],{"type":35,"value":5453},{"type":29,"tag":37,"props":6737,"children":6738},{},[6739],{"type":29,"tag":55,"props":6740,"children":6741},{},[6742],{"type":35,"value":6743},"Le gain pour les tests :",{"type":29,"tag":640,"props":6745,"children":6747},{"code":6746,"language":2192,"meta":8,"className":2190,"style":8},"# Test sans base de données ni Sendgrid — s'exécute en millisecondes\nclass InMemoryOrderRepository(OrderRepository):\n    def __init__(self):\n        self.orders = {}\n\n    def save(self, order_data: dict) -> str:\n        order_id = str(uuid.uuid4())\n        self.orders[order_id] = order_data\n        return order_id\n\ndef test_create_order():\n    repository = InMemoryOrderRepository()\n    notifier = MockEmailNotifier()\n    service = OrderService(repository, notifier)\n\n    order_id = service.create_order({\"email\": \"user@example.com\", \"items\": [...]})\n\n    assert order_id in repository.orders\n    assert len(notifier.sent_confirmations) == 1\n",[6748],{"type":29,"tag":554,"props":6749,"children":6750},{"__ignoreMap":8},[6751,6759,6783,6806,6831,6838,6889,6927,6966,6977,6984,7000,7020,7040,7076,7083,7156,7163,7194],{"type":29,"tag":890,"props":6752,"children":6753},{"class":892,"line":893},[6754],{"type":29,"tag":890,"props":6755,"children":6756},{"style":897},[6757],{"type":35,"value":6758},"# Test sans base de données ni Sendgrid — s'exécute en millisecondes\n",{"type":29,"tag":890,"props":6760,"children":6761},{"class":892,"line":453},[6762,6766,6771,6775,6779],{"type":29,"tag":890,"props":6763,"children":6764},{"style":906},[6765],{"type":35,"value":5192},{"type":29,"tag":890,"props":6767,"children":6768},{"style":5195},[6769],{"type":35,"value":6770}," InMemoryOrderRepository",{"type":29,"tag":890,"props":6772,"children":6773},{"style":5201},[6774],{"type":35,"value":3070},{"type":29,"tag":890,"props":6776,"children":6777},{"style":5195},[6778],{"type":35,"value":5630},{"type":29,"tag":890,"props":6780,"children":6781},{"style":5201},[6782],{"type":35,"value":5233},{"type":29,"tag":890,"props":6784,"children":6785},{"class":892,"line":459},[6786,6790,6794,6798,6802],{"type":29,"tag":890,"props":6787,"children":6788},{"style":906},[6789],{"type":35,"value":5212},{"type":29,"tag":890,"props":6791,"children":6792},{"style":5215},[6793],{"type":35,"value":5218},{"type":29,"tag":890,"props":6795,"children":6796},{"style":5201},[6797],{"type":35,"value":3070},{"type":29,"tag":890,"props":6799,"children":6800},{"style":5225},[6801],{"type":35,"value":5228},{"type":29,"tag":890,"props":6803,"children":6804},{"style":5201},[6805],{"type":35,"value":5233},{"type":29,"tag":890,"props":6807,"children":6808},{"class":892,"line":957},[6809,6813,6817,6822,6826],{"type":29,"tag":890,"props":6810,"children":6811},{"style":5239},[6812],{"type":35,"value":5242},{"type":29,"tag":890,"props":6814,"children":6815},{"style":5201},[6816],{"type":35,"value":332},{"type":29,"tag":890,"props":6818,"children":6819},{"style":912},[6820],{"type":35,"value":6821},"orders ",{"type":29,"tag":890,"props":6823,"children":6824},{"style":936},[6825],{"type":35,"value":2217},{"type":29,"tag":890,"props":6827,"children":6828},{"style":5201},[6829],{"type":35,"value":6830}," {}\n",{"type":29,"tag":890,"props":6832,"children":6833},{"class":892,"line":966},[6834],{"type":29,"tag":890,"props":6835,"children":6836},{"emptyLinePlaceholder":13},[6837],{"type":35,"value":963},{"type":29,"tag":890,"props":6839,"children":6840},{"class":892,"line":975},[6841,6845,6849,6853,6857,6861,6865,6869,6873,6877,6881,6885],{"type":29,"tag":890,"props":6842,"children":6843},{"style":906},[6844],{"type":35,"value":5212},{"type":29,"tag":890,"props":6846,"children":6847},{"style":5378},[6848],{"type":35,"value":5755},{"type":29,"tag":890,"props":6850,"children":6851},{"style":5201},[6852],{"type":35,"value":3070},{"type":29,"tag":890,"props":6854,"children":6855},{"style":5225},[6856],{"type":35,"value":5228},{"type":29,"tag":890,"props":6858,"children":6859},{"style":5201},[6860],{"type":35,"value":3653},{"type":29,"tag":890,"props":6862,"children":6863},{"style":5396},[6864],{"type":35,"value":5399},{"type":29,"tag":890,"props":6866,"children":6867},{"style":5201},[6868],{"type":35,"value":5776},{"type":29,"tag":890,"props":6870,"children":6871},{"style":5779},[6872],{"type":35,"value":5782},{"type":29,"tag":890,"props":6874,"children":6875},{"style":5201},[6876],{"type":35,"value":2871},{"type":29,"tag":890,"props":6878,"children":6879},{"style":5201},[6880],{"type":35,"value":5791},{"type":29,"tag":890,"props":6882,"children":6883},{"style":5779},[6884],{"type":35,"value":5796},{"type":29,"tag":890,"props":6886,"children":6887},{"style":5201},[6888],{"type":35,"value":5204},{"type":29,"tag":890,"props":6890,"children":6891},{"class":892,"line":996},[6892,6896,6900,6904,6908,6913,6917,6922],{"type":29,"tag":890,"props":6893,"children":6894},{"style":912},[6895],{"type":35,"value":5412},{"type":29,"tag":890,"props":6897,"children":6898},{"style":936},[6899],{"type":35,"value":2217},{"type":29,"tag":890,"props":6901,"children":6902},{"style":5779},[6903],{"type":35,"value":5796},{"type":29,"tag":890,"props":6905,"children":6906},{"style":5201},[6907],{"type":35,"value":3070},{"type":29,"tag":890,"props":6909,"children":6910},{"style":912},[6911],{"type":35,"value":6912},"uuid",{"type":29,"tag":890,"props":6914,"children":6915},{"style":5201},[6916],{"type":35,"value":332},{"type":29,"tag":890,"props":6918,"children":6919},{"style":5258},[6920],{"type":35,"value":6921},"uuid4",{"type":29,"tag":890,"props":6923,"children":6924},{"style":5201},[6925],{"type":35,"value":6926},"())\n",{"type":29,"tag":890,"props":6928,"children":6929},{"class":892,"line":5370},[6930,6934,6938,6942,6946,6951,6956,6961],{"type":29,"tag":890,"props":6931,"children":6932},{"style":5239},[6933],{"type":35,"value":5242},{"type":29,"tag":890,"props":6935,"children":6936},{"style":5201},[6937],{"type":35,"value":332},{"type":29,"tag":890,"props":6939,"children":6940},{"style":5396},[6941],{"type":35,"value":559},{"type":29,"tag":890,"props":6943,"children":6944},{"style":5201},[6945],{"type":35,"value":5491},{"type":29,"tag":890,"props":6947,"children":6948},{"style":5396},[6949],{"type":35,"value":6950},"order_id",{"type":29,"tag":890,"props":6952,"children":6953},{"style":5201},[6954],{"type":35,"value":6955},"]",{"type":29,"tag":890,"props":6957,"children":6958},{"style":936},[6959],{"type":35,"value":6960}," =",{"type":29,"tag":890,"props":6962,"children":6963},{"style":912},[6964],{"type":35,"value":6965}," order_data\n",{"type":29,"tag":890,"props":6967,"children":6968},{"class":892,"line":5406},[6969,6973],{"type":29,"tag":890,"props":6970,"children":6971},{"style":906},[6972],{"type":35,"value":5528},{"type":29,"tag":890,"props":6974,"children":6975},{"style":912},[6976],{"type":35,"value":5533},{"type":29,"tag":890,"props":6978,"children":6979},{"class":892,"line":5456},[6980],{"type":29,"tag":890,"props":6981,"children":6982},{"emptyLinePlaceholder":13},[6983],{"type":35,"value":963},{"type":29,"tag":890,"props":6985,"children":6986},{"class":892,"line":5522},[6987,6991,6996],{"type":29,"tag":890,"props":6988,"children":6989},{"style":906},[6990],{"type":35,"value":6609},{"type":29,"tag":890,"props":6992,"children":6993},{"style":5378},[6994],{"type":35,"value":6995}," test_create_order",{"type":29,"tag":890,"props":6997,"children":6998},{"style":5201},[6999],{"type":35,"value":6619},{"type":29,"tag":890,"props":7001,"children":7002},{"class":892,"line":5927},[7003,7007,7011,7015],{"type":29,"tag":890,"props":7004,"children":7005},{"style":912},[7006],{"type":35,"value":6627},{"type":29,"tag":890,"props":7008,"children":7009},{"style":936},[7010],{"type":35,"value":2217},{"type":29,"tag":890,"props":7012,"children":7013},{"style":5258},[7014],{"type":35,"value":6770},{"type":29,"tag":890,"props":7016,"children":7017},{"style":5201},[7018],{"type":35,"value":7019},"()\n",{"type":29,"tag":890,"props":7021,"children":7022},{"class":892,"line":5935},[7023,7027,7031,7036],{"type":29,"tag":890,"props":7024,"children":7025},{"style":912},[7026],{"type":35,"value":6655},{"type":29,"tag":890,"props":7028,"children":7029},{"style":936},[7030],{"type":35,"value":2217},{"type":29,"tag":890,"props":7032,"children":7033},{"style":5258},[7034],{"type":35,"value":7035}," MockEmailNotifier",{"type":29,"tag":890,"props":7037,"children":7038},{"style":5201},[7039],{"type":35,"value":7019},{"type":29,"tag":890,"props":7041,"children":7042},{"class":892,"line":5944},[7043,7048,7052,7056,7060,7064,7068,7072],{"type":29,"tag":890,"props":7044,"children":7045},{"style":912},[7046],{"type":35,"value":7047},"    service ",{"type":29,"tag":890,"props":7049,"children":7050},{"style":936},[7051],{"type":35,"value":2217},{"type":29,"tag":890,"props":7053,"children":7054},{"style":5258},[7055],{"type":35,"value":5198},{"type":29,"tag":890,"props":7057,"children":7058},{"style":5201},[7059],{"type":35,"value":3070},{"type":29,"tag":890,"props":7061,"children":7062},{"style":912},[7063],{"type":35,"value":6153},{"type":29,"tag":890,"props":7065,"children":7066},{"style":5201},[7067],{"type":35,"value":3653},{"type":29,"tag":890,"props":7069,"children":7070},{"style":912},[7071],{"type":35,"value":6004},{"type":29,"tag":890,"props":7073,"children":7074},{"style":5201},[7075],{"type":35,"value":5453},{"type":29,"tag":890,"props":7077,"children":7078},{"class":892,"line":5960},[7079],{"type":29,"tag":890,"props":7080,"children":7081},{"emptyLinePlaceholder":13},[7082],{"type":35,"value":963},{"type":29,"tag":890,"props":7084,"children":7085},{"class":892,"line":6019},[7086,7091,7095,7100,7104,7109,7114,7119,7123,7128,7132,7137,7141,7146,7151],{"type":29,"tag":890,"props":7087,"children":7088},{"style":912},[7089],{"type":35,"value":7090},"    order_id ",{"type":29,"tag":890,"props":7092,"children":7093},{"style":936},[7094],{"type":35,"value":2217},{"type":29,"tag":890,"props":7096,"children":7097},{"style":912},[7098],{"type":35,"value":7099}," service",{"type":29,"tag":890,"props":7101,"children":7102},{"style":5201},[7103],{"type":35,"value":332},{"type":29,"tag":890,"props":7105,"children":7106},{"style":5258},[7107],{"type":35,"value":7108},"create_order",{"type":29,"tag":890,"props":7110,"children":7111},{"style":5201},[7112],{"type":35,"value":7113},"({",{"type":29,"tag":890,"props":7115,"children":7116},{"style":2226},[7117],{"type":35,"value":7118},"\"email\"",{"type":29,"tag":890,"props":7120,"children":7121},{"style":5201},[7122],{"type":35,"value":5776},{"type":29,"tag":890,"props":7124,"children":7125},{"style":2226},[7126],{"type":35,"value":7127}," \"user@example.com\"",{"type":29,"tag":890,"props":7129,"children":7130},{"style":5201},[7131],{"type":35,"value":3653},{"type":29,"tag":890,"props":7133,"children":7134},{"style":2226},[7135],{"type":35,"value":7136}," \"items\"",{"type":29,"tag":890,"props":7138,"children":7139},{"style":5201},[7140],{"type":35,"value":5776},{"type":29,"tag":890,"props":7142,"children":7143},{"style":5201},[7144],{"type":35,"value":7145}," [",{"type":29,"tag":890,"props":7147,"children":7148},{"style":5690},[7149],{"type":35,"value":7150},"...",{"type":29,"tag":890,"props":7152,"children":7153},{"style":5201},[7154],{"type":35,"value":7155},"]})\n",{"type":29,"tag":890,"props":7157,"children":7158},{"class":892,"line":6045},[7159],{"type":29,"tag":890,"props":7160,"children":7161},{"emptyLinePlaceholder":13},[7162],{"type":35,"value":963},{"type":29,"tag":890,"props":7164,"children":7165},{"class":892,"line":6071},[7166,7171,7176,7181,7185,7189],{"type":29,"tag":890,"props":7167,"children":7168},{"style":906},[7169],{"type":35,"value":7170},"    assert",{"type":29,"tag":890,"props":7172,"children":7173},{"style":912},[7174],{"type":35,"value":7175}," order_id ",{"type":29,"tag":890,"props":7177,"children":7178},{"style":906},[7179],{"type":35,"value":7180},"in",{"type":29,"tag":890,"props":7182,"children":7183},{"style":912},[7184],{"type":35,"value":5986},{"type":29,"tag":890,"props":7186,"children":7187},{"style":5201},[7188],{"type":35,"value":332},{"type":29,"tag":890,"props":7190,"children":7191},{"style":912},[7192],{"type":35,"value":7193},"orders\n",{"type":29,"tag":890,"props":7195,"children":7196},{"class":892,"line":6079},[7197,7201,7206,7210,7214,7218,7223,7227,7232],{"type":29,"tag":890,"props":7198,"children":7199},{"style":906},[7200],{"type":35,"value":7170},{"type":29,"tag":890,"props":7202,"children":7203},{"style":5779},[7204],{"type":35,"value":7205}," len",{"type":29,"tag":890,"props":7207,"children":7208},{"style":5201},[7209],{"type":35,"value":3070},{"type":29,"tag":890,"props":7211,"children":7212},{"style":912},[7213],{"type":35,"value":6190},{"type":29,"tag":890,"props":7215,"children":7216},{"style":5201},[7217],{"type":35,"value":332},{"type":29,"tag":890,"props":7219,"children":7220},{"style":912},[7221],{"type":35,"value":7222},"sent_confirmations",{"type":29,"tag":890,"props":7224,"children":7225},{"style":5201},[7226],{"type":35,"value":2871},{"type":29,"tag":890,"props":7228,"children":7229},{"style":936},[7230],{"type":35,"value":7231}," ==",{"type":29,"tag":890,"props":7233,"children":7234},{"style":5296},[7235],{"type":35,"value":7236}," 1\n",{"type":29,"tag":166,"props":7238,"children":7240},{"cta":168,"href":169,"title":7239,"type":171},"Votre codebase est difficile à tester parce que les dépendances sont fortement couplées ?",[7241],{"type":29,"tag":37,"props":7242,"children":7243},{},[7244],{"type":35,"value":7245},"Introduire le DIP dans un codebase existant nécessite une stratégie progressive, pas un refactoring massif qui bloque toute l'équipe. En 30 minutes, on peut identifier les zones de couplage les plus problématiques et définir un plan de refactoring réaliste avec des gains mesurables.",{"type":29,"tag":66,"props":7247,"children":7248},{},[],{"type":29,"tag":70,"props":7250,"children":7252},{"id":7251},"exemple-2-typescript-interfaces-et-injection-par-framework",[7253],{"type":35,"value":7254},"Exemple 2 : TypeScript, interfaces et injection par framework",{"type":29,"tag":640,"props":7256,"children":7260},{"code":7257,"language":7258,"meta":8,"className":7259,"style":8},"// Les abstractions (interfaces TypeScript)\ninterface OrderRepository {\n    save(orderData: OrderData): Promise\u003Cstring>;\n    findById(orderId: string): Promise\u003COrder | null>;\n}\n\ninterface PaymentGateway {\n    charge(amount: number, currency: string, paymentMethod: string): Promise\u003CPaymentResult>;\n}\n\n// Le module de haut niveau\nclass OrderService {\n    constructor(\n        private readonly repository: OrderRepository,\n        private readonly payment: PaymentGateway\n    ) {}\n\n    async createPaidOrder(orderData: OrderData): Promise\u003COrder> {\n        const paymentResult = await this.payment.charge(\n            orderData.total,\n            orderData.currency,\n            orderData.paymentMethodId\n        );\n\n        if (!paymentResult.success) {\n            throw new PaymentFailedError(paymentResult.errorCode);\n        }\n\n        const orderId = await this.repository.save({\n            ...orderData,\n            paymentId: paymentResult.transactionId,\n            status: 'paid'\n        });\n\n        return this.repository.findById(orderId);\n    }\n}\n\n// Test — sans Stripe, sans base de données\ndescribe('OrderService', () => {\n    it('should create order with successful payment', async () => {\n        const mockRepository: OrderRepository = {\n            save: jest.fn().mockResolvedValue('order-123'),\n            findById: jest.fn().mockResolvedValue({ id: 'order-123', status: 'paid' })\n        };\n\n        const mockPayment: PaymentGateway = {\n            charge: jest.fn().mockResolvedValue({ success: true, transactionId: 'txn-456' })\n        };\n\n        const service = new OrderService(mockRepository, mockPayment);\n        const order = await service.createPaidOrder({ total: 1000, currency: 'EUR' });\n\n        expect(order.status).toBe('paid');\n    });\n});\n","typescript","language-typescript shiki shiki-themes catppuccin-frappe github-dark",[7261],{"type":29,"tag":554,"props":7262,"children":7263},{"__ignoreMap":8},[7264,7272,7289,7349,7415,7423,7430,7446,7535,7542,7549,7557,7572,7585,7615,7640,7652,7659,7716,7767,7788,7808,7824,7836,7843,7880,7917,7925,7932,7980,7996,8025,8042,8058,8065,8102,8110,8117,8125,8134,8170,8209,8238,8296,8382,8391,8399,8428,8513,8521,8529,8571,8656,8664,8713,8730],{"type":29,"tag":890,"props":7265,"children":7266},{"class":892,"line":893},[7267],{"type":29,"tag":890,"props":7268,"children":7269},{"style":897},[7270],{"type":35,"value":7271},"// Les abstractions (interfaces TypeScript)\n",{"type":29,"tag":890,"props":7273,"children":7274},{"class":892,"line":453},[7275,7280,7284],{"type":29,"tag":890,"props":7276,"children":7277},{"style":906},[7278],{"type":35,"value":7279},"interface",{"type":29,"tag":890,"props":7281,"children":7282},{"style":5195},[7283],{"type":35,"value":5721},{"type":29,"tag":890,"props":7285,"children":7286},{"style":5201},[7287],{"type":35,"value":7288}," {\n",{"type":29,"tag":890,"props":7290,"children":7291},{"class":892,"line":459},[7292,7297,7301,7306,7310,7315,7319,7323,7328,7334,7339,7344],{"type":29,"tag":890,"props":7293,"children":7294},{"style":5378},[7295],{"type":35,"value":7296},"    save",{"type":29,"tag":890,"props":7298,"children":7299},{"style":5201},[7300],{"type":35,"value":3070},{"type":29,"tag":890,"props":7302,"children":7303},{"style":5268},[7304],{"type":35,"value":7305},"orderData",{"type":29,"tag":890,"props":7307,"children":7308},{"style":936},[7309],{"type":35,"value":5776},{"type":29,"tag":890,"props":7311,"children":7312},{"style":5195},[7313],{"type":35,"value":7314}," OrderData",{"type":29,"tag":890,"props":7316,"children":7317},{"style":5201},[7318],{"type":35,"value":2871},{"type":29,"tag":890,"props":7320,"children":7321},{"style":936},[7322],{"type":35,"value":5776},{"type":29,"tag":890,"props":7324,"children":7325},{"style":5195},[7326],{"type":35,"value":7327}," Promise",{"type":29,"tag":890,"props":7329,"children":7331},{"style":7330},"--shiki-default:#99D1DB;--shiki-dark:#E1E4E8",[7332],{"type":35,"value":7333},"\u003C",{"type":29,"tag":890,"props":7335,"children":7336},{"style":5910},[7337],{"type":35,"value":7338},"string",{"type":29,"tag":890,"props":7340,"children":7341},{"style":7330},[7342],{"type":35,"value":7343},">",{"type":29,"tag":890,"props":7345,"children":7346},{"style":5201},[7347],{"type":35,"value":7348},";\n",{"type":29,"tag":890,"props":7350,"children":7351},{"class":892,"line":957},[7352,7357,7361,7366,7370,7375,7379,7383,7387,7391,7396,7401,7407,7411],{"type":29,"tag":890,"props":7353,"children":7354},{"style":5378},[7355],{"type":35,"value":7356},"    findById",{"type":29,"tag":890,"props":7358,"children":7359},{"style":5201},[7360],{"type":35,"value":3070},{"type":29,"tag":890,"props":7362,"children":7363},{"style":5268},[7364],{"type":35,"value":7365},"orderId",{"type":29,"tag":890,"props":7367,"children":7368},{"style":936},[7369],{"type":35,"value":5776},{"type":29,"tag":890,"props":7371,"children":7372},{"style":5910},[7373],{"type":35,"value":7374}," string",{"type":29,"tag":890,"props":7376,"children":7377},{"style":5201},[7378],{"type":35,"value":2871},{"type":29,"tag":890,"props":7380,"children":7381},{"style":936},[7382],{"type":35,"value":5776},{"type":29,"tag":890,"props":7384,"children":7385},{"style":5195},[7386],{"type":35,"value":7327},{"type":29,"tag":890,"props":7388,"children":7389},{"style":7330},[7390],{"type":35,"value":7333},{"type":29,"tag":890,"props":7392,"children":7393},{"style":5195},[7394],{"type":35,"value":7395},"Order",{"type":29,"tag":890,"props":7397,"children":7398},{"style":936},[7399],{"type":35,"value":7400}," |",{"type":29,"tag":890,"props":7402,"children":7404},{"style":7403},"--shiki-default:#CA9EE6;--shiki-default-font-style:italic;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit",[7405],{"type":35,"value":7406}," null",{"type":29,"tag":890,"props":7408,"children":7409},{"style":7330},[7410],{"type":35,"value":7343},{"type":29,"tag":890,"props":7412,"children":7413},{"style":5201},[7414],{"type":35,"value":7348},{"type":29,"tag":890,"props":7416,"children":7417},{"class":892,"line":966},[7418],{"type":29,"tag":890,"props":7419,"children":7420},{"style":5201},[7421],{"type":35,"value":7422},"}\n",{"type":29,"tag":890,"props":7424,"children":7425},{"class":892,"line":975},[7426],{"type":29,"tag":890,"props":7427,"children":7428},{"emptyLinePlaceholder":13},[7429],{"type":35,"value":963},{"type":29,"tag":890,"props":7431,"children":7432},{"class":892,"line":996},[7433,7437,7442],{"type":29,"tag":890,"props":7434,"children":7435},{"style":906},[7436],{"type":35,"value":7279},{"type":29,"tag":890,"props":7438,"children":7439},{"style":5195},[7440],{"type":35,"value":7441}," PaymentGateway",{"type":29,"tag":890,"props":7443,"children":7444},{"style":5201},[7445],{"type":35,"value":7288},{"type":29,"tag":890,"props":7447,"children":7448},{"class":892,"line":5370},[7449,7454,7458,7463,7467,7472,7476,7481,7485,7489,7493,7498,7502,7506,7510,7514,7518,7522,7527,7531],{"type":29,"tag":890,"props":7450,"children":7451},{"style":5378},[7452],{"type":35,"value":7453},"    charge",{"type":29,"tag":890,"props":7455,"children":7456},{"style":5201},[7457],{"type":35,"value":3070},{"type":29,"tag":890,"props":7459,"children":7460},{"style":5268},[7461],{"type":35,"value":7462},"amount",{"type":29,"tag":890,"props":7464,"children":7465},{"style":936},[7466],{"type":35,"value":5776},{"type":29,"tag":890,"props":7468,"children":7469},{"style":5910},[7470],{"type":35,"value":7471}," number",{"type":29,"tag":890,"props":7473,"children":7474},{"style":5201},[7475],{"type":35,"value":3653},{"type":29,"tag":890,"props":7477,"children":7478},{"style":5268},[7479],{"type":35,"value":7480}," currency",{"type":29,"tag":890,"props":7482,"children":7483},{"style":936},[7484],{"type":35,"value":5776},{"type":29,"tag":890,"props":7486,"children":7487},{"style":5910},[7488],{"type":35,"value":7374},{"type":29,"tag":890,"props":7490,"children":7491},{"style":5201},[7492],{"type":35,"value":3653},{"type":29,"tag":890,"props":7494,"children":7495},{"style":5268},[7496],{"type":35,"value":7497}," paymentMethod",{"type":29,"tag":890,"props":7499,"children":7500},{"style":936},[7501],{"type":35,"value":5776},{"type":29,"tag":890,"props":7503,"children":7504},{"style":5910},[7505],{"type":35,"value":7374},{"type":29,"tag":890,"props":7507,"children":7508},{"style":5201},[7509],{"type":35,"value":2871},{"type":29,"tag":890,"props":7511,"children":7512},{"style":936},[7513],{"type":35,"value":5776},{"type":29,"tag":890,"props":7515,"children":7516},{"style":5195},[7517],{"type":35,"value":7327},{"type":29,"tag":890,"props":7519,"children":7520},{"style":7330},[7521],{"type":35,"value":7333},{"type":29,"tag":890,"props":7523,"children":7524},{"style":5195},[7525],{"type":35,"value":7526},"PaymentResult",{"type":29,"tag":890,"props":7528,"children":7529},{"style":7330},[7530],{"type":35,"value":7343},{"type":29,"tag":890,"props":7532,"children":7533},{"style":5201},[7534],{"type":35,"value":7348},{"type":29,"tag":890,"props":7536,"children":7537},{"class":892,"line":5406},[7538],{"type":29,"tag":890,"props":7539,"children":7540},{"style":5201},[7541],{"type":35,"value":7422},{"type":29,"tag":890,"props":7543,"children":7544},{"class":892,"line":5456},[7545],{"type":29,"tag":890,"props":7546,"children":7547},{"emptyLinePlaceholder":13},[7548],{"type":35,"value":963},{"type":29,"tag":890,"props":7550,"children":7551},{"class":892,"line":5522},[7552],{"type":29,"tag":890,"props":7553,"children":7554},{"style":897},[7555],{"type":35,"value":7556},"// Le module de haut niveau\n",{"type":29,"tag":890,"props":7558,"children":7559},{"class":892,"line":5927},[7560,7564,7568],{"type":29,"tag":890,"props":7561,"children":7562},{"style":906},[7563],{"type":35,"value":5192},{"type":29,"tag":890,"props":7565,"children":7566},{"style":5195},[7567],{"type":35,"value":5198},{"type":29,"tag":890,"props":7569,"children":7570},{"style":5201},[7571],{"type":35,"value":7288},{"type":29,"tag":890,"props":7573,"children":7574},{"class":892,"line":5935},[7575,7580],{"type":29,"tag":890,"props":7576,"children":7577},{"style":906},[7578],{"type":35,"value":7579},"    constructor",{"type":29,"tag":890,"props":7581,"children":7582},{"style":5201},[7583],{"type":35,"value":7584},"(\n",{"type":29,"tag":890,"props":7586,"children":7587},{"class":892,"line":5944},[7588,7593,7598,7602,7606,7610],{"type":29,"tag":890,"props":7589,"children":7590},{"style":906},[7591],{"type":35,"value":7592},"        private",{"type":29,"tag":890,"props":7594,"children":7595},{"style":906},[7596],{"type":35,"value":7597}," readonly",{"type":29,"tag":890,"props":7599,"children":7600},{"style":5268},[7601],{"type":35,"value":5986},{"type":29,"tag":890,"props":7603,"children":7604},{"style":936},[7605],{"type":35,"value":5776},{"type":29,"tag":890,"props":7607,"children":7608},{"style":5195},[7609],{"type":35,"value":5721},{"type":29,"tag":890,"props":7611,"children":7612},{"style":5201},[7613],{"type":35,"value":7614},",\n",{"type":29,"tag":890,"props":7616,"children":7617},{"class":892,"line":5960},[7618,7622,7626,7631,7635],{"type":29,"tag":890,"props":7619,"children":7620},{"style":906},[7621],{"type":35,"value":7592},{"type":29,"tag":890,"props":7623,"children":7624},{"style":906},[7625],{"type":35,"value":7597},{"type":29,"tag":890,"props":7627,"children":7628},{"style":5268},[7629],{"type":35,"value":7630}," payment",{"type":29,"tag":890,"props":7632,"children":7633},{"style":936},[7634],{"type":35,"value":5776},{"type":29,"tag":890,"props":7636,"children":7637},{"style":5195},[7638],{"type":35,"value":7639}," PaymentGateway\n",{"type":29,"tag":890,"props":7641,"children":7642},{"class":892,"line":6019},[7643,7648],{"type":29,"tag":890,"props":7644,"children":7645},{"style":5201},[7646],{"type":35,"value":7647},"    )",{"type":29,"tag":890,"props":7649,"children":7650},{"style":5201},[7651],{"type":35,"value":6830},{"type":29,"tag":890,"props":7653,"children":7654},{"class":892,"line":6045},[7655],{"type":29,"tag":890,"props":7656,"children":7657},{"emptyLinePlaceholder":13},[7658],{"type":35,"value":963},{"type":29,"tag":890,"props":7660,"children":7661},{"class":892,"line":6071},[7662,7667,7672,7676,7680,7684,7688,7692,7696,7700,7704,7708,7712],{"type":29,"tag":890,"props":7663,"children":7664},{"style":906},[7665],{"type":35,"value":7666},"    async",{"type":29,"tag":890,"props":7668,"children":7669},{"style":5378},[7670],{"type":35,"value":7671}," createPaidOrder",{"type":29,"tag":890,"props":7673,"children":7674},{"style":5201},[7675],{"type":35,"value":3070},{"type":29,"tag":890,"props":7677,"children":7678},{"style":5268},[7679],{"type":35,"value":7305},{"type":29,"tag":890,"props":7681,"children":7682},{"style":936},[7683],{"type":35,"value":5776},{"type":29,"tag":890,"props":7685,"children":7686},{"style":5195},[7687],{"type":35,"value":7314},{"type":29,"tag":890,"props":7689,"children":7690},{"style":5201},[7691],{"type":35,"value":2871},{"type":29,"tag":890,"props":7693,"children":7694},{"style":936},[7695],{"type":35,"value":5776},{"type":29,"tag":890,"props":7697,"children":7698},{"style":5195},[7699],{"type":35,"value":7327},{"type":29,"tag":890,"props":7701,"children":7702},{"style":7330},[7703],{"type":35,"value":7333},{"type":29,"tag":890,"props":7705,"children":7706},{"style":5195},[7707],{"type":35,"value":7395},{"type":29,"tag":890,"props":7709,"children":7710},{"style":7330},[7711],{"type":35,"value":7343},{"type":29,"tag":890,"props":7713,"children":7714},{"style":5201},[7715],{"type":35,"value":7288},{"type":29,"tag":890,"props":7717,"children":7718},{"class":892,"line":6079},[7719,7724,7729,7733,7738,7744,7749,7754,7758,7763],{"type":29,"tag":890,"props":7720,"children":7721},{"style":906},[7722],{"type":35,"value":7723},"        const",{"type":29,"tag":890,"props":7725,"children":7726},{"style":5690},[7727],{"type":35,"value":7728}," paymentResult",{"type":29,"tag":890,"props":7730,"children":7731},{"style":936},[7732],{"type":35,"value":6960},{"type":29,"tag":890,"props":7734,"children":7735},{"style":906},[7736],{"type":35,"value":7737}," await",{"type":29,"tag":890,"props":7739,"children":7741},{"style":7740},"--shiki-default:#E78284;--shiki-dark:#79B8FF",[7742],{"type":35,"value":7743}," this",{"type":29,"tag":890,"props":7745,"children":7747},{"style":7746},"--shiki-default:#81C8BE;--shiki-dark:#E1E4E8",[7748],{"type":35,"value":332},{"type":29,"tag":890,"props":7750,"children":7751},{"style":912},[7752],{"type":35,"value":7753},"payment",{"type":29,"tag":890,"props":7755,"children":7756},{"style":7746},[7757],{"type":35,"value":332},{"type":29,"tag":890,"props":7759,"children":7760},{"style":5378},[7761],{"type":35,"value":7762},"charge",{"type":29,"tag":890,"props":7764,"children":7765},{"style":912},[7766],{"type":35,"value":7584},{"type":29,"tag":890,"props":7768,"children":7769},{"class":892,"line":6131},[7770,7775,7779,7784],{"type":29,"tag":890,"props":7771,"children":7772},{"style":912},[7773],{"type":35,"value":7774},"            orderData",{"type":29,"tag":890,"props":7776,"children":7777},{"style":7746},[7778],{"type":35,"value":332},{"type":29,"tag":890,"props":7780,"children":7781},{"style":912},[7782],{"type":35,"value":7783},"total",{"type":29,"tag":890,"props":7785,"children":7786},{"style":5201},[7787],{"type":35,"value":7614},{"type":29,"tag":890,"props":7789,"children":7790},{"class":892,"line":6176},[7791,7795,7799,7804],{"type":29,"tag":890,"props":7792,"children":7793},{"style":912},[7794],{"type":35,"value":7774},{"type":29,"tag":890,"props":7796,"children":7797},{"style":7746},[7798],{"type":35,"value":332},{"type":29,"tag":890,"props":7800,"children":7801},{"style":912},[7802],{"type":35,"value":7803},"currency",{"type":29,"tag":890,"props":7805,"children":7806},{"style":5201},[7807],{"type":35,"value":7614},{"type":29,"tag":890,"props":7809,"children":7810},{"class":892,"line":6237},[7811,7815,7819],{"type":29,"tag":890,"props":7812,"children":7813},{"style":912},[7814],{"type":35,"value":7774},{"type":29,"tag":890,"props":7816,"children":7817},{"style":7746},[7818],{"type":35,"value":332},{"type":29,"tag":890,"props":7820,"children":7821},{"style":912},[7822],{"type":35,"value":7823},"paymentMethodId\n",{"type":29,"tag":890,"props":7825,"children":7826},{"class":892,"line":6249},[7827,7832],{"type":29,"tag":890,"props":7828,"children":7829},{"style":912},[7830],{"type":35,"value":7831},"        )",{"type":29,"tag":890,"props":7833,"children":7834},{"style":5201},[7835],{"type":35,"value":7348},{"type":29,"tag":890,"props":7837,"children":7838},{"class":892,"line":6257},[7839],{"type":29,"tag":890,"props":7840,"children":7841},{"emptyLinePlaceholder":13},[7842],{"type":35,"value":963},{"type":29,"tag":890,"props":7844,"children":7845},{"class":892,"line":6266},[7846,7851,7856,7861,7866,7870,7875],{"type":29,"tag":890,"props":7847,"children":7848},{"style":906},[7849],{"type":35,"value":7850},"        if",{"type":29,"tag":890,"props":7852,"children":7853},{"style":912},[7854],{"type":35,"value":7855}," (",{"type":29,"tag":890,"props":7857,"children":7858},{"style":936},[7859],{"type":35,"value":7860},"!",{"type":29,"tag":890,"props":7862,"children":7863},{"style":912},[7864],{"type":35,"value":7865},"paymentResult",{"type":29,"tag":890,"props":7867,"children":7868},{"style":7746},[7869],{"type":35,"value":332},{"type":29,"tag":890,"props":7871,"children":7872},{"style":912},[7873],{"type":35,"value":7874},"success) ",{"type":29,"tag":890,"props":7876,"children":7877},{"style":5201},[7878],{"type":35,"value":7879},"{\n",{"type":29,"tag":890,"props":7881,"children":7882},{"class":892,"line":6291},[7883,7888,7894,7899,7904,7908,7913],{"type":29,"tag":890,"props":7884,"children":7885},{"style":906},[7886],{"type":35,"value":7887},"            throw",{"type":29,"tag":890,"props":7889,"children":7891},{"style":7890},"--shiki-default:#CA9EE6;--shiki-default-font-weight:bold;--shiki-dark:#F97583;--shiki-dark-font-weight:inherit",[7892],{"type":35,"value":7893}," new",{"type":29,"tag":890,"props":7895,"children":7896},{"style":5378},[7897],{"type":35,"value":7898}," PaymentFailedError",{"type":29,"tag":890,"props":7900,"children":7901},{"style":912},[7902],{"type":35,"value":7903},"(paymentResult",{"type":29,"tag":890,"props":7905,"children":7906},{"style":7746},[7907],{"type":35,"value":332},{"type":29,"tag":890,"props":7909,"children":7910},{"style":912},[7911],{"type":35,"value":7912},"errorCode)",{"type":29,"tag":890,"props":7914,"children":7915},{"style":5201},[7916],{"type":35,"value":7348},{"type":29,"tag":890,"props":7918,"children":7919},{"class":892,"line":6343},[7920],{"type":29,"tag":890,"props":7921,"children":7922},{"style":5201},[7923],{"type":35,"value":7924},"        }\n",{"type":29,"tag":890,"props":7926,"children":7927},{"class":892,"line":6393},[7928],{"type":29,"tag":890,"props":7929,"children":7930},{"emptyLinePlaceholder":13},[7931],{"type":35,"value":963},{"type":29,"tag":890,"props":7933,"children":7934},{"class":892,"line":6401},[7935,7939,7944,7948,7952,7956,7960,7964,7968,7972,7976],{"type":29,"tag":890,"props":7936,"children":7937},{"style":906},[7938],{"type":35,"value":7723},{"type":29,"tag":890,"props":7940,"children":7941},{"style":5690},[7942],{"type":35,"value":7943}," orderId",{"type":29,"tag":890,"props":7945,"children":7946},{"style":936},[7947],{"type":35,"value":6960},{"type":29,"tag":890,"props":7949,"children":7950},{"style":906},[7951],{"type":35,"value":7737},{"type":29,"tag":890,"props":7953,"children":7954},{"style":7740},[7955],{"type":35,"value":7743},{"type":29,"tag":890,"props":7957,"children":7958},{"style":7746},[7959],{"type":35,"value":332},{"type":29,"tag":890,"props":7961,"children":7962},{"style":912},[7963],{"type":35,"value":6153},{"type":29,"tag":890,"props":7965,"children":7966},{"style":7746},[7967],{"type":35,"value":332},{"type":29,"tag":890,"props":7969,"children":7970},{"style":5378},[7971],{"type":35,"value":5439},{"type":29,"tag":890,"props":7973,"children":7974},{"style":912},[7975],{"type":35,"value":3070},{"type":29,"tag":890,"props":7977,"children":7978},{"style":5201},[7979],{"type":35,"value":7879},{"type":29,"tag":890,"props":7981,"children":7982},{"class":892,"line":5101},[7983,7988,7992],{"type":29,"tag":890,"props":7984,"children":7985},{"style":936},[7986],{"type":35,"value":7987},"            ...",{"type":29,"tag":890,"props":7989,"children":7990},{"style":912},[7991],{"type":35,"value":7305},{"type":29,"tag":890,"props":7993,"children":7994},{"style":5201},[7995],{"type":35,"value":7614},{"type":29,"tag":890,"props":7997,"children":7998},{"class":892,"line":4563},[7999,8004,8008,8012,8016,8021],{"type":29,"tag":890,"props":8000,"children":8001},{"style":912},[8002],{"type":35,"value":8003},"            paymentId",{"type":29,"tag":890,"props":8005,"children":8006},{"style":7746},[8007],{"type":35,"value":5776},{"type":29,"tag":890,"props":8009,"children":8010},{"style":912},[8011],{"type":35,"value":7728},{"type":29,"tag":890,"props":8013,"children":8014},{"style":7746},[8015],{"type":35,"value":332},{"type":29,"tag":890,"props":8017,"children":8018},{"style":912},[8019],{"type":35,"value":8020},"transactionId",{"type":29,"tag":890,"props":8022,"children":8023},{"style":5201},[8024],{"type":35,"value":7614},{"type":29,"tag":890,"props":8026,"children":8027},{"class":892,"line":4099},[8028,8033,8037],{"type":29,"tag":890,"props":8029,"children":8030},{"style":912},[8031],{"type":35,"value":8032},"            status",{"type":29,"tag":890,"props":8034,"children":8035},{"style":7746},[8036],{"type":35,"value":5776},{"type":29,"tag":890,"props":8038,"children":8039},{"style":2226},[8040],{"type":35,"value":8041}," 'paid'\n",{"type":29,"tag":890,"props":8043,"children":8044},{"class":892,"line":6595},[8045,8050,8054],{"type":29,"tag":890,"props":8046,"children":8047},{"style":5201},[8048],{"type":35,"value":8049},"        }",{"type":29,"tag":890,"props":8051,"children":8052},{"style":912},[8053],{"type":35,"value":2871},{"type":29,"tag":890,"props":8055,"children":8056},{"style":5201},[8057],{"type":35,"value":7348},{"type":29,"tag":890,"props":8059,"children":8060},{"class":892,"line":1263},[8061],{"type":29,"tag":890,"props":8062,"children":8063},{"emptyLinePlaceholder":13},[8064],{"type":35,"value":963},{"type":29,"tag":890,"props":8066,"children":8067},{"class":892,"line":477},[8068,8072,8076,8080,8084,8088,8093,8098],{"type":29,"tag":890,"props":8069,"children":8070},{"style":906},[8071],{"type":35,"value":5528},{"type":29,"tag":890,"props":8073,"children":8074},{"style":7740},[8075],{"type":35,"value":7743},{"type":29,"tag":890,"props":8077,"children":8078},{"style":7746},[8079],{"type":35,"value":332},{"type":29,"tag":890,"props":8081,"children":8082},{"style":912},[8083],{"type":35,"value":6153},{"type":29,"tag":890,"props":8085,"children":8086},{"style":7746},[8087],{"type":35,"value":332},{"type":29,"tag":890,"props":8089,"children":8090},{"style":5378},[8091],{"type":35,"value":8092},"findById",{"type":29,"tag":890,"props":8094,"children":8095},{"style":912},[8096],{"type":35,"value":8097},"(orderId)",{"type":29,"tag":890,"props":8099,"children":8100},{"style":5201},[8101],{"type":35,"value":7348},{"type":29,"tag":890,"props":8103,"children":8104},{"class":892,"line":11},[8105],{"type":29,"tag":890,"props":8106,"children":8107},{"style":5201},[8108],{"type":35,"value":8109},"    }\n",{"type":29,"tag":890,"props":8111,"children":8112},{"class":892,"line":2110},[8113],{"type":29,"tag":890,"props":8114,"children":8115},{"style":5201},[8116],{"type":35,"value":7422},{"type":29,"tag":890,"props":8118,"children":8120},{"class":892,"line":8119},38,[8121],{"type":29,"tag":890,"props":8122,"children":8123},{"emptyLinePlaceholder":13},[8124],{"type":35,"value":963},{"type":29,"tag":890,"props":8126,"children":8128},{"class":892,"line":8127},39,[8129],{"type":29,"tag":890,"props":8130,"children":8131},{"style":897},[8132],{"type":35,"value":8133},"// Test — sans Stripe, sans base de données\n",{"type":29,"tag":890,"props":8135,"children":8137},{"class":892,"line":8136},40,[8138,8143,8147,8152,8156,8161,8166],{"type":29,"tag":890,"props":8139,"children":8140},{"style":5378},[8141],{"type":35,"value":8142},"describe",{"type":29,"tag":890,"props":8144,"children":8145},{"style":912},[8146],{"type":35,"value":3070},{"type":29,"tag":890,"props":8148,"children":8149},{"style":2226},[8150],{"type":35,"value":8151},"'OrderService'",{"type":29,"tag":890,"props":8153,"children":8154},{"style":5201},[8155],{"type":35,"value":3653},{"type":29,"tag":890,"props":8157,"children":8158},{"style":5201},[8159],{"type":35,"value":8160}," ()",{"type":29,"tag":890,"props":8162,"children":8163},{"style":936},[8164],{"type":35,"value":8165}," =>",{"type":29,"tag":890,"props":8167,"children":8168},{"style":5201},[8169],{"type":35,"value":7288},{"type":29,"tag":890,"props":8171,"children":8173},{"class":892,"line":8172},41,[8174,8179,8183,8188,8192,8197,8201,8205],{"type":29,"tag":890,"props":8175,"children":8176},{"style":5378},[8177],{"type":35,"value":8178},"    it",{"type":29,"tag":890,"props":8180,"children":8181},{"style":912},[8182],{"type":35,"value":3070},{"type":29,"tag":890,"props":8184,"children":8185},{"style":2226},[8186],{"type":35,"value":8187},"'should create order with successful payment'",{"type":29,"tag":890,"props":8189,"children":8190},{"style":5201},[8191],{"type":35,"value":3653},{"type":29,"tag":890,"props":8193,"children":8194},{"style":906},[8195],{"type":35,"value":8196}," async",{"type":29,"tag":890,"props":8198,"children":8199},{"style":5201},[8200],{"type":35,"value":8160},{"type":29,"tag":890,"props":8202,"children":8203},{"style":936},[8204],{"type":35,"value":8165},{"type":29,"tag":890,"props":8206,"children":8207},{"style":5201},[8208],{"type":35,"value":7288},{"type":29,"tag":890,"props":8210,"children":8212},{"class":892,"line":8211},42,[8213,8217,8222,8226,8230,8234],{"type":29,"tag":890,"props":8214,"children":8215},{"style":906},[8216],{"type":35,"value":7723},{"type":29,"tag":890,"props":8218,"children":8219},{"style":5690},[8220],{"type":35,"value":8221}," mockRepository",{"type":29,"tag":890,"props":8223,"children":8224},{"style":936},[8225],{"type":35,"value":5776},{"type":29,"tag":890,"props":8227,"children":8228},{"style":5195},[8229],{"type":35,"value":5721},{"type":29,"tag":890,"props":8231,"children":8232},{"style":936},[8233],{"type":35,"value":6960},{"type":29,"tag":890,"props":8235,"children":8236},{"style":5201},[8237],{"type":35,"value":7288},{"type":29,"tag":890,"props":8239,"children":8241},{"class":892,"line":8240},43,[8242,8247,8251,8256,8260,8265,8270,8274,8279,8283,8288,8292],{"type":29,"tag":890,"props":8243,"children":8244},{"style":912},[8245],{"type":35,"value":8246},"            save",{"type":29,"tag":890,"props":8248,"children":8249},{"style":7746},[8250],{"type":35,"value":5776},{"type":29,"tag":890,"props":8252,"children":8253},{"style":912},[8254],{"type":35,"value":8255}," jest",{"type":29,"tag":890,"props":8257,"children":8258},{"style":7746},[8259],{"type":35,"value":332},{"type":29,"tag":890,"props":8261,"children":8262},{"style":5378},[8263],{"type":35,"value":8264},"fn",{"type":29,"tag":890,"props":8266,"children":8267},{"style":912},[8268],{"type":35,"value":8269},"()",{"type":29,"tag":890,"props":8271,"children":8272},{"style":7746},[8273],{"type":35,"value":332},{"type":29,"tag":890,"props":8275,"children":8276},{"style":5378},[8277],{"type":35,"value":8278},"mockResolvedValue",{"type":29,"tag":890,"props":8280,"children":8281},{"style":912},[8282],{"type":35,"value":3070},{"type":29,"tag":890,"props":8284,"children":8285},{"style":2226},[8286],{"type":35,"value":8287},"'order-123'",{"type":29,"tag":890,"props":8289,"children":8290},{"style":912},[8291],{"type":35,"value":2871},{"type":29,"tag":890,"props":8293,"children":8294},{"style":5201},[8295],{"type":35,"value":7614},{"type":29,"tag":890,"props":8297,"children":8299},{"class":892,"line":8298},44,[8300,8305,8309,8313,8317,8321,8325,8329,8333,8337,8341,8346,8350,8355,8359,8364,8368,8373,8378],{"type":29,"tag":890,"props":8301,"children":8302},{"style":912},[8303],{"type":35,"value":8304},"            findById",{"type":29,"tag":890,"props":8306,"children":8307},{"style":7746},[8308],{"type":35,"value":5776},{"type":29,"tag":890,"props":8310,"children":8311},{"style":912},[8312],{"type":35,"value":8255},{"type":29,"tag":890,"props":8314,"children":8315},{"style":7746},[8316],{"type":35,"value":332},{"type":29,"tag":890,"props":8318,"children":8319},{"style":5378},[8320],{"type":35,"value":8264},{"type":29,"tag":890,"props":8322,"children":8323},{"style":912},[8324],{"type":35,"value":8269},{"type":29,"tag":890,"props":8326,"children":8327},{"style":7746},[8328],{"type":35,"value":332},{"type":29,"tag":890,"props":8330,"children":8331},{"style":5378},[8332],{"type":35,"value":8278},{"type":29,"tag":890,"props":8334,"children":8335},{"style":912},[8336],{"type":35,"value":3070},{"type":29,"tag":890,"props":8338,"children":8339},{"style":5201},[8340],{"type":35,"value":2235},{"type":29,"tag":890,"props":8342,"children":8343},{"style":912},[8344],{"type":35,"value":8345}," id",{"type":29,"tag":890,"props":8347,"children":8348},{"style":7746},[8349],{"type":35,"value":5776},{"type":29,"tag":890,"props":8351,"children":8352},{"style":2226},[8353],{"type":35,"value":8354}," 'order-123'",{"type":29,"tag":890,"props":8356,"children":8357},{"style":5201},[8358],{"type":35,"value":3653},{"type":29,"tag":890,"props":8360,"children":8361},{"style":912},[8362],{"type":35,"value":8363}," status",{"type":29,"tag":890,"props":8365,"children":8366},{"style":7746},[8367],{"type":35,"value":5776},{"type":29,"tag":890,"props":8369,"children":8370},{"style":2226},[8371],{"type":35,"value":8372}," 'paid'",{"type":29,"tag":890,"props":8374,"children":8375},{"style":5201},[8376],{"type":35,"value":8377}," }",{"type":29,"tag":890,"props":8379,"children":8380},{"style":912},[8381],{"type":35,"value":5453},{"type":29,"tag":890,"props":8383,"children":8385},{"class":892,"line":8384},45,[8386],{"type":29,"tag":890,"props":8387,"children":8388},{"style":5201},[8389],{"type":35,"value":8390},"        };\n",{"type":29,"tag":890,"props":8392,"children":8394},{"class":892,"line":8393},46,[8395],{"type":29,"tag":890,"props":8396,"children":8397},{"emptyLinePlaceholder":13},[8398],{"type":35,"value":963},{"type":29,"tag":890,"props":8400,"children":8402},{"class":892,"line":8401},47,[8403,8407,8412,8416,8420,8424],{"type":29,"tag":890,"props":8404,"children":8405},{"style":906},[8406],{"type":35,"value":7723},{"type":29,"tag":890,"props":8408,"children":8409},{"style":5690},[8410],{"type":35,"value":8411}," mockPayment",{"type":29,"tag":890,"props":8413,"children":8414},{"style":936},[8415],{"type":35,"value":5776},{"type":29,"tag":890,"props":8417,"children":8418},{"style":5195},[8419],{"type":35,"value":7441},{"type":29,"tag":890,"props":8421,"children":8422},{"style":936},[8423],{"type":35,"value":6960},{"type":29,"tag":890,"props":8425,"children":8426},{"style":5201},[8427],{"type":35,"value":7288},{"type":29,"tag":890,"props":8429,"children":8431},{"class":892,"line":8430},48,[8432,8437,8441,8445,8449,8453,8457,8461,8465,8469,8473,8478,8482,8487,8491,8496,8500,8505,8509],{"type":29,"tag":890,"props":8433,"children":8434},{"style":912},[8435],{"type":35,"value":8436},"            charge",{"type":29,"tag":890,"props":8438,"children":8439},{"style":7746},[8440],{"type":35,"value":5776},{"type":29,"tag":890,"props":8442,"children":8443},{"style":912},[8444],{"type":35,"value":8255},{"type":29,"tag":890,"props":8446,"children":8447},{"style":7746},[8448],{"type":35,"value":332},{"type":29,"tag":890,"props":8450,"children":8451},{"style":5378},[8452],{"type":35,"value":8264},{"type":29,"tag":890,"props":8454,"children":8455},{"style":912},[8456],{"type":35,"value":8269},{"type":29,"tag":890,"props":8458,"children":8459},{"style":7746},[8460],{"type":35,"value":332},{"type":29,"tag":890,"props":8462,"children":8463},{"style":5378},[8464],{"type":35,"value":8278},{"type":29,"tag":890,"props":8466,"children":8467},{"style":912},[8468],{"type":35,"value":3070},{"type":29,"tag":890,"props":8470,"children":8471},{"style":5201},[8472],{"type":35,"value":2235},{"type":29,"tag":890,"props":8474,"children":8475},{"style":912},[8476],{"type":35,"value":8477}," success",{"type":29,"tag":890,"props":8479,"children":8480},{"style":7746},[8481],{"type":35,"value":5776},{"type":29,"tag":890,"props":8483,"children":8484},{"style":5296},[8485],{"type":35,"value":8486}," true",{"type":29,"tag":890,"props":8488,"children":8489},{"style":5201},[8490],{"type":35,"value":3653},{"type":29,"tag":890,"props":8492,"children":8493},{"style":912},[8494],{"type":35,"value":8495}," transactionId",{"type":29,"tag":890,"props":8497,"children":8498},{"style":7746},[8499],{"type":35,"value":5776},{"type":29,"tag":890,"props":8501,"children":8502},{"style":2226},[8503],{"type":35,"value":8504}," 'txn-456'",{"type":29,"tag":890,"props":8506,"children":8507},{"style":5201},[8508],{"type":35,"value":8377},{"type":29,"tag":890,"props":8510,"children":8511},{"style":912},[8512],{"type":35,"value":5453},{"type":29,"tag":890,"props":8514,"children":8516},{"class":892,"line":8515},49,[8517],{"type":29,"tag":890,"props":8518,"children":8519},{"style":5201},[8520],{"type":35,"value":8390},{"type":29,"tag":890,"props":8522,"children":8524},{"class":892,"line":8523},50,[8525],{"type":29,"tag":890,"props":8526,"children":8527},{"emptyLinePlaceholder":13},[8528],{"type":35,"value":963},{"type":29,"tag":890,"props":8530,"children":8532},{"class":892,"line":8531},51,[8533,8537,8541,8545,8549,8553,8558,8562,8567],{"type":29,"tag":890,"props":8534,"children":8535},{"style":906},[8536],{"type":35,"value":7723},{"type":29,"tag":890,"props":8538,"children":8539},{"style":5690},[8540],{"type":35,"value":7099},{"type":29,"tag":890,"props":8542,"children":8543},{"style":936},[8544],{"type":35,"value":6960},{"type":29,"tag":890,"props":8546,"children":8547},{"style":7890},[8548],{"type":35,"value":7893},{"type":29,"tag":890,"props":8550,"children":8551},{"style":5378},[8552],{"type":35,"value":5198},{"type":29,"tag":890,"props":8554,"children":8555},{"style":912},[8556],{"type":35,"value":8557},"(mockRepository",{"type":29,"tag":890,"props":8559,"children":8560},{"style":5201},[8561],{"type":35,"value":3653},{"type":29,"tag":890,"props":8563,"children":8564},{"style":912},[8565],{"type":35,"value":8566}," mockPayment)",{"type":29,"tag":890,"props":8568,"children":8569},{"style":5201},[8570],{"type":35,"value":7348},{"type":29,"tag":890,"props":8572,"children":8574},{"class":892,"line":8573},52,[8575,8579,8584,8588,8592,8596,8600,8605,8609,8613,8618,8622,8627,8631,8635,8639,8644,8648,8652],{"type":29,"tag":890,"props":8576,"children":8577},{"style":906},[8578],{"type":35,"value":7723},{"type":29,"tag":890,"props":8580,"children":8581},{"style":5690},[8582],{"type":35,"value":8583}," order",{"type":29,"tag":890,"props":8585,"children":8586},{"style":936},[8587],{"type":35,"value":6960},{"type":29,"tag":890,"props":8589,"children":8590},{"style":906},[8591],{"type":35,"value":7737},{"type":29,"tag":890,"props":8593,"children":8594},{"style":912},[8595],{"type":35,"value":7099},{"type":29,"tag":890,"props":8597,"children":8598},{"style":7746},[8599],{"type":35,"value":332},{"type":29,"tag":890,"props":8601,"children":8602},{"style":5378},[8603],{"type":35,"value":8604},"createPaidOrder",{"type":29,"tag":890,"props":8606,"children":8607},{"style":912},[8608],{"type":35,"value":3070},{"type":29,"tag":890,"props":8610,"children":8611},{"style":5201},[8612],{"type":35,"value":2235},{"type":29,"tag":890,"props":8614,"children":8615},{"style":912},[8616],{"type":35,"value":8617}," total",{"type":29,"tag":890,"props":8619,"children":8620},{"style":7746},[8621],{"type":35,"value":5776},{"type":29,"tag":890,"props":8623,"children":8624},{"style":5296},[8625],{"type":35,"value":8626}," 1000",{"type":29,"tag":890,"props":8628,"children":8629},{"style":5201},[8630],{"type":35,"value":3653},{"type":29,"tag":890,"props":8632,"children":8633},{"style":912},[8634],{"type":35,"value":7480},{"type":29,"tag":890,"props":8636,"children":8637},{"style":7746},[8638],{"type":35,"value":5776},{"type":29,"tag":890,"props":8640,"children":8641},{"style":2226},[8642],{"type":35,"value":8643}," 'EUR'",{"type":29,"tag":890,"props":8645,"children":8646},{"style":5201},[8647],{"type":35,"value":8377},{"type":29,"tag":890,"props":8649,"children":8650},{"style":912},[8651],{"type":35,"value":2871},{"type":29,"tag":890,"props":8653,"children":8654},{"style":5201},[8655],{"type":35,"value":7348},{"type":29,"tag":890,"props":8657,"children":8659},{"class":892,"line":8658},53,[8660],{"type":29,"tag":890,"props":8661,"children":8662},{"emptyLinePlaceholder":13},[8663],{"type":35,"value":963},{"type":29,"tag":890,"props":8665,"children":8667},{"class":892,"line":8666},54,[8668,8673,8678,8682,8687,8691,8696,8700,8705,8709],{"type":29,"tag":890,"props":8669,"children":8670},{"style":5378},[8671],{"type":35,"value":8672},"        expect",{"type":29,"tag":890,"props":8674,"children":8675},{"style":912},[8676],{"type":35,"value":8677},"(order",{"type":29,"tag":890,"props":8679,"children":8680},{"style":7746},[8681],{"type":35,"value":332},{"type":29,"tag":890,"props":8683,"children":8684},{"style":912},[8685],{"type":35,"value":8686},"status)",{"type":29,"tag":890,"props":8688,"children":8689},{"style":7746},[8690],{"type":35,"value":332},{"type":29,"tag":890,"props":8692,"children":8693},{"style":5378},[8694],{"type":35,"value":8695},"toBe",{"type":29,"tag":890,"props":8697,"children":8698},{"style":912},[8699],{"type":35,"value":3070},{"type":29,"tag":890,"props":8701,"children":8702},{"style":2226},[8703],{"type":35,"value":8704},"'paid'",{"type":29,"tag":890,"props":8706,"children":8707},{"style":912},[8708],{"type":35,"value":2871},{"type":29,"tag":890,"props":8710,"children":8711},{"style":5201},[8712],{"type":35,"value":7348},{"type":29,"tag":890,"props":8714,"children":8716},{"class":892,"line":8715},55,[8717,8722,8726],{"type":29,"tag":890,"props":8718,"children":8719},{"style":5201},[8720],{"type":35,"value":8721},"    }",{"type":29,"tag":890,"props":8723,"children":8724},{"style":912},[8725],{"type":35,"value":2871},{"type":29,"tag":890,"props":8727,"children":8728},{"style":5201},[8729],{"type":35,"value":7348},{"type":29,"tag":890,"props":8731,"children":8733},{"class":892,"line":8732},56,[8734,8738,8742],{"type":29,"tag":890,"props":8735,"children":8736},{"style":5201},[8737],{"type":35,"value":2245},{"type":29,"tag":890,"props":8739,"children":8740},{"style":912},[8741],{"type":35,"value":2871},{"type":29,"tag":890,"props":8743,"children":8744},{"style":5201},[8745],{"type":35,"value":7348},{"type":29,"tag":37,"props":8747,"children":8748},{},[8749,8754],{"type":29,"tag":55,"props":8750,"children":8751},{},[8752],{"type":35,"value":8753},"L'avantage TypeScript :",{"type":35,"value":8755}," les interfaces sont vérifiées à la compilation. Si une implémentation ne respecte pas l'interface, le compilateur rejette le code avant même l'exécution.",{"type":29,"tag":66,"props":8757,"children":8758},{},[],{"type":29,"tag":70,"props":8760,"children":8762},{"id":8761},"exemple-3-java-le-dip-avec-spring",[8763],{"type":35,"value":8764},"Exemple 3 : Java, le DIP avec Spring",{"type":29,"tag":640,"props":8766,"children":8770},{"code":8767,"language":8768,"meta":8,"className":8769,"style":8},"// L'abstraction\npublic interface NotificationService {\n    void sendOrderConfirmation(String userId, String orderId);\n    void sendShippingUpdate(String userId, String orderId, String trackingCode);\n}\n\n// Le module de haut niveau (service métier)\n@Service\npublic class OrderFulfillmentService {\n\n    private final OrderRepository orderRepository;\n    private final NotificationService notificationService;\n\n    public OrderFulfillmentService(\n            OrderRepository orderRepository,\n            NotificationService notificationService) {\n        this.orderRepository = orderRepository;\n        this.notificationService = notificationService;\n    }\n\n    public void fulfillOrder(String orderId) {\n        Order order = orderRepository.findById(orderId)\n            .orElseThrow(() -> new OrderNotFoundException(orderId));\n\n        order.setStatus(OrderStatus.FULFILLING);\n        orderRepository.save(order);\n\n        notificationService.sendOrderConfirmation(order.getUserId(), orderId);\n    }\n}\n\n// Implémentation de test\n@Service\n@Profile(\"test\")\npublic class MockNotificationService implements NotificationService {\n\n    private final List\u003CString> sentNotifications = new ArrayList\u003C>();\n\n    @Override\n    public void sendOrderConfirmation(String userId, String orderId) {\n        sentNotifications.add(\"confirmation:\" + userId + \":\" + orderId);\n    }\n}\n","java","language-java shiki shiki-themes catppuccin-frappe github-dark",[8771],{"type":29,"tag":554,"props":8772,"children":8773},{"__ignoreMap":8},[8774,8782,8804,8850,8903,8910,8917,8925,8940,8961,8968,8994,9018,9025,9041,9057,9077,9106,9134,9141,9148,9185,9226,9270,9277,9316,9345,9352,9399,9406,9413,9420,9428,9439,9464,9493,9500,9551,9558,9571,9618,9676,9683],{"type":29,"tag":890,"props":8775,"children":8776},{"class":892,"line":893},[8777],{"type":29,"tag":890,"props":8778,"children":8779},{"style":897},[8780],{"type":35,"value":8781},"// L'abstraction\n",{"type":29,"tag":890,"props":8783,"children":8784},{"class":892,"line":453},[8785,8790,8795,8800],{"type":29,"tag":890,"props":8786,"children":8787},{"style":906},[8788],{"type":35,"value":8789},"public",{"type":29,"tag":890,"props":8791,"children":8792},{"style":906},[8793],{"type":35,"value":8794}," interface",{"type":29,"tag":890,"props":8796,"children":8797},{"style":5195},[8798],{"type":35,"value":8799}," NotificationService",{"type":29,"tag":890,"props":8801,"children":8802},{"style":5201},[8803],{"type":35,"value":7288},{"type":29,"tag":890,"props":8805,"children":8806},{"class":892,"line":459},[8807,8812,8817,8821,8827,8832,8836,8841,8845],{"type":29,"tag":890,"props":8808,"children":8809},{"style":906},[8810],{"type":35,"value":8811},"    void",{"type":29,"tag":890,"props":8813,"children":8814},{"style":5378},[8815],{"type":35,"value":8816}," sendOrderConfirmation",{"type":29,"tag":890,"props":8818,"children":8819},{"style":5201},[8820],{"type":35,"value":3070},{"type":29,"tag":890,"props":8822,"children":8824},{"style":8823},"--shiki-default:#CA9EE6;--shiki-dark:#E1E4E8",[8825],{"type":35,"value":8826},"String",{"type":29,"tag":890,"props":8828,"children":8829},{"style":5268},[8830],{"type":35,"value":8831}," userId",{"type":29,"tag":890,"props":8833,"children":8834},{"style":5201},[8835],{"type":35,"value":3653},{"type":29,"tag":890,"props":8837,"children":8838},{"style":8823},[8839],{"type":35,"value":8840}," String",{"type":29,"tag":890,"props":8842,"children":8843},{"style":5268},[8844],{"type":35,"value":7943},{"type":29,"tag":890,"props":8846,"children":8847},{"style":5201},[8848],{"type":35,"value":8849},");\n",{"type":29,"tag":890,"props":8851,"children":8852},{"class":892,"line":957},[8853,8857,8862,8866,8870,8874,8878,8882,8886,8890,8894,8899],{"type":29,"tag":890,"props":8854,"children":8855},{"style":906},[8856],{"type":35,"value":8811},{"type":29,"tag":890,"props":8858,"children":8859},{"style":5378},[8860],{"type":35,"value":8861}," sendShippingUpdate",{"type":29,"tag":890,"props":8863,"children":8864},{"style":5201},[8865],{"type":35,"value":3070},{"type":29,"tag":890,"props":8867,"children":8868},{"style":8823},[8869],{"type":35,"value":8826},{"type":29,"tag":890,"props":8871,"children":8872},{"style":5268},[8873],{"type":35,"value":8831},{"type":29,"tag":890,"props":8875,"children":8876},{"style":5201},[8877],{"type":35,"value":3653},{"type":29,"tag":890,"props":8879,"children":8880},{"style":8823},[8881],{"type":35,"value":8840},{"type":29,"tag":890,"props":8883,"children":8884},{"style":5268},[8885],{"type":35,"value":7943},{"type":29,"tag":890,"props":8887,"children":8888},{"style":5201},[8889],{"type":35,"value":3653},{"type":29,"tag":890,"props":8891,"children":8892},{"style":8823},[8893],{"type":35,"value":8840},{"type":29,"tag":890,"props":8895,"children":8896},{"style":5268},[8897],{"type":35,"value":8898}," trackingCode",{"type":29,"tag":890,"props":8900,"children":8901},{"style":5201},[8902],{"type":35,"value":8849},{"type":29,"tag":890,"props":8904,"children":8905},{"class":892,"line":966},[8906],{"type":29,"tag":890,"props":8907,"children":8908},{"style":5201},[8909],{"type":35,"value":7422},{"type":29,"tag":890,"props":8911,"children":8912},{"class":892,"line":975},[8913],{"type":29,"tag":890,"props":8914,"children":8915},{"emptyLinePlaceholder":13},[8916],{"type":35,"value":963},{"type":29,"tag":890,"props":8918,"children":8919},{"class":892,"line":996},[8920],{"type":29,"tag":890,"props":8921,"children":8922},{"style":897},[8923],{"type":35,"value":8924},"// Le module de haut niveau (service métier)\n",{"type":29,"tag":890,"props":8926,"children":8927},{"class":892,"line":5370},[8928,8934],{"type":29,"tag":890,"props":8929,"children":8931},{"style":8930},"--shiki-default:#EF9F76;--shiki-dark:#E1E4E8",[8932],{"type":35,"value":8933},"@",{"type":29,"tag":890,"props":8935,"children":8937},{"style":8936},"--shiki-default:#EF9F76;--shiki-dark:#F97583",[8938],{"type":35,"value":8939},"Service\n",{"type":29,"tag":890,"props":8941,"children":8942},{"class":892,"line":5406},[8943,8947,8952,8957],{"type":29,"tag":890,"props":8944,"children":8945},{"style":906},[8946],{"type":35,"value":8789},{"type":29,"tag":890,"props":8948,"children":8949},{"style":906},[8950],{"type":35,"value":8951}," class",{"type":29,"tag":890,"props":8953,"children":8954},{"style":5195},[8955],{"type":35,"value":8956}," OrderFulfillmentService",{"type":29,"tag":890,"props":8958,"children":8959},{"style":5201},[8960],{"type":35,"value":7288},{"type":29,"tag":890,"props":8962,"children":8963},{"class":892,"line":5456},[8964],{"type":29,"tag":890,"props":8965,"children":8966},{"emptyLinePlaceholder":13},[8967],{"type":35,"value":963},{"type":29,"tag":890,"props":8969,"children":8970},{"class":892,"line":5522},[8971,8976,8981,8985,8990],{"type":29,"tag":890,"props":8972,"children":8973},{"style":906},[8974],{"type":35,"value":8975},"    private",{"type":29,"tag":890,"props":8977,"children":8978},{"style":906},[8979],{"type":35,"value":8980}," final",{"type":29,"tag":890,"props":8982,"children":8983},{"style":8823},[8984],{"type":35,"value":5721},{"type":29,"tag":890,"props":8986,"children":8987},{"style":912},[8988],{"type":35,"value":8989}," orderRepository",{"type":29,"tag":890,"props":8991,"children":8992},{"style":5201},[8993],{"type":35,"value":7348},{"type":29,"tag":890,"props":8995,"children":8996},{"class":892,"line":5927},[8997,9001,9005,9009,9014],{"type":29,"tag":890,"props":8998,"children":8999},{"style":906},[9000],{"type":35,"value":8975},{"type":29,"tag":890,"props":9002,"children":9003},{"style":906},[9004],{"type":35,"value":8980},{"type":29,"tag":890,"props":9006,"children":9007},{"style":8823},[9008],{"type":35,"value":8799},{"type":29,"tag":890,"props":9010,"children":9011},{"style":912},[9012],{"type":35,"value":9013}," notificationService",{"type":29,"tag":890,"props":9015,"children":9016},{"style":5201},[9017],{"type":35,"value":7348},{"type":29,"tag":890,"props":9019,"children":9020},{"class":892,"line":5935},[9021],{"type":29,"tag":890,"props":9022,"children":9023},{"emptyLinePlaceholder":13},[9024],{"type":35,"value":963},{"type":29,"tag":890,"props":9026,"children":9027},{"class":892,"line":5944},[9028,9033,9037],{"type":29,"tag":890,"props":9029,"children":9030},{"style":906},[9031],{"type":35,"value":9032},"    public",{"type":29,"tag":890,"props":9034,"children":9035},{"style":5378},[9036],{"type":35,"value":8956},{"type":29,"tag":890,"props":9038,"children":9039},{"style":5201},[9040],{"type":35,"value":7584},{"type":29,"tag":890,"props":9042,"children":9043},{"class":892,"line":5960},[9044,9049,9053],{"type":29,"tag":890,"props":9045,"children":9046},{"style":8823},[9047],{"type":35,"value":9048},"            OrderRepository",{"type":29,"tag":890,"props":9050,"children":9051},{"style":5268},[9052],{"type":35,"value":8989},{"type":29,"tag":890,"props":9054,"children":9055},{"style":5201},[9056],{"type":35,"value":7614},{"type":29,"tag":890,"props":9058,"children":9059},{"class":892,"line":6019},[9060,9065,9069,9073],{"type":29,"tag":890,"props":9061,"children":9062},{"style":8823},[9063],{"type":35,"value":9064},"            NotificationService",{"type":29,"tag":890,"props":9066,"children":9067},{"style":5268},[9068],{"type":35,"value":9013},{"type":29,"tag":890,"props":9070,"children":9071},{"style":5201},[9072],{"type":35,"value":2871},{"type":29,"tag":890,"props":9074,"children":9075},{"style":5201},[9076],{"type":35,"value":7288},{"type":29,"tag":890,"props":9078,"children":9079},{"class":892,"line":6045},[9080,9085,9089,9094,9098,9102],{"type":29,"tag":890,"props":9081,"children":9082},{"style":7740},[9083],{"type":35,"value":9084},"        this",{"type":29,"tag":890,"props":9086,"children":9087},{"style":5201},[9088],{"type":35,"value":332},{"type":29,"tag":890,"props":9090,"children":9091},{"style":912},[9092],{"type":35,"value":9093},"orderRepository ",{"type":29,"tag":890,"props":9095,"children":9096},{"style":936},[9097],{"type":35,"value":2217},{"type":29,"tag":890,"props":9099,"children":9100},{"style":912},[9101],{"type":35,"value":8989},{"type":29,"tag":890,"props":9103,"children":9104},{"style":5201},[9105],{"type":35,"value":7348},{"type":29,"tag":890,"props":9107,"children":9108},{"class":892,"line":6071},[9109,9113,9117,9122,9126,9130],{"type":29,"tag":890,"props":9110,"children":9111},{"style":7740},[9112],{"type":35,"value":9084},{"type":29,"tag":890,"props":9114,"children":9115},{"style":5201},[9116],{"type":35,"value":332},{"type":29,"tag":890,"props":9118,"children":9119},{"style":912},[9120],{"type":35,"value":9121},"notificationService ",{"type":29,"tag":890,"props":9123,"children":9124},{"style":936},[9125],{"type":35,"value":2217},{"type":29,"tag":890,"props":9127,"children":9128},{"style":912},[9129],{"type":35,"value":9013},{"type":29,"tag":890,"props":9131,"children":9132},{"style":5201},[9133],{"type":35,"value":7348},{"type":29,"tag":890,"props":9135,"children":9136},{"class":892,"line":6079},[9137],{"type":29,"tag":890,"props":9138,"children":9139},{"style":5201},[9140],{"type":35,"value":8109},{"type":29,"tag":890,"props":9142,"children":9143},{"class":892,"line":6131},[9144],{"type":29,"tag":890,"props":9145,"children":9146},{"emptyLinePlaceholder":13},[9147],{"type":35,"value":963},{"type":29,"tag":890,"props":9149,"children":9150},{"class":892,"line":6176},[9151,9155,9160,9165,9169,9173,9177,9181],{"type":29,"tag":890,"props":9152,"children":9153},{"style":906},[9154],{"type":35,"value":9032},{"type":29,"tag":890,"props":9156,"children":9157},{"style":906},[9158],{"type":35,"value":9159}," void",{"type":29,"tag":890,"props":9161,"children":9162},{"style":5378},[9163],{"type":35,"value":9164}," fulfillOrder",{"type":29,"tag":890,"props":9166,"children":9167},{"style":5201},[9168],{"type":35,"value":3070},{"type":29,"tag":890,"props":9170,"children":9171},{"style":8823},[9172],{"type":35,"value":8826},{"type":29,"tag":890,"props":9174,"children":9175},{"style":5268},[9176],{"type":35,"value":7943},{"type":29,"tag":890,"props":9178,"children":9179},{"style":5201},[9180],{"type":35,"value":2871},{"type":29,"tag":890,"props":9182,"children":9183},{"style":5201},[9184],{"type":35,"value":7288},{"type":29,"tag":890,"props":9186,"children":9187},{"class":892,"line":6237},[9188,9193,9198,9202,9206,9210,9214,9218,9222],{"type":29,"tag":890,"props":9189,"children":9190},{"style":8823},[9191],{"type":35,"value":9192},"        Order",{"type":29,"tag":890,"props":9194,"children":9195},{"style":912},[9196],{"type":35,"value":9197}," order ",{"type":29,"tag":890,"props":9199,"children":9200},{"style":936},[9201],{"type":35,"value":2217},{"type":29,"tag":890,"props":9203,"children":9204},{"style":912},[9205],{"type":35,"value":8989},{"type":29,"tag":890,"props":9207,"children":9208},{"style":5201},[9209],{"type":35,"value":332},{"type":29,"tag":890,"props":9211,"children":9212},{"style":5378},[9213],{"type":35,"value":8092},{"type":29,"tag":890,"props":9215,"children":9216},{"style":5201},[9217],{"type":35,"value":3070},{"type":29,"tag":890,"props":9219,"children":9220},{"style":912},[9221],{"type":35,"value":7365},{"type":29,"tag":890,"props":9223,"children":9224},{"style":5201},[9225],{"type":35,"value":5453},{"type":29,"tag":890,"props":9227,"children":9228},{"class":892,"line":6249},[9229,9234,9239,9244,9248,9252,9257,9261,9265],{"type":29,"tag":890,"props":9230,"children":9231},{"style":5201},[9232],{"type":35,"value":9233},"            .",{"type":29,"tag":890,"props":9235,"children":9236},{"style":5378},[9237],{"type":35,"value":9238},"orElseThrow",{"type":29,"tag":890,"props":9240,"children":9241},{"style":5201},[9242],{"type":35,"value":9243},"(()",{"type":29,"tag":890,"props":9245,"children":9246},{"style":906},[9247],{"type":35,"value":5791},{"type":29,"tag":890,"props":9249,"children":9250},{"style":906},[9251],{"type":35,"value":7893},{"type":29,"tag":890,"props":9253,"children":9254},{"style":5378},[9255],{"type":35,"value":9256}," OrderNotFoundException",{"type":29,"tag":890,"props":9258,"children":9259},{"style":5201},[9260],{"type":35,"value":3070},{"type":29,"tag":890,"props":9262,"children":9263},{"style":912},[9264],{"type":35,"value":7365},{"type":29,"tag":890,"props":9266,"children":9267},{"style":5201},[9268],{"type":35,"value":9269},"));\n",{"type":29,"tag":890,"props":9271,"children":9272},{"class":892,"line":6257},[9273],{"type":29,"tag":890,"props":9274,"children":9275},{"emptyLinePlaceholder":13},[9276],{"type":35,"value":963},{"type":29,"tag":890,"props":9278,"children":9279},{"class":892,"line":6266},[9280,9285,9289,9294,9298,9303,9307,9312],{"type":29,"tag":890,"props":9281,"children":9282},{"style":912},[9283],{"type":35,"value":9284},"        order",{"type":29,"tag":890,"props":9286,"children":9287},{"style":5201},[9288],{"type":35,"value":332},{"type":29,"tag":890,"props":9290,"children":9291},{"style":5378},[9292],{"type":35,"value":9293},"setStatus",{"type":29,"tag":890,"props":9295,"children":9296},{"style":5201},[9297],{"type":35,"value":3070},{"type":29,"tag":890,"props":9299,"children":9300},{"style":912},[9301],{"type":35,"value":9302},"OrderStatus",{"type":29,"tag":890,"props":9304,"children":9305},{"style":5201},[9306],{"type":35,"value":332},{"type":29,"tag":890,"props":9308,"children":9309},{"style":912},[9310],{"type":35,"value":9311},"FULFILLING",{"type":29,"tag":890,"props":9313,"children":9314},{"style":5201},[9315],{"type":35,"value":8849},{"type":29,"tag":890,"props":9317,"children":9318},{"class":892,"line":6291},[9319,9324,9328,9332,9336,9341],{"type":29,"tag":890,"props":9320,"children":9321},{"style":912},[9322],{"type":35,"value":9323},"        orderRepository",{"type":29,"tag":890,"props":9325,"children":9326},{"style":5201},[9327],{"type":35,"value":332},{"type":29,"tag":890,"props":9329,"children":9330},{"style":5378},[9331],{"type":35,"value":5439},{"type":29,"tag":890,"props":9333,"children":9334},{"style":5201},[9335],{"type":35,"value":3070},{"type":29,"tag":890,"props":9337,"children":9338},{"style":912},[9339],{"type":35,"value":9340},"order",{"type":29,"tag":890,"props":9342,"children":9343},{"style":5201},[9344],{"type":35,"value":8849},{"type":29,"tag":890,"props":9346,"children":9347},{"class":892,"line":6343},[9348],{"type":29,"tag":890,"props":9349,"children":9350},{"emptyLinePlaceholder":13},[9351],{"type":35,"value":963},{"type":29,"tag":890,"props":9353,"children":9354},{"class":892,"line":6393},[9355,9360,9364,9369,9373,9377,9381,9386,9391,9395],{"type":29,"tag":890,"props":9356,"children":9357},{"style":912},[9358],{"type":35,"value":9359},"        notificationService",{"type":29,"tag":890,"props":9361,"children":9362},{"style":5201},[9363],{"type":35,"value":332},{"type":29,"tag":890,"props":9365,"children":9366},{"style":5378},[9367],{"type":35,"value":9368},"sendOrderConfirmation",{"type":29,"tag":890,"props":9370,"children":9371},{"style":5201},[9372],{"type":35,"value":3070},{"type":29,"tag":890,"props":9374,"children":9375},{"style":912},[9376],{"type":35,"value":9340},{"type":29,"tag":890,"props":9378,"children":9379},{"style":5201},[9380],{"type":35,"value":332},{"type":29,"tag":890,"props":9382,"children":9383},{"style":5378},[9384],{"type":35,"value":9385},"getUserId",{"type":29,"tag":890,"props":9387,"children":9388},{"style":5201},[9389],{"type":35,"value":9390},"(),",{"type":29,"tag":890,"props":9392,"children":9393},{"style":912},[9394],{"type":35,"value":7943},{"type":29,"tag":890,"props":9396,"children":9397},{"style":5201},[9398],{"type":35,"value":8849},{"type":29,"tag":890,"props":9400,"children":9401},{"class":892,"line":6401},[9402],{"type":29,"tag":890,"props":9403,"children":9404},{"style":5201},[9405],{"type":35,"value":8109},{"type":29,"tag":890,"props":9407,"children":9408},{"class":892,"line":5101},[9409],{"type":29,"tag":890,"props":9410,"children":9411},{"style":5201},[9412],{"type":35,"value":7422},{"type":29,"tag":890,"props":9414,"children":9415},{"class":892,"line":4563},[9416],{"type":29,"tag":890,"props":9417,"children":9418},{"emptyLinePlaceholder":13},[9419],{"type":35,"value":963},{"type":29,"tag":890,"props":9421,"children":9422},{"class":892,"line":4099},[9423],{"type":29,"tag":890,"props":9424,"children":9425},{"style":897},[9426],{"type":35,"value":9427},"// Implémentation de test\n",{"type":29,"tag":890,"props":9429,"children":9430},{"class":892,"line":6595},[9431,9435],{"type":29,"tag":890,"props":9432,"children":9433},{"style":8930},[9434],{"type":35,"value":8933},{"type":29,"tag":890,"props":9436,"children":9437},{"style":8936},[9438],{"type":35,"value":8939},{"type":29,"tag":890,"props":9440,"children":9441},{"class":892,"line":1263},[9442,9446,9451,9455,9460],{"type":29,"tag":890,"props":9443,"children":9444},{"style":8930},[9445],{"type":35,"value":8933},{"type":29,"tag":890,"props":9447,"children":9448},{"style":8936},[9449],{"type":35,"value":9450},"Profile",{"type":29,"tag":890,"props":9452,"children":9453},{"style":5201},[9454],{"type":35,"value":3070},{"type":29,"tag":890,"props":9456,"children":9457},{"style":2226},[9458],{"type":35,"value":9459},"\"test\"",{"type":29,"tag":890,"props":9461,"children":9462},{"style":5201},[9463],{"type":35,"value":5453},{"type":29,"tag":890,"props":9465,"children":9466},{"class":892,"line":477},[9467,9471,9475,9480,9485,9489],{"type":29,"tag":890,"props":9468,"children":9469},{"style":906},[9470],{"type":35,"value":8789},{"type":29,"tag":890,"props":9472,"children":9473},{"style":906},[9474],{"type":35,"value":8951},{"type":29,"tag":890,"props":9476,"children":9477},{"style":5195},[9478],{"type":35,"value":9479}," MockNotificationService",{"type":29,"tag":890,"props":9481,"children":9482},{"style":906},[9483],{"type":35,"value":9484}," implements",{"type":29,"tag":890,"props":9486,"children":9487},{"style":5195},[9488],{"type":35,"value":8799},{"type":29,"tag":890,"props":9490,"children":9491},{"style":5201},[9492],{"type":35,"value":7288},{"type":29,"tag":890,"props":9494,"children":9495},{"class":892,"line":11},[9496],{"type":29,"tag":890,"props":9497,"children":9498},{"emptyLinePlaceholder":13},[9499],{"type":35,"value":963},{"type":29,"tag":890,"props":9501,"children":9502},{"class":892,"line":2110},[9503,9507,9511,9516,9520,9524,9528,9533,9537,9541,9546],{"type":29,"tag":890,"props":9504,"children":9505},{"style":906},[9506],{"type":35,"value":8975},{"type":29,"tag":890,"props":9508,"children":9509},{"style":906},[9510],{"type":35,"value":8980},{"type":29,"tag":890,"props":9512,"children":9513},{"style":8823},[9514],{"type":35,"value":9515}," List",{"type":29,"tag":890,"props":9517,"children":9518},{"style":5201},[9519],{"type":35,"value":7333},{"type":29,"tag":890,"props":9521,"children":9522},{"style":906},[9523],{"type":35,"value":8826},{"type":29,"tag":890,"props":9525,"children":9526},{"style":5201},[9527],{"type":35,"value":7343},{"type":29,"tag":890,"props":9529,"children":9530},{"style":912},[9531],{"type":35,"value":9532}," sentNotifications ",{"type":29,"tag":890,"props":9534,"children":9535},{"style":936},[9536],{"type":35,"value":2217},{"type":29,"tag":890,"props":9538,"children":9539},{"style":906},[9540],{"type":35,"value":7893},{"type":29,"tag":890,"props":9542,"children":9543},{"style":8823},[9544],{"type":35,"value":9545}," ArrayList",{"type":29,"tag":890,"props":9547,"children":9548},{"style":5201},[9549],{"type":35,"value":9550},"\u003C>();\n",{"type":29,"tag":890,"props":9552,"children":9553},{"class":892,"line":8119},[9554],{"type":29,"tag":890,"props":9555,"children":9556},{"emptyLinePlaceholder":13},[9557],{"type":35,"value":963},{"type":29,"tag":890,"props":9559,"children":9560},{"class":892,"line":8127},[9561,9566],{"type":29,"tag":890,"props":9562,"children":9563},{"style":8930},[9564],{"type":35,"value":9565},"    @",{"type":29,"tag":890,"props":9567,"children":9568},{"style":8936},[9569],{"type":35,"value":9570},"Override\n",{"type":29,"tag":890,"props":9572,"children":9573},{"class":892,"line":8136},[9574,9578,9582,9586,9590,9594,9598,9602,9606,9610,9614],{"type":29,"tag":890,"props":9575,"children":9576},{"style":906},[9577],{"type":35,"value":9032},{"type":29,"tag":890,"props":9579,"children":9580},{"style":906},[9581],{"type":35,"value":9159},{"type":29,"tag":890,"props":9583,"children":9584},{"style":5378},[9585],{"type":35,"value":8816},{"type":29,"tag":890,"props":9587,"children":9588},{"style":5201},[9589],{"type":35,"value":3070},{"type":29,"tag":890,"props":9591,"children":9592},{"style":8823},[9593],{"type":35,"value":8826},{"type":29,"tag":890,"props":9595,"children":9596},{"style":5268},[9597],{"type":35,"value":8831},{"type":29,"tag":890,"props":9599,"children":9600},{"style":5201},[9601],{"type":35,"value":3653},{"type":29,"tag":890,"props":9603,"children":9604},{"style":8823},[9605],{"type":35,"value":8840},{"type":29,"tag":890,"props":9607,"children":9608},{"style":5268},[9609],{"type":35,"value":7943},{"type":29,"tag":890,"props":9611,"children":9612},{"style":5201},[9613],{"type":35,"value":2871},{"type":29,"tag":890,"props":9615,"children":9616},{"style":5201},[9617],{"type":35,"value":7288},{"type":29,"tag":890,"props":9619,"children":9620},{"class":892,"line":8172},[9621,9626,9630,9635,9639,9644,9649,9654,9659,9664,9668,9672],{"type":29,"tag":890,"props":9622,"children":9623},{"style":912},[9624],{"type":35,"value":9625},"        sentNotifications",{"type":29,"tag":890,"props":9627,"children":9628},{"style":5201},[9629],{"type":35,"value":332},{"type":29,"tag":890,"props":9631,"children":9632},{"style":5378},[9633],{"type":35,"value":9634},"add",{"type":29,"tag":890,"props":9636,"children":9637},{"style":5201},[9638],{"type":35,"value":3070},{"type":29,"tag":890,"props":9640,"children":9641},{"style":2226},[9642],{"type":35,"value":9643},"\"confirmation:\"",{"type":29,"tag":890,"props":9645,"children":9646},{"style":936},[9647],{"type":35,"value":9648}," +",{"type":29,"tag":890,"props":9650,"children":9651},{"style":912},[9652],{"type":35,"value":9653}," userId ",{"type":29,"tag":890,"props":9655,"children":9656},{"style":936},[9657],{"type":35,"value":9658},"+",{"type":29,"tag":890,"props":9660,"children":9661},{"style":2226},[9662],{"type":35,"value":9663}," \":\"",{"type":29,"tag":890,"props":9665,"children":9666},{"style":936},[9667],{"type":35,"value":9648},{"type":29,"tag":890,"props":9669,"children":9670},{"style":912},[9671],{"type":35,"value":7943},{"type":29,"tag":890,"props":9673,"children":9674},{"style":5201},[9675],{"type":35,"value":8849},{"type":29,"tag":890,"props":9677,"children":9678},{"class":892,"line":8211},[9679],{"type":29,"tag":890,"props":9680,"children":9681},{"style":5201},[9682],{"type":35,"value":8109},{"type":29,"tag":890,"props":9684,"children":9685},{"class":892,"line":8240},[9686],{"type":29,"tag":890,"props":9687,"children":9688},{"style":5201},[9689],{"type":35,"value":7422},{"type":29,"tag":37,"props":9691,"children":9692},{},[9693,9698,9700,9706],{"type":29,"tag":55,"props":9694,"children":9695},{},[9696],{"type":35,"value":9697},"L'avantage Spring :",{"type":35,"value":9699}," ",{"type":29,"tag":554,"props":9701,"children":9703},{"className":9702},[],[9704],{"type":35,"value":9705},"@Profile(\"test\")",{"type":35,"value":9707}," permet d'utiliser automatiquement le mock en environnement de test sans modifier le code métier. Le framework gère le wiring, le code métier reste pur.",{"type":29,"tag":66,"props":9709,"children":9710},{},[],{"type":29,"tag":70,"props":9712,"children":9714},{"id":9713},"quand-appliquer-le-dip-et-quand-ne-pas-le-faire",[9715],{"type":35,"value":9716},"Quand appliquer le DIP, et quand ne pas le faire",{"type":29,"tag":37,"props":9718,"children":9719},{},[9720],{"type":29,"tag":55,"props":9721,"children":9722},{},[9723],{"type":35,"value":9724},"Appliquer le DIP :",{"type":29,"tag":1069,"props":9726,"children":9727},{},[9728,9733,9738],{"type":29,"tag":1073,"props":9729,"children":9730},{},[9731],{"type":35,"value":9732},"Toute dépendance vers un système externe (base de données, API tierce, service d'email, service de paiement, file de message)",{"type":29,"tag":1073,"props":9734,"children":9735},{},[9736],{"type":35,"value":9737},"Toute dépendance vers une infrastructure susceptible de changer",{"type":29,"tag":1073,"props":9739,"children":9740},{},[9741],{"type":35,"value":9742},"Tout code que vous voulez unit-tester sans infrastructure",{"type":29,"tag":37,"props":9744,"children":9745},{},[9746],{"type":29,"tag":55,"props":9747,"children":9748},{},[9749],{"type":35,"value":9750},"Ne pas appliquer le DIP mécaniquement :",{"type":29,"tag":1069,"props":9752,"children":9753},{},[9754,9759,9764],{"type":29,"tag":1073,"props":9755,"children":9756},{},[9757],{"type":35,"value":9758},"Les entités et value objects du domaine (Order, User, Money) : pas de logique d'infrastructure",{"type":29,"tag":1073,"props":9760,"children":9761},{},[9762],{"type":35,"value":9763},"Les utilitaires purs (calculs mathématiques, formatage de dates) : pas d'effet de bord",{"type":29,"tag":1073,"props":9765,"children":9766},{},[9767],{"type":35,"value":9768},"Les dépendances stables et peu susceptibles de changer dans des petits projets",{"type":29,"tag":37,"props":9770,"children":9771},{},[9772,9777,9779,9785],{"type":29,"tag":55,"props":9773,"children":9774},{},[9775],{"type":35,"value":9776},"Le signal",{"type":35,"value":9778}," : si écrire un test unitaire pour votre classe nécessite de démarrer une base de données, une queue de messages, ou de configurer un service externe, appliquez le DIP. Cette question est aussi centrale dans les ",{"type":29,"tag":43,"props":9780,"children":9782},{"href":9781},"/fr/dette-technique/tests-integration-legacy-pieges",[9783],{"type":35,"value":9784},"tests d'intégration sur du code legacy",{"type":35,"value":9786}," : l'absence de DIP est souvent ce qui rend ces tests si difficiles et si fragiles à mettre en place.",{"type":29,"tag":66,"props":9788,"children":9789},{},[],{"type":29,"tag":70,"props":9791,"children":9793},{"id":9792},"faq-sur-le-dependency-inversion-principle",[9794],{"type":35,"value":9795},"FAQ sur le Dependency Inversion Principle",{"type":29,"tag":371,"props":9797,"children":9798},{},[9799,9804],{"type":29,"tag":375,"props":9800,"children":9801},{},[9802],{"type":35,"value":9803},"1. Quelle est la différence entre DIP et Dependency Injection ?",{"type":29,"tag":37,"props":9805,"children":9806},{},[9807],{"type":35,"value":9808},"Le DIP est un principe architectural : les modules doivent dépendre d'abstractions. La Dependency Injection (DI) est une technique d'implémentation du DIP : les dépendances sont fournies de l'extérieur plutôt que créées à l'intérieur. On peut respecter le DIP sans DI (ex : factory pattern). On peut utiliser la DI sans respecter le DIP (ex : injecter une classe concrète sans interface). En pratique, les deux vont généralement ensemble.",{"type":29,"tag":371,"props":9810,"children":9811},{},[9812,9817],{"type":29,"tag":375,"props":9813,"children":9814},{},[9815],{"type":35,"value":9816},"2. Les containers DI (Spring, .NET DI, Angular) font-ils le travail à notre place ?",{"type":29,"tag":37,"props":9818,"children":9819},{},[9820],{"type":35,"value":9821},"Ils automatisent le wiring (qui injecte quoi), mais ne créent pas les abstractions à notre place. Spring injecte les classes concrètes si vous ne créez pas d'interfaces. La discipline architecturale de créer des interfaces pour les dépendances d'infrastructure reste une décision de l'équipe. Le framework ne peut pas la prendre à votre place.",{"type":29,"tag":371,"props":9823,"children":9824},{},[9825,9830],{"type":29,"tag":375,"props":9826,"children":9827},{},[9828],{"type":35,"value":9829},"3. Le DIP ne crée-t-il pas trop d'abstractions ?",{"type":29,"tag":37,"props":9831,"children":9832},{},[9833],{"type":35,"value":9834},"Oui, si mal appliqué. Créer une interface pour chaque classe, même les plus stables, est du sur-engineering. La règle que Martin Fowler formule clairement : créer une abstraction quand il y a au moins 2 implémentations possibles (production + test, provider A + provider B) ou quand la dépendance est vers un système externe. \"Pas d'abstraction prématurée\" s'applique au DIP comme à tout principe.",{"type":29,"tag":371,"props":9836,"children":9837},{},[9838,9843],{"type":29,"tag":375,"props":9839,"children":9840},{},[9841],{"type":35,"value":9842},"4. Comment introduire le DIP progressivement dans un codebase existant ?",{"type":29,"tag":37,"props":9844,"children":9845},{},[9846,9848,9854],{"type":35,"value":9847},"Le strangler fig pattern appliqué au DIP : ne pas refactorer tout le code existant d'un coup. À chaque nouvelle fonctionnalité ou bug fix qui touche une classe avec dépendances directes, extraire l'interface et introduire l'injection. Après 6 mois de cette discipline, les zones les plus actives du codebase respectent le DIP. Les zones stables peuvent rester dans l'état existant si elles ne causent pas de problèmes. Dans un contexte de ",{"type":29,"tag":43,"props":9849,"children":9851},{"href":9850},"/fr/dette-technique/legacy-code-evaluer-risque",[9852],{"type":35,"value":9853},"code legacy fortement couplé",{"type":35,"value":9855},", cette approche progressive est souvent la seule viable sans bloquer les livraisons.",{"type":29,"tag":371,"props":9857,"children":9858},{},[9859,9864],{"type":29,"tag":375,"props":9860,"children":9861},{},[9862],{"type":35,"value":9863},"5. Le DIP s'applique-t-il aux frontends (React, Vue) ?",{"type":29,"tag":37,"props":9865,"children":9866},{},[9867,9869,9875,9877,9883,9885,9891],{"type":35,"value":9868},"Oui. En React : les composants ne doivent pas appeler directement ",{"type":29,"tag":554,"props":9870,"children":9872},{"className":9871},[],[9873],{"type":35,"value":9874},"fetch()",{"type":35,"value":9876}," ou ",{"type":29,"tag":554,"props":9878,"children":9880},{"className":9879},[],[9881],{"type":35,"value":9882},"axios",{"type":35,"value":9884}," : ils doivent dépendre d'une abstraction (un service, un hook custom, un context) qui peut être mockée dans les tests. ",{"type":29,"tag":554,"props":9886,"children":9888},{"className":9887},[],[9889],{"type":35,"value":9890},"useOrderService()",{"type":35,"value":9892}," hook qui cache l'implémentation HTTP, facilement mockable dans les tests. Le DIP s'applique partout où il y a des effets de bord, frontend inclus.",{"type":29,"tag":66,"props":9894,"children":9895},{},[],{"type":29,"tag":166,"props":9897,"children":9898},{"cta":1232,"href":1233,"title":444,"type":445},[9899],{"type":29,"tag":37,"props":9900,"children":9901},{},[9902],{"type":35,"value":9903},"L'Engineering Maturity Self-Assessment couvre le domaine Craft & Conception : évaluez votre niveau sur les principes SOLID, le couplage, et la testabilité. Obtenez un score de maturité et des recommandations concrètes en 10 minutes.",{"type":29,"tag":1241,"props":9905,"children":9906},{},[9907],{"type":35,"value":1245},{"title":8,"searchDepth":453,"depth":453,"links":9909},[9910,9911,9912,9913,9914,9915,9916],{"id":5141,"depth":453,"text":5144},{"id":5593,"depth":453,"text":5596},{"id":5659,"depth":453,"text":5662},{"id":7251,"depth":453,"text":7254},{"id":8761,"depth":453,"text":8764},{"id":9713,"depth":453,"text":9716},{"id":9792,"depth":453,"text":9795},"content:fr:architecture-craft:dependency-inversion-pratique.md","fr/architecture-craft/dependency-inversion-pratique.md","fr/architecture-craft/dependency-inversion-pratique",{"_path":4958,"_dir":1260,"_draft":7,"_partial":7,"_locale":8,"title":9921,"description":9922,"id":6401,"date":9923,"listed":13,"nocomments":7,"hidden":7,"categories":9924,"tags":9925,"--cover":9929,"readingTime":9930,"body":9935,"_type":466,"_id":10584,"_source":468,"_file":10585,"_stem":10586,"_extension":471},"Engineering culture : les 6 rituels qui font la différence","La culture ne se proclame pas, elle se construit par des rituels répétés. Les 6 pratiques concrètes qui construisent une culture d'excellence technique sur 12 mois.","2026-03-11",[1260],[9926,9927,18,9928],"Engineering Culture","Rituels","Excellence Technique","covers/articles/engineering-culture-rituels.jpg",{"text":9931,"minutes":9932,"time":9933,"words":9934},"10 min read",9.295,557700,1859,{"type":26,"children":9936,"toc":10574},[9937,9942,9947,9952,9972,9977,9980,9986,9996,10001,10009,10037,10047,10050,10056,10065,10070,10078,10101,10111,10121,10130,10133,10139,10148,10153,10161,10184,10192,10215,10225,10228,10234,10243,10248,10256,10279,10289,10299,10302,10308,10317,10329,10339,10349,10359,10362,10368,10377,10382,10392,10416,10419,10425,10435,10443,10466,10476,10481,10484,10490,10511,10524,10537,10550,10563,10566],{"type":29,"tag":30,"props":9938,"children":9940},{"id":9939},"engineering-culture-les-6-rituels-qui-font-la-différence",[9941],{"type":35,"value":9921},{"type":29,"tag":37,"props":9943,"children":9944},{},[9945],{"type":35,"value":9946},"Dans un client dans le secteur financier où j'accompagnais l'équipe engineering, les valeurs d'entreprise affichaient \"excellence technique\" et \"partage de connaissance\" sur tous les murs. La réalité : chaque développeur gardait sa connaissance pour lui comme un avantage concurrentiel interne, les post-mortems cherchaient des coupables, et personne ne proposait de sujets pour les tech talks parce que personne n'avait jamais vu de tech talk se tenir.",{"type":29,"tag":37,"props":9948,"children":9949},{},[9950],{"type":35,"value":9951},"La culture n'était pas mauvaise parce que les valeurs étaient mauvaises. La culture était mauvaise parce qu'il n'y avait aucun rituel pour les incarner.",{"type":29,"tag":37,"props":9953,"children":9954},{},[9955,9957,9963,9965,9970],{"type":35,"value":9956},"Patrick Lencioni dans ",{"type":29,"tag":9958,"props":9959,"children":9960},"em",{},[9961],{"type":35,"value":9962},"The Five Dysfunctions of a Team",{"type":35,"value":9964}," et les recherches DORA sur l'état du DevOps convergent vers la même conclusion : ",{"type":29,"tag":55,"props":9966,"children":9967},{},[9968],{"type":35,"value":9969},"la performance d'une équipe engineering est davantage fonction de sa culture que de ses outils ou de ses processus",{"type":35,"value":9971},". Dans les 100 000 réponses analysées par le programme DORA chaque année, les équipes elite performers ont toutes en commun des pratiques culturelles spécifiques, pas des valeurs affichées. Des actes répétés.",{"type":29,"tag":37,"props":9973,"children":9974},{},[9975],{"type":35,"value":9976},"Voici les 6 rituels que j'ai implémentés et observés changer des équipes.",{"type":29,"tag":66,"props":9978,"children":9979},{},[],{"type":29,"tag":70,"props":9981,"children":9983},{"id":9982},"rituel-1-le-post-mortem-blameless",[9984],{"type":35,"value":9985},"Rituel 1 : Le post-mortem blameless",{"type":29,"tag":37,"props":9987,"children":9988},{},[9989,9994],{"type":29,"tag":55,"props":9990,"children":9991},{},[9992],{"type":35,"value":9993},"Ce qu'il construit :",{"type":35,"value":9995}," une culture de l'apprentissage collectif et de la sécurité psychologique.",{"type":29,"tag":37,"props":9997,"children":9998},{},[9999],{"type":35,"value":10000},"Après chaque incident en production significatif, l'équipe se réunit dans les 48 heures pour une analyse structurée. L'objectif n'est pas de trouver un coupable : c'est de comprendre le système qui a rendu l'incident possible.",{"type":29,"tag":37,"props":10002,"children":10003},{},[10004],{"type":29,"tag":55,"props":10005,"children":10006},{},[10007],{"type":35,"value":10008},"Format que j'utilise :",{"type":29,"tag":1069,"props":10010,"children":10011},{},[10012,10017,10022,10027,10032],{"type":29,"tag":1073,"props":10013,"children":10014},{},[10015],{"type":35,"value":10016},"45 à 60 minutes maximum",{"type":29,"tag":1073,"props":10018,"children":10019},{},[10020],{"type":35,"value":10021},"Chronologie des événements (pas des personnes)",{"type":29,"tag":1073,"props":10023,"children":10024},{},[10025],{"type":35,"value":10026},"5 Pourquoi pour remonter à la cause racine",{"type":29,"tag":1073,"props":10028,"children":10029},{},[10030],{"type":35,"value":10031},"Actions correctives sur le système (process, monitoring, test), jamais \"être plus vigilant\"",{"type":29,"tag":1073,"props":10033,"children":10034},{},[10035],{"type":35,"value":10036},"Document partagé avec toute l'équipe",{"type":29,"tag":37,"props":10038,"children":10039},{},[10040,10045],{"type":29,"tag":55,"props":10041,"children":10042},{},[10043],{"type":35,"value":10044},"Ce que le \"blameless\" change concrètement :",{"type":35,"value":10046}," quand les incidents sont des opportunités d'apprentissage sans conséquence sur la carrière des personnes, les développeurs signalent les incidents plus tôt, cherchent plus profondément les causes racines, et implémentent des corrections systémiques. La règle absolue : pas de \"c'est la faute de X\". Si quelqu'un a fait une erreur, la question est \"pourquoi le système a-t-il rendu cette erreur possible ?\"",{"type":29,"tag":66,"props":10048,"children":10049},{},[],{"type":29,"tag":70,"props":10051,"children":10053},{"id":10052},"rituel-2-la-tech-talk-mensuelle",[10054],{"type":35,"value":10055},"Rituel 2 : La Tech Talk mensuelle",{"type":29,"tag":37,"props":10057,"children":10058},{},[10059,10063],{"type":29,"tag":55,"props":10060,"children":10061},{},[10062],{"type":35,"value":9993},{"type":35,"value":10064}," une culture du partage de connaissance et de la curiosité intellectuelle.",{"type":29,"tag":37,"props":10066,"children":10067},{},[10068],{"type":35,"value":10069},"Une fois par mois, un membre de l'équipe présente pendant 30 minutes un sujet technique, pas nécessairement lié au projet en cours. Une technologie qu'il explore, un problème qu'il a résolu, un livre qu'il a lu, une conférence qu'il a regardée.",{"type":29,"tag":37,"props":10071,"children":10072},{},[10073],{"type":29,"tag":55,"props":10074,"children":10075},{},[10076],{"type":35,"value":10077},"Pourquoi ce rituel fonctionne :",{"type":29,"tag":1069,"props":10079,"children":10080},{},[10081,10086,10091,10096],{"type":29,"tag":1073,"props":10082,"children":10083},{},[10084],{"type":35,"value":10085},"Il valorise l'apprentissage continu comme norme culturelle, pas comme hobby personnel",{"type":29,"tag":1073,"props":10087,"children":10088},{},[10089],{"type":35,"value":10090},"Il expose l'équipe à des perspectives qu'elle n'aurait pas explorées",{"type":29,"tag":1073,"props":10092,"children":10093},{},[10094],{"type":35,"value":10095},"Il développe les compétences de communication technique des présentateurs",{"type":29,"tag":1073,"props":10097,"children":10098},{},[10099],{"type":35,"value":10100},"Il crée des conversations qui durent au-delà de la session",{"type":29,"tag":37,"props":10102,"children":10103},{},[10104,10109],{"type":29,"tag":55,"props":10105,"children":10106},{},[10107],{"type":35,"value":10108},"Comment je l'instaure :",{"type":35,"value":10110}," je présente en premier. Cela enlève la pression du \"qui va se lancer\" et montre que c'est un espace sans jugement. Après 2 à 3 sessions, une rotation naturelle s'installe. Je ne force jamais : le volontariat maintient la qualité.",{"type":29,"tag":37,"props":10112,"children":10113},{},[10114,10119],{"type":29,"tag":55,"props":10115,"children":10116},{},[10117],{"type":35,"value":10118},"Le seuil de qualité que j'impose :",{"type":35,"value":10120}," pas besoin d'être expert pour présenter. \"J'ai exploré X cette semaine, voici ce que j'ai trouvé intéressant, voici les questions que je n'ai pas encore résolues\" est une Tech Talk de qualité. Parfois meilleure que la présentation d'un expert, parce qu'elle montre le processus d'apprentissage.",{"type":29,"tag":166,"props":10122,"children":10124},{"cta":168,"href":169,"title":10123,"type":171},"Vous voulez construire une culture d'excellence technique mais ne savez pas par quels rituels commencer ?",[10125],{"type":29,"tag":37,"props":10126,"children":10127},{},[10128],{"type":35,"value":10129},"Les rituels qui fonctionnent dépendent de la culture actuelle de l'équipe, de sa taille, et de son contexte. Implanter tous les rituels d'un coup crée de la surcharge et génère du rejet. En 30 minutes, je peux identifier les 2 à 3 rituels les plus impactants pour votre situation et définir un plan d'implémentation réaliste.",{"type":29,"tag":66,"props":10131,"children":10132},{},[],{"type":29,"tag":70,"props":10134,"children":10136},{"id":10135},"rituel-3-la-session-de-code-review-collective",[10137],{"type":35,"value":10138},"Rituel 3 : La session de code review collective",{"type":29,"tag":37,"props":10140,"children":10141},{},[10142,10146],{"type":29,"tag":55,"props":10143,"children":10144},{},[10145],{"type":35,"value":9993},{"type":35,"value":10147}," des standards techniques partagés et une culture de feedback constructif.",{"type":29,"tag":37,"props":10149,"children":10150},{},[10151],{"type":35,"value":10152},"Toutes les 2 semaines, l'équipe passe 45 minutes à reviewer ensemble une PR récente, soit un changement intéressant sur le plan technique, soit une PR qui a suscité des discussions en review asynchrone.",{"type":29,"tag":37,"props":10154,"children":10155},{},[10156],{"type":29,"tag":55,"props":10157,"children":10158},{},[10159],{"type":35,"value":10160},"Ce que ce rituel apprend concrètement :",{"type":29,"tag":1069,"props":10162,"children":10163},{},[10164,10169,10174,10179],{"type":29,"tag":1073,"props":10165,"children":10166},{},[10167],{"type":35,"value":10168},"Comment les seniors pensent quand ils reviewent du code",{"type":29,"tag":1073,"props":10170,"children":10171},{},[10172],{"type":35,"value":10173},"Les standards non écrits que les seniors appliquent intuitivement",{"type":29,"tag":1073,"props":10175,"children":10176},{},[10177],{"type":35,"value":10178},"Comment donner du feedback constructif (en observant les seniors le faire)",{"type":29,"tag":1073,"props":10180,"children":10181},{},[10182],{"type":35,"value":10183},"Les patterns à éviter dans cette base de code spécifique",{"type":29,"tag":37,"props":10185,"children":10186},{},[10187],{"type":29,"tag":55,"props":10188,"children":10189},{},[10190],{"type":35,"value":10191},"Format :",{"type":29,"tag":1069,"props":10193,"children":10194},{},[10195,10200,10205,10210],{"type":29,"tag":1073,"props":10196,"children":10197},{},[10198],{"type":35,"value":10199},"L'auteur présente le contexte (2 min)",{"type":29,"tag":1073,"props":10201,"children":10202},{},[10203],{"type":35,"value":10204},"Review collective en temps réel sur un écran partagé (30 min)",{"type":29,"tag":1073,"props":10206,"children":10207},{},[10208],{"type":35,"value":10209},"Discussion des trade-offs et décisions (10 min)",{"type":29,"tag":1073,"props":10211,"children":10212},{},[10213],{"type":35,"value":10214},"Synthèse des enseignements (5 min)",{"type":29,"tag":37,"props":10216,"children":10217},{},[10218,10223],{"type":29,"tag":55,"props":10219,"children":10220},{},[10221],{"type":35,"value":10222},"Ce que j'observe systématiquement :",{"type":35,"value":10224}," les développeurs juniors exposés à des sessions de review collective progressent significativement plus vite sur la qualité du code que ceux qui reçoivent uniquement des reviews asynchrones. La différence n'est pas dans le contenu du feedback : c'est dans la visibilité du raisonnement du reviewer.",{"type":29,"tag":66,"props":10226,"children":10227},{},[],{"type":29,"tag":70,"props":10229,"children":10231},{"id":10230},"rituel-4-lengineering-retrospective-trimestrielle",[10232],{"type":35,"value":10233},"Rituel 4 : L'Engineering Retrospective trimestrielle",{"type":29,"tag":37,"props":10235,"children":10236},{},[10237,10241],{"type":29,"tag":55,"props":10238,"children":10239},{},[10240],{"type":35,"value":9993},{"type":35,"value":10242}," une culture d'amélioration continue de l'engineering lui-même, séparée de la rétrospective produit.",{"type":29,"tag":37,"props":10244,"children":10245},{},[10246],{"type":35,"value":10247},"Une fois par trimestre, l'équipe consacre 2 heures à évaluer l'état de l'engineering, pas la delivery produit (c'est la rétro Scrum), mais les pratiques techniques elles-mêmes.",{"type":29,"tag":37,"props":10249,"children":10250},{},[10251],{"type":29,"tag":55,"props":10252,"children":10253},{},[10254],{"type":35,"value":10255},"Questions que j'utilise :",{"type":29,"tag":1069,"props":10257,"children":10258},{},[10259,10264,10269,10274],{"type":29,"tag":1073,"props":10260,"children":10261},{},[10262],{"type":35,"value":10263},"Quelles pratiques techniques avons-nous améliorées ce trimestre ?",{"type":29,"tag":1073,"props":10265,"children":10266},{},[10267],{"type":35,"value":10268},"Quelle partie de notre codebase nous ralentit le plus ?",{"type":29,"tag":1073,"props":10270,"children":10271},{},[10272],{"type":35,"value":10273},"Quelle compétence technique manque à l'équipe ?",{"type":29,"tag":1073,"props":10275,"children":10276},{},[10277],{"type":35,"value":10278},"Si on refaisait l'architecture de X aujourd'hui, on ferait quoi différemment ?",{"type":29,"tag":37,"props":10280,"children":10281},{},[10282,10287],{"type":29,"tag":55,"props":10283,"children":10284},{},[10285],{"type":35,"value":10286},"Pourquoi la séparation de la rétro produit est essentielle :",{"type":35,"value":10288}," dans une rétro Scrum classique, les préoccupations produit dominent (fonctionnalités en retard, bugs business, pression du sprint). Les sujets techniques sont traités superficiellement ou pas du tout. La rétro engineering dédiée crée l'espace pour des discussions profondes sur la dette technique, les pratiques, et les compétences.",{"type":29,"tag":37,"props":10290,"children":10291},{},[10292,10297],{"type":29,"tag":55,"props":10293,"children":10294},{},[10295],{"type":35,"value":10296},"Livrable :",{"type":35,"value":10298}," 3 actions d'amélioration technique priorisées pour le prochain trimestre. Trackées comme des stories dans le backlog, pas des intentions qui disparaissent dans un document Wiki.",{"type":29,"tag":66,"props":10300,"children":10301},{},[],{"type":29,"tag":70,"props":10303,"children":10305},{"id":10304},"rituel-5-le-pair-programming-de-découverte",[10306],{"type":35,"value":10307},"Rituel 5 : Le Pair Programming de découverte",{"type":29,"tag":37,"props":10309,"children":10310},{},[10311,10315],{"type":29,"tag":55,"props":10312,"children":10313},{},[10314],{"type":35,"value":9993},{"type":35,"value":10316}," une culture de collaboration et de transfert de connaissance horizontal.",{"type":29,"tag":37,"props":10318,"children":10319},{},[10320,10322,10327],{"type":35,"value":10321},"2 heures par semaine, 2 développeurs travaillent ensemble sur un problème, pas nécessairement pour aller plus vite, mais pour apprendre l'un de l'autre. Le ",{"type":29,"tag":43,"props":10323,"children":10324},{"href":345},[10325],{"type":35,"value":10326},"ROI du pair programming",{"type":35,"value":10328}," est documenté : 15% de défauts en moins sur les tâches complexes.",{"type":29,"tag":37,"props":10330,"children":10331},{},[10332,10337],{"type":29,"tag":55,"props":10333,"children":10334},{},[10335],{"type":35,"value":10336},"La différence avec le pair programming utilitaire :",{"type":35,"value":10338}," ce pair programming est intentionnellement hétérogène (junior + senior, frontend + backend, nouveau + vieux dans l'équipe) et vise le transfert de connaissance autant que le code produit.",{"type":29,"tag":37,"props":10340,"children":10341},{},[10342,10347],{"type":29,"tag":55,"props":10343,"children":10344},{},[10345],{"type":35,"value":10346},"Rotation :",{"type":35,"value":10348}," une nouvelle paire chaque semaine. Sur une équipe de 8, chaque développeur travaille avec un collègue différent toutes les 4 semaines. En 6 mois, chaque développeur a travaillé avec chaque autre membre de l'équipe au moins une fois.",{"type":29,"tag":37,"props":10350,"children":10351},{},[10352,10357],{"type":29,"tag":55,"props":10353,"children":10354},{},[10355],{"type":35,"value":10356},"Ce que ce rituel prévient :",{"type":35,"value":10358}," le knowledge siloing (seul X connaît ce service), l'isolement des développeurs juniors, et les tensions entre les sous-groupes de l'équipe. Dans cette organisation, ce rituel seul a réduit le bus factor sur les services critiques de 1 à 3 en moins de 6 mois.",{"type":29,"tag":66,"props":10360,"children":10361},{},[],{"type":29,"tag":70,"props":10363,"children":10365},{"id":10364},"rituel-6-le-craft-backlog-visible",[10366],{"type":35,"value":10367},"Rituel 6 : Le Craft Backlog visible",{"type":29,"tag":37,"props":10369,"children":10370},{},[10371,10375],{"type":29,"tag":55,"props":10372,"children":10373},{},[10374],{"type":35,"value":9993},{"type":35,"value":10376}," une culture de la qualité et de la viabilité à long terme du code.",{"type":29,"tag":37,"props":10378,"children":10379},{},[10380],{"type":35,"value":10381},"Un backlog visible dédié aux améliorations techniques : remboursement de dette technique, refactoring, mise à jour des dépendances, amélioration de la couverture de tests. Pas dans le backlog produit. Dans un backlog séparé, visible de tout le monde y compris du management.",{"type":29,"tag":37,"props":10383,"children":10384},{},[10385,10390],{"type":29,"tag":55,"props":10386,"children":10387},{},[10388],{"type":35,"value":10389},"Pourquoi la visibilité est clé :",{"type":35,"value":10391}," la dette technique invisible n'est pas prioritarisée. La dette technique visible avec un impact estimé (en temps de développement supplémentaire et en risque business) peut être défendue auprès du leadership.",{"type":29,"tag":37,"props":10393,"children":10394},{},[10395,10400,10402,10407,10409,10414],{"type":29,"tag":55,"props":10396,"children":10397},{},[10398],{"type":35,"value":10399},"La règle du 20% :",{"type":35,"value":10401}," 20% de la capacité de chaque sprint est allouée au craft backlog. Pour obtenir ce budget, consultez le guide pour ",{"type":29,"tag":43,"props":10403,"children":10404},{"href":2060},[10405],{"type":35,"value":10406},"faire approuver un programme de refactoring par le business",{"type":35,"value":10408},". Non-négociable, comme l'investissement dans la sécurité ou les tests. Cette règle doit être défendue par le manager et le CTO auprès du business. Will Larson décrit ce principe dans ",{"type":29,"tag":9958,"props":10410,"children":10411},{},[10412],{"type":35,"value":10413},"An Elegant Puzzle",{"type":35,"value":10415}," : le travail de maintenance du système n'est pas un coût, c'est la condition de la vélocité future.",{"type":29,"tag":66,"props":10417,"children":10418},{},[],{"type":29,"tag":70,"props":10420,"children":10422},{"id":10421},"comment-implémenter-les-6-rituels-sans-créer-de-surcharge",[10423],{"type":35,"value":10424},"Comment implémenter les 6 rituels sans créer de surcharge",{"type":29,"tag":37,"props":10426,"children":10427},{},[10428,10433],{"type":29,"tag":55,"props":10429,"children":10430},{},[10431],{"type":35,"value":10432},"Démarrer par 2, pas 6.",{"type":35,"value":10434}," Implémenter tous les rituels simultanément crée une charge d'organisation excessive et dilue l'attention. Je commence par les 2 rituels les plus adaptés à la situation actuelle de l'équipe.",{"type":29,"tag":37,"props":10436,"children":10437},{},[10438],{"type":29,"tag":55,"props":10439,"children":10440},{},[10441],{"type":35,"value":10442},"Mes recommandations par situation :",{"type":29,"tag":1069,"props":10444,"children":10445},{},[10446,10451,10456,10461],{"type":29,"tag":1073,"props":10447,"children":10448},{},[10449],{"type":35,"value":10450},"Équipe avec peu de sécurité psychologique → Post-mortem blameless + Pair programming de découverte",{"type":29,"tag":1073,"props":10452,"children":10453},{},[10454],{"type":35,"value":10455},"Équipe avec fort knowledge siloing → Pair programming de découverte + Tech Talk mensuelle",{"type":29,"tag":1073,"props":10457,"children":10458},{},[10459],{"type":35,"value":10460},"Équipe avec culture de qualité faible → Code review collective + Craft Backlog visible",{"type":29,"tag":1073,"props":10462,"children":10463},{},[10464],{"type":35,"value":10465},"Équipe en forte croissance → Tech Talk mensuelle + Pair programming de découverte",{"type":29,"tag":37,"props":10467,"children":10468},{},[10469,10474],{"type":29,"tag":55,"props":10470,"children":10471},{},[10472],{"type":35,"value":10473},"Le timing réaliste :",{"type":35,"value":10475}," les rituels prennent 3 à 6 mois pour s'ancrer dans la culture. La première session est souvent maladroite. La cinquième est naturelle. La vingtième fait partie de l'identité de l'équipe.",{"type":29,"tag":37,"props":10477,"children":10478},{},[10479],{"type":35,"value":10480},"Dans ce client, après 12 mois d'implémentation progressive des 6 rituels, les signaux culturels avaient radicalement changé : les incidents étaient signalés plus tôt, la documentation avait augmenté spontanément, et 3 développeurs avaient présenté à des conférences externes, quelque chose qui n'était jamais arrivé avant. La culture ne s'était pas transformée parce qu'on avait changé les valeurs affichées. Elle s'était transformée parce qu'on avait changé les comportements répétés chaque semaine.",{"type":29,"tag":66,"props":10482,"children":10483},{},[],{"type":29,"tag":70,"props":10485,"children":10487},{"id":10486},"faq-sur-les-rituels-de-culture-engineering",[10488],{"type":35,"value":10489},"FAQ sur les rituels de culture engineering",{"type":29,"tag":371,"props":10491,"children":10492},{},[10493,10498],{"type":29,"tag":375,"props":10494,"children":10495},{},[10496],{"type":35,"value":10497},"Comment maintenir les rituels quand l'équipe est sous pression de delivery ?",{"type":29,"tag":37,"props":10499,"children":10500},{},[10501,10503,10509],{"type":35,"value":10502},"C'est précisément sous pression que les rituels sont le plus importants, et le plus menacés. Ma règle : certains rituels sont compressibles (la Tech Talk peut passer à 20 min), aucun n'est supprimable. Un post-mortem annulé envoie le message que l'apprentissage n'est pas prioritaire. La solution : prévoir des formats compressés pour les périodes de pression, pas des annulations. Consultez le ",{"type":29,"tag":43,"props":10504,"children":10506},{"href":10505},"/fr/pratiques-agiles/retrospective-agile-format-efficace",[10507],{"type":35,"value":10508},"format de rétrospective en 5 étapes",{"type":35,"value":10510}," qui génère vraiment du changement. L'habitude survit aux compressions. Elle ne survit pas aux suppressions répétées.",{"type":29,"tag":371,"props":10512,"children":10513},{},[10514,10519],{"type":29,"tag":375,"props":10515,"children":10516},{},[10517],{"type":35,"value":10518},"Ces rituels fonctionnent-ils en équipe distribuée ou full remote ?",{"type":29,"tag":37,"props":10520,"children":10521},{},[10522],{"type":35,"value":10523},"Oui, avec adaptation. Le post-mortem et la review collective fonctionnent en visioconférence. La Tech Talk est souvent plus accessible en remote (enregistrement possible). Le pair programming de découverte nécessite des outils adaptés (Live Share dans VSCode, Tuple). La rétro engineering se fait sur Miro ou Mural. Le craft backlog est naturellement digital. Le pair programming est le seul rituel qui perd en efficacité remote : compenser par des sessions plus courtes mais plus fréquentes.",{"type":29,"tag":371,"props":10525,"children":10526},{},[10527,10532],{"type":29,"tag":375,"props":10528,"children":10529},{},[10530],{"type":35,"value":10531},"Comment mesurer l'impact des rituels sur la culture ?",{"type":29,"tag":37,"props":10533,"children":10534},{},[10535],{"type":35,"value":10536},"Les métriques proxy que j'utilise : fréquence de signalement des incidents (hausse → meilleure sécurité psychologique), nombre de PR commentées par les juniors (hausse → moins de peur du feedback), rotation des knowledge owners sur le codebase (hausse → moins de siloing), nombre de sujets proposés pour les Tech Talks (hausse → curiosité intellectuelle). Ces proxy suffisent pour évaluer la direction.",{"type":29,"tag":371,"props":10538,"children":10539},{},[10540,10545],{"type":29,"tag":375,"props":10541,"children":10542},{},[10543],{"type":35,"value":10544},"Faut-il impliquer le management dans les rituels ?",{"type":29,"tag":37,"props":10546,"children":10547},{},[10548],{"type":35,"value":10549},"La présence du management aux post-mortems blameless est importante : elle signale que la direction soutient la culture d'apprentissage sans recherche de coupable. Pour les Tech Talks et les reviews collectives, la présence est optionnelle, mais l'intérêt démontré (regarder l'enregistrement, commenter) est un signal fort. Le management ne devrait jamais animer les rituels : c'est à l'équipe de se les approprier.",{"type":29,"tag":371,"props":10551,"children":10552},{},[10553,10558],{"type":29,"tag":375,"props":10554,"children":10555},{},[10556],{"type":35,"value":10557},"Que faire si les rituels ne \"prennent pas\" après 3 mois ?",{"type":29,"tag":37,"props":10559,"children":10560},{},[10561],{"type":35,"value":10562},"Trois diagnostics possibles. Le rituel n'adresse pas un problème réel de l'équipe : remplacer par un rituel plus adapté. La facilitation est insuffisante : investir dans la formation du facilitateur ou faire appel à un externe pour les premières sessions. Il y a un problème de sécurité psychologique plus profond (peur de s'exprimer, culture punitive) : les rituels ne peuvent pas fonctionner sans un niveau minimal de confiance. Résoudre d'abord le problème structurel.",{"type":29,"tag":66,"props":10564,"children":10565},{},[],{"type":29,"tag":166,"props":10567,"children":10568},{"cta":1232,"href":1233,"title":444,"type":445},[10569],{"type":29,"tag":37,"props":10570,"children":10571},{},[10572],{"type":35,"value":10573},"L'Engineering Maturity Self-Assessment couvre le domaine Culture Engineering : évaluez la maturité culturelle de votre équipe sur les rituels techniques, les pratiques de collaboration, et l'amélioration continue. Score et recommandations en 10 minutes.",{"title":8,"searchDepth":453,"depth":453,"links":10575},[10576,10577,10578,10579,10580,10581,10582,10583],{"id":9982,"depth":453,"text":9985},{"id":10052,"depth":453,"text":10055},{"id":10135,"depth":453,"text":10138},{"id":10230,"depth":453,"text":10233},{"id":10304,"depth":453,"text":10307},{"id":10364,"depth":453,"text":10367},{"id":10421,"depth":453,"text":10424},{"id":10486,"depth":453,"text":10489},"content:fr:management:engineering-culture-rituels.md","fr/management/engineering-culture-rituels.md","fr/management/engineering-culture-rituels",{"_path":10588,"_dir":2107,"_draft":7,"_partial":7,"_locale":8,"title":10589,"description":10590,"id":6393,"date":10591,"listed":13,"nocomments":7,"hidden":7,"categories":10592,"tags":10593,"--cover":10597,"readingTime":10598,"body":10602,"_type":466,"_id":11776,"_source":468,"_file":11777,"_stem":11778,"_extension":471},"/fr/intelligence-artificielle/ia-documentation-technique-cas-usage","IA et documentation technique : les cas d'usage qui marchent vraiment","L'IA peut automatiser 60% de la documentation technique — mais pas les 60% auxquels on pense en premier. Les cas d'usage validés et ceux à éviter.","2026-03-09",[2107],[10594,2115,10595,10596],"Documentation","Automatisation","Developer Experience","covers/articles/ia-documentation-technique.jpg",{"text":9931,"minutes":10599,"time":10600,"words":10601},9.03,541800,1806,{"type":26,"children":10603,"toc":11765},[10604,10609,10614,10619,10627,10630,10636,10641,10651,10661,10666,10669,10675,10685,10695,10756,10761,10769,10772,10778,10787,10796,11348,11360,11369,11372,11378,11387,11396,11401,11409,11419,11429,11432,11438,11447,11456,11461,11524,11536,11539,11545,11554,11563,11567,11575,11580,11583,11589,11604,11614,11624,11627,11633,11650,11660,11670,11675,11678,11684,11697,11710,11723,11736,11749,11752,11761],{"type":29,"tag":30,"props":10605,"children":10607},{"id":10606},"ia-et-documentation-technique-les-cas-dusage-qui-marchent-vraiment",[10608],{"type":35,"value":10589},{"type":29,"tag":37,"props":10610,"children":10611},{},[10612],{"type":35,"value":10613},"J'accompagnais une équipe de 12 développeurs chez un client dans l'édition logicielle. Leur base de code avait 23 services. Zéro documentation. Les nouvelles recrues passaient 3 semaines à poser des questions aux développeurs seniors, qui, eux, perdaient 30 à 45 minutes par jour à répondre. Un coût invisible mais massif, mesuré quand j'ai fait le calcul avec le CTO.",{"type":29,"tag":37,"props":10615,"children":10616},{},[10617],{"type":35,"value":10618},"Nous avons organisé un sprint de documentation de 2 jours avec assistance Claude. Résultat : 18 services avaient des READMEs et des docs d'API générés. Temps de révision humaine : 30 à 45 minutes par service. Le lead time d'onboarding est passé de 3 semaines à 10 jours. 18 services documentés en 2 jours, contre 18 semaines si fait manuellement.",{"type":29,"tag":37,"props":10620,"children":10621},{},[10622],{"type":29,"tag":55,"props":10623,"children":10624},{},[10625],{"type":35,"value":10626},"L'IA peut automatiser 60% de la documentation technique. Mais pas les 60% auxquels on pense en premier. Les équipes qui espèrent que l'IA va écrire leurs ADR et leur documentation d'architecture sont déçues. Celles qui l'utilisent pour les bons cas d'usage gagnent des heures par semaine.",{"type":29,"tag":66,"props":10628,"children":10629},{},[],{"type":29,"tag":70,"props":10631,"children":10633},{"id":10632},"ce-que-lia-documente-bien-et-ce-quelle-documente-mal",[10634],{"type":35,"value":10635},"Ce que l'IA documente bien, et ce qu'elle documente mal",{"type":29,"tag":37,"props":10637,"children":10638},{},[10639],{"type":35,"value":10640},"J'ai testé et observé suffisamment de déploiements pour établir une règle simple :",{"type":29,"tag":37,"props":10642,"children":10643},{},[10644,10649],{"type":29,"tag":55,"props":10645,"children":10646},{},[10647],{"type":35,"value":10648},"L'IA documente bien le \"quoi\" :",{"type":35,"value":10650}," ce que le code fait, comment appeler une API, quels paramètres une fonction accepte, quelle est la structure d'un objet. Ces informations sont dans le code, l'IA les extrait et les formate.",{"type":29,"tag":37,"props":10652,"children":10653},{},[10654,10659],{"type":29,"tag":55,"props":10655,"children":10656},{},[10657],{"type":35,"value":10658},"L'IA documente mal le \"pourquoi\" :",{"type":35,"value":10660}," pourquoi ce choix d'architecture, pourquoi cette contrainte de performance, pourquoi cette API a été dépréciée. Ces informations ne sont pas dans le code, elles sont dans les cerveaux des développeurs qui ont pris ces décisions.",{"type":29,"tag":37,"props":10662,"children":10663},{},[10664],{"type":35,"value":10665},"La règle d'usage : utilisez l'IA pour documenter le \"quoi\" ; investissez le temps humain sur le \"pourquoi\".",{"type":29,"tag":66,"props":10667,"children":10668},{},[],{"type":29,"tag":70,"props":10670,"children":10672},{"id":10671},"cas-dusage-1-génération-de-documentation-dapi-roi-élevé",[10673],{"type":35,"value":10674},"Cas d'usage 1 : Génération de documentation d'API (ROI élevé)",{"type":29,"tag":37,"props":10676,"children":10677},{},[10678,10683],{"type":29,"tag":55,"props":10679,"children":10680},{},[10681],{"type":35,"value":10682},"Le problème :",{"type":35,"value":10684}," les APIs internes ne sont souvent pas documentées. Chaque développeur qui intègre un nouveau service perd 2 à 4 heures à comprendre les endpoints, les paramètres, et les formats de réponse en lisant le code.",{"type":29,"tag":37,"props":10686,"children":10687},{},[10688,10693],{"type":29,"tag":55,"props":10689,"children":10690},{},[10691],{"type":35,"value":10692},"Ce que l'IA fait :",{"type":35,"value":10694}," à partir du code d'un controller, d'un router Express, ou d'un fichier de routes FastAPI, l'IA génère une documentation structurée (format OpenAPI/Swagger ou Markdown) avec les endpoints, les paramètres, les types, et des exemples.",{"type":29,"tag":640,"props":10696,"children":10698},{"code":10697,"language":2192,"meta":8,"className":2190,"style":8},"# Prompt pour Claude/GPT-4\n\"\"\"\nVoici le code d'un router FastAPI. Génère une documentation OpenAPI complète\navec description de chaque endpoint, paramètres, types, et exemples de requête/réponse.\n\n[coller le code du router]\n\"\"\"\n",[10699],{"type":29,"tag":554,"props":10700,"children":10701},{"__ignoreMap":8},[10702,10710,10718,10726,10734,10741,10749],{"type":29,"tag":890,"props":10703,"children":10704},{"class":892,"line":893},[10705],{"type":29,"tag":890,"props":10706,"children":10707},{"style":897},[10708],{"type":35,"value":10709},"# Prompt pour Claude/GPT-4\n",{"type":29,"tag":890,"props":10711,"children":10712},{"class":892,"line":453},[10713],{"type":29,"tag":890,"props":10714,"children":10715},{"style":2226},[10716],{"type":35,"value":10717},"\"\"\"\n",{"type":29,"tag":890,"props":10719,"children":10720},{"class":892,"line":459},[10721],{"type":29,"tag":890,"props":10722,"children":10723},{"style":2226},[10724],{"type":35,"value":10725},"Voici le code d'un router FastAPI. Génère une documentation OpenAPI complète\n",{"type":29,"tag":890,"props":10727,"children":10728},{"class":892,"line":957},[10729],{"type":29,"tag":890,"props":10730,"children":10731},{"style":2226},[10732],{"type":35,"value":10733},"avec description de chaque endpoint, paramètres, types, et exemples de requête/réponse.\n",{"type":29,"tag":890,"props":10735,"children":10736},{"class":892,"line":966},[10737],{"type":29,"tag":890,"props":10738,"children":10739},{"emptyLinePlaceholder":13},[10740],{"type":35,"value":963},{"type":29,"tag":890,"props":10742,"children":10743},{"class":892,"line":975},[10744],{"type":29,"tag":890,"props":10745,"children":10746},{"style":2226},[10747],{"type":35,"value":10748},"[coller le code du router]\n",{"type":29,"tag":890,"props":10750,"children":10751},{"class":892,"line":996},[10752],{"type":29,"tag":890,"props":10753,"children":10754},{"style":2226},[10755],{"type":35,"value":10717},{"type":29,"tag":37,"props":10757,"children":10758},{},[10759],{"type":35,"value":10760},"Résultat typique : une documentation OpenAPI utilisable en 5 minutes de génération + 15 minutes de révision humaine pour vérifier l'exactitude et ajouter les informations contextuelles (qui appelle cette API, dans quel flux business, quelles sont les contraintes de rate limiting).",{"type":29,"tag":37,"props":10762,"children":10763},{},[10764],{"type":29,"tag":55,"props":10765,"children":10766},{},[10767],{"type":35,"value":10768},"Gain : 3 à 4 heures de documentation manuelle → 20 minutes.",{"type":29,"tag":66,"props":10770,"children":10771},{},[],{"type":29,"tag":70,"props":10773,"children":10775},{"id":10774},"cas-dusage-2-commentaires-et-docstrings-dans-le-code-roi-moyen",[10776],{"type":35,"value":10777},"Cas d'usage 2 : Commentaires et docstrings dans le code (ROI moyen)",{"type":29,"tag":37,"props":10779,"children":10780},{},[10781,10785],{"type":29,"tag":55,"props":10782,"children":10783},{},[10784],{"type":35,"value":10682},{"type":35,"value":10786}," le code existant n'a pas de commentaires. Les fonctions complexes sont difficiles à comprendre sans connaître le contexte de leur création.",{"type":29,"tag":37,"props":10788,"children":10789},{},[10790,10794],{"type":29,"tag":55,"props":10791,"children":10792},{},[10793],{"type":35,"value":10692},{"type":35,"value":10795}," elle génère des docstrings JSDoc, Python Docstrings, ou JavaDoc pour les fonctions et classes existantes.",{"type":29,"tag":640,"props":10797,"children":10801},{"code":10798,"language":10799,"meta":8,"className":10800,"style":8},"// Avant\nfunction calculateEligibility(user, subscription, promoCode) {\n    if (!user.verified) return { eligible: false, reason: 'NOT_VERIFIED' };\n    if (subscription.status !== 'active') return { eligible: false, reason: 'INACTIVE_SUB' };\n    if (promoCode && promoCode.usageCount >= promoCode.maxUsage) {\n        return { eligible: false, reason: 'PROMO_EXHAUSTED' };\n    }\n    return { eligible: true };\n}\n\n// Après génération IA\n/**\n * Détermine l'éligibilité d'un utilisateur à appliquer un code promo.\n *\n * @param {User} user - L'utilisateur demandant l'application du promo\n * @param {Subscription} subscription - L'abonnement actif de l'utilisateur\n * @param {PromoCode|null} promoCode - Le code promo à valider (peut être null)\n * @returns {{ eligible: boolean, reason?: string }} Résultat de l'éligibilité\n */\n","javascript","language-javascript shiki shiki-themes catppuccin-frappe github-dark",[10802],{"type":29,"tag":554,"props":10803,"children":10804},{"__ignoreMap":8},[10805,10813,10861,10937,11014,11066,11110,11117,11144,11151,11158,11166,11174,11182,11190,11232,11269,11306,11340],{"type":29,"tag":890,"props":10806,"children":10807},{"class":892,"line":893},[10808],{"type":29,"tag":890,"props":10809,"children":10810},{"style":897},[10811],{"type":35,"value":10812},"// Avant\n",{"type":29,"tag":890,"props":10814,"children":10815},{"class":892,"line":453},[10816,10821,10826,10830,10835,10839,10844,10848,10853,10857],{"type":29,"tag":890,"props":10817,"children":10818},{"style":906},[10819],{"type":35,"value":10820},"function",{"type":29,"tag":890,"props":10822,"children":10823},{"style":5378},[10824],{"type":35,"value":10825}," calculateEligibility",{"type":29,"tag":890,"props":10827,"children":10828},{"style":5201},[10829],{"type":35,"value":3070},{"type":29,"tag":890,"props":10831,"children":10832},{"style":5268},[10833],{"type":35,"value":10834},"user",{"type":29,"tag":890,"props":10836,"children":10837},{"style":5201},[10838],{"type":35,"value":3653},{"type":29,"tag":890,"props":10840,"children":10841},{"style":5268},[10842],{"type":35,"value":10843}," subscription",{"type":29,"tag":890,"props":10845,"children":10846},{"style":5201},[10847],{"type":35,"value":3653},{"type":29,"tag":890,"props":10849,"children":10850},{"style":5268},[10851],{"type":35,"value":10852}," promoCode",{"type":29,"tag":890,"props":10854,"children":10855},{"style":5201},[10856],{"type":35,"value":2871},{"type":29,"tag":890,"props":10858,"children":10859},{"style":5201},[10860],{"type":35,"value":7288},{"type":29,"tag":890,"props":10862,"children":10863},{"class":892,"line":459},[10864,10869,10873,10877,10881,10885,10890,10895,10900,10905,10909,10914,10918,10923,10927,10932],{"type":29,"tag":890,"props":10865,"children":10866},{"style":906},[10867],{"type":35,"value":10868},"    if",{"type":29,"tag":890,"props":10870,"children":10871},{"style":912},[10872],{"type":35,"value":7855},{"type":29,"tag":890,"props":10874,"children":10875},{"style":936},[10876],{"type":35,"value":7860},{"type":29,"tag":890,"props":10878,"children":10879},{"style":912},[10880],{"type":35,"value":10834},{"type":29,"tag":890,"props":10882,"children":10883},{"style":7746},[10884],{"type":35,"value":332},{"type":29,"tag":890,"props":10886,"children":10887},{"style":912},[10888],{"type":35,"value":10889},"verified) ",{"type":29,"tag":890,"props":10891,"children":10892},{"style":906},[10893],{"type":35,"value":10894},"return",{"type":29,"tag":890,"props":10896,"children":10897},{"style":5201},[10898],{"type":35,"value":10899}," {",{"type":29,"tag":890,"props":10901,"children":10902},{"style":912},[10903],{"type":35,"value":10904}," eligible",{"type":29,"tag":890,"props":10906,"children":10907},{"style":7746},[10908],{"type":35,"value":5776},{"type":29,"tag":890,"props":10910,"children":10911},{"style":5296},[10912],{"type":35,"value":10913}," false",{"type":29,"tag":890,"props":10915,"children":10916},{"style":5201},[10917],{"type":35,"value":3653},{"type":29,"tag":890,"props":10919,"children":10920},{"style":912},[10921],{"type":35,"value":10922}," reason",{"type":29,"tag":890,"props":10924,"children":10925},{"style":7746},[10926],{"type":35,"value":5776},{"type":29,"tag":890,"props":10928,"children":10929},{"style":2226},[10930],{"type":35,"value":10931}," 'NOT_VERIFIED'",{"type":29,"tag":890,"props":10933,"children":10934},{"style":5201},[10935],{"type":35,"value":10936}," };\n",{"type":29,"tag":890,"props":10938,"children":10939},{"class":892,"line":957},[10940,10944,10949,10953,10958,10963,10968,10973,10977,10981,10985,10989,10993,10997,11001,11005,11010],{"type":29,"tag":890,"props":10941,"children":10942},{"style":906},[10943],{"type":35,"value":10868},{"type":29,"tag":890,"props":10945,"children":10946},{"style":912},[10947],{"type":35,"value":10948}," (subscription",{"type":29,"tag":890,"props":10950,"children":10951},{"style":7746},[10952],{"type":35,"value":332},{"type":29,"tag":890,"props":10954,"children":10955},{"style":912},[10956],{"type":35,"value":10957},"status ",{"type":29,"tag":890,"props":10959,"children":10960},{"style":936},[10961],{"type":35,"value":10962},"!==",{"type":29,"tag":890,"props":10964,"children":10965},{"style":2226},[10966],{"type":35,"value":10967}," 'active'",{"type":29,"tag":890,"props":10969,"children":10970},{"style":912},[10971],{"type":35,"value":10972},") ",{"type":29,"tag":890,"props":10974,"children":10975},{"style":906},[10976],{"type":35,"value":10894},{"type":29,"tag":890,"props":10978,"children":10979},{"style":5201},[10980],{"type":35,"value":10899},{"type":29,"tag":890,"props":10982,"children":10983},{"style":912},[10984],{"type":35,"value":10904},{"type":29,"tag":890,"props":10986,"children":10987},{"style":7746},[10988],{"type":35,"value":5776},{"type":29,"tag":890,"props":10990,"children":10991},{"style":5296},[10992],{"type":35,"value":10913},{"type":29,"tag":890,"props":10994,"children":10995},{"style":5201},[10996],{"type":35,"value":3653},{"type":29,"tag":890,"props":10998,"children":10999},{"style":912},[11000],{"type":35,"value":10922},{"type":29,"tag":890,"props":11002,"children":11003},{"style":7746},[11004],{"type":35,"value":5776},{"type":29,"tag":890,"props":11006,"children":11007},{"style":2226},[11008],{"type":35,"value":11009}," 'INACTIVE_SUB'",{"type":29,"tag":890,"props":11011,"children":11012},{"style":5201},[11013],{"type":35,"value":10936},{"type":29,"tag":890,"props":11015,"children":11016},{"class":892,"line":966},[11017,11021,11026,11031,11035,11039,11044,11049,11053,11057,11062],{"type":29,"tag":890,"props":11018,"children":11019},{"style":906},[11020],{"type":35,"value":10868},{"type":29,"tag":890,"props":11022,"children":11023},{"style":912},[11024],{"type":35,"value":11025}," (promoCode ",{"type":29,"tag":890,"props":11027,"children":11028},{"style":936},[11029],{"type":35,"value":11030},"&&",{"type":29,"tag":890,"props":11032,"children":11033},{"style":912},[11034],{"type":35,"value":10852},{"type":29,"tag":890,"props":11036,"children":11037},{"style":7746},[11038],{"type":35,"value":332},{"type":29,"tag":890,"props":11040,"children":11041},{"style":912},[11042],{"type":35,"value":11043},"usageCount ",{"type":29,"tag":890,"props":11045,"children":11046},{"style":936},[11047],{"type":35,"value":11048},">=",{"type":29,"tag":890,"props":11050,"children":11051},{"style":912},[11052],{"type":35,"value":10852},{"type":29,"tag":890,"props":11054,"children":11055},{"style":7746},[11056],{"type":35,"value":332},{"type":29,"tag":890,"props":11058,"children":11059},{"style":912},[11060],{"type":35,"value":11061},"maxUsage) ",{"type":29,"tag":890,"props":11063,"children":11064},{"style":5201},[11065],{"type":35,"value":7879},{"type":29,"tag":890,"props":11067,"children":11068},{"class":892,"line":975},[11069,11073,11077,11081,11085,11089,11093,11097,11101,11106],{"type":29,"tag":890,"props":11070,"children":11071},{"style":906},[11072],{"type":35,"value":5528},{"type":29,"tag":890,"props":11074,"children":11075},{"style":5201},[11076],{"type":35,"value":10899},{"type":29,"tag":890,"props":11078,"children":11079},{"style":912},[11080],{"type":35,"value":10904},{"type":29,"tag":890,"props":11082,"children":11083},{"style":7746},[11084],{"type":35,"value":5776},{"type":29,"tag":890,"props":11086,"children":11087},{"style":5296},[11088],{"type":35,"value":10913},{"type":29,"tag":890,"props":11090,"children":11091},{"style":5201},[11092],{"type":35,"value":3653},{"type":29,"tag":890,"props":11094,"children":11095},{"style":912},[11096],{"type":35,"value":10922},{"type":29,"tag":890,"props":11098,"children":11099},{"style":7746},[11100],{"type":35,"value":5776},{"type":29,"tag":890,"props":11102,"children":11103},{"style":2226},[11104],{"type":35,"value":11105}," 'PROMO_EXHAUSTED'",{"type":29,"tag":890,"props":11107,"children":11108},{"style":5201},[11109],{"type":35,"value":10936},{"type":29,"tag":890,"props":11111,"children":11112},{"class":892,"line":996},[11113],{"type":29,"tag":890,"props":11114,"children":11115},{"style":5201},[11116],{"type":35,"value":8109},{"type":29,"tag":890,"props":11118,"children":11119},{"class":892,"line":5370},[11120,11124,11128,11132,11136,11140],{"type":29,"tag":890,"props":11121,"children":11122},{"style":906},[11123],{"type":35,"value":6711},{"type":29,"tag":890,"props":11125,"children":11126},{"style":5201},[11127],{"type":35,"value":10899},{"type":29,"tag":890,"props":11129,"children":11130},{"style":912},[11131],{"type":35,"value":10904},{"type":29,"tag":890,"props":11133,"children":11134},{"style":7746},[11135],{"type":35,"value":5776},{"type":29,"tag":890,"props":11137,"children":11138},{"style":5296},[11139],{"type":35,"value":8486},{"type":29,"tag":890,"props":11141,"children":11142},{"style":5201},[11143],{"type":35,"value":10936},{"type":29,"tag":890,"props":11145,"children":11146},{"class":892,"line":5406},[11147],{"type":29,"tag":890,"props":11148,"children":11149},{"style":5201},[11150],{"type":35,"value":7422},{"type":29,"tag":890,"props":11152,"children":11153},{"class":892,"line":5456},[11154],{"type":29,"tag":890,"props":11155,"children":11156},{"emptyLinePlaceholder":13},[11157],{"type":35,"value":963},{"type":29,"tag":890,"props":11159,"children":11160},{"class":892,"line":5522},[11161],{"type":29,"tag":890,"props":11162,"children":11163},{"style":897},[11164],{"type":35,"value":11165},"// Après génération IA\n",{"type":29,"tag":890,"props":11167,"children":11168},{"class":892,"line":5927},[11169],{"type":29,"tag":890,"props":11170,"children":11171},{"style":897},[11172],{"type":35,"value":11173},"/**\n",{"type":29,"tag":890,"props":11175,"children":11176},{"class":892,"line":5935},[11177],{"type":29,"tag":890,"props":11178,"children":11179},{"style":897},[11180],{"type":35,"value":11181}," * Détermine l'éligibilité d'un utilisateur à appliquer un code promo.\n",{"type":29,"tag":890,"props":11183,"children":11184},{"class":892,"line":5944},[11185],{"type":29,"tag":890,"props":11186,"children":11187},{"style":897},[11188],{"type":35,"value":11189}," *\n",{"type":29,"tag":890,"props":11191,"children":11192},{"class":892,"line":5960},[11193,11198,11203,11208,11213,11218,11222,11227],{"type":29,"tag":890,"props":11194,"children":11195},{"style":897},[11196],{"type":35,"value":11197}," * ",{"type":29,"tag":890,"props":11199,"children":11201},{"style":11200},"--shiki-default:#949CBB;--shiki-dark:#F97583",[11202],{"type":35,"value":8933},{"type":29,"tag":890,"props":11204,"children":11205},{"style":906},[11206],{"type":35,"value":11207},"param",{"type":29,"tag":890,"props":11209,"children":11211},{"style":11210},"--shiki-default:#949CBB;--shiki-dark:#B392F0",[11212],{"type":35,"value":10899},{"type":29,"tag":890,"props":11214,"children":11215},{"style":5195},[11216],{"type":35,"value":11217},"User",{"type":29,"tag":890,"props":11219,"children":11220},{"style":11210},[11221],{"type":35,"value":2245},{"type":29,"tag":890,"props":11223,"children":11224},{"style":5993},[11225],{"type":35,"value":11226}," user",{"type":29,"tag":890,"props":11228,"children":11229},{"style":897},[11230],{"type":35,"value":11231}," - L'utilisateur demandant l'application du promo\n",{"type":29,"tag":890,"props":11233,"children":11234},{"class":892,"line":6019},[11235,11239,11243,11247,11251,11256,11260,11264],{"type":29,"tag":890,"props":11236,"children":11237},{"style":897},[11238],{"type":35,"value":11197},{"type":29,"tag":890,"props":11240,"children":11241},{"style":11200},[11242],{"type":35,"value":8933},{"type":29,"tag":890,"props":11244,"children":11245},{"style":906},[11246],{"type":35,"value":11207},{"type":29,"tag":890,"props":11248,"children":11249},{"style":11210},[11250],{"type":35,"value":10899},{"type":29,"tag":890,"props":11252,"children":11253},{"style":5195},[11254],{"type":35,"value":11255},"Subscription",{"type":29,"tag":890,"props":11257,"children":11258},{"style":11210},[11259],{"type":35,"value":2245},{"type":29,"tag":890,"props":11261,"children":11262},{"style":5993},[11263],{"type":35,"value":10843},{"type":29,"tag":890,"props":11265,"children":11266},{"style":897},[11267],{"type":35,"value":11268}," - L'abonnement actif de l'utilisateur\n",{"type":29,"tag":890,"props":11270,"children":11271},{"class":892,"line":6045},[11272,11276,11280,11284,11288,11293,11297,11301],{"type":29,"tag":890,"props":11273,"children":11274},{"style":897},[11275],{"type":35,"value":11197},{"type":29,"tag":890,"props":11277,"children":11278},{"style":11200},[11279],{"type":35,"value":8933},{"type":29,"tag":890,"props":11281,"children":11282},{"style":906},[11283],{"type":35,"value":11207},{"type":29,"tag":890,"props":11285,"children":11286},{"style":11210},[11287],{"type":35,"value":10899},{"type":29,"tag":890,"props":11289,"children":11290},{"style":5195},[11291],{"type":35,"value":11292},"PromoCode|null",{"type":29,"tag":890,"props":11294,"children":11295},{"style":11210},[11296],{"type":35,"value":2245},{"type":29,"tag":890,"props":11298,"children":11299},{"style":5993},[11300],{"type":35,"value":10852},{"type":29,"tag":890,"props":11302,"children":11303},{"style":897},[11304],{"type":35,"value":11305}," - Le code promo à valider (peut être null)\n",{"type":29,"tag":890,"props":11307,"children":11308},{"class":892,"line":6071},[11309,11313,11317,11322,11326,11331,11335],{"type":29,"tag":890,"props":11310,"children":11311},{"style":897},[11312],{"type":35,"value":11197},{"type":29,"tag":890,"props":11314,"children":11315},{"style":11200},[11316],{"type":35,"value":8933},{"type":29,"tag":890,"props":11318,"children":11319},{"style":906},[11320],{"type":35,"value":11321},"returns",{"type":29,"tag":890,"props":11323,"children":11324},{"style":11210},[11325],{"type":35,"value":10899},{"type":29,"tag":890,"props":11327,"children":11328},{"style":5195},[11329],{"type":35,"value":11330},"{ eligible: boolean, reason?: string }",{"type":29,"tag":890,"props":11332,"children":11333},{"style":11210},[11334],{"type":35,"value":2245},{"type":29,"tag":890,"props":11336,"children":11337},{"style":897},[11338],{"type":35,"value":11339}," Résultat de l'éligibilité\n",{"type":29,"tag":890,"props":11341,"children":11342},{"class":892,"line":6079},[11343],{"type":29,"tag":890,"props":11344,"children":11345},{"style":897},[11346],{"type":35,"value":11347}," */\n",{"type":29,"tag":37,"props":11349,"children":11350},{},[11351,11353,11358],{"type":35,"value":11352},"Limite importante : l'IA génère des docstrings corrects sur la forme, mais peut se tromper sur la sémantique métier. Toujours réviser pour vérifier que la description correspond au comportement réel. la génération IA réduit le temps d'écriture de 80%, elle ne remplace pas la révision humaine. Voir comment intégrer l'",{"type":29,"tag":43,"props":11354,"children":11355},{"href":2106},[11356],{"type":35,"value":11357},"IA dans la code review",{"type":35,"value":11359}," pour un workflow cohérent.",{"type":29,"tag":166,"props":11361,"children":11363},{"cta":168,"href":169,"title":11362,"type":171},"Votre équipe perd du temps sur une base de code non documentée et vous cherchez un plan pragmatique ?",[11364],{"type":29,"tag":37,"props":11365,"children":11366},{},[11367],{"type":35,"value":11368},"Vous savez que la documentation est en retard et que ça coûte cher en onboarding et en interruptions des seniors. Mais vous ne savez pas par où commencer avec l'IA. En 30 minutes, on identifie les 3 actions à impact immédiat sur la productivité de votre équipe.",{"type":29,"tag":66,"props":11370,"children":11371},{},[],{"type":29,"tag":70,"props":11373,"children":11375},{"id":11374},"cas-dusage-3-readme-de-service-et-onboarding-roi-élevé",[11376],{"type":35,"value":11377},"Cas d'usage 3 : README de service et onboarding (ROI élevé)",{"type":29,"tag":37,"props":11379,"children":11380},{},[11381,11385],{"type":29,"tag":55,"props":11382,"children":11383},{},[11384],{"type":35,"value":10682},{"type":35,"value":11386}," chaque service d'un système distribué devrait avoir un README qui explique son rôle, comment le démarrer en local, comment le tester, et les variables d'environnement requises. En pratique, ces READMEs sont absents ou obsolètes.",{"type":29,"tag":37,"props":11388,"children":11389},{},[11390,11394],{"type":29,"tag":55,"props":11391,"children":11392},{},[11393],{"type":35,"value":10692},{"type":35,"value":11395}," à partir du code source (package.json, Dockerfile, docker-compose.yml, code principal), l'IA génère un README structuré.",{"type":29,"tag":37,"props":11397,"children":11398},{},[11399],{"type":35,"value":11400},"Prompt type :",{"type":29,"tag":640,"props":11402,"children":11404},{"code":11403},"Voici le package.json, le Dockerfile, et le fichier main.ts d'un service Node.js.\nGénère un README.md complet incluant :\n- Description du service et son rôle dans l'architecture\n- Prérequis\n- Installation et démarrage en local\n- Variables d'environnement (liste depuis le code)\n- Endpoints principaux\n- Comment lancer les tests\n",[11405],{"type":29,"tag":554,"props":11406,"children":11407},{"__ignoreMap":8},[11408],{"type":35,"value":11403},{"type":29,"tag":37,"props":11410,"children":11411},{},[11412,11417],{"type":29,"tag":55,"props":11413,"children":11414},{},[11415],{"type":35,"value":11416},"Ce que l'humain ajoute :",{"type":35,"value":11418}," le contexte business (quel problème ce service résout), les dépendances avec les autres services, les décisions d'architecture importantes.",{"type":29,"tag":37,"props":11420,"children":11421},{},[11422,11427],{"type":29,"tag":55,"props":11423,"children":11424},{},[11425],{"type":35,"value":11426},"Gain pour l'onboarding :",{"type":35,"value":11428}," un nouveau développeur avec des READMEs à jour démarre en autonomie 3 à 5 jours plus tôt qu'avec des READMEs absents. Sur une équipe qui recrute 4 personnes par an, c'est 12 à 20 jours de productivité récupérés chaque année.",{"type":29,"tag":66,"props":11430,"children":11431},{},[],{"type":29,"tag":70,"props":11433,"children":11435},{"id":11434},"cas-dusage-4-résumés-de-pr-et-commit-messages-roi-élevé",[11436],{"type":35,"value":11437},"Cas d'usage 4 : Résumés de PR et commit messages (ROI élevé)",{"type":29,"tag":37,"props":11439,"children":11440},{},[11441,11445],{"type":29,"tag":55,"props":11442,"children":11443},{},[11444],{"type":35,"value":10682},{"type":35,"value":11446}," les commit messages et descriptions de PR sont soit vides (\"fix bug\", \"update code\"), soit trop détaillés pour être lus. L'historique git devient inutilisable.",{"type":29,"tag":37,"props":11448,"children":11449},{},[11450,11454],{"type":29,"tag":55,"props":11451,"children":11452},{},[11453],{"type":35,"value":10692},{"type":35,"value":11455}," à partir du diff d'une PR, l'IA génère un résumé structuré (ce qui a changé, pourquoi, les impacts potentiels, le plan de test).",{"type":29,"tag":37,"props":11457,"children":11458},{},[11459],{"type":35,"value":11460},"GitHub Copilot peut générer des descriptions de PR automatiquement. Alternativement, un script pre-commit qui appelle l'API Claude avec le diff :",{"type":29,"tag":640,"props":11462,"children":11466},{"code":11463,"language":11464,"meta":8,"className":11465,"style":8},"# Script pre-commit simplifié\ngit diff --cached | claude -p \"Génère un commit message conventionnel en anglais\npour ce diff. Format: type(scope): description. Types: feat/fix/refactor/test/docs\"\n","bash","language-bash shiki shiki-themes catppuccin-frappe github-dark",[11467],{"type":29,"tag":554,"props":11468,"children":11469},{"__ignoreMap":8},[11470,11478,11516],{"type":29,"tag":890,"props":11471,"children":11472},{"class":892,"line":893},[11473],{"type":29,"tag":890,"props":11474,"children":11475},{"style":897},[11476],{"type":35,"value":11477},"# Script pre-commit simplifié\n",{"type":29,"tag":890,"props":11479,"children":11480},{"class":892,"line":453},[11481,11486,11491,11497,11501,11506,11511],{"type":29,"tag":890,"props":11482,"children":11483},{"style":5378},[11484],{"type":35,"value":11485},"git",{"type":29,"tag":890,"props":11487,"children":11488},{"style":2226},[11489],{"type":35,"value":11490}," diff",{"type":29,"tag":890,"props":11492,"children":11494},{"style":11493},"--shiki-default:#A6D189;--shiki-dark:#79B8FF",[11495],{"type":35,"value":11496}," --cached",{"type":29,"tag":890,"props":11498,"children":11499},{"style":936},[11500],{"type":35,"value":7400},{"type":29,"tag":890,"props":11502,"children":11503},{"style":5378},[11504],{"type":35,"value":11505}," claude",{"type":29,"tag":890,"props":11507,"children":11508},{"style":11493},[11509],{"type":35,"value":11510}," -p",{"type":29,"tag":890,"props":11512,"children":11513},{"style":2226},[11514],{"type":35,"value":11515}," \"Génère un commit message conventionnel en anglais\n",{"type":29,"tag":890,"props":11517,"children":11518},{"class":892,"line":459},[11519],{"type":29,"tag":890,"props":11520,"children":11521},{"style":2226},[11522],{"type":35,"value":11523},"pour ce diff. Format: type(scope): description. Types: feat/fix/refactor/test/docs\"\n",{"type":29,"tag":37,"props":11525,"children":11526},{},[11527,11529,11534],{"type":35,"value":11528},"Bénéfice secondaire : des descriptions de PR de qualité améliorent le processus de code review, le reviewer comprend rapidement l'intention du changement avant de lire le code. Une étude de ",{"type":29,"tag":55,"props":11530,"children":11531},{},[11532],{"type":35,"value":11533},"l'équipe DevEx de Google (2023)",{"type":35,"value":11535}," sur la qualité des PRs indique que des descriptions claires réduisent le temps de review de 15 à 25%.",{"type":29,"tag":66,"props":11537,"children":11538},{},[],{"type":29,"tag":70,"props":11540,"children":11542},{"id":11541},"cas-dusage-5-mise-à-jour-de-documentation-existante-roi-moyen",[11543],{"type":35,"value":11544},"Cas d'usage 5 : Mise à jour de documentation existante (ROI moyen)",{"type":29,"tag":37,"props":11546,"children":11547},{},[11548,11552],{"type":29,"tag":55,"props":11549,"children":11550},{},[11551],{"type":35,"value":10682},{"type":35,"value":11553}," la documentation existante se désynchronise du code. Une API change, la documentation ne change pas. Un développeur suit la doc et se retrouve avec des erreurs incompréhensibles.",{"type":29,"tag":37,"props":11555,"children":11556},{},[11557,11561],{"type":29,"tag":55,"props":11558,"children":11559},{},[11560],{"type":35,"value":10692},{"type":35,"value":11562}," comparer la documentation existante avec le code actuel et identifier les divergences.",{"type":29,"tag":37,"props":11564,"children":11565},{},[11566],{"type":35,"value":11400},{"type":29,"tag":640,"props":11568,"children":11570},{"code":11569},"Voici la documentation actuelle de l'API /users/{id}/subscriptions :\n[documentation]\n\nVoici le code actuel de cet endpoint :\n[code]\n\nIdentifie les divergences entre la documentation et le code, et propose\nune documentation mise à jour.\n",[11571],{"type":29,"tag":554,"props":11572,"children":11573},{"__ignoreMap":8},[11574],{"type":35,"value":11569},{"type":29,"tag":37,"props":11576,"children":11577},{},[11578],{"type":35,"value":11579},"Limite : l'IA identifie les divergences techniques (paramètres manquants, types incorrects) mais pas les divergences de logique métier. La révision humaine reste nécessaire.",{"type":29,"tag":66,"props":11581,"children":11582},{},[],{"type":29,"tag":70,"props":11584,"children":11586},{"id":11585},"ce-que-lia-ne-peut-pas-documenter",[11587],{"type":35,"value":11588},"Ce que l'IA ne peut pas documenter",{"type":29,"tag":37,"props":11590,"children":11591},{},[11592,11602],{"type":29,"tag":55,"props":11593,"children":11594},{},[11595,11600],{"type":29,"tag":43,"props":11596,"children":11597},{"href":599},[11598],{"type":35,"value":11599},"Décisions d'architecture",{"type":35,"value":11601}," :",{"type":35,"value":11603}," pourquoi Event Sourcing plutôt que CRUD, pourquoi PostgreSQL plutôt que MongoDB, pourquoi ce découpage en microservices. Ces décisions ont un contexte (contraintes techniques, état de l'équipe, urgence du moment) que l'IA ne peut pas reconstruire. Les ADR (Architecture Decision Records) restent un exercice humain.",{"type":29,"tag":37,"props":11605,"children":11606},{},[11607,11612],{"type":29,"tag":55,"props":11608,"children":11609},{},[11610],{"type":35,"value":11611},"Contraintes non-exprimées dans le code :",{"type":35,"value":11613}," un timeout à 3 secondes dans une config qui existe parce qu'un service tiers SLA garantit 99% de réponses en moins de 2,5 secondes. Sans commentaire humain, l'IA ne peut pas savoir que cette valeur ne doit pas changer.",{"type":29,"tag":37,"props":11615,"children":11616},{},[11617,11622],{"type":29,"tag":55,"props":11618,"children":11619},{},[11620],{"type":35,"value":11621},"Le \"pourquoi ça ne marche pas\" :",{"type":35,"value":11623}," les runbooks de debugging, les solutions aux problèmes connus, les workarounds pour les bugs connus des dépendances. Ces informations viennent de l'expérience terrain, pas du code.",{"type":29,"tag":66,"props":11625,"children":11626},{},[],{"type":29,"tag":70,"props":11628,"children":11630},{"id":11629},"comment-intégrer-lia-dans-le-workflow-de-documentation",[11631],{"type":35,"value":11632},"Comment intégrer l'IA dans le workflow de documentation",{"type":29,"tag":37,"props":11634,"children":11635},{},[11636,11641,11643,11648],{"type":29,"tag":55,"props":11637,"children":11638},{},[11639],{"type":35,"value":11640},"Option A : Documentation as part of PR :",{"type":35,"value":11642}," ajouter à la ",{"type":29,"tag":43,"props":11644,"children":11645},{"href":4940},[11646],{"type":35,"value":11647},"Definition of Done",{"type":35,"value":11649}," que toute nouvelle API ou service doit avoir sa documentation générée par IA et révisée par l'auteur. Le reviewer vérifie la documentation comme il vérifie le code.",{"type":29,"tag":37,"props":11651,"children":11652},{},[11653,11658],{"type":29,"tag":55,"props":11654,"children":11655},{},[11656],{"type":35,"value":11657},"Option B : Sprint de documentation :",{"type":35,"value":11659}," une fois par trimestre, un sprint de 2 jours dédié à la mise à jour de la documentation avec assistance IA. Chaque développeur génère la doc de ses services et la révise.",{"type":29,"tag":37,"props":11661,"children":11662},{},[11663,11668],{"type":29,"tag":55,"props":11664,"children":11665},{},[11666],{"type":35,"value":11667},"Option C : Automatisation continue :",{"type":35,"value":11669}," un pipeline CI qui génère automatiquement la documentation OpenAPI à partir des annotations de code et la déploie dans un portail de documentation (Stoplight, Backstage). La doc est toujours à jour avec le code.",{"type":29,"tag":37,"props":11671,"children":11672},{},[11673],{"type":35,"value":11674},"La séquence que je recommande : commencer par les READMEs des services critiques (impact onboarding immédiat), puis la documentation des APIs internes (impact developer experience), puis les résumés de PR (impact code review quality).",{"type":29,"tag":66,"props":11676,"children":11677},{},[],{"type":29,"tag":70,"props":11679,"children":11681},{"id":11680},"faq-sur-lia-et-la-documentation-technique",[11682],{"type":35,"value":11683},"FAQ sur l'IA et la documentation technique",{"type":29,"tag":371,"props":11685,"children":11686},{},[11687,11692],{"type":29,"tag":375,"props":11688,"children":11689},{},[11690],{"type":35,"value":11691},"1. La documentation générée par IA est-elle fiable ?",{"type":29,"tag":37,"props":11693,"children":11694},{},[11695],{"type":35,"value":11696},"Pour le \"quoi\" technique (paramètres, types, structure), oui, avec révision. L'IA peut se tromper sur la sémantique d'une valeur de retour ou sur le comportement dans les cas d'erreur. La règle : toute documentation générée est relue par le développeur qui connaît le code avant d'être mergée. La génération IA réduit le temps d'écriture de 80%, elle ne remplace pas la révision humaine.",{"type":29,"tag":371,"props":11698,"children":11699},{},[11700,11705],{"type":29,"tag":375,"props":11701,"children":11702},{},[11703],{"type":35,"value":11704},"2. Quels outils IA utiliser pour la documentation ?",{"type":29,"tag":37,"props":11706,"children":11707},{},[11708],{"type":35,"value":11709},"GitHub Copilot intégré dans l'IDE génère des docstrings en temps réel. Claude ou GPT-4 pour la génération de READMEs et docs d'API depuis le code. Mintlify Doc Writer (extension VSCode) pour les docstrings. Pour la documentation OpenAPI automatique, les annotations natives de FastAPI ou Spring Boot font mieux que l'IA, le framework le gère nativement.",{"type":29,"tag":371,"props":11711,"children":11712},{},[11713,11718],{"type":29,"tag":375,"props":11714,"children":11715},{},[11716],{"type":35,"value":11717},"3. Comment éviter que la documentation générée soit obsolète dès le lendemain ?",{"type":29,"tag":37,"props":11719,"children":11720},{},[11721],{"type":35,"value":11722},"Deux stratégies : (1) Documentation automatique synchronisée avec le code (OpenAPI généré par le framework, Storybook pour les composants frontend), toujours à jour par construction. (2) Documentation révisée par humain + tests de documentation qui vérifient que les exemples de code dans la doc compilent et retournent les bons résultats. L'approche hybride : génération automatique pour les APIs, révision humaine pour les guides.",{"type":29,"tag":371,"props":11724,"children":11725},{},[11726,11731],{"type":29,"tag":375,"props":11727,"children":11728},{},[11729],{"type":35,"value":11730},"4. Les développeurs seniors résistent à documenter même avec l'IA : comment les convaincre ?",{"type":29,"tag":37,"props":11732,"children":11733},{},[11734],{"type":35,"value":11735},"En changeant le cadre. La documentation n'est pas un effort pour les autres, c'est une réduction du coût de maintenance pour soi. Le développeur senior qui documente son service aujourd'hui est celui qui ne répondra plus à 3 questions par semaine sur ce service dans 6 mois. Calculez le coût réel des interruptions : 3 questions × 30 min × 52 semaines = 78 heures/an, contre 2 heures de documentation avec IA. L'argument est économique, pas moral.",{"type":29,"tag":371,"props":11737,"children":11738},{},[11739,11744],{"type":29,"tag":375,"props":11740,"children":11741},{},[11742],{"type":35,"value":11743},"5. Faut-il documenter en français ou en anglais ?",{"type":29,"tag":37,"props":11745,"children":11746},{},[11747],{"type":35,"value":11748},"Le code et les commentaires techniques dans la même langue que le reste du codebase (souvent anglais dans les équipes internationales). Les READMEs et guides internes dans la langue de l'équipe. La règle pratique : si un document sera lu par des personnes externes à l'équipe → anglais. Si interne à l'équipe → langue de l'équipe.",{"type":29,"tag":66,"props":11750,"children":11751},{},[],{"type":29,"tag":166,"props":11753,"children":11755},{"cta":11754,"href":443,"title":4072,"type":445},"Télécharger la checklist gratuite →",[11756],{"type":29,"tag":37,"props":11757,"children":11758},{},[11759],{"type":35,"value":11760},"La checklist AI-Ready inclut les cas d'usage IA validés par pilier (documentation, code review, tests, architecture) et le framework d'évaluation d'adoption pour votre équipe. Avec les métriques de ROI pour chaque cas d'usage.",{"type":29,"tag":1241,"props":11762,"children":11763},{},[11764],{"type":35,"value":1245},{"title":8,"searchDepth":453,"depth":453,"links":11766},[11767,11768,11769,11770,11771,11772,11773,11774,11775],{"id":10632,"depth":453,"text":10635},{"id":10671,"depth":453,"text":10674},{"id":10774,"depth":453,"text":10777},{"id":11374,"depth":453,"text":11377},{"id":11434,"depth":453,"text":11437},{"id":11541,"depth":453,"text":11544},{"id":11585,"depth":453,"text":11588},{"id":11629,"depth":453,"text":11632},{"id":11680,"depth":453,"text":11683},"content:fr:intelligence-artificielle:ia-documentation-technique-cas-usage.md","fr/intelligence-artificielle/ia-documentation-technique-cas-usage.md","fr/intelligence-artificielle/ia-documentation-technique-cas-usage",1775679727995]