[{"data":1,"prerenderedAt":4634},["ShallowReactive",2],{"search-api":-1,"listing-tag-dette-technique-page-1":3},[4,973,3251],{"_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":20,"readingTime":21,"body":26,"_type":967,"_id":968,"_source":969,"_file":970,"_stem":971,"_extension":972},"/fr/dette-technique/5-raisons-app-meurt-18-mois","dette-technique",false,"","5 raisons pour lesquelles votre app meurt à 18 mois (et 5 pratiques pour 10 ans)","On dit code legacy comme si c'était une fatalité. La plupart des apps meurent à 18 mois pour 5 raisons craft précises. Voici lesquelles, et comment tenir.",69,"2026-05-25",true,[6],[6,16,17,18,19],"software-craftsmanship","ddd","adr","code-durable","covers/articles/5-raisons-app-meurt-18-mois.jpg",{"text":22,"minutes":23,"time":24,"words":25},"15 min read",14.865,891900,2973,{"type":27,"children":28,"toc":954},"root",[29,49,54,58,65,77,82,96,118,140,143,149,166,176,193,206,211,214,220,229,238,256,334,339,342,348,357,366,383,388,391,404,407,413,422,431,441,454,457,463,472,481,491,496,509,512,518,523,531,536,629,634,637,643,648,783,796,799,805,810,815,820,831,843,846,852,867,880,893,906,926,939,942],{"type":30,"tag":31,"props":32,"children":33},"element","p",{},[34],{"type":30,"tag":35,"props":36,"children":37},"strong",{},[38,41,47],{"type":39,"value":40},"text","En 2024, j'ai assisté en consultant externe à la décision de réécrire complètement une application chez un client dans le secteur bancaire. L'app avait 22 mois. 480 000 lignes de code. Toute l'équipe d'origine était partie. Le coût de modification d'une feature simple était devenu prohibitif. Le verdict du CTO : ",{"type":30,"tag":42,"props":43,"children":44},"em",{},[45],{"type":39,"value":46},"\"on repart de zéro, c'est moins cher.\"",{"type":39,"value":48}," Cette phrase, je l'ai entendue 7 fois en 25 ans. Et à chaque fois, ce n'est pas le temps qui a tué l'application. C'est 5 choix craft qui n'avaient pas été faits.",{"type":30,"tag":31,"props":50,"children":51},{},[52],{"type":39,"value":53},"Cet article est le compagnon de fond de la série sur le code durable. Voici les 5 raisons systémiques de la mort à 18 mois, et les 5 pratiques craft qui changent radicalement la trajectoire.",{"type":30,"tag":55,"props":56,"children":57},"hr",{},[],{"type":30,"tag":59,"props":60,"children":62},"h2",{"id":61},"le-mythe-de-lappli-qui-meurt-parce-quelle-vieillit",[63],{"type":39,"value":64},"Le mythe de l'appli qui meurt parce qu'elle vieillit",{"type":30,"tag":31,"props":66,"children":67},{},[68,70,75],{"type":39,"value":69},"On parle de ",{"type":30,"tag":42,"props":71,"children":72},{},[73],{"type":39,"value":74},"\"code legacy\"",{"type":39,"value":76}," comme si c'était une fatalité du temps. Comme si toute application atteignait fatalement un point où elle devenait impossible à maintenir. C'est faux, et c'est démontré.",{"type":30,"tag":31,"props":78,"children":79},{},[80],{"type":39,"value":81},"Sur les 11 codebases bancaires que j'ai auditées depuis 2024, j'ai trouvé une application de 19 ans encore activement développée, lisible, modifiable, avec un onboarding nouvel-arrivant de 3 semaines. À côté, j'ai vu 4 applications de moins de 24 mois où le CTO planifiait une réécriture parce que la modification coûtait trop cher.",{"type":30,"tag":31,"props":83,"children":84},{},[85,87,94],{"type":39,"value":86},"Le facteur âge n'est pas la variable explicative. Le facteur discipline craft l'est. Selon la classification du ",{"type":30,"tag":88,"props":89,"children":91},"a",{"href":90},"/fr/dette-technique/introduction-maturite-engineering-5-niveaux",[92],{"type":39,"value":93},"niveau de maturité engineering",{"type":39,"value":95}," que j'utilise en mission, une équipe de niveau 3+ peut maintenir une application 10 à 15 ans sans réécriture majeure. Une équipe de niveau 1-2 voit la fatigue de codebase apparaître à 12-18 mois.",{"type":30,"tag":97,"props":98,"children":99},"blockquote",{},[100],{"type":30,"tag":31,"props":101,"children":102},{},[103,108,110,116],{"type":30,"tag":35,"props":104,"children":105},{},[106],{"type":39,"value":107},"Ce que j'ai observé",{"type":39,"value":109}," : dans l'équipe bancaire dont je parle en intro, j'ai fait un audit post-mortem du repo en cours de mort. Les 5 mécanismes ci-dessous étaient tous présents. Aucun n'avait été identifié pendant la vie de l'application. Tous auraient pu être évités avec une discipline craft installée dès les 3 premiers mois, en s'inspirant des ",{"type":30,"tag":88,"props":111,"children":113},{"href":112},"/fr/dette-technique/clean-code-software-craftsmanship-principes-java",[114],{"type":39,"value":115},"principes Clean Code et software craftsmanship",{"type":39,"value":117}," que je rappelle systématiquement.",{"type":30,"tag":31,"props":119,"children":120},{},[121,123,131,133,138],{"type":39,"value":122},"Cet article s'appuie aussi sur ce que je vois revenir dans les Reels storytelling que je publie sur ",{"type":30,"tag":88,"props":124,"children":128},{"href":125,"rel":126},"https://www.instagram.com/kamangacode/",[127],"nofollow",[129],{"type":39,"value":130},"mon profil Instagram kamangacode",{"type":39,"value":132},". Le cas n°1 du ",{"type":30,"tag":42,"props":134,"children":135},{},[136],{"type":39,"value":137},"\"projet que j'ai vu mourir à 18 mois\"",{"type":39,"value":139}," est celui-ci. Et il est rejouable autant de fois qu'on veut. Voici comment ne plus jamais le rejouer.",{"type":30,"tag":55,"props":141,"children":142},{},[],{"type":30,"tag":59,"props":144,"children":146},{"id":145},"raison-1-aucun-pourquoi-tracé-et-la-pratique-adr",[147],{"type":39,"value":148},"Raison #1 : aucun POURQUOI tracé (et la pratique ADR)",{"type":30,"tag":31,"props":150,"children":151},{},[152,157,159,164],{"type":30,"tag":35,"props":153,"children":154},{},[155],{"type":39,"value":156},"Symptôme",{"type":39,"value":158}," : à 12 mois, plus personne dans l'équipe ne sait ",{"type":30,"tag":42,"props":160,"children":161},{},[162],{"type":39,"value":163},"pourquoi",{"type":39,"value":165}," on a choisi cette architecture, ce framework, ce pattern. Chaque refacto devient une redécouverte du métier. Le coût n'est pas dans le code, il est dans la fouille archéologique.",{"type":30,"tag":31,"props":167,"children":168},{},[169,174],{"type":30,"tag":35,"props":170,"children":171},{},[172],{"type":39,"value":173},"Mécanisme",{"type":39,"value":175}," : pendant les 3 premiers mois d'une app, les décisions architecturales sont prises rapidement, oralement, en stand-up ou en pair. Personne ne les trace. Six mois plus tard, le développeur qui a pris la décision part. Douze mois plus tard, la décision est devenue une coutume non expliquée. À 18 mois, c'est une contrainte non négociée dont plus personne ne se souvient de la raison.",{"type":30,"tag":31,"props":177,"children":178},{},[179,184,186,191],{"type":30,"tag":35,"props":180,"children":181},{},[182],{"type":39,"value":183},"Pratique craft : ADR (Architecture Decision Records).",{"type":39,"value":185}," Michael Nygard a écrit en 2011 l'article fondateur ",{"type":30,"tag":42,"props":187,"children":188},{},[189],{"type":39,"value":190},"\"Documenting Architecture Decisions\"",{"type":39,"value":192}," qui propose un format ultra-minimaliste : Contexte, Options envisagées, Décision, Conséquences. 15 lignes. 30 minutes à rédiger. Versionné dans le repo comme du code.",{"type":30,"tag":31,"props":194,"children":195},{},[196,198,204],{"type":39,"value":197},"Sur le repo crmcoaching que je maintiens depuis 6 mois, je suis à 52 ADRs. Chaque décision structurante (choix de stack, pattern, dépendance, trade-off) a sa trace. Quand je revisite une décision 4 mois plus tard, je retrouve mon raisonnement en 30 secondes. Quand un nouveau dev arrive, il lit la collection d'ADRs comme une généalogie de l'application. C'est exactement ce que recommande ",{"type":30,"tag":88,"props":199,"children":201},{"href":200},"/fr/architecture-craft/adr-architecture-decision-record",[202],{"type":39,"value":203},"la pratique des ADR pour les décisions structurantes",{"type":39,"value":205},".",{"type":30,"tag":31,"props":207,"children":208},{},[209],{"type":39,"value":210},"Sur les missions où j'installe cette discipline, le ratio ADR / 100 commits passe de 0,3 à 2,5 en 6 mois. Et le temps d'onboarding d'un nouveau dev baisse de 35% en moyenne.",{"type":30,"tag":55,"props":212,"children":213},{},[],{"type":30,"tag":59,"props":215,"children":217},{"id":216},"raison-2-pas-de-frontières-métier-et-la-pratique-bounded-contexts",[218],{"type":39,"value":219},"Raison #2 : pas de frontières métier (et la pratique Bounded Contexts)",{"type":30,"tag":31,"props":221,"children":222},{},[223,227],{"type":30,"tag":35,"props":224,"children":225},{},[226],{"type":39,"value":156},{"type":39,"value":228}," : modifier 1 module touche 3 autres. Le module \"facturation\" appelle directement le module \"stock\" qui touche au module \"auth\". Tout dépend de tout. Aucun refacto local n'est possible. Chaque feature devient une chirurgie sur l'ensemble du corps.",{"type":30,"tag":31,"props":230,"children":231},{},[232,236],{"type":30,"tag":35,"props":233,"children":234},{},[235],{"type":39,"value":173},{"type":39,"value":237}," : les premières features sont écrites vite, dans le même répertoire, avec des appels directs entre modules. Au bout de 6 mois, la matrice de dépendances ressemble à un plat de spaghettis. Au bout de 12 mois, l'équipe n'ose plus toucher au module central par peur de casser ce qu'elle ne voit pas.",{"type":30,"tag":31,"props":239,"children":240},{},[241,246,248,254],{"type":30,"tag":35,"props":242,"children":243},{},[244],{"type":39,"value":245},"Pratique craft : Bounded Contexts",{"type":39,"value":247}," issus du ",{"type":30,"tag":88,"props":249,"children":251},{"href":250},"/fr/architecture-craft/decouvrir-domain-driven-design-ddd-avantages-exemples-java",[252],{"type":39,"value":253},"Domain-Driven Design d'Eric Evans",{"type":39,"value":255}," (2003). Chaque module a un sens métier précis et délimité. Les communications entre modules passent par des contrats explicites (events, APIs, requêtes), jamais par des appels internes croisés. C'est l'application directe de ce que le DDD décrit comme la condition de scalabilité humaine d'une codebase.",{"type":30,"tag":31,"props":257,"children":258},{},[259,261,268,270,276,277,283,284,290,291,297,298,304,305,311,312,318,320,325,327,332],{"type":39,"value":260},"Sur le crmcoaching, j'ai défini 8 bounded contexts dès le démarrage : ",{"type":30,"tag":262,"props":263,"children":265},"code",{"className":264},[],[266],{"type":39,"value":267},"booking",{"type":39,"value":269},", ",{"type":30,"tag":262,"props":271,"children":273},{"className":272},[],[274],{"type":39,"value":275},"lead",{"type":39,"value":269},{"type":30,"tag":262,"props":278,"children":280},{"className":279},[],[281],{"type":39,"value":282},"calendar",{"type":39,"value":269},{"type":30,"tag":262,"props":285,"children":287},{"className":286},[],[288],{"type":39,"value":289},"payment",{"type":39,"value":269},{"type":30,"tag":262,"props":292,"children":294},{"className":293},[],[295],{"type":39,"value":296},"notification",{"type":39,"value":269},{"type":30,"tag":262,"props":299,"children":301},{"className":300},[],[302],{"type":39,"value":303},"audit",{"type":39,"value":269},{"type":30,"tag":262,"props":306,"children":308},{"className":307},[],[309],{"type":39,"value":310},"auth",{"type":39,"value":269},{"type":30,"tag":262,"props":313,"children":315},{"className":314},[],[316],{"type":39,"value":317},"tenant",{"type":39,"value":319},". Chacun a sa frontière, son langage ubiquitaire, son équipe de fait (même si je suis seul à coder, je ne mélange jamais les responsabilités). Quand je modifie ",{"type":30,"tag":262,"props":321,"children":323},{"className":322},[],[324],{"type":39,"value":267},{"type":39,"value":326},", je sais que ",{"type":30,"tag":262,"props":328,"children":330},{"className":329},[],[331],{"type":39,"value":289},{"type":39,"value":333}," ne sera pas affecté tant que je ne change pas le contrat d'événement entre les deux. La même logique structure l'architecture hexagonale appliquée en Java.",{"type":30,"tag":31,"props":335,"children":336},{},[337],{"type":39,"value":338},"Cette discipline porte ses fruits à partir du 6ème mois. Avant, elle ressemble à de la sur-organisation. Après, elle ressemble à un investissement qui paie. Sur les missions où j'introduis les bounded contexts en refacto progressif, je vois le temps de modification des features baisser de 40% en moyenne sur 9 mois.",{"type":30,"tag":55,"props":340,"children":341},{},[],{"type":30,"tag":59,"props":343,"children":345},{"id":344},"raison-3-tests-qui-testent-des-mocks-et-la-pratique-ac-level-coverage",[346],{"type":39,"value":347},"Raison #3 : tests qui testent des mocks (et la pratique AC-level coverage)",{"type":30,"tag":31,"props":349,"children":350},{},[351,355],{"type":30,"tag":35,"props":352,"children":353},{},[354],{"type":39,"value":156},{"type":39,"value":356}," : 87% de couverture technique affichée par le rapport SonarQube. Et pourtant, des bugs en prod toutes les semaines. Le filet de tests est dense mais inutile, parce qu'il teste des mocks plutôt que des comportements observables.",{"type":30,"tag":31,"props":358,"children":359},{},[360,364],{"type":30,"tag":35,"props":361,"children":362},{},[363],{"type":39,"value":173},{"type":39,"value":365}," : Claude (et avant lui les juniors) génère des tests qui vérifient que la fonction A appelle la fonction B. Si vous changez l'implémentation pour appeler la fonction C avec le même résultat métier, le test casse, sans qu'aucun bug n'ait été introduit. C'est le pire des deux mondes : couplage fort à l'implémentation, zéro garantie de comportement, faux sentiment de sécurité.",{"type":30,"tag":31,"props":367,"children":368},{},[369,374,376,382],{"type":30,"tag":35,"props":370,"children":371},{},[372],{"type":39,"value":373},"Pratique craft : Acceptance Criteria + couverture AC-level.",{"type":39,"value":375}," Dan North a posé les bases dans ses articles BDD fondateurs de 2006. Format Given/When/Then. Chaque comportement métier exprimé en langage naturel, puis instrumenté en test. L'implémentation peut changer 5 fois, le test reste valable tant que le comportement est respecté. C'est exactement la philosophie défendue dans ",{"type":30,"tag":88,"props":377,"children":379},{"href":378},"/fr/pratiques-agiles/adopter-behaviour-driven-development-bdd-guide-agile",[380],{"type":39,"value":381},"l'adoption du Behaviour-Driven Development",{"type":39,"value":205},{"type":30,"tag":31,"props":384,"children":385},{},[386],{"type":39,"value":387},"Sur le crmcoaching, j'ai 47 acceptance criteria explicites, chacun couvert par un test behavior-level. Mon ratio \"tests utiles / tests totaux\" est à 78%. La couverture brute est plus basse que sur un repo IA-heavy non audité (62% vs 87%), mais la couverture utile triple. Sur les missions où j'instaure cette transition, le change failure rate baisse de 50% en 4 mois. La Definition of Done bien établie est l'autre pilier de cette discipline, et elle se complète bien avec les pièges classiques des tests d'intégration sur du legacy.",{"type":30,"tag":55,"props":389,"children":390},{},[],{"type":30,"tag":392,"props":393,"children":398},"cta",{"cta":394,"href":395,"title":396,"type":397},"Coder comme un senior →","https://app.kamanga.fr/forms/mentoring","Vous voulez prendre les réflexes craft qui font tenir une codebase 10 ans ?","call",[399],{"type":30,"tag":31,"props":400,"children":401},{},[402],{"type":39,"value":403},"Tracer un ADR, nommer une frontière métier, écrire un test qui survit au refacto : ça ne se lit pas, ça se travaille au contact d'un cas réel. En mentoring 1:1, je relis votre code avec vous et on installe ces réflexes sur vos propres modules, pas sur des exemples génériques. Vous repartez en sachant reconnaître les 5 mécanismes de pourrissement avant qu'ils s'installent, et en ayant les gestes pour les couper.",{"type":30,"tag":55,"props":405,"children":406},{},[],{"type":30,"tag":59,"props":408,"children":410},{"id":409},"raison-4-pas-de-discipline-de-refacto-et-la-pratique-strangler-fig",[411],{"type":39,"value":412},"Raison #4 : pas de discipline de refacto (et la pratique Strangler Fig)",{"type":30,"tag":31,"props":414,"children":415},{},[416,420],{"type":30,"tag":35,"props":417,"children":418},{},[419],{"type":39,"value":156},{"type":39,"value":421}," : la dette technique grossit en silence. \"Plus tard\" devient \"jamais\". Au bout de 18 mois, le module legacy fait peur à toute l'équipe. Personne ne veut le toucher. Le coût composé de la dette atteint 1,5x par an (chiffre que je vois revenir sur la majorité de mes audits).",{"type":30,"tag":31,"props":423,"children":424},{},[425,429],{"type":30,"tag":35,"props":426,"children":427},{},[428],{"type":39,"value":173},{"type":39,"value":430}," : sans discipline explicite de refacto, le code se dégrade par accumulation de petits compromis. Chaque feature pressée ajoute son raccourci. Chaque deadline impose son TODO non traité. À 18 mois, la dette accumulée demanderait 3 mois de stop production pour être remboursée, ce qui est inacceptable, donc on continue, et elle continue de grossir.",{"type":30,"tag":31,"props":432,"children":433},{},[434,439],{"type":30,"tag":35,"props":435,"children":436},{},[437],{"type":39,"value":438},"Pratique craft : Strangler Fig Application (Martin Fowler, 2004).",{"type":39,"value":440}," Au lieu de réécrire d'un coup, on encapsule le legacy derrière une interface, et on remplace progressivement module par module. Chaque refacto est documenté en ADR (raison #1 + raison #4 se renforcent), chaque module remplacé libère un peu d'air à l'équipe.",{"type":30,"tag":31,"props":442,"children":443},{},[444,446,452],{"type":39,"value":445},"Sur les missions où j'installe cette discipline, je couple le Strangler Fig avec ",{"type":30,"tag":88,"props":447,"children":449},{"href":448},"/fr/dette-technique/programme-refactoring-approuve-business",[450],{"type":39,"value":451},"un programme de refacto approuvé business",{"type":39,"value":453},". 20% du temps équipe sur 6 mois consacré au remplacement progressif. Pas plus. Pas de \"big bang refacto\". Le résultat : à 12 mois, 40% du legacy est neutralisé, sans avoir mis en pause la livraison de features. C'est aussi ce que défend la Boy Scout Rule appliquée au quotidien : on laisse le code un peu plus propre que comment on l'a trouvé, à chaque PR. Ce travail s'appuie sur l'évaluation préalable du risque legacy pour prioriser correctement.",{"type":30,"tag":55,"props":455,"children":456},{},[],{"type":30,"tag":59,"props":458,"children":460},{"id":459},"raison-5-tout-est-dans-une-seule-tête-et-la-pratique-docs-as-code",[461],{"type":39,"value":462},"Raison #5 : tout est dans une seule tête (et la pratique Docs as code)",{"type":30,"tag":31,"props":464,"children":465},{},[466,470],{"type":30,"tag":35,"props":467,"children":468},{},[469],{"type":39,"value":156},{"type":39,"value":471}," : un développeur part, 30% du savoir métier part avec lui. Trois mois plus tard, l'équipe redécouvre des décisions qu'elle pensait actées. Six mois plus tard, des bugs réapparaissent parce que personne ne se souvient des contraintes initiales.",{"type":30,"tag":31,"props":473,"children":474},{},[475,479],{"type":30,"tag":35,"props":476,"children":477},{},[478],{"type":39,"value":173},{"type":39,"value":480}," : pendant les 12 premiers mois, l'équipe est stable. Les développeurs portent le contexte dans leur tête. Personne ne sent le besoin de tracer. À 12-18 mois, le premier départ révèle le trou. À 24 mois, les rotations cumulées ont fait disparaître la moitié du savoir non écrit.",{"type":30,"tag":31,"props":482,"children":483},{},[484,489],{"type":30,"tag":35,"props":485,"children":486},{},[487],{"type":39,"value":488},"Pratique craft : Docs as code, artifacts vivants versionnés.",{"type":39,"value":490}," Pas une documentation Confluence séparée du repo (qui pourrit en 6 mois). Une documentation dans le repo, à côté du code, mise à jour dans les mêmes PR que le code. ADRs (raison #1), README de module (raison #2), Acceptance Criteria (raison #3), playbooks d'incident, journal de décisions, etc.",{"type":30,"tag":31,"props":492,"children":493},{},[494],{"type":39,"value":495},"Sur le crmcoaching, j'ai 280 fichiers de documentation versionnés dans le repo. Pas des pages mortes, des artifacts vivants : 52 ADRs, 47 ACs, 22 playbooks d'incident, 8 README de bounded context, 18 schemas d'architecture, etc. Le ratio docs / code est à 18% en LOC. C'est ce qui permet à un nouveau dev d'être productif en 3 semaines au lieu de 7, et c'est ce qui fait survivre le contexte aux personnes.",{"type":30,"tag":31,"props":497,"children":498},{},[499,501,507],{"type":39,"value":500},"Cette discipline est aussi ce qui permet à une équipe de tenir l'usage massif de l'IA : Claude lit les ADRs et les contrats de bounded context comme contexte, et propose des solutions cohérentes avec l'architecture, au lieu d'inventer des patterns inadaptés. C'est le sujet de fond traité dans ",{"type":30,"tag":88,"props":502,"children":504},{"href":503},"/fr/intelligence-artificielle/ia-documentation-technique-cas-usage",[505],{"type":39,"value":506},"l'usage de l'IA pour la documentation technique",{"type":39,"value":508},", où l'IA devient un amplificateur d'écriture craft plutôt qu'un raccourci.",{"type":30,"tag":55,"props":510,"children":511},{},[],{"type":30,"tag":59,"props":513,"children":515},{"id":514},"synthèse-le-code-qui-tient-à-10-ans",[516],{"type":39,"value":517},"Synthèse : le code qui tient à 10 ans",{"type":30,"tag":31,"props":519,"children":520},{},[521],{"type":39,"value":522},"Voici la phrase signature que j'utilise en mission, en conférence, en stand-up :",{"type":30,"tag":31,"props":524,"children":525},{},[526],{"type":30,"tag":42,"props":527,"children":528},{},[529],{"type":39,"value":530},"\"Le code qui tient à 10 ans n'est pas le code qui marche aujourd'hui. C'est le code dont les décisions sont tracées, les frontières sont nommées, les comportements sont testés, la dette est remboursée et le savoir est partagé.\"",{"type":30,"tag":31,"props":532,"children":533},{},[534],{"type":39,"value":535},"Ces 5 conditions ne sont pas optionnelles. Ce sont les 5 piliers du craft durable. Une codebase peut survivre à l'absence d'un pilier pendant 6 à 12 mois. Au-delà, elle entre en pourrissement accéléré. Avec les 5 piliers en place, elle peut tenir 10 à 15 ans, traverser 3 ou 4 rotations d'équipe, et accueillir de nouvelles features sans réécriture majeure.",{"type":30,"tag":537,"props":538,"children":539},"table",{},[540,559],{"type":30,"tag":541,"props":542,"children":543},"thead",{},[544],{"type":30,"tag":545,"props":546,"children":547},"tr",{},[548,554],{"type":30,"tag":549,"props":550,"children":551},"th",{},[552],{"type":39,"value":553},"Raison de la mort à 18 mois",{"type":30,"tag":549,"props":555,"children":556},{},[557],{"type":39,"value":558},"Pratique craft de survie 10 ans",{"type":30,"tag":560,"props":561,"children":562},"tbody",{},[563,577,590,603,616],{"type":30,"tag":545,"props":564,"children":565},{},[566,572],{"type":30,"tag":567,"props":568,"children":569},"td",{},[570],{"type":39,"value":571},"#1 Aucun POURQUOI tracé",{"type":30,"tag":567,"props":573,"children":574},{},[575],{"type":39,"value":576},"ADRs versionnées dans le repo",{"type":30,"tag":545,"props":578,"children":579},{},[580,585],{"type":30,"tag":567,"props":581,"children":582},{},[583],{"type":39,"value":584},"#2 Pas de frontières métier",{"type":30,"tag":567,"props":586,"children":587},{},[588],{"type":39,"value":589},"Bounded Contexts (DDD)",{"type":30,"tag":545,"props":591,"children":592},{},[593,598],{"type":30,"tag":567,"props":594,"children":595},{},[596],{"type":39,"value":597},"#3 Tests qui testent des mocks",{"type":30,"tag":567,"props":599,"children":600},{},[601],{"type":39,"value":602},"Acceptance Criteria + tests behavior-level",{"type":30,"tag":545,"props":604,"children":605},{},[606,611],{"type":30,"tag":567,"props":607,"children":608},{},[609],{"type":39,"value":610},"#4 Pas de discipline de refacto",{"type":30,"tag":567,"props":612,"children":613},{},[614],{"type":39,"value":615},"Strangler Fig + 20% temps équipe",{"type":30,"tag":545,"props":617,"children":618},{},[619,624],{"type":30,"tag":567,"props":620,"children":621},{},[622],{"type":39,"value":623},"#5 Tout est dans une tête",{"type":30,"tag":567,"props":625,"children":626},{},[627],{"type":39,"value":628},"Docs as code, artifacts vivants versionnés",{"type":30,"tag":31,"props":630,"children":631},{},[632],{"type":39,"value":633},"Cette grille tient sur un poster A4. Je la donne à chaque équipe en fin de mission. Elle se lit en 30 secondes. Elle structure 10 ans de discipline, et elle prolonge naturellement les pratiques décrites dans comment écrire du code évolutif en développement logiciel.",{"type":30,"tag":55,"props":635,"children":636},{},[],{"type":30,"tag":59,"props":638,"children":640},{"id":639},"ce-que-ça-change-concrètement",[641],{"type":39,"value":642},"Ce que ça change concrètement",{"type":30,"tag":31,"props":644,"children":645},{},[646],{"type":39,"value":647},"Sur les 4 dernières missions où j'ai installé les 5 piliers (audit + plan en 90 jours + accompagnement 6 mois), voici les chiffres avant/après.",{"type":30,"tag":537,"props":649,"children":650},{},[651,672],{"type":30,"tag":541,"props":652,"children":653},{},[654],{"type":30,"tag":545,"props":655,"children":656},{},[657,662,667],{"type":30,"tag":549,"props":658,"children":659},{},[660],{"type":39,"value":661},"Métrique",{"type":30,"tag":549,"props":663,"children":664},{},[665],{"type":39,"value":666},"Avant audit",{"type":30,"tag":549,"props":668,"children":669},{},[670],{"type":39,"value":671},"Après 12 mois",{"type":30,"tag":560,"props":673,"children":674},{},[675,693,711,729,747,765],{"type":30,"tag":545,"props":676,"children":677},{},[678,683,688],{"type":30,"tag":567,"props":679,"children":680},{},[681],{"type":39,"value":682},"Coût moyen d'une feature simple",{"type":30,"tag":567,"props":684,"children":685},{},[686],{"type":39,"value":687},"4,2 jours",{"type":30,"tag":567,"props":689,"children":690},{},[691],{"type":39,"value":692},"1,6 jour",{"type":30,"tag":545,"props":694,"children":695},{},[696,701,706],{"type":30,"tag":567,"props":697,"children":698},{},[699],{"type":39,"value":700},"Onboarding nouveau dev (1ère PR mergée)",{"type":30,"tag":567,"props":702,"children":703},{},[704],{"type":39,"value":705},"7 semaines",{"type":30,"tag":567,"props":707,"children":708},{},[709],{"type":39,"value":710},"3,5 semaines",{"type":30,"tag":545,"props":712,"children":713},{},[714,719,724],{"type":30,"tag":567,"props":715,"children":716},{},[717],{"type":39,"value":718},"Bugs régression par release",{"type":30,"tag":567,"props":720,"children":721},{},[722],{"type":39,"value":723},"5-7",{"type":30,"tag":567,"props":725,"children":726},{},[727],{"type":39,"value":728},"0-1",{"type":30,"tag":545,"props":730,"children":731},{},[732,737,742],{"type":30,"tag":567,"props":733,"children":734},{},[735],{"type":39,"value":736},"Discussions \"et si on réécrivait tout ?\"",{"type":30,"tag":567,"props":738,"children":739},{},[740],{"type":39,"value":741},"1 par trimestre",{"type":30,"tag":567,"props":743,"children":744},{},[745],{"type":39,"value":746},"0",{"type":30,"tag":545,"props":748,"children":749},{},[750,755,760],{"type":30,"tag":567,"props":751,"children":752},{},[753],{"type":39,"value":754},"Ratio docs / code",{"type":30,"tag":567,"props":756,"children":757},{},[758],{"type":39,"value":759},"4%",{"type":30,"tag":567,"props":761,"children":762},{},[763],{"type":39,"value":764},"16%",{"type":30,"tag":545,"props":766,"children":767},{},[768,773,778],{"type":30,"tag":567,"props":769,"children":770},{},[771],{"type":39,"value":772},"ADRs créées dans l'année",{"type":30,"tag":567,"props":774,"children":775},{},[776],{"type":39,"value":777},"3",{"type":30,"tag":567,"props":779,"children":780},{},[781],{"type":39,"value":782},"47",{"type":30,"tag":31,"props":784,"children":785},{},[786,788,794],{"type":39,"value":787},"Le gain économique est mesurable. Une équipe de 5 développeurs qui passe de 4,2 à 1,6 jours par feature livre 2,6 fois plus de valeur pour le même coût salarial. C'est aussi le sujet que je détaille dans ",{"type":30,"tag":88,"props":789,"children":791},{"href":790},"/fr/dette-technique/ingenierie-logicielle-avantage-concurrentiel",[792],{"type":39,"value":793},"l'ingénierie logicielle comme avantage concurrentiel",{"type":39,"value":795},". Le craft n'est pas une dépense engineering, c'est un levier business avec ROI mesurable.",{"type":30,"tag":55,"props":797,"children":798},{},[],{"type":30,"tag":59,"props":800,"children":802},{"id":801},"conclusion",[803],{"type":39,"value":804},"Conclusion",{"type":30,"tag":31,"props":806,"children":807},{},[808],{"type":39,"value":809},"Ce que je veux que vous reteniez de cet article, c'est que la mort d'une application à 18 mois n'est jamais accidentelle. C'est le résultat prévisible de 5 absences de discipline que j'ai vues se rejouer 7 fois en 25 ans. Et symétriquement, la durabilité d'une application à 10 ans n'est jamais miraculeuse. C'est le résultat prévisible de 5 disciplines installées dès les 3 premiers mois.",{"type":30,"tag":31,"props":811,"children":812},{},[813],{"type":39,"value":814},"Le bon moment pour installer ces 5 disciplines, c'était au démarrage. Le deuxième meilleur moment, c'est maintenant. Chaque mois où vous tardez, vous payez en intérêts composés. Chaque ADR que vous écrivez aujourd'hui économise 5 heures de fouille archéologique dans 18 mois. Chaque bounded context que vous définissez aujourd'hui économise 3 jours de coordination dans 12 mois. Chaque test behavior-level aujourd'hui économise un incident en prod dans 6 mois.",{"type":30,"tag":31,"props":816,"children":817},{},[818],{"type":39,"value":819},"Si en lisant ces lignes vous reconnaissez votre situation, vous avez deux choix. Vous pouvez continuer à laisser les 5 raisons s'installer un peu plus chaque sprint. Ou vous pouvez commencer lundi matin, par 1 ADR sur la décision la plus structurante des 3 derniers mois, et bâtir la suite. La discipline craft ne vient pas d'un coup. Elle vient pratique par pratique, ADR par ADR, test par test. Et au bout de 12 mois, vous regardez en arrière et vous ne reconnaissez plus votre codebase, dans le bon sens.",{"type":30,"tag":31,"props":821,"children":822},{},[823,825,830],{"type":39,"value":824},"Pour la suite des patterns de durabilité que je documente chaque semaine en mission, retrouvez-moi sur ",{"type":30,"tag":88,"props":826,"children":828},{"href":125,"rel":827},[127],[829],{"type":39,"value":130},{"type":39,"value":205},{"type":30,"tag":392,"props":832,"children":837},{"cta":833,"href":834,"title":835,"type":836},"Les 100 pratiques que l'IA n'enseigne pas →","https://kamanga.fr/referentiel-craft","Ces 5 piliers craft font partie d'un référentiel de 100 pratiques","product",[838],{"type":30,"tag":31,"props":839,"children":840},{},[841],{"type":39,"value":842},"Les 5 disciplines décrites ici (ADR, bounded contexts, tests behavior-level, Strangler Fig, docs as code) ne sont qu'une partie de ce que j'applique pour qu'une codebase tienne 10 ans. Le Craft Bundle réunit les 100 pratiques craft que j'utilise au quotidien pour coder propre et durable. Celles que l'IA ne vous apprendra jamais, parce qu'elle ne les a jamais vues survivre à 3 rotations d'équipe en prod.",{"type":30,"tag":55,"props":844,"children":845},{},[],{"type":30,"tag":59,"props":847,"children":849},{"id":848},"faq-sur-le-code-durable-et-les-5-piliers-craft",[850],{"type":39,"value":851},"FAQ sur le code durable et les 5 piliers craft",{"type":30,"tag":853,"props":854,"children":855},"details",{},[856,862],{"type":30,"tag":857,"props":858,"children":859},"summary",{},[860],{"type":39,"value":861},"1. Faut-il installer les 5 piliers en même temps ou séquentiellement ?",{"type":30,"tag":31,"props":863,"children":864},{},[865],{"type":39,"value":866},"Séquentiellement, et dans un ordre précis. Mon plan en 90 jours commence par les ADRs (raison #1), parce que c'est la pratique qui se met en place en 1 semaine et qui débloque les 4 autres (la décision d'installer les autres piliers devient elle-même un ADR). Puis viennent les tests behavior-level (raison #3), parce qu'ils protègent les refactos à venir. Puis les Bounded Contexts (raison #2). Puis le Strangler Fig (raison #4). Puis la docs as code globale (raison #5). En 90 jours, les fondations sont là.",{"type":30,"tag":853,"props":868,"children":869},{},[870,875],{"type":30,"tag":857,"props":871,"children":872},{},[873],{"type":39,"value":874},"2. Combien coûte cette discipline en charge supplémentaire pour l'équipe ?",{"type":30,"tag":31,"props":876,"children":877},{},[878],{"type":39,"value":879},"Pendant les 3 premiers mois : 15 à 20% du temps équipe. Pendant les 3 mois suivants : 10 à 12%. Au-delà de 6 mois : 5 à 8%, intégré au flux normal de développement. Et à partir du 12ème mois, c'est un gain net : le temps économisé sur les modifications et l'onboarding dépasse le temps investi dans la discipline. Le ROI s'observe entre M6 et M9.",{"type":30,"tag":853,"props":881,"children":882},{},[883,888],{"type":30,"tag":857,"props":884,"children":885},{},[886],{"type":39,"value":887},"3. Le DDD n'est-il pas trop lourd pour une équipe de 3-5 personnes ?",{"type":30,"tag":31,"props":889,"children":890},{},[891],{"type":39,"value":892},"Le DDD complet, avec ses tactical patterns (aggregates, value objects, repositories, etc.), peut être surdimensionné pour une petite équipe. Mais les Bounded Contexts au sens stratégique sont applicables à n'importe quelle taille d'équipe. Sur le crmcoaching, je suis seul à coder et j'ai 8 bounded contexts. Ça prend 1 heure à définir au démarrage et ça change la maintenabilité sur 10 ans. La règle : commencez petit (3-4 bounded contexts), laissez-les évoluer avec votre compréhension du métier.",{"type":30,"tag":853,"props":894,"children":895},{},[896,901],{"type":30,"tag":857,"props":897,"children":898},{},[899],{"type":39,"value":900},"4. Comment vendre cette discipline à un COMEX qui veut \"livrer plus vite\" ?",{"type":30,"tag":31,"props":902,"children":903},{},[904],{"type":39,"value":905},"Avec le tableau avant/après et le ROI calculé. 2,6 fois plus de features livrées à coût équivalent, c'est l'argument qui passe. Le COMEX n'achète pas du craft, il achète de la productivité durable. Quand vous présentez les 5 piliers comme un programme de productivité long terme (et non comme une exigence morale du dev), l'adoption est radicalement plus facile.",{"type":30,"tag":853,"props":907,"children":908},{},[909,914],{"type":30,"tag":857,"props":910,"children":911},{},[912],{"type":39,"value":913},"5. Les 5 piliers fonctionnent-ils avec du code IA-généré massivement ?",{"type":30,"tag":31,"props":915,"children":916},{},[917,919,925],{"type":39,"value":918},"Encore mieux. Une codebase IA-heavy non disciplinée meurt à 12-15 mois au lieu de 18 (la production de code accélère, la dette s'accumule plus vite). Une codebase IA-heavy avec les 5 piliers tient plus longtemps que les codebases purement humaines des années 2010, parce que Claude lit les ADRs comme contexte et produit du code aligné avec l'architecture en place. Le couplage discipline craft + IA est la combinaison gagnante de 2026, et c'est exactement ce que documente la série sur les ",{"type":30,"tag":88,"props":920,"children":922},{"href":921},"/fr/intelligence-artificielle/recap-5-pieges-claude-semaine-1",[923],{"type":39,"value":924},"pièges Claude et leurs contre-patterns craft",{"type":39,"value":205},{"type":30,"tag":853,"props":927,"children":928},{},[929,934],{"type":30,"tag":857,"props":930,"children":931},{},[932],{"type":39,"value":933},"6. Que faire si mon équipe résiste à installer les ADR (raison #1) ?",{"type":30,"tag":31,"props":935,"children":936},{},[937],{"type":39,"value":938},"Commencez seul. Écrivez 5 ADRs sur les 5 décisions les plus importantes des 3 derniers mois. Mettez-les dans le repo. Référencez-les dans vos prochaines PR. À 2 mois, un autre dev de l'équipe écrira son premier ADR sans qu'on lui demande. À 4 mois, c'est dans la culture. La résistance n'est jamais idéologique, elle est inertielle. Le bon levier, c'est l'exemplarité, pas la prescription. C'est exactement la mécanique qui transforme la qualité de revue de code en réflexe partagé.",{"type":30,"tag":55,"props":940,"children":941},{},[],{"type":30,"tag":392,"props":943,"children":948},{"cta":944,"href":945,"title":946,"type":947},"Évaluer la maturité de mon équipe →","/mes-ressources","Ressource gratuite : Engineering Maturity Assessment","resource",[949],{"type":30,"tag":31,"props":950,"children":951},{},[952],{"type":39,"value":953},"L'EMA est l'outil que je propose au début de chaque mission. Il mesure la maturité de votre équipe sur les 5 piliers du craft durable (et 3 autres axes engineering : observabilité, sécurité, delivery). Quelques minutes pour identifier laquelle des 5 raisons accélère le plus la mort de votre application, et où concentrer vos efforts en priorité dans les 90 prochains jours.",{"title":8,"searchDepth":955,"depth":955,"links":956},2,[957,958,959,960,961,962,963,964,965,966],{"id":61,"depth":955,"text":64},{"id":145,"depth":955,"text":148},{"id":216,"depth":955,"text":219},{"id":344,"depth":955,"text":347},{"id":409,"depth":955,"text":412},{"id":459,"depth":955,"text":462},{"id":514,"depth":955,"text":517},{"id":639,"depth":955,"text":642},{"id":801,"depth":955,"text":804},{"id":848,"depth":955,"text":851},"markdown","content:fr:dette-technique:5-raisons-app-meurt-18-mois.md","content","fr/dette-technique/5-raisons-app-meurt-18-mois.md","fr/dette-technique/5-raisons-app-meurt-18-mois","md",{"_path":974,"_dir":975,"_draft":7,"_partial":7,"_locale":8,"title":976,"description":977,"id":978,"date":979,"listed":13,"nocomments":7,"hidden":7,"categories":980,"tags":981,"cover":986,"readingTime":987,"body":992,"_type":967,"_id":3248,"_source":969,"_file":3249,"_stem":3250,"_extension":972},"/fr/intelligence-artificielle/faux-ami-code-claude-coute-cher","intelligence-artificielle","Le code Claude 'qui marche' est souvent celui qui vous coûte le plus cher","Démonstration chiffrée des 3 faux amis du code IA-généré : copier-coller invisible, abstractions accidentelles, sur-ingénierie. Et la règle YAGNI + AI.",65,"2026-05-13",[975],[982,6,983,984,985],"claude-code","yagni","sur-ingenierie","ia","covers/articles/faux-ami-code-claude-coute-cher.jpg",{"text":988,"minutes":989,"time":990,"words":991},"14 min read",13.37,802200,2674,{"type":27,"children":993,"toc":3237},[994,1002,1007,1010,1016,1037,1046,1051,1063,1089,1092,1098,1103,1124,1619,1632,1644,1657,1660,1666,1671,2077,2098,2103,2137,2142,2145,2154,2157,2163,2168,2680,2693,2698,2717,2720,2726,2731,2844,2849,2860,2863,2869,2874,2884,2901,2911,2921,2926,2929,2933,2938,3049,3076,3079,3083,3088,3093,3098,3109,3118,3121,3127,3140,3161,3174,3187,3200,3220,3223,3231],{"type":30,"tag":31,"props":995,"children":996},{},[997],{"type":30,"tag":35,"props":998,"children":999},{},[1000],{"type":39,"value":1001},"En construisant crmcoaching avec Claude, j'ai vu ces 3 faux amis s'installer dans mes premiers commits bien avant d'avoir mis la discipline en place. Tests verts, ESLint au vert, tout compilait. Et pourtant, chaque nouvelle feature prenait de plus en plus de temps, et modifier un use case existant devenait une navigation dans de la complexité que je n'avais jamais demandée. Pas à cause d'une mauvaise architecture de départ. À cause de 3 patterns que Claude installe silencieusement si on ne lui oppose pas de contraintes explicites.",{"type":30,"tag":31,"props":1003,"children":1004},{},[1005],{"type":39,"value":1006},"Voici les 3 patterns que j'ai identifiés sur mes propres commits, les chiffres de leur coût caché, et la règle craft de 2026 qui les neutralise.",{"type":30,"tag":55,"props":1008,"children":1009},{},[],{"type":30,"tag":59,"props":1011,"children":1013},{"id":1012},"le-mythe-du-ça-compile-cest-bon",[1014],{"type":39,"value":1015},"Le mythe du \"ça compile, c'est bon\"",{"type":30,"tag":31,"props":1017,"children":1018},{},[1019,1021,1028,1030,1036],{"type":39,"value":1020},"Le constat de base est documenté. Selon le ",{"type":30,"tag":88,"props":1022,"children":1025},{"href":1023,"rel":1024},"https://www.gitclear.com/ai_assistant_code_quality_2024_research",[127],[1026],{"type":39,"value":1027},"GitClear AI Copilot Code Quality Report 2024",{"type":39,"value":1029},", sur les repos qui utilisent intensivement un assistant comme Claude, le ratio de code \"copié-collé\" a augmenté de 8 fois depuis 2022. La taille moyenne des PR a grossi de 12%. Le temps de revue par PR a baissé de 14%. Concrètement : on écrit plus, on revoit moins, on duplique plus, ce qui correspond exactement au pattern que je décris dans ",{"type":30,"tag":88,"props":1031,"children":1033},{"href":1032},"/fr/intelligence-artificielle/ia-code-review-retour-experience",[1034],{"type":39,"value":1035},"le retour d'expérience sur la code review IA",{"type":39,"value":205},{"type":30,"tag":31,"props":1038,"children":1039},{},[1040],{"type":30,"tag":1041,"props":1042,"children":1045},"img",{"alt":1043,"src":1044},"La gestion des leads dans crmcoaching, le SaaS que je développe avec Claude","/images/crm/crm-coaching-lead.png",[],{"type":30,"tag":31,"props":1047,"children":1048},{},[1049],{"type":39,"value":1050},"Le piège, c'est que tout ça produit du code qui marche. Les tests passent. Les utilisateurs sont contents. ESLint ne crie pas. Le piège n'apparaît pas tout de suite, il apparaît à 3 ou 6 mois, quand vous devez modifier ce code et que vous découvrez le coût réel des choix initiaux.",{"type":30,"tag":97,"props":1052,"children":1053},{},[1054],{"type":30,"tag":31,"props":1055,"children":1056},{},[1057,1061],{"type":30,"tag":35,"props":1058,"children":1059},{},[1060],{"type":39,"value":107},{"type":39,"value":1062}," : dans les premiers commits de crmcoaching, j'ai compté les fonctions dupliquées à plus de 70% de similarité. Plusieurs paires identifiées, toutes nées du même réflexe Claude : je prompte pour résoudre un problème dans un use case, Claude livre une fonction ressemblant à une qui existe déjà ailleurs dans le repo, je ne vais pas chercher l'existante, je colle la nouvelle. Chaque paire est une dette future : il faudra modifier 2 endroits, faire le diff cognitif, risquer la divergence.",{"type":30,"tag":31,"props":1064,"children":1065},{},[1066,1068,1073,1075,1080,1082,1087],{"type":39,"value":1067},"Donald Knuth avait écrit en 1974 que ",{"type":30,"tag":42,"props":1069,"children":1070},{},[1071],{"type":39,"value":1072},"\"premature optimization is the root of all evil\"",{"type":39,"value":1074},". Sa formule s'applique aussi à l'abstraction. En 2026, je dirais que ",{"type":30,"tag":42,"props":1076,"children":1077},{},[1078],{"type":39,"value":1079},"\"l'abstraction prématurée IA-générée est la racine du mal silencieux\"",{"type":39,"value":1081},". Le mal silencieux, c'est celui qui ne fait pas planter la prod, mais qui ralentit tout le monde sans que personne ne sache pourquoi. C'est aussi ce qu'éclairent ",{"type":30,"tag":88,"props":1083,"children":1084},{"href":112},[1085],{"type":39,"value":1086},"les principes Clean Code et software craftsmanship",{"type":39,"value":1088}," : la qualité ne se voit pas dans le code \"qui marche\", elle se voit dans le code \"qu'on peut modifier sans souffrir\".",{"type":30,"tag":55,"props":1090,"children":1091},{},[],{"type":30,"tag":59,"props":1093,"children":1095},{"id":1094},"faux-ami-1-le-copier-coller-invisible",[1096],{"type":39,"value":1097},"Faux ami #1 : le copier-coller invisible",{"type":30,"tag":31,"props":1099,"children":1100},{},[1101],{"type":39,"value":1102},"C'est le plus fréquent et le plus sous-estimé. Claude répète des fonctions parce que c'est plus statistique que de chercher la fonction existante dans le repo. Le développeur l'accepte parce que le code \"marche\".",{"type":30,"tag":31,"props":1104,"children":1105},{},[1106,1108,1114,1116,1122],{"type":39,"value":1107},"Voici un exemple tiré de mes premiers commits sur crmcoaching. Deux use cases différents, ",{"type":30,"tag":262,"props":1109,"children":1111},{"className":1110},[],[1112],{"type":39,"value":1113},"CreateOffer",{"type":39,"value":1115}," et ",{"type":30,"tag":262,"props":1117,"children":1119},{"className":1118},[],[1120],{"type":39,"value":1121},"CreateMentoringCheckoutIntent",{"type":39,"value":1123},", écrits à quelques semaines d'écart. Deux fonctions quasi identiques, à 6 fichiers de distance :",{"type":30,"tag":1125,"props":1126,"children":1130},"pre",{"className":1127,"code":1128,"language":1129,"meta":8,"style":8},"language-typescript shiki shiki-themes catppuccin-frappe github-dark","// apps/api/src/application/offer/use-cases/create-offer.use-case.ts\nfunction computeMonthlyOfferPrice(\n  yearlyPrice: number,\n  fees: number,\n): number {\n  const subtotal = yearlyPrice / 12;\n  const withFees = subtotal + fees / 12;\n  return Math.round(withFees * 100) / 100;\n}\n\n// apps/api/src/application/mentoring/use-cases/create-mentoring-checkout-intent.use-case.ts\nfunction calculateSubscriptionAmount(\n  annualAmount: number,\n  charges: number,\n): number {\n  const base = annualAmount / 12;\n  const total = base + charges / 12;\n  return Math.round(total * 100) / 100;\n}\n","typescript",[1131],{"type":30,"tag":262,"props":1132,"children":1133},{"__ignoreMap":8},[1134,1146,1167,1194,1215,1237,1279,1323,1379,1388,1397,1406,1423,1444,1465,1485,1519,1562,1611],{"type":30,"tag":1135,"props":1136,"children":1139},"span",{"class":1137,"line":1138},"line",1,[1140],{"type":30,"tag":1135,"props":1141,"children":1143},{"style":1142},"--shiki-default:#737994;--shiki-default-font-style:italic;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit",[1144],{"type":39,"value":1145},"// apps/api/src/application/offer/use-cases/create-offer.use-case.ts\n",{"type":30,"tag":1135,"props":1147,"children":1148},{"class":1137,"line":955},[1149,1155,1161],{"type":30,"tag":1135,"props":1150,"children":1152},{"style":1151},"--shiki-default:#CA9EE6;--shiki-dark:#F97583",[1153],{"type":39,"value":1154},"function",{"type":30,"tag":1135,"props":1156,"children":1158},{"style":1157},"--shiki-default:#8CAAEE;--shiki-default-font-style:italic;--shiki-dark:#B392F0;--shiki-dark-font-style:inherit",[1159],{"type":39,"value":1160}," computeMonthlyOfferPrice",{"type":30,"tag":1135,"props":1162,"children":1164},{"style":1163},"--shiki-default:#949CBB;--shiki-dark:#E1E4E8",[1165],{"type":39,"value":1166},"(\n",{"type":30,"tag":1135,"props":1168,"children":1170},{"class":1137,"line":1169},3,[1171,1177,1183,1189],{"type":30,"tag":1135,"props":1172,"children":1174},{"style":1173},"--shiki-default:#EA999C;--shiki-default-font-style:italic;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit",[1175],{"type":39,"value":1176},"  yearlyPrice",{"type":30,"tag":1135,"props":1178,"children":1180},{"style":1179},"--shiki-default:#81C8BE;--shiki-dark:#F97583",[1181],{"type":39,"value":1182},":",{"type":30,"tag":1135,"props":1184,"children":1186},{"style":1185},"--shiki-default:#CA9EE6;--shiki-dark:#79B8FF",[1187],{"type":39,"value":1188}," number",{"type":30,"tag":1135,"props":1190,"children":1191},{"style":1163},[1192],{"type":39,"value":1193},",\n",{"type":30,"tag":1135,"props":1195,"children":1197},{"class":1137,"line":1196},4,[1198,1203,1207,1211],{"type":30,"tag":1135,"props":1199,"children":1200},{"style":1173},[1201],{"type":39,"value":1202},"  fees",{"type":30,"tag":1135,"props":1204,"children":1205},{"style":1179},[1206],{"type":39,"value":1182},{"type":30,"tag":1135,"props":1208,"children":1209},{"style":1185},[1210],{"type":39,"value":1188},{"type":30,"tag":1135,"props":1212,"children":1213},{"style":1163},[1214],{"type":39,"value":1193},{"type":30,"tag":1135,"props":1216,"children":1218},{"class":1137,"line":1217},5,[1219,1224,1228,1232],{"type":30,"tag":1135,"props":1220,"children":1221},{"style":1163},[1222],{"type":39,"value":1223},")",{"type":30,"tag":1135,"props":1225,"children":1226},{"style":1179},[1227],{"type":39,"value":1182},{"type":30,"tag":1135,"props":1229,"children":1230},{"style":1185},[1231],{"type":39,"value":1188},{"type":30,"tag":1135,"props":1233,"children":1234},{"style":1163},[1235],{"type":39,"value":1236}," {\n",{"type":30,"tag":1135,"props":1238,"children":1240},{"class":1137,"line":1239},6,[1241,1246,1252,1257,1263,1268,1274],{"type":30,"tag":1135,"props":1242,"children":1243},{"style":1151},[1244],{"type":39,"value":1245},"  const",{"type":30,"tag":1135,"props":1247,"children":1249},{"style":1248},"--shiki-default:#C6D0F5;--shiki-dark:#79B8FF",[1250],{"type":39,"value":1251}," subtotal",{"type":30,"tag":1135,"props":1253,"children":1254},{"style":1179},[1255],{"type":39,"value":1256}," =",{"type":30,"tag":1135,"props":1258,"children":1260},{"style":1259},"--shiki-default:#C6D0F5;--shiki-dark:#E1E4E8",[1261],{"type":39,"value":1262}," yearlyPrice ",{"type":30,"tag":1135,"props":1264,"children":1265},{"style":1179},[1266],{"type":39,"value":1267},"/",{"type":30,"tag":1135,"props":1269,"children":1271},{"style":1270},"--shiki-default:#EF9F76;--shiki-dark:#79B8FF",[1272],{"type":39,"value":1273}," 12",{"type":30,"tag":1135,"props":1275,"children":1276},{"style":1163},[1277],{"type":39,"value":1278},";\n",{"type":30,"tag":1135,"props":1280,"children":1282},{"class":1137,"line":1281},7,[1283,1287,1292,1296,1301,1306,1311,1315,1319],{"type":30,"tag":1135,"props":1284,"children":1285},{"style":1151},[1286],{"type":39,"value":1245},{"type":30,"tag":1135,"props":1288,"children":1289},{"style":1248},[1290],{"type":39,"value":1291}," withFees",{"type":30,"tag":1135,"props":1293,"children":1294},{"style":1179},[1295],{"type":39,"value":1256},{"type":30,"tag":1135,"props":1297,"children":1298},{"style":1259},[1299],{"type":39,"value":1300}," subtotal ",{"type":30,"tag":1135,"props":1302,"children":1303},{"style":1179},[1304],{"type":39,"value":1305},"+",{"type":30,"tag":1135,"props":1307,"children":1308},{"style":1259},[1309],{"type":39,"value":1310}," fees ",{"type":30,"tag":1135,"props":1312,"children":1313},{"style":1179},[1314],{"type":39,"value":1267},{"type":30,"tag":1135,"props":1316,"children":1317},{"style":1270},[1318],{"type":39,"value":1273},{"type":30,"tag":1135,"props":1320,"children":1321},{"style":1163},[1322],{"type":39,"value":1278},{"type":30,"tag":1135,"props":1324,"children":1326},{"class":1137,"line":1325},8,[1327,1332,1337,1342,1347,1352,1357,1362,1367,1371,1375],{"type":30,"tag":1135,"props":1328,"children":1329},{"style":1151},[1330],{"type":39,"value":1331},"  return",{"type":30,"tag":1135,"props":1333,"children":1334},{"style":1259},[1335],{"type":39,"value":1336}," Math",{"type":30,"tag":1135,"props":1338,"children":1340},{"style":1339},"--shiki-default:#81C8BE;--shiki-dark:#E1E4E8",[1341],{"type":39,"value":205},{"type":30,"tag":1135,"props":1343,"children":1344},{"style":1157},[1345],{"type":39,"value":1346},"round",{"type":30,"tag":1135,"props":1348,"children":1349},{"style":1259},[1350],{"type":39,"value":1351},"(withFees ",{"type":30,"tag":1135,"props":1353,"children":1354},{"style":1179},[1355],{"type":39,"value":1356},"*",{"type":30,"tag":1135,"props":1358,"children":1359},{"style":1270},[1360],{"type":39,"value":1361}," 100",{"type":30,"tag":1135,"props":1363,"children":1364},{"style":1259},[1365],{"type":39,"value":1366},") ",{"type":30,"tag":1135,"props":1368,"children":1369},{"style":1179},[1370],{"type":39,"value":1267},{"type":30,"tag":1135,"props":1372,"children":1373},{"style":1270},[1374],{"type":39,"value":1361},{"type":30,"tag":1135,"props":1376,"children":1377},{"style":1163},[1378],{"type":39,"value":1278},{"type":30,"tag":1135,"props":1380,"children":1382},{"class":1137,"line":1381},9,[1383],{"type":30,"tag":1135,"props":1384,"children":1385},{"style":1163},[1386],{"type":39,"value":1387},"}\n",{"type":30,"tag":1135,"props":1389,"children":1391},{"class":1137,"line":1390},10,[1392],{"type":30,"tag":1135,"props":1393,"children":1394},{"emptyLinePlaceholder":13},[1395],{"type":39,"value":1396},"\n",{"type":30,"tag":1135,"props":1398,"children":1400},{"class":1137,"line":1399},11,[1401],{"type":30,"tag":1135,"props":1402,"children":1403},{"style":1142},[1404],{"type":39,"value":1405},"// apps/api/src/application/mentoring/use-cases/create-mentoring-checkout-intent.use-case.ts\n",{"type":30,"tag":1135,"props":1407,"children":1409},{"class":1137,"line":1408},12,[1410,1414,1419],{"type":30,"tag":1135,"props":1411,"children":1412},{"style":1151},[1413],{"type":39,"value":1154},{"type":30,"tag":1135,"props":1415,"children":1416},{"style":1157},[1417],{"type":39,"value":1418}," calculateSubscriptionAmount",{"type":30,"tag":1135,"props":1420,"children":1421},{"style":1163},[1422],{"type":39,"value":1166},{"type":30,"tag":1135,"props":1424,"children":1426},{"class":1137,"line":1425},13,[1427,1432,1436,1440],{"type":30,"tag":1135,"props":1428,"children":1429},{"style":1173},[1430],{"type":39,"value":1431},"  annualAmount",{"type":30,"tag":1135,"props":1433,"children":1434},{"style":1179},[1435],{"type":39,"value":1182},{"type":30,"tag":1135,"props":1437,"children":1438},{"style":1185},[1439],{"type":39,"value":1188},{"type":30,"tag":1135,"props":1441,"children":1442},{"style":1163},[1443],{"type":39,"value":1193},{"type":30,"tag":1135,"props":1445,"children":1447},{"class":1137,"line":1446},14,[1448,1453,1457,1461],{"type":30,"tag":1135,"props":1449,"children":1450},{"style":1173},[1451],{"type":39,"value":1452},"  charges",{"type":30,"tag":1135,"props":1454,"children":1455},{"style":1179},[1456],{"type":39,"value":1182},{"type":30,"tag":1135,"props":1458,"children":1459},{"style":1185},[1460],{"type":39,"value":1188},{"type":30,"tag":1135,"props":1462,"children":1463},{"style":1163},[1464],{"type":39,"value":1193},{"type":30,"tag":1135,"props":1466,"children":1468},{"class":1137,"line":1467},15,[1469,1473,1477,1481],{"type":30,"tag":1135,"props":1470,"children":1471},{"style":1163},[1472],{"type":39,"value":1223},{"type":30,"tag":1135,"props":1474,"children":1475},{"style":1179},[1476],{"type":39,"value":1182},{"type":30,"tag":1135,"props":1478,"children":1479},{"style":1185},[1480],{"type":39,"value":1188},{"type":30,"tag":1135,"props":1482,"children":1483},{"style":1163},[1484],{"type":39,"value":1236},{"type":30,"tag":1135,"props":1486,"children":1488},{"class":1137,"line":1487},16,[1489,1493,1498,1502,1507,1511,1515],{"type":30,"tag":1135,"props":1490,"children":1491},{"style":1151},[1492],{"type":39,"value":1245},{"type":30,"tag":1135,"props":1494,"children":1495},{"style":1248},[1496],{"type":39,"value":1497}," base",{"type":30,"tag":1135,"props":1499,"children":1500},{"style":1179},[1501],{"type":39,"value":1256},{"type":30,"tag":1135,"props":1503,"children":1504},{"style":1259},[1505],{"type":39,"value":1506}," annualAmount ",{"type":30,"tag":1135,"props":1508,"children":1509},{"style":1179},[1510],{"type":39,"value":1267},{"type":30,"tag":1135,"props":1512,"children":1513},{"style":1270},[1514],{"type":39,"value":1273},{"type":30,"tag":1135,"props":1516,"children":1517},{"style":1163},[1518],{"type":39,"value":1278},{"type":30,"tag":1135,"props":1520,"children":1522},{"class":1137,"line":1521},17,[1523,1527,1532,1536,1541,1545,1550,1554,1558],{"type":30,"tag":1135,"props":1524,"children":1525},{"style":1151},[1526],{"type":39,"value":1245},{"type":30,"tag":1135,"props":1528,"children":1529},{"style":1248},[1530],{"type":39,"value":1531}," total",{"type":30,"tag":1135,"props":1533,"children":1534},{"style":1179},[1535],{"type":39,"value":1256},{"type":30,"tag":1135,"props":1537,"children":1538},{"style":1259},[1539],{"type":39,"value":1540}," base ",{"type":30,"tag":1135,"props":1542,"children":1543},{"style":1179},[1544],{"type":39,"value":1305},{"type":30,"tag":1135,"props":1546,"children":1547},{"style":1259},[1548],{"type":39,"value":1549}," charges ",{"type":30,"tag":1135,"props":1551,"children":1552},{"style":1179},[1553],{"type":39,"value":1267},{"type":30,"tag":1135,"props":1555,"children":1556},{"style":1270},[1557],{"type":39,"value":1273},{"type":30,"tag":1135,"props":1559,"children":1560},{"style":1163},[1561],{"type":39,"value":1278},{"type":30,"tag":1135,"props":1563,"children":1565},{"class":1137,"line":1564},18,[1566,1570,1574,1578,1582,1587,1591,1595,1599,1603,1607],{"type":30,"tag":1135,"props":1567,"children":1568},{"style":1151},[1569],{"type":39,"value":1331},{"type":30,"tag":1135,"props":1571,"children":1572},{"style":1259},[1573],{"type":39,"value":1336},{"type":30,"tag":1135,"props":1575,"children":1576},{"style":1339},[1577],{"type":39,"value":205},{"type":30,"tag":1135,"props":1579,"children":1580},{"style":1157},[1581],{"type":39,"value":1346},{"type":30,"tag":1135,"props":1583,"children":1584},{"style":1259},[1585],{"type":39,"value":1586},"(total ",{"type":30,"tag":1135,"props":1588,"children":1589},{"style":1179},[1590],{"type":39,"value":1356},{"type":30,"tag":1135,"props":1592,"children":1593},{"style":1270},[1594],{"type":39,"value":1361},{"type":30,"tag":1135,"props":1596,"children":1597},{"style":1259},[1598],{"type":39,"value":1366},{"type":30,"tag":1135,"props":1600,"children":1601},{"style":1179},[1602],{"type":39,"value":1267},{"type":30,"tag":1135,"props":1604,"children":1605},{"style":1270},[1606],{"type":39,"value":1361},{"type":30,"tag":1135,"props":1608,"children":1609},{"style":1163},[1610],{"type":39,"value":1278},{"type":30,"tag":1135,"props":1612,"children":1614},{"class":1137,"line":1613},19,[1615],{"type":30,"tag":1135,"props":1616,"children":1617},{"style":1163},[1618],{"type":39,"value":1387},{"type":30,"tag":31,"props":1620,"children":1621},{},[1622,1624,1630],{"type":39,"value":1623},"Même calcul, deux noms, deux fichiers, deux tests, deux maintenances. Le jour où la logique d'arrondi change (par exemple passer à ",{"type":30,"tag":262,"props":1625,"children":1627},{"className":1626},[],[1628],{"type":39,"value":1629},"Math.ceil",{"type":39,"value":1631}," pour la comptabilité), il faut retrouver les 2 endroits. La dette n'est pas dans le code lui-même, elle est dans la divergence future.",{"type":30,"tag":31,"props":1633,"children":1634},{},[1635,1637,1642],{"type":39,"value":1636},"Le contre-pattern craft : avant chaque PR, je demande explicitement à Claude ",{"type":30,"tag":42,"props":1638,"children":1639},{},[1640],{"type":39,"value":1641},"\"cherche dans le repo s'il existe déjà une fonction équivalente à ce que tu viens d'écrire, et propose une refacto qui mutualise\"",{"type":39,"value":1643},". Claude fait ce travail très bien si on le lui demande. Il ne le fait jamais spontanément. Et c'est ce réflexe que la Boy Scout Rule impose à chaque PR : on laisse le repo un peu plus propre qu'on l'a trouvé.",{"type":30,"tag":31,"props":1645,"children":1646},{},[1647,1649,1655],{"type":39,"value":1648},"Sur le crmcoaching, j'ai aujourd'hui 3 utilitaires de calcul financier dans ",{"type":30,"tag":262,"props":1650,"children":1652},{"className":1651},[],[1653],{"type":39,"value":1654},"packages/shared",{"type":39,"value":1656},". Sur un repo équivalent IA-heavy non audité, j'en aurais vu 12 à 15. La différence se voit au bout de 12 mois sur le temps de modification.",{"type":30,"tag":55,"props":1658,"children":1659},{},[],{"type":30,"tag":59,"props":1661,"children":1663},{"id":1662},"faux-ami-2-les-abstractions-accidentelles",[1664],{"type":39,"value":1665},"Faux ami #2 : les abstractions accidentelles",{"type":30,"tag":31,"props":1667,"children":1668},{},[1669],{"type":39,"value":1670},"Le deuxième faux ami est plus subtil. Claude adore les interfaces, les classes abstraites, les patterns enterprise. Si vous lui demandez un service de notation de leads, il vous livre, sur un projet NestJS :",{"type":30,"tag":1125,"props":1672,"children":1674},{"className":1127,"code":1673,"language":1129,"meta":8,"style":8},"// 1. L'interface\nexport interface LeadScorer {\n  score(lead: Lead): number;\n}\n\n// 2. L'unique implémentation, déjà injectable via @Injectable()\n@Injectable()\nexport class StandardLeadScorer implements LeadScorer {\n  score(lead: Lead): number {\n    return lead.interactionCount * 10 + (lead.hasEmail ? 20 : 0);\n  }\n}\n\n// 3. La factory superflue, jamais utilisée par le DI NestJS\nexport class LeadScorerFactory {\n  static create(type: string): LeadScorer {\n    return new StandardLeadScorer();\n  }\n}\n",[1675],{"type":30,"tag":262,"props":1676,"children":1677},{"__ignoreMap":8},[1678,1686,1709,1751,1758,1765,1773,1793,1823,1862,1940,1948,1955,1962,1970,1990,2037,2063,2070],{"type":30,"tag":1135,"props":1679,"children":1680},{"class":1137,"line":1138},[1681],{"type":30,"tag":1135,"props":1682,"children":1683},{"style":1142},[1684],{"type":39,"value":1685},"// 1. L'interface\n",{"type":30,"tag":1135,"props":1687,"children":1688},{"class":1137,"line":955},[1689,1694,1699,1705],{"type":30,"tag":1135,"props":1690,"children":1691},{"style":1151},[1692],{"type":39,"value":1693},"export",{"type":30,"tag":1135,"props":1695,"children":1696},{"style":1151},[1697],{"type":39,"value":1698}," interface",{"type":30,"tag":1135,"props":1700,"children":1702},{"style":1701},"--shiki-default:#E5C890;--shiki-default-font-style:italic;--shiki-dark:#B392F0;--shiki-dark-font-style:inherit",[1703],{"type":39,"value":1704}," LeadScorer",{"type":30,"tag":1135,"props":1706,"children":1707},{"style":1163},[1708],{"type":39,"value":1236},{"type":30,"tag":1135,"props":1710,"children":1711},{"class":1137,"line":1169},[1712,1717,1722,1726,1730,1735,1739,1743,1747],{"type":30,"tag":1135,"props":1713,"children":1714},{"style":1157},[1715],{"type":39,"value":1716},"  score",{"type":30,"tag":1135,"props":1718,"children":1719},{"style":1163},[1720],{"type":39,"value":1721},"(",{"type":30,"tag":1135,"props":1723,"children":1724},{"style":1173},[1725],{"type":39,"value":275},{"type":30,"tag":1135,"props":1727,"children":1728},{"style":1179},[1729],{"type":39,"value":1182},{"type":30,"tag":1135,"props":1731,"children":1732},{"style":1701},[1733],{"type":39,"value":1734}," Lead",{"type":30,"tag":1135,"props":1736,"children":1737},{"style":1163},[1738],{"type":39,"value":1223},{"type":30,"tag":1135,"props":1740,"children":1741},{"style":1179},[1742],{"type":39,"value":1182},{"type":30,"tag":1135,"props":1744,"children":1745},{"style":1185},[1746],{"type":39,"value":1188},{"type":30,"tag":1135,"props":1748,"children":1749},{"style":1163},[1750],{"type":39,"value":1278},{"type":30,"tag":1135,"props":1752,"children":1753},{"class":1137,"line":1196},[1754],{"type":30,"tag":1135,"props":1755,"children":1756},{"style":1163},[1757],{"type":39,"value":1387},{"type":30,"tag":1135,"props":1759,"children":1760},{"class":1137,"line":1217},[1761],{"type":30,"tag":1135,"props":1762,"children":1763},{"emptyLinePlaceholder":13},[1764],{"type":39,"value":1396},{"type":30,"tag":1135,"props":1766,"children":1767},{"class":1137,"line":1239},[1768],{"type":30,"tag":1135,"props":1769,"children":1770},{"style":1142},[1771],{"type":39,"value":1772},"// 2. L'unique implémentation, déjà injectable via @Injectable()\n",{"type":30,"tag":1135,"props":1774,"children":1775},{"class":1137,"line":1281},[1776,1782,1787],{"type":30,"tag":1135,"props":1777,"children":1779},{"style":1778},"--shiki-default:#8CAAEE;--shiki-default-font-style:italic;--shiki-dark:#E1E4E8;--shiki-dark-font-style:inherit",[1780],{"type":39,"value":1781},"@",{"type":30,"tag":1135,"props":1783,"children":1784},{"style":1157},[1785],{"type":39,"value":1786},"Injectable",{"type":30,"tag":1135,"props":1788,"children":1790},{"style":1789},"--shiki-default:#EF9F76;--shiki-dark:#E1E4E8",[1791],{"type":39,"value":1792},"()\n",{"type":30,"tag":1135,"props":1794,"children":1795},{"class":1137,"line":1325},[1796,1800,1805,1810,1815,1819],{"type":30,"tag":1135,"props":1797,"children":1798},{"style":1151},[1799],{"type":39,"value":1693},{"type":30,"tag":1135,"props":1801,"children":1802},{"style":1151},[1803],{"type":39,"value":1804}," class",{"type":30,"tag":1135,"props":1806,"children":1807},{"style":1701},[1808],{"type":39,"value":1809}," StandardLeadScorer",{"type":30,"tag":1135,"props":1811,"children":1812},{"style":1151},[1813],{"type":39,"value":1814}," implements",{"type":30,"tag":1135,"props":1816,"children":1817},{"style":1701},[1818],{"type":39,"value":1704},{"type":30,"tag":1135,"props":1820,"children":1821},{"style":1163},[1822],{"type":39,"value":1236},{"type":30,"tag":1135,"props":1824,"children":1825},{"class":1137,"line":1381},[1826,1830,1834,1838,1842,1846,1850,1854,1858],{"type":30,"tag":1135,"props":1827,"children":1828},{"style":1157},[1829],{"type":39,"value":1716},{"type":30,"tag":1135,"props":1831,"children":1832},{"style":1163},[1833],{"type":39,"value":1721},{"type":30,"tag":1135,"props":1835,"children":1836},{"style":1173},[1837],{"type":39,"value":275},{"type":30,"tag":1135,"props":1839,"children":1840},{"style":1179},[1841],{"type":39,"value":1182},{"type":30,"tag":1135,"props":1843,"children":1844},{"style":1701},[1845],{"type":39,"value":1734},{"type":30,"tag":1135,"props":1847,"children":1848},{"style":1163},[1849],{"type":39,"value":1223},{"type":30,"tag":1135,"props":1851,"children":1852},{"style":1179},[1853],{"type":39,"value":1182},{"type":30,"tag":1135,"props":1855,"children":1856},{"style":1185},[1857],{"type":39,"value":1188},{"type":30,"tag":1135,"props":1859,"children":1860},{"style":1163},[1861],{"type":39,"value":1236},{"type":30,"tag":1135,"props":1863,"children":1864},{"class":1137,"line":1390},[1865,1870,1875,1879,1884,1888,1893,1898,1903,1907,1912,1917,1922,1927,1932,1936],{"type":30,"tag":1135,"props":1866,"children":1867},{"style":1151},[1868],{"type":39,"value":1869},"    return",{"type":30,"tag":1135,"props":1871,"children":1872},{"style":1259},[1873],{"type":39,"value":1874}," lead",{"type":30,"tag":1135,"props":1876,"children":1877},{"style":1339},[1878],{"type":39,"value":205},{"type":30,"tag":1135,"props":1880,"children":1881},{"style":1259},[1882],{"type":39,"value":1883},"interactionCount ",{"type":30,"tag":1135,"props":1885,"children":1886},{"style":1179},[1887],{"type":39,"value":1356},{"type":30,"tag":1135,"props":1889,"children":1890},{"style":1270},[1891],{"type":39,"value":1892}," 10",{"type":30,"tag":1135,"props":1894,"children":1895},{"style":1179},[1896],{"type":39,"value":1897}," +",{"type":30,"tag":1135,"props":1899,"children":1900},{"style":1259},[1901],{"type":39,"value":1902}," (lead",{"type":30,"tag":1135,"props":1904,"children":1905},{"style":1339},[1906],{"type":39,"value":205},{"type":30,"tag":1135,"props":1908,"children":1909},{"style":1259},[1910],{"type":39,"value":1911},"hasEmail ",{"type":30,"tag":1135,"props":1913,"children":1914},{"style":1179},[1915],{"type":39,"value":1916},"?",{"type":30,"tag":1135,"props":1918,"children":1919},{"style":1270},[1920],{"type":39,"value":1921}," 20",{"type":30,"tag":1135,"props":1923,"children":1924},{"style":1179},[1925],{"type":39,"value":1926}," :",{"type":30,"tag":1135,"props":1928,"children":1929},{"style":1270},[1930],{"type":39,"value":1931}," 0",{"type":30,"tag":1135,"props":1933,"children":1934},{"style":1259},[1935],{"type":39,"value":1223},{"type":30,"tag":1135,"props":1937,"children":1938},{"style":1163},[1939],{"type":39,"value":1278},{"type":30,"tag":1135,"props":1941,"children":1942},{"class":1137,"line":1399},[1943],{"type":30,"tag":1135,"props":1944,"children":1945},{"style":1163},[1946],{"type":39,"value":1947},"  }\n",{"type":30,"tag":1135,"props":1949,"children":1950},{"class":1137,"line":1408},[1951],{"type":30,"tag":1135,"props":1952,"children":1953},{"style":1163},[1954],{"type":39,"value":1387},{"type":30,"tag":1135,"props":1956,"children":1957},{"class":1137,"line":1425},[1958],{"type":30,"tag":1135,"props":1959,"children":1960},{"emptyLinePlaceholder":13},[1961],{"type":39,"value":1396},{"type":30,"tag":1135,"props":1963,"children":1964},{"class":1137,"line":1446},[1965],{"type":30,"tag":1135,"props":1966,"children":1967},{"style":1142},[1968],{"type":39,"value":1969},"// 3. La factory superflue, jamais utilisée par le DI NestJS\n",{"type":30,"tag":1135,"props":1971,"children":1972},{"class":1137,"line":1467},[1973,1977,1981,1986],{"type":30,"tag":1135,"props":1974,"children":1975},{"style":1151},[1976],{"type":39,"value":1693},{"type":30,"tag":1135,"props":1978,"children":1979},{"style":1151},[1980],{"type":39,"value":1804},{"type":30,"tag":1135,"props":1982,"children":1983},{"style":1701},[1984],{"type":39,"value":1985}," LeadScorerFactory",{"type":30,"tag":1135,"props":1987,"children":1988},{"style":1163},[1989],{"type":39,"value":1236},{"type":30,"tag":1135,"props":1991,"children":1992},{"class":1137,"line":1487},[1993,1998,2003,2007,2012,2016,2021,2025,2029,2033],{"type":30,"tag":1135,"props":1994,"children":1995},{"style":1151},[1996],{"type":39,"value":1997},"  static",{"type":30,"tag":1135,"props":1999,"children":2000},{"style":1157},[2001],{"type":39,"value":2002}," create",{"type":30,"tag":1135,"props":2004,"children":2005},{"style":1163},[2006],{"type":39,"value":1721},{"type":30,"tag":1135,"props":2008,"children":2009},{"style":1173},[2010],{"type":39,"value":2011},"type",{"type":30,"tag":1135,"props":2013,"children":2014},{"style":1179},[2015],{"type":39,"value":1182},{"type":30,"tag":1135,"props":2017,"children":2018},{"style":1185},[2019],{"type":39,"value":2020}," string",{"type":30,"tag":1135,"props":2022,"children":2023},{"style":1163},[2024],{"type":39,"value":1223},{"type":30,"tag":1135,"props":2026,"children":2027},{"style":1179},[2028],{"type":39,"value":1182},{"type":30,"tag":1135,"props":2030,"children":2031},{"style":1701},[2032],{"type":39,"value":1704},{"type":30,"tag":1135,"props":2034,"children":2035},{"style":1163},[2036],{"type":39,"value":1236},{"type":30,"tag":1135,"props":2038,"children":2039},{"class":1137,"line":1521},[2040,2044,2050,2054,2059],{"type":30,"tag":1135,"props":2041,"children":2042},{"style":1151},[2043],{"type":39,"value":1869},{"type":30,"tag":1135,"props":2045,"children":2047},{"style":2046},"--shiki-default:#CA9EE6;--shiki-default-font-weight:bold;--shiki-dark:#F97583;--shiki-dark-font-weight:inherit",[2048],{"type":39,"value":2049}," new",{"type":30,"tag":1135,"props":2051,"children":2052},{"style":1157},[2053],{"type":39,"value":1809},{"type":30,"tag":1135,"props":2055,"children":2056},{"style":1259},[2057],{"type":39,"value":2058},"()",{"type":30,"tag":1135,"props":2060,"children":2061},{"style":1163},[2062],{"type":39,"value":1278},{"type":30,"tag":1135,"props":2064,"children":2065},{"class":1137,"line":1564},[2066],{"type":30,"tag":1135,"props":2067,"children":2068},{"style":1163},[2069],{"type":39,"value":1947},{"type":30,"tag":1135,"props":2071,"children":2072},{"class":1137,"line":1613},[2073],{"type":30,"tag":1135,"props":2074,"children":2075},{"style":1163},[2076],{"type":39,"value":1387},{"type":30,"tag":31,"props":2078,"children":2079},{},[2080,2082,2088,2090,2096],{"type":39,"value":2081},"Une interface, un ",{"type":30,"tag":262,"props":2083,"children":2085},{"className":2084},[],[2086],{"type":39,"value":2087},"@Injectable()",{"type":39,"value":2089},", une factory. Pour calculer un score avec 2 opérations. Une seule implémentation concrète. NestJS injecte directement ",{"type":30,"tag":262,"props":2091,"children":2093},{"className":2092},[],[2094],{"type":39,"value":2095},"StandardLeadScorer",{"type":39,"value":2097}," partout. La factory n'est appelée nulle part, sauf dans un test. Aucun besoin d'inversion réel.",{"type":30,"tag":31,"props":2099,"children":2100},{},[2101],{"type":39,"value":2102},"Cette sur-ingénierie a un coût concret. À chaque modification, vous passez par 3 fichiers au lieu d'un. Vous écrivez 2 fois plus de tests (le mock de l'interface + le test de l'implémentation). Vous augmentez la charge cognitive pour tout nouveau dev. Et le pire : si le métier demande un jour une vraie variation, vous ne la verrez pas dans le pattern existant parce que tout est déjà \"préparé\" pour des variations qui n'existent pas.",{"type":30,"tag":31,"props":2104,"children":2105},{},[2106,2108,2113,2115,2120,2122,2128,2130,2136],{"type":39,"value":2107},"Le contre-pattern craft, c'est ce que Martin Fowler appelait ",{"type":30,"tag":42,"props":2109,"children":2110},{},[2111],{"type":39,"value":2112},"\"Rule of Three\"",{"type":39,"value":2114}," dans ",{"type":30,"tag":42,"props":2116,"children":2117},{},[2118],{"type":39,"value":2119},"Refactoring",{"type":39,"value":2121}," (2018). Vous ne créez une abstraction qu'à partir du troisième cas concret. Si une fonction n'a qu'une implémentation, c'est une fonction. Pas une interface, pas une factory, pas une classe abstraite. Une fonction. C'est exactement la philosophie défendue dans ",{"type":30,"tag":88,"props":2123,"children":2125},{"href":2124},"/fr/dette-technique/yagni-ecrire-code-qualite-sans-fonctionnalites-inutiles",[2126],{"type":39,"value":2127},"YAGNI : écrire du code de qualité sans fonctionnalités inutiles",{"type":39,"value":2129}," et dans le ",{"type":30,"tag":88,"props":2131,"children":2133},{"href":2132},"/fr/dette-technique/principe-kiss-bonnes-pratiques-java",[2134],{"type":39,"value":2135},"principe KISS appliqué en Java",{"type":39,"value":205},{"type":30,"tag":31,"props":2138,"children":2139},{},[2140],{"type":39,"value":2141},"Sur le crmcoaching, j'ai 47 use cases sans aucune interface devant eux. Quand j'aurai une vraie variation à modéliser (typiquement après 6 mois de production), je créerai l'interface à partir des 3 cas réels. Pas avant.",{"type":30,"tag":55,"props":2143,"children":2144},{},[],{"type":30,"tag":392,"props":2146,"children":2148},{"cta":394,"href":395,"title":2147,"type":397},"Vous voulez repérer ces abstractions accidentelles dans vos PR Claude avant de les merger ?",[2149],{"type":30,"tag":31,"props":2150,"children":2151},{},[2152],{"type":39,"value":2153},"Refuser une interface inutile ou une factory qui ne sert à rien, ça ne s'apprend pas en lisant un article : ça se travaille sur votre propre code. En mentoring 1:1, je relis vos PR Claude avec vous, je vous montre où l'IA installe de la sur-ingénierie en silence, et vous repartez avec le réflexe YAGNI qui garde votre repo simple. C'est du face à face pour monter en niveau, pas un audit d'équipe.",{"type":30,"tag":55,"props":2155,"children":2156},{},[],{"type":30,"tag":59,"props":2158,"children":2160},{"id":2159},"faux-ami-3-la-sur-ingénierie-déguisée",[2161],{"type":39,"value":2162},"Faux ami #3 : la sur-ingénierie déguisée",{"type":30,"tag":31,"props":2164,"children":2165},{},[2166],{"type":39,"value":2167},"Le troisième faux ami est le plus visible mais le plus accepté. Claude adore livrer des architectures enterprise pour des problèmes triviaux. Vous demandez un handler pour récupérer un client par id, vous recevez :",{"type":30,"tag":1125,"props":2169,"children":2171},{"className":1127,"code":2170,"language":1129,"meta":8,"style":8},"// QueryHandler + ClientRepositoryPort + EventBusPort + MetricsPort + 2 adapters\n@Injectable()\nexport class GetClientQueryHandler {\n  constructor(\n    private readonly clientRepository: ClientRepositoryPort,\n    private readonly eventBus: EventBusPort,\n    private readonly metrics: MetricsPort,\n  ) {}\n\n  async handle(query: GetClientQuery): Promise\u003CGetClientResult> {\n    const client = await this.clientRepository.findById(query.clientId);\n    if (!client) {\n      throw new ClientNotFoundException(query.clientId);\n    }\n    await this.eventBus.publish(new ClientRetrievedEvent(query.clientId));\n    this.metrics.increment('client.retrieved');\n    return new GetClientResult(client);\n  }\n}\n",[2172],{"type":30,"tag":262,"props":2173,"children":2174},{"__ignoreMap":8},[2175,2183,2198,2218,2230,2261,2290,2319,2332,2339,2403,2467,2495,2528,2536,2597,2641,2666,2673],{"type":30,"tag":1135,"props":2176,"children":2177},{"class":1137,"line":1138},[2178],{"type":30,"tag":1135,"props":2179,"children":2180},{"style":1142},[2181],{"type":39,"value":2182},"// QueryHandler + ClientRepositoryPort + EventBusPort + MetricsPort + 2 adapters\n",{"type":30,"tag":1135,"props":2184,"children":2185},{"class":1137,"line":955},[2186,2190,2194],{"type":30,"tag":1135,"props":2187,"children":2188},{"style":1778},[2189],{"type":39,"value":1781},{"type":30,"tag":1135,"props":2191,"children":2192},{"style":1157},[2193],{"type":39,"value":1786},{"type":30,"tag":1135,"props":2195,"children":2196},{"style":1789},[2197],{"type":39,"value":1792},{"type":30,"tag":1135,"props":2199,"children":2200},{"class":1137,"line":1169},[2201,2205,2209,2214],{"type":30,"tag":1135,"props":2202,"children":2203},{"style":1151},[2204],{"type":39,"value":1693},{"type":30,"tag":1135,"props":2206,"children":2207},{"style":1151},[2208],{"type":39,"value":1804},{"type":30,"tag":1135,"props":2210,"children":2211},{"style":1701},[2212],{"type":39,"value":2213}," GetClientQueryHandler",{"type":30,"tag":1135,"props":2215,"children":2216},{"style":1163},[2217],{"type":39,"value":1236},{"type":30,"tag":1135,"props":2219,"children":2220},{"class":1137,"line":1196},[2221,2226],{"type":30,"tag":1135,"props":2222,"children":2223},{"style":1151},[2224],{"type":39,"value":2225},"  constructor",{"type":30,"tag":1135,"props":2227,"children":2228},{"style":1163},[2229],{"type":39,"value":1166},{"type":30,"tag":1135,"props":2231,"children":2232},{"class":1137,"line":1217},[2233,2238,2243,2248,2252,2257],{"type":30,"tag":1135,"props":2234,"children":2235},{"style":1151},[2236],{"type":39,"value":2237},"    private",{"type":30,"tag":1135,"props":2239,"children":2240},{"style":1151},[2241],{"type":39,"value":2242}," readonly",{"type":30,"tag":1135,"props":2244,"children":2245},{"style":1173},[2246],{"type":39,"value":2247}," clientRepository",{"type":30,"tag":1135,"props":2249,"children":2250},{"style":1179},[2251],{"type":39,"value":1182},{"type":30,"tag":1135,"props":2253,"children":2254},{"style":1701},[2255],{"type":39,"value":2256}," ClientRepositoryPort",{"type":30,"tag":1135,"props":2258,"children":2259},{"style":1163},[2260],{"type":39,"value":1193},{"type":30,"tag":1135,"props":2262,"children":2263},{"class":1137,"line":1239},[2264,2268,2272,2277,2281,2286],{"type":30,"tag":1135,"props":2265,"children":2266},{"style":1151},[2267],{"type":39,"value":2237},{"type":30,"tag":1135,"props":2269,"children":2270},{"style":1151},[2271],{"type":39,"value":2242},{"type":30,"tag":1135,"props":2273,"children":2274},{"style":1173},[2275],{"type":39,"value":2276}," eventBus",{"type":30,"tag":1135,"props":2278,"children":2279},{"style":1179},[2280],{"type":39,"value":1182},{"type":30,"tag":1135,"props":2282,"children":2283},{"style":1701},[2284],{"type":39,"value":2285}," EventBusPort",{"type":30,"tag":1135,"props":2287,"children":2288},{"style":1163},[2289],{"type":39,"value":1193},{"type":30,"tag":1135,"props":2291,"children":2292},{"class":1137,"line":1281},[2293,2297,2301,2306,2310,2315],{"type":30,"tag":1135,"props":2294,"children":2295},{"style":1151},[2296],{"type":39,"value":2237},{"type":30,"tag":1135,"props":2298,"children":2299},{"style":1151},[2300],{"type":39,"value":2242},{"type":30,"tag":1135,"props":2302,"children":2303},{"style":1173},[2304],{"type":39,"value":2305}," metrics",{"type":30,"tag":1135,"props":2307,"children":2308},{"style":1179},[2309],{"type":39,"value":1182},{"type":30,"tag":1135,"props":2311,"children":2312},{"style":1701},[2313],{"type":39,"value":2314}," MetricsPort",{"type":30,"tag":1135,"props":2316,"children":2317},{"style":1163},[2318],{"type":39,"value":1193},{"type":30,"tag":1135,"props":2320,"children":2321},{"class":1137,"line":1325},[2322,2327],{"type":30,"tag":1135,"props":2323,"children":2324},{"style":1163},[2325],{"type":39,"value":2326},"  )",{"type":30,"tag":1135,"props":2328,"children":2329},{"style":1163},[2330],{"type":39,"value":2331}," {}\n",{"type":30,"tag":1135,"props":2333,"children":2334},{"class":1137,"line":1381},[2335],{"type":30,"tag":1135,"props":2336,"children":2337},{"emptyLinePlaceholder":13},[2338],{"type":39,"value":1396},{"type":30,"tag":1135,"props":2340,"children":2341},{"class":1137,"line":1390},[2342,2347,2352,2356,2361,2365,2370,2374,2378,2383,2389,2394,2399],{"type":30,"tag":1135,"props":2343,"children":2344},{"style":1151},[2345],{"type":39,"value":2346},"  async",{"type":30,"tag":1135,"props":2348,"children":2349},{"style":1157},[2350],{"type":39,"value":2351}," handle",{"type":30,"tag":1135,"props":2353,"children":2354},{"style":1163},[2355],{"type":39,"value":1721},{"type":30,"tag":1135,"props":2357,"children":2358},{"style":1173},[2359],{"type":39,"value":2360},"query",{"type":30,"tag":1135,"props":2362,"children":2363},{"style":1179},[2364],{"type":39,"value":1182},{"type":30,"tag":1135,"props":2366,"children":2367},{"style":1701},[2368],{"type":39,"value":2369}," GetClientQuery",{"type":30,"tag":1135,"props":2371,"children":2372},{"style":1163},[2373],{"type":39,"value":1223},{"type":30,"tag":1135,"props":2375,"children":2376},{"style":1179},[2377],{"type":39,"value":1182},{"type":30,"tag":1135,"props":2379,"children":2380},{"style":1701},[2381],{"type":39,"value":2382}," Promise",{"type":30,"tag":1135,"props":2384,"children":2386},{"style":2385},"--shiki-default:#99D1DB;--shiki-dark:#E1E4E8",[2387],{"type":39,"value":2388},"\u003C",{"type":30,"tag":1135,"props":2390,"children":2391},{"style":1701},[2392],{"type":39,"value":2393},"GetClientResult",{"type":30,"tag":1135,"props":2395,"children":2396},{"style":2385},[2397],{"type":39,"value":2398},">",{"type":30,"tag":1135,"props":2400,"children":2401},{"style":1163},[2402],{"type":39,"value":1236},{"type":30,"tag":1135,"props":2404,"children":2405},{"class":1137,"line":1399},[2406,2411,2416,2420,2425,2431,2435,2440,2444,2449,2454,2458,2463],{"type":30,"tag":1135,"props":2407,"children":2408},{"style":1151},[2409],{"type":39,"value":2410},"    const",{"type":30,"tag":1135,"props":2412,"children":2413},{"style":1248},[2414],{"type":39,"value":2415}," client",{"type":30,"tag":1135,"props":2417,"children":2418},{"style":1179},[2419],{"type":39,"value":1256},{"type":30,"tag":1135,"props":2421,"children":2422},{"style":1151},[2423],{"type":39,"value":2424}," await",{"type":30,"tag":1135,"props":2426,"children":2428},{"style":2427},"--shiki-default:#E78284;--shiki-dark:#79B8FF",[2429],{"type":39,"value":2430}," this",{"type":30,"tag":1135,"props":2432,"children":2433},{"style":1339},[2434],{"type":39,"value":205},{"type":30,"tag":1135,"props":2436,"children":2437},{"style":1259},[2438],{"type":39,"value":2439},"clientRepository",{"type":30,"tag":1135,"props":2441,"children":2442},{"style":1339},[2443],{"type":39,"value":205},{"type":30,"tag":1135,"props":2445,"children":2446},{"style":1157},[2447],{"type":39,"value":2448},"findById",{"type":30,"tag":1135,"props":2450,"children":2451},{"style":1259},[2452],{"type":39,"value":2453},"(query",{"type":30,"tag":1135,"props":2455,"children":2456},{"style":1339},[2457],{"type":39,"value":205},{"type":30,"tag":1135,"props":2459,"children":2460},{"style":1259},[2461],{"type":39,"value":2462},"clientId)",{"type":30,"tag":1135,"props":2464,"children":2465},{"style":1163},[2466],{"type":39,"value":1278},{"type":30,"tag":1135,"props":2468,"children":2469},{"class":1137,"line":1408},[2470,2475,2480,2485,2490],{"type":30,"tag":1135,"props":2471,"children":2472},{"style":1151},[2473],{"type":39,"value":2474},"    if",{"type":30,"tag":1135,"props":2476,"children":2477},{"style":1259},[2478],{"type":39,"value":2479}," (",{"type":30,"tag":1135,"props":2481,"children":2482},{"style":1179},[2483],{"type":39,"value":2484},"!",{"type":30,"tag":1135,"props":2486,"children":2487},{"style":1259},[2488],{"type":39,"value":2489},"client) ",{"type":30,"tag":1135,"props":2491,"children":2492},{"style":1163},[2493],{"type":39,"value":2494},"{\n",{"type":30,"tag":1135,"props":2496,"children":2497},{"class":1137,"line":1425},[2498,2503,2507,2512,2516,2520,2524],{"type":30,"tag":1135,"props":2499,"children":2500},{"style":1151},[2501],{"type":39,"value":2502},"      throw",{"type":30,"tag":1135,"props":2504,"children":2505},{"style":2046},[2506],{"type":39,"value":2049},{"type":30,"tag":1135,"props":2508,"children":2509},{"style":1157},[2510],{"type":39,"value":2511}," ClientNotFoundException",{"type":30,"tag":1135,"props":2513,"children":2514},{"style":1259},[2515],{"type":39,"value":2453},{"type":30,"tag":1135,"props":2517,"children":2518},{"style":1339},[2519],{"type":39,"value":205},{"type":30,"tag":1135,"props":2521,"children":2522},{"style":1259},[2523],{"type":39,"value":2462},{"type":30,"tag":1135,"props":2525,"children":2526},{"style":1163},[2527],{"type":39,"value":1278},{"type":30,"tag":1135,"props":2529,"children":2530},{"class":1137,"line":1446},[2531],{"type":30,"tag":1135,"props":2532,"children":2533},{"style":1163},[2534],{"type":39,"value":2535},"    }\n",{"type":30,"tag":1135,"props":2537,"children":2538},{"class":1137,"line":1467},[2539,2544,2548,2552,2557,2561,2566,2570,2575,2580,2584,2588,2593],{"type":30,"tag":1135,"props":2540,"children":2541},{"style":1151},[2542],{"type":39,"value":2543},"    await",{"type":30,"tag":1135,"props":2545,"children":2546},{"style":2427},[2547],{"type":39,"value":2430},{"type":30,"tag":1135,"props":2549,"children":2550},{"style":1339},[2551],{"type":39,"value":205},{"type":30,"tag":1135,"props":2553,"children":2554},{"style":1259},[2555],{"type":39,"value":2556},"eventBus",{"type":30,"tag":1135,"props":2558,"children":2559},{"style":1339},[2560],{"type":39,"value":205},{"type":30,"tag":1135,"props":2562,"children":2563},{"style":1157},[2564],{"type":39,"value":2565},"publish",{"type":30,"tag":1135,"props":2567,"children":2568},{"style":1259},[2569],{"type":39,"value":1721},{"type":30,"tag":1135,"props":2571,"children":2572},{"style":2046},[2573],{"type":39,"value":2574},"new",{"type":30,"tag":1135,"props":2576,"children":2577},{"style":1157},[2578],{"type":39,"value":2579}," ClientRetrievedEvent",{"type":30,"tag":1135,"props":2581,"children":2582},{"style":1259},[2583],{"type":39,"value":2453},{"type":30,"tag":1135,"props":2585,"children":2586},{"style":1339},[2587],{"type":39,"value":205},{"type":30,"tag":1135,"props":2589,"children":2590},{"style":1259},[2591],{"type":39,"value":2592},"clientId))",{"type":30,"tag":1135,"props":2594,"children":2595},{"style":1163},[2596],{"type":39,"value":1278},{"type":30,"tag":1135,"props":2598,"children":2599},{"class":1137,"line":1487},[2600,2605,2609,2614,2618,2623,2627,2633,2637],{"type":30,"tag":1135,"props":2601,"children":2602},{"style":2427},[2603],{"type":39,"value":2604},"    this",{"type":30,"tag":1135,"props":2606,"children":2607},{"style":1339},[2608],{"type":39,"value":205},{"type":30,"tag":1135,"props":2610,"children":2611},{"style":1259},[2612],{"type":39,"value":2613},"metrics",{"type":30,"tag":1135,"props":2615,"children":2616},{"style":1339},[2617],{"type":39,"value":205},{"type":30,"tag":1135,"props":2619,"children":2620},{"style":1157},[2621],{"type":39,"value":2622},"increment",{"type":30,"tag":1135,"props":2624,"children":2625},{"style":1259},[2626],{"type":39,"value":1721},{"type":30,"tag":1135,"props":2628,"children":2630},{"style":2629},"--shiki-default:#A6D189;--shiki-dark:#9ECBFF",[2631],{"type":39,"value":2632},"'client.retrieved'",{"type":30,"tag":1135,"props":2634,"children":2635},{"style":1259},[2636],{"type":39,"value":1223},{"type":30,"tag":1135,"props":2638,"children":2639},{"style":1163},[2640],{"type":39,"value":1278},{"type":30,"tag":1135,"props":2642,"children":2643},{"class":1137,"line":1521},[2644,2648,2652,2657,2662],{"type":30,"tag":1135,"props":2645,"children":2646},{"style":1151},[2647],{"type":39,"value":1869},{"type":30,"tag":1135,"props":2649,"children":2650},{"style":2046},[2651],{"type":39,"value":2049},{"type":30,"tag":1135,"props":2653,"children":2654},{"style":1157},[2655],{"type":39,"value":2656}," GetClientResult",{"type":30,"tag":1135,"props":2658,"children":2659},{"style":1259},[2660],{"type":39,"value":2661},"(client)",{"type":30,"tag":1135,"props":2663,"children":2664},{"style":1163},[2665],{"type":39,"value":1278},{"type":30,"tag":1135,"props":2667,"children":2668},{"class":1137,"line":1564},[2669],{"type":30,"tag":1135,"props":2670,"children":2671},{"style":1163},[2672],{"type":39,"value":1947},{"type":30,"tag":1135,"props":2674,"children":2675},{"class":1137,"line":1613},[2676],{"type":30,"tag":1135,"props":2677,"children":2678},{"style":1163},[2679],{"type":39,"value":1387},{"type":30,"tag":31,"props":2681,"children":2682},{},[2683,2685,2691],{"type":39,"value":2684},"30 lignes, 4 fichiers, 3 ports, 1 event qui n'est lu par personne. Pour faire ",{"type":30,"tag":262,"props":2686,"children":2688},{"className":2687},[],[2689],{"type":39,"value":2690},"prisma.client.findUnique({ where: { id } })",{"type":39,"value":2692},". Le coût direct : 4x plus de code à lire pour un nouveau dev. Le coût indirect : la signature de tous les handlers du repo devient ce pattern, donc même les use cases qui justifieraient un découpage simple le portent.",{"type":30,"tag":31,"props":2694,"children":2695},{},[2696],{"type":39,"value":2697},"Le contre-pattern, c'est le principe de proportionnalité. Sur le crmcoaching, j'applique cette règle : si l'opération métier tient en une phrase (\"lire un client par id\"), le code tient en une fonction avec une query Prisma directe. Si elle nécessite 3 étapes coordonnées avec compensation possible, alors un handler peut se justifier. Sinon, c'est de la dette emballée en pattern.",{"type":30,"tag":31,"props":2699,"children":2700},{},[2701,2703,2708,2710,2715],{"type":39,"value":2702},"Robert C. Martin, dans ",{"type":30,"tag":42,"props":2704,"children":2705},{},[2706],{"type":39,"value":2707},"Clean Architecture",{"type":39,"value":2709}," (2017), insiste sur ce point : l'architecture doit ",{"type":30,"tag":42,"props":2711,"children":2712},{},[2713],{"type":39,"value":2714},"suivre",{"type":39,"value":2716}," la complexité du domaine, pas la précéder. Si vous précédez une complexité qui n'existe pas, vous payez aujourd'hui un coût pour des cas qui ne viendront jamais. C'est aussi ce que rappelle le guide du code lisible en software craftsmanship.",{"type":30,"tag":55,"props":2718,"children":2719},{},[],{"type":30,"tag":59,"props":2721,"children":2723},{"id":2722},"calcul-du-vrai-coût-caché",[2724],{"type":39,"value":2725},"Calcul du vrai coût caché",{"type":30,"tag":31,"props":2727,"children":2728},{},[2729],{"type":39,"value":2730},"J'ai mesuré le coût cumulé des 3 faux amis en comparant mes commits de début de projet (avant discipline) avec l'état actuel de crmcoaching. Voici les chiffres, comparés à un repo équivalent où la discipline craft est tenue depuis le début.",{"type":30,"tag":537,"props":2732,"children":2733},{},[2734,2754],{"type":30,"tag":541,"props":2735,"children":2736},{},[2737],{"type":30,"tag":545,"props":2738,"children":2739},{},[2740,2744,2749],{"type":30,"tag":549,"props":2741,"children":2742},{},[2743],{"type":39,"value":661},{"type":30,"tag":549,"props":2745,"children":2746},{},[2747],{"type":39,"value":2748},"Repo IA non audité",{"type":30,"tag":549,"props":2750,"children":2751},{},[2752],{"type":39,"value":2753},"Repo IA + discipline craft",{"type":30,"tag":560,"props":2755,"children":2756},{},[2757,2775,2793,2810,2826],{"type":30,"tag":545,"props":2758,"children":2759},{},[2760,2765,2770],{"type":30,"tag":567,"props":2761,"children":2762},{},[2763],{"type":39,"value":2764},"Temps moyen pour ajouter une feature simple",{"type":30,"tag":567,"props":2766,"children":2767},{},[2768],{"type":39,"value":2769},"3,5 jours",{"type":30,"tag":567,"props":2771,"children":2772},{},[2773],{"type":39,"value":2774},"1,2 jour",{"type":30,"tag":545,"props":2776,"children":2777},{},[2778,2783,2788],{"type":30,"tag":567,"props":2779,"children":2780},{},[2781],{"type":39,"value":2782},"Temps moyen pour modifier une feature existante",{"type":30,"tag":567,"props":2784,"children":2785},{},[2786],{"type":39,"value":2787},"5 jours",{"type":30,"tag":567,"props":2789,"children":2790},{},[2791],{"type":39,"value":2792},"1,8 jour",{"type":30,"tag":545,"props":2794,"children":2795},{},[2796,2801,2805],{"type":30,"tag":567,"props":2797,"children":2798},{},[2799],{"type":39,"value":2800},"Onboarding d'un nouveau dev (jusqu'à 1ère PR mergée)",{"type":30,"tag":567,"props":2802,"children":2803},{},[2804],{"type":39,"value":705},{"type":30,"tag":567,"props":2806,"children":2807},{},[2808],{"type":39,"value":2809},"3 semaines",{"type":30,"tag":545,"props":2811,"children":2812},{},[2813,2817,2822],{"type":30,"tag":567,"props":2814,"children":2815},{},[2816],{"type":39,"value":718},{"type":30,"tag":567,"props":2818,"children":2819},{},[2820],{"type":39,"value":2821},"4-6",{"type":30,"tag":567,"props":2823,"children":2824},{},[2825],{"type":39,"value":728},{"type":30,"tag":545,"props":2827,"children":2828},{},[2829,2834,2839],{"type":30,"tag":567,"props":2830,"children":2831},{},[2832],{"type":39,"value":2833},"Lignes de code pour 1 use case métier",{"type":30,"tag":567,"props":2835,"children":2836},{},[2837],{"type":39,"value":2838},"280 LOC en moyenne",{"type":30,"tag":567,"props":2840,"children":2841},{},[2842],{"type":39,"value":2843},"95 LOC en moyenne",{"type":30,"tag":31,"props":2845,"children":2846},{},[2847],{"type":39,"value":2848},"Le ratio est de 1 à 3 sur la plupart des métriques. Concrètement, sans discipline craft, une équipe de 5 développeurs paie l'équivalent d'1,5 développeur de \"taxe complexité\" chaque mois, sans valeur ajoutée pour les utilisateurs. À 8 000 euros de coût total mensuel chargé par développeur, c'est 12 000 euros par mois. 144 000 euros par an. Sans qu'aucune feature ne s'ajoute en plus.",{"type":30,"tag":31,"props":2850,"children":2851},{},[2852,2854,2858],{"type":39,"value":2853},"C'est le coût silencieux dont je parle quand je dis qu'une codebase IA-heavy non auditée coûte cher, et c'est l'angle business que je détaille dans ",{"type":30,"tag":88,"props":2855,"children":2856},{"href":790},[2857],{"type":39,"value":793},{"type":39,"value":2859},". Personne ne le voit dans le P&L, parce que c'est de la vélocité non gagnée, pas une dépense identifiable. Mais il est là.",{"type":30,"tag":55,"props":2861,"children":2862},{},[],{"type":30,"tag":59,"props":2864,"children":2866},{"id":2865},"la-règle-2026-yagni-ai",[2867],{"type":39,"value":2868},"La règle 2026 : YAGNI + AI",{"type":30,"tag":31,"props":2870,"children":2871},{},[2872],{"type":39,"value":2873},"Voici la règle que j'applique sur crmcoaching et que je recommande à toutes les équipes IA-heavy.",{"type":30,"tag":31,"props":2875,"children":2876},{},[2877,2882],{"type":30,"tag":35,"props":2878,"children":2879},{},[2880],{"type":39,"value":2881},"Règle 1 : pas d'abstraction sans 3 implémentations réelles.",{"type":39,"value":2883}," Pas d'interface devant une seule classe. Pas de factory pour 1 type. Pas de port hexagonal devant un module qui ne peut pas être remplacé. La règle des 3 vient de Martin Fowler, elle date des années 2000, elle s'applique parfaitement à 2026.",{"type":30,"tag":31,"props":2885,"children":2886},{},[2887,2892,2894,2899],{"type":30,"tag":35,"props":2888,"children":2889},{},[2890],{"type":39,"value":2891},"Règle 2 : avant chaque PR Claude, prompter \"cherche les doublons\".",{"type":39,"value":2893}," ",{"type":30,"tag":42,"props":2895,"children":2896},{},[2897],{"type":39,"value":2898},"\"Avant de finaliser, vérifie dans le repo s'il existe déjà une fonction qui fait à 80% la même chose. Si oui, refactore pour mutualiser plutôt que dupliquer.\"",{"type":39,"value":2900}," Claude le fait très bien quand on lui demande. Il ne le fait jamais spontanément.",{"type":30,"tag":31,"props":2902,"children":2903},{},[2904,2909],{"type":30,"tag":35,"props":2905,"children":2906},{},[2907],{"type":39,"value":2908},"Règle 3 : proportionnalité code/domaine.",{"type":39,"value":2910}," Une opération métier triviale = une fonction. Une opération métier coordonnée = un handler/service. Une opération métier critique avec compensation = un saga ou un pattern de coordination explicite. Le code suit le domaine, pas l'inverse.",{"type":30,"tag":31,"props":2912,"children":2913},{},[2914,2919],{"type":30,"tag":35,"props":2915,"children":2916},{},[2917],{"type":39,"value":2918},"Règle 4 : audit des LOC par feature.",{"type":39,"value":2920}," Je mesure tous les 3 mois le nombre de lignes ajoutées par feature livrée. Si la métrique grimpe de plus de 30%, c'est un signal de sur-ingénierie qui s'installe. C'est la même logique qu'en clean code : on ne contrôle que ce qu'on mesure, et la Definition of Done doit inclure ce signal.",{"type":30,"tag":31,"props":2922,"children":2923},{},[2924],{"type":39,"value":2925},"Avec ces 4 règles, le repo crmcoaching tourne à environ 95 LOC par use case métier complet (avec tests + adapter + handler). C'est 3x moins que la moyenne IA-heavy que je vois sur des repos partagés. C'est aussi 3x plus rapide à modifier.",{"type":30,"tag":55,"props":2927,"children":2928},{},[],{"type":30,"tag":59,"props":2930,"children":2931},{"id":639},[2932],{"type":39,"value":642},{"type":30,"tag":31,"props":2934,"children":2935},{},[2936],{"type":39,"value":2937},"Sur les 3 dernières missions où j'ai installé cette discipline (audit + refacto + grille de review), voici les chiffres avant/après mesurés sur 6 mois.",{"type":30,"tag":537,"props":2939,"children":2940},{},[2941,2960],{"type":30,"tag":541,"props":2942,"children":2943},{},[2944],{"type":30,"tag":545,"props":2945,"children":2946},{},[2947,2951,2955],{"type":30,"tag":549,"props":2948,"children":2949},{},[2950],{"type":39,"value":661},{"type":30,"tag":549,"props":2952,"children":2953},{},[2954],{"type":39,"value":666},{"type":30,"tag":549,"props":2956,"children":2957},{},[2958],{"type":39,"value":2959},"Après 6 mois",{"type":30,"tag":560,"props":2961,"children":2962},{},[2963,2981,2998,3015,3031],{"type":30,"tag":545,"props":2964,"children":2965},{},[2966,2971,2976],{"type":30,"tag":567,"props":2967,"children":2968},{},[2969],{"type":39,"value":2970},"LOC moyennes par use case",{"type":30,"tag":567,"props":2972,"children":2973},{},[2974],{"type":39,"value":2975},"280",{"type":30,"tag":567,"props":2977,"children":2978},{},[2979],{"type":39,"value":2980},"110",{"type":30,"tag":545,"props":2982,"children":2983},{},[2984,2989,2993],{"type":30,"tag":567,"props":2985,"children":2986},{},[2987],{"type":39,"value":2988},"Fonctions dupliquées dans le repo",{"type":30,"tag":567,"props":2990,"children":2991},{},[2992],{"type":39,"value":782},{"type":30,"tag":567,"props":2994,"children":2995},{},[2996],{"type":39,"value":2997},"8",{"type":30,"tag":545,"props":2999,"children":3000},{},[3001,3006,3010],{"type":30,"tag":567,"props":3002,"children":3003},{},[3004],{"type":39,"value":3005},"Temps d'onboarding d'un nouveau dev",{"type":30,"tag":567,"props":3007,"children":3008},{},[3009],{"type":39,"value":705},{"type":30,"tag":567,"props":3011,"children":3012},{},[3013],{"type":39,"value":3014},"4 semaines",{"type":30,"tag":545,"props":3016,"children":3017},{},[3018,3023,3027],{"type":30,"tag":567,"props":3019,"children":3020},{},[3021],{"type":39,"value":3022},"Bugs de régression par release",{"type":30,"tag":567,"props":3024,"children":3025},{},[3026],{"type":39,"value":2821},{"type":30,"tag":567,"props":3028,"children":3029},{},[3030],{"type":39,"value":728},{"type":30,"tag":545,"props":3032,"children":3033},{},[3034,3039,3044],{"type":30,"tag":567,"props":3035,"children":3036},{},[3037],{"type":39,"value":3038},"Vélocité (story points/sprint)",{"type":30,"tag":567,"props":3040,"children":3041},{},[3042],{"type":39,"value":3043},"stable",{"type":30,"tag":567,"props":3045,"children":3046},{},[3047],{"type":39,"value":3048},"+28%",{"type":30,"tag":31,"props":3050,"children":3051},{},[3052,3054,3059,3061,3066,3068,3074],{"type":39,"value":3053},"Le gain n'est pas qu'esthétique. La vélocité augmente parce que les développeurs passent moins de temps à naviguer dans la complexité accidentelle, et plus de temps à livrer de la valeur métier. C'est ce que la DORA mesure quand elle parle de ",{"type":30,"tag":42,"props":3055,"children":3056},{},[3057],{"type":39,"value":3058},"throughput",{"type":39,"value":3060}," et de ",{"type":30,"tag":42,"props":3062,"children":3063},{},[3064],{"type":39,"value":3065},"stability",{"type":39,"value":3067}," combinés, et c'est précisément le levier qu'une ",{"type":30,"tag":88,"props":3069,"children":3071},{"href":3070},"/fr/dette-technique/revue-de-code-java-guide-exemples",[3072],{"type":39,"value":3073},"revue de code structurée",{"type":39,"value":3075}," permet d'enclencher.",{"type":30,"tag":55,"props":3077,"children":3078},{},[],{"type":30,"tag":59,"props":3080,"children":3081},{"id":801},[3082],{"type":39,"value":804},{"type":30,"tag":31,"props":3084,"children":3085},{},[3086],{"type":39,"value":3087},"Ce que je veux que vous reteniez de cet article, c'est que le code Claude \"qui marche\" n'est pas une garantie de qualité, c'est une garantie de fonctionnement à T0. La qualité d'un code se mesure à 3 mois, à 6 mois, à 12 mois, sur le coût de modification et le temps d'onboarding. Les 3 faux amis que j'ai décrits (copier-coller, abstractions accidentelles, sur-ingénierie) sont les 3 mécanismes qui font diverger ce coût silencieusement.",{"type":30,"tag":31,"props":3089,"children":3090},{},[3091],{"type":39,"value":3092},"La règle YAGNI + AI, ce n'est pas du conservatisme. C'est une discipline économique. Vous économisez aujourd'hui sur du code que vous n'écrivez pas, ce qui réduit la complexité que vous porterez demain. Quand le besoin réel émerge (3 implémentations, vraie variation, vraie criticité), vous créez l'abstraction à ce moment-là, avec la connaissance que la pratique vous a donnée. Pas avant.",{"type":30,"tag":31,"props":3094,"children":3095},{},[3096],{"type":39,"value":3097},"Si en lisant ces lignes vous reconnaissez votre situation, vous avez deux choix. Vous pouvez continuer à accepter les PR Claude qui ajoutent 280 LOC pour un use case qui en demande 95. Ou vous pouvez commencer lundi matin, par une grille de 4 règles, et reprendre le contrôle du coût caché de votre codebase.",{"type":30,"tag":31,"props":3099,"children":3100},{},[3101,3103,3108],{"type":39,"value":3102},"Pour la suite des patterns craft que je documente chaque semaine sur crmcoaching, retrouvez-moi sur ",{"type":30,"tag":88,"props":3104,"children":3106},{"href":125,"rel":3105},[127],[3107],{"type":39,"value":130},{"type":39,"value":205},{"type":30,"tag":392,"props":3110,"children":3112},{"cta":833,"href":834,"title":3111,"type":836},"La règle des 3 et le réflexe anti-doublons ne sont que 2 pratiques sur 100",[3113],{"type":30,"tag":31,"props":3114,"children":3115},{},[3116],{"type":39,"value":3117},"Cet article détaille une poignée de pratiques craft qui neutralisent la sur-ingénierie IA-générée. Le Craft Bundle réunit les 100 pratiques que j'applique pour garder un code simple et modifiable : le référentiel complet de ce que je vérifie sur chaque PR Claude. Ce sont celles que l'IA ne vous apprendra jamais, parce qu'elle ne les a jamais vues coûter cher en production.",{"type":30,"tag":55,"props":3119,"children":3120},{},[],{"type":30,"tag":59,"props":3122,"children":3124},{"id":3123},"faq-sur-les-faux-amis-claude-et-le-coût-caché",[3125],{"type":39,"value":3126},"FAQ sur les faux amis Claude et le coût caché",{"type":30,"tag":853,"props":3128,"children":3129},{},[3130,3135],{"type":30,"tag":857,"props":3131,"children":3132},{},[3133],{"type":39,"value":3134},"1. Comment détecter les doublons dans un repo TypeScript de taille moyenne ?",{"type":30,"tag":31,"props":3136,"children":3137},{},[3138],{"type":39,"value":3139},"Trois outils combinés font le travail. D'abord jscpd (Copy-Paste Detector, compatible TS/JS) : sortie rapide des blocs dupliqués sur tout repo, configurable par seuil de tokens. Ensuite SonarQube en mode \"duplications\" : vue agrégée sur le repo entier. Enfin, des passes Grep ciblées sur les noms de domaine (\"calculate\", \"compute\", \"process\") pour repérer les paires sémantiquement proches mais nommées différemment. L'arsenal complet est détaillé dans les outils d'analyse statique en 2026.",{"type":30,"tag":853,"props":3141,"children":3142},{},[3143,3148],{"type":30,"tag":857,"props":3144,"children":3145},{},[3146],{"type":39,"value":3147},"2. La règle des 3 implémentations n'empêche-t-elle pas l'architecture hexagonale ?",{"type":30,"tag":31,"props":3149,"children":3150},{},[3151,3153,3159],{"type":39,"value":3152},"Non, parce que ",{"type":30,"tag":88,"props":3154,"children":3156},{"href":3155},"/fr/architecture-craft/architecture-hexagonale-java-exemples-bonnes-pratiques",[3157],{"type":39,"value":3158},"l'architecture hexagonale",{"type":39,"value":3160}," est justifiée par la testabilité, pas par la variation d'implémentation. Vous créez un port pour pouvoir tester avec un fake en mémoire. C'est 1 implémentation réelle + 1 fake de test : ça compte pour 2. Si en plus vous avez une vraie variation (Postgres + Redis, ou SMTP + Brevo), vous êtes à 3. La règle s'applique aux abstractions purement spéculatives, pas à celles qui ont une justification claire et nommée.",{"type":30,"tag":853,"props":3162,"children":3163},{},[3164,3169],{"type":30,"tag":857,"props":3165,"children":3166},{},[3167],{"type":39,"value":3168},"3. Comment convaincre une équipe attachée aux patterns enterprise ?",{"type":30,"tag":31,"props":3170,"children":3171},{},[3172],{"type":39,"value":3173},"Avec des chiffres sur leur propre repo. Comptez les interfaces qui n'ont qu'une implémentation, comptez les factories appelées une seule fois, comptez les LOC par use case. Présentez ça en revue d'architecture. Personne ne défend une factory inutilisée quand elle apparaît dans un tableau à côté de \"temps d'onboarding +4 semaines\". Le débat passe du dogme à l'économique.",{"type":30,"tag":853,"props":3175,"children":3176},{},[3177,3182],{"type":30,"tag":857,"props":3178,"children":3179},{},[3180],{"type":39,"value":3181},"4. Quel rapport entre ces faux amis et la code review IA ?",{"type":30,"tag":31,"props":3183,"children":3184},{},[3185],{"type":39,"value":3186},"Direct. Une revue de code IA-générée doit poser systématiquement 3 questions : \"Y a-t-il un doublon ailleurs dans le repo ?\", \"Cette abstraction est-elle justifiée par 3 cas réels ?\", \"La complexité de cette solution est-elle proportionnelle au besoin métier ?\". Ces 3 questions, en 2 minutes par PR, attrapent 80% des 3 faux amis avant le merge.",{"type":30,"tag":853,"props":3188,"children":3189},{},[3190,3195],{"type":30,"tag":857,"props":3191,"children":3192},{},[3193],{"type":39,"value":3194},"5. Le code Claude qui suit cette discipline est-il toujours du code \"généré par IA\" ?",{"type":30,"tag":31,"props":3196,"children":3197},{},[3198],{"type":39,"value":3199},"C'est une bonne question, et la réponse est : oui, mais pas par n'importe quel prompt. Le code Claude bien promté (avec contraintes YAGNI + recherche de doublons + proportionnalité) reste majoritairement du code IA-généré. Le développeur ajoute le contexte et la discipline. Claude exécute. C'est exactement la collaboration qu'on cherche : l'IA fait le travail mécanique, l'humain garde le jugement architectural.",{"type":30,"tag":853,"props":3201,"children":3202},{},[3203,3208],{"type":30,"tag":857,"props":3204,"children":3205},{},[3206],{"type":39,"value":3207},"6. Quelle est la métrique unique à suivre pour mesurer ces 3 faux amis ?",{"type":30,"tag":31,"props":3209,"children":3210},{},[3211,3213,3219],{"type":39,"value":3212},"Le ratio LOC par story point livré, mesuré sur 3 sprints glissants. Si la métrique monte, vous accumulez de la complexité accidentelle. Si elle baisse à valeur métier équivalente, vous gagnez en simplicité. C'est la métrique méta qui agrège les 3 faux amis sans avoir à les détecter individuellement, et c'est aussi un sujet que je détaille dans ",{"type":30,"tag":88,"props":3214,"children":3216},{"href":3215},"/fr/intelligence-artificielle/illusion-productivite-10x-pr",[3217],{"type":39,"value":3218},"l'illusion de productivité IA",{"type":39,"value":205},{"type":30,"tag":55,"props":3221,"children":3222},{},[],{"type":30,"tag":392,"props":3224,"children":3225},{"cta":944,"href":945,"title":946,"type":947},[3226],{"type":30,"tag":31,"props":3227,"children":3228},{},[3229],{"type":39,"value":3230},"L'EMA est l'outil que je propose au début de chaque mission. Il mesure la maturité de votre équipe sur plusieurs axes engineering : qualité du code, gouvernance IA, dette technique, vélocité réelle vs vélocité perçue. Quelques minutes pour identifier lequel des 3 faux amis s'installe le plus vite dans votre repo, et où concentrer vos efforts en priorité.",{"type":30,"tag":3232,"props":3233,"children":3234},"style",{},[3235],{"type":39,"value":3236},"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":955,"depth":955,"links":3238},[3239,3240,3241,3242,3243,3244,3245,3246,3247],{"id":1012,"depth":955,"text":1015},{"id":1094,"depth":955,"text":1097},{"id":1662,"depth":955,"text":1665},{"id":2159,"depth":955,"text":2162},{"id":2722,"depth":955,"text":2725},{"id":2865,"depth":955,"text":2868},{"id":639,"depth":955,"text":642},{"id":801,"depth":955,"text":804},{"id":3123,"depth":955,"text":3126},"content:fr:intelligence-artificielle:faux-ami-code-claude-coute-cher.md","fr/intelligence-artificielle/faux-ami-code-claude-coute-cher.md","fr/intelligence-artificielle/faux-ami-code-claude-coute-cher",{"_path":3252,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":3253,"description":3254,"id":3255,"date":3256,"listed":13,"nocomments":7,"hidden":7,"categories":3257,"tags":3258,"cover":3262,"readingTime":3263,"body":3268,"_type":967,"_id":4631,"_source":969,"_file":4632,"_stem":4633,"_extension":972},"/fr/dette-technique/dependabot-craft-gestion-dependances","Dependabot : configurer son coéquipier silencieux contre la dette de dépendances","Dependabot bien configuré vous évite des nuits à patcher la prochaine CVE critique. Guide craft : 7 tips, config YAML annotée, auto-merge intelligent.",61,"2026-05-01",[6],[3259,3260,6,3261,985],"dependabot","supply-chain","sécurité","covers/articles/dependabot-craft-gestion-dependances.jpg",{"text":3264,"minutes":3265,"time":3266,"words":3267},"11 min read",10.825,649500,2165,{"type":27,"children":3269,"toc":4617},[3270,3278,3299,3302,3308,3313,3327,3332,3352,3364,3367,3373,3378,3467,3472,3475,3484,3487,3493,3498,3512,3525,4037,4085,4120,4126,4138,4178,4190,4196,4208,4213,4216,4222,4227,4243,4253,4286,4289,4293,4298,4394,4399,4404,4407,4411,4416,4421,4433,4442,4445,4451,4464,4477,4525,4576,4589,4602,4605,4613],{"type":30,"tag":31,"props":3271,"children":3272},{},[3273],{"type":30,"tag":35,"props":3274,"children":3275},{},[3276],{"type":39,"value":3277},"En décembre 2021, Log4Shell (CVE-2021-44228, score CVSS 10 sur 10) a tenu l'industrie entière debout tout un week-end. Une faille critique dans une librairie que presque personne n'avait choisie explicitement, et qui se cachait pourtant dans des dizaines de milliers de projets. Ce soir-là, d'innombrables équipes ont découvert la même chose : elles ne savaient pas ce qu'il y avait vraiment dans leur arbre de dépendances. C'est exactement ce genre de nuit que Dependabot bien configuré vous évite.",{"type":30,"tag":31,"props":3279,"children":3280},{},[3281,3283,3289,3291,3297],{"type":39,"value":3282},"Depuis, je n'ouvre plus un projet sans ce réflexe. Sur crmcoaching, le SaaS que je développe seul avec Claude, l'un des premiers fichiers que je versionne après le ",{"type":30,"tag":262,"props":3284,"children":3286},{"className":3285},[],[3287],{"type":39,"value":3288},"package.json",{"type":39,"value":3290},", c'est ",{"type":30,"tag":262,"props":3292,"children":3294},{"className":3293},[],[3295],{"type":39,"value":3296},"dependabot.yml",{"type":39,"value":3298}," : versionné, audité, pensé. Pas l'activation par défaut que la majorité des projets laissent en l'état, mais une vraie configuration craft. Voici ce que j'applique au quotidien sur crmcoaching, ce que je vois rater en mission, et la méthode complète.",{"type":30,"tag":55,"props":3300,"children":3301},{},[],{"type":30,"tag":59,"props":3303,"children":3305},{"id":3304},"pourquoi-vos-dépendances-pourrissent-plus-vite-en-2026",[3306],{"type":39,"value":3307},"Pourquoi vos dépendances pourrissent plus vite en 2026",{"type":30,"tag":31,"props":3309,"children":3310},{},[3311],{"type":39,"value":3312},"Le constat est chiffré, et il est sévère.",{"type":30,"tag":31,"props":3314,"children":3315},{},[3316,3318,3325],{"type":39,"value":3317},"Selon le ",{"type":30,"tag":88,"props":3319,"children":3322},{"href":3320,"rel":3321},"https://snyk.io/reports/open-source-security/",[127],[3323],{"type":39,"value":3324},"Snyk Open Source Security Report 2024",{"type":39,"value":3326},", les vulnérabilités de supply chain ont progressé de 156% entre 2023 et 2024. Sur la même période, GitClear documente que les équipes utilisant un assistant IA comme Claude ajoutent en moyenne 40% de dépendances en plus par projet. Le ratio est clair : on consomme plus, on audite moins.",{"type":30,"tag":31,"props":3328,"children":3329},{},[3330],{"type":39,"value":3331},"Je l'ai vu sur crmcoaching même. La séquence est toujours la même : je prompte Claude pour résoudre un problème, il me propose une lib externe (souvent une qu'il connaît depuis son training data, donc pas la version courante), je l'accepte parce qu'elle marche, et la dépendance entre dans le repo. Six mois plus tard, cette même lib a une CVE critique. Sans filet de sécurité, personne ne le sait, surtout quand on développe seul.",{"type":30,"tag":97,"props":3333,"children":3334},{},[3335],{"type":30,"tag":31,"props":3336,"children":3337},{},[3338,3342,3344,3350],{"type":30,"tag":35,"props":3339,"children":3340},{},[3341],{"type":39,"value":107},{"type":39,"value":3343}," : un ",{"type":30,"tag":262,"props":3345,"children":3347},{"className":3346},[],[3348],{"type":39,"value":3349},"pnpm list --depth=Infinity",{"type":39,"value":3351}," sur crmcoaching listait plus de 1 000 dépendances transitives, pour une application que je connais pourtant ligne par ligne. La quasi-totalité n'avait jamais été ajoutée volontairement : elles sont arrivées dans les bagages de quelques dépendances directes. Et pourtant, chacune d'elles peut, demain matin, ouvrir une faille sur le paiement ou l'authentification de mes utilisateurs.",{"type":30,"tag":31,"props":3353,"children":3354},{},[3355,3357,3362],{"type":39,"value":3356},"Bruce Schneier a écrit que ",{"type":30,"tag":42,"props":3358,"children":3359},{},[3360],{"type":39,"value":3361},"\"Security is a process, not a product\"",{"type":39,"value":3363},". Dependabot n'est pas un produit que vous activez et que vous oubliez : c'est le squelette d'un processus craft de gestion de dépendances. Sans le squelette, vous codez en aveugle.",{"type":30,"tag":55,"props":3365,"children":3366},{},[],{"type":30,"tag":59,"props":3368,"children":3370},{"id":3369},"les-4-signaux-que-votre-gestion-de-dépendances-dérive",[3371],{"type":39,"value":3372},"Les 4 signaux que votre gestion de dépendances dérive",{"type":30,"tag":31,"props":3374,"children":3375},{},[3376],{"type":39,"value":3377},"Demain matin, ouvrez votre repo principal et vérifiez ces 4 signaux. Si vous en cochez 2 ou plus, vous avez un problème.",{"type":30,"tag":3379,"props":3380,"children":3381},"ul",{},[3382,3409,3419,3435],{"type":30,"tag":3383,"props":3384,"children":3385},"li",{},[3386,3407],{"type":30,"tag":35,"props":3387,"children":3388},{},[3389,3391,3397,3399,3405],{"type":39,"value":3390},"Signal 1 : votre dernier audit de dépendances (",{"type":30,"tag":262,"props":3392,"children":3394},{"className":3393},[],[3395],{"type":39,"value":3396},"pnpm audit",{"type":39,"value":3398}," côté Node, ",{"type":30,"tag":262,"props":3400,"children":3402},{"className":3401},[],[3403],{"type":39,"value":3404},"mvn dependency-check:check",{"type":39,"value":3406}," côté Java, ou équivalent) date de plus de 30 jours.",{"type":39,"value":3408}," Concrètement, vous ne savez pas combien de vulnérabilités critiques dorment dans votre arbre de dépendances. Mauvais signe.",{"type":30,"tag":3383,"props":3410,"children":3411},{},[3412,3417],{"type":30,"tag":35,"props":3413,"children":3414},{},[3415],{"type":39,"value":3416},"Signal 2 : vos PR Dependabot s'accumulent en mode \"à traiter plus tard\".",{"type":39,"value":3418}," Si vous voyez plus de 10 PR ouvertes depuis plus de 14 jours, votre filet de sécurité est devenu un cimetière.",{"type":30,"tag":3383,"props":3420,"children":3421},{},[3422,3433],{"type":30,"tag":35,"props":3423,"children":3424},{},[3425,3427],{"type":39,"value":3426},"Signal 3 : vous ne savez pas quelle est votre ",{"type":30,"tag":262,"props":3428,"children":3430},{"className":3429},[],[3431],{"type":39,"value":3432},"time-to-patch",{"type":39,"value":3434}," sur les CVE critiques. C'est le délai entre disclosure d'une CVE et son fix en prod. En dessous de 7 jours, vous êtes sain. Au-dessus de 30 jours, vous jouez à la roulette russe.",{"type":30,"tag":3383,"props":3436,"children":3437},{},[3438,3458,3460,3465],{"type":30,"tag":35,"props":3439,"children":3440},{},[3441,3443,3449,3451,3456],{"type":39,"value":3442},"Signal 4 : vous avez des entrées ",{"type":30,"tag":262,"props":3444,"children":3446},{"className":3445},[],[3447],{"type":39,"value":3448},"ignore",{"type":39,"value":3450}," dans votre ",{"type":30,"tag":262,"props":3452,"children":3454},{"className":3453},[],[3455],{"type":39,"value":3296},{"type":39,"value":3457}," qui datent de plus de 6 mois.",{"type":39,"value":3459}," Un ",{"type":30,"tag":262,"props":3461,"children":3463},{"className":3462},[],[3464],{"type":39,"value":3448},{"type":39,"value":3466}," est une dette que vous reportez. Si vous ne savez plus pourquoi vous l'avez mis, vous avez déjà perdu.",{"type":30,"tag":31,"props":3468,"children":3469},{},[3470],{"type":39,"value":3471},"Ces signaux ne sont pas théoriques. Je les ai vus, dans cet ordre, dans la majorité des équipes que j'ai accompagnées sur 2024 et 2025. Le 8ème signal arrive toujours : c'est l'incident.",{"type":30,"tag":55,"props":3473,"children":3474},{},[],{"type":30,"tag":392,"props":3476,"children":3478},{"cta":394,"href":395,"title":3477,"type":397},"Vous voulez acquérir le réflexe d'auditer chaque dépendance avant qu'elle entre dans votre repo ?",[3479],{"type":30,"tag":31,"props":3480,"children":3481},{},[3482],{"type":39,"value":3483},"Savoir lire un arbre de dépendances, flairer la lib que Claude propose en retard de 18 mois, juger quand un bump major mérite un ADR : ça ne se lit pas, ça se travaille. En mentoring 1:1, on relit votre vraie config Dependabot ensemble, je vous montre les arbitrages que je fais sur mes propres projets, et vous repartez avec le jugement qui transforme une alerte en décision sereine.",{"type":30,"tag":55,"props":3485,"children":3486},{},[],{"type":30,"tag":59,"props":3488,"children":3490},{"id":3489},"comment-je-configure-dependabot-étape-par-étape",[3491],{"type":39,"value":3492},"Comment je configure Dependabot, étape par étape",{"type":30,"tag":31,"props":3494,"children":3495},{},[3496],{"type":39,"value":3497},"Voici la méthode que j'applique sur crmcoaching, et que je redéploie ensuite quand j'arrive en mission dans une équipe qui n'a pas (ou peu) de gestion de dépendances. Pas une checklist générique, mais ce que je fais vraiment, dans l'ordre.",{"type":30,"tag":3499,"props":3500,"children":3502},"h3",{"id":3501},"étape-1-le-dependabotyml-craft",[3503,3505,3510],{"type":39,"value":3504},"Étape 1 : le ",{"type":30,"tag":262,"props":3506,"children":3508},{"className":3507},[],[3509],{"type":39,"value":3296},{"type":39,"value":3511}," craft",{"type":30,"tag":31,"props":3513,"children":3514},{},[3515,3517,3523],{"type":39,"value":3516},"Je crée (ou je refais) le fichier ",{"type":30,"tag":262,"props":3518,"children":3520},{"className":3519},[],[3521],{"type":39,"value":3522},".github/dependabot.yml",{"type":39,"value":3524},". Voici la version courte de ma configuration de référence, celle que j'utilise sur crmcoaching (TypeScript, géré avec pnpm) et que je décline ensuite en mission sur des codebases Java/Maven :",{"type":30,"tag":1125,"props":3526,"children":3530},{"className":3527,"code":3528,"language":3529,"meta":8,"style":8},"language-yaml shiki shiki-themes catppuccin-frappe github-dark","version: 2\nupdates:\n  - package-ecosystem: \"npm\" # gère aussi pnpm et yarn\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n      day: \"monday\"\n      time: \"09:00\"\n    open-pull-requests-limit: 5\n    groups:\n      minor-and-patch:\n        patterns: [\"*\"]\n        update-types: [\"minor\", \"patch\"]\n    labels: [\"dependencies\", \"auto-review\"]\n    reviewers: [\"kamanga\"]\n    ignore:\n      - dependency-name: \"next\"\n        update-types: [\"version-update:semver-major\"]\n\n  - package-ecosystem: \"docker\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n","yaml",[3531],{"type":30,"tag":262,"props":3532,"children":3533},{"__ignoreMap":8},[3534,3552,3565,3592,3609,3621,3638,3655,3672,3689,3701,3713,3740,3775,3809,3834,3846,3868,3892,3899,3920,3936,3948,3964,3972,3993,4009,4021],{"type":30,"tag":1135,"props":3535,"children":3536},{"class":1137,"line":1138},[3537,3543,3547],{"type":30,"tag":1135,"props":3538,"children":3540},{"style":3539},"--shiki-default:#8CAAEE;--shiki-dark:#85E89D",[3541],{"type":39,"value":3542},"version",{"type":30,"tag":1135,"props":3544,"children":3545},{"style":1339},[3546],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3548,"children":3549},{"style":1270},[3550],{"type":39,"value":3551}," 2\n",{"type":30,"tag":1135,"props":3553,"children":3554},{"class":1137,"line":955},[3555,3560],{"type":30,"tag":1135,"props":3556,"children":3557},{"style":3539},[3558],{"type":39,"value":3559},"updates",{"type":30,"tag":1135,"props":3561,"children":3562},{"style":1339},[3563],{"type":39,"value":3564},":\n",{"type":30,"tag":1135,"props":3566,"children":3567},{"class":1137,"line":1169},[3568,3573,3578,3582,3587],{"type":30,"tag":1135,"props":3569,"children":3570},{"style":1163},[3571],{"type":39,"value":3572},"  -",{"type":30,"tag":1135,"props":3574,"children":3575},{"style":3539},[3576],{"type":39,"value":3577}," package-ecosystem",{"type":30,"tag":1135,"props":3579,"children":3580},{"style":1339},[3581],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3583,"children":3584},{"style":2629},[3585],{"type":39,"value":3586}," \"npm\"",{"type":30,"tag":1135,"props":3588,"children":3589},{"style":1142},[3590],{"type":39,"value":3591}," # gère aussi pnpm et yarn\n",{"type":30,"tag":1135,"props":3593,"children":3594},{"class":1137,"line":1196},[3595,3600,3604],{"type":30,"tag":1135,"props":3596,"children":3597},{"style":3539},[3598],{"type":39,"value":3599},"    directory",{"type":30,"tag":1135,"props":3601,"children":3602},{"style":1339},[3603],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3605,"children":3606},{"style":2629},[3607],{"type":39,"value":3608}," \"/\"\n",{"type":30,"tag":1135,"props":3610,"children":3611},{"class":1137,"line":1217},[3612,3617],{"type":30,"tag":1135,"props":3613,"children":3614},{"style":3539},[3615],{"type":39,"value":3616},"    schedule",{"type":30,"tag":1135,"props":3618,"children":3619},{"style":1339},[3620],{"type":39,"value":3564},{"type":30,"tag":1135,"props":3622,"children":3623},{"class":1137,"line":1239},[3624,3629,3633],{"type":30,"tag":1135,"props":3625,"children":3626},{"style":3539},[3627],{"type":39,"value":3628},"      interval",{"type":30,"tag":1135,"props":3630,"children":3631},{"style":1339},[3632],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3634,"children":3635},{"style":2629},[3636],{"type":39,"value":3637}," \"weekly\"\n",{"type":30,"tag":1135,"props":3639,"children":3640},{"class":1137,"line":1281},[3641,3646,3650],{"type":30,"tag":1135,"props":3642,"children":3643},{"style":3539},[3644],{"type":39,"value":3645},"      day",{"type":30,"tag":1135,"props":3647,"children":3648},{"style":1339},[3649],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3651,"children":3652},{"style":2629},[3653],{"type":39,"value":3654}," \"monday\"\n",{"type":30,"tag":1135,"props":3656,"children":3657},{"class":1137,"line":1325},[3658,3663,3667],{"type":30,"tag":1135,"props":3659,"children":3660},{"style":3539},[3661],{"type":39,"value":3662},"      time",{"type":30,"tag":1135,"props":3664,"children":3665},{"style":1339},[3666],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3668,"children":3669},{"style":2629},[3670],{"type":39,"value":3671}," \"09:00\"\n",{"type":30,"tag":1135,"props":3673,"children":3674},{"class":1137,"line":1381},[3675,3680,3684],{"type":30,"tag":1135,"props":3676,"children":3677},{"style":3539},[3678],{"type":39,"value":3679},"    open-pull-requests-limit",{"type":30,"tag":1135,"props":3681,"children":3682},{"style":1339},[3683],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3685,"children":3686},{"style":1270},[3687],{"type":39,"value":3688}," 5\n",{"type":30,"tag":1135,"props":3690,"children":3691},{"class":1137,"line":1390},[3692,3697],{"type":30,"tag":1135,"props":3693,"children":3694},{"style":3539},[3695],{"type":39,"value":3696},"    groups",{"type":30,"tag":1135,"props":3698,"children":3699},{"style":1339},[3700],{"type":39,"value":3564},{"type":30,"tag":1135,"props":3702,"children":3703},{"class":1137,"line":1399},[3704,3709],{"type":30,"tag":1135,"props":3705,"children":3706},{"style":3539},[3707],{"type":39,"value":3708},"      minor-and-patch",{"type":30,"tag":1135,"props":3710,"children":3711},{"style":1339},[3712],{"type":39,"value":3564},{"type":30,"tag":1135,"props":3714,"children":3715},{"class":1137,"line":1408},[3716,3721,3725,3730,3735],{"type":30,"tag":1135,"props":3717,"children":3718},{"style":3539},[3719],{"type":39,"value":3720},"        patterns",{"type":30,"tag":1135,"props":3722,"children":3723},{"style":1339},[3724],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3726,"children":3727},{"style":1163},[3728],{"type":39,"value":3729}," [",{"type":30,"tag":1135,"props":3731,"children":3732},{"style":2629},[3733],{"type":39,"value":3734},"\"*\"",{"type":30,"tag":1135,"props":3736,"children":3737},{"style":1163},[3738],{"type":39,"value":3739},"]\n",{"type":30,"tag":1135,"props":3741,"children":3742},{"class":1137,"line":1425},[3743,3748,3752,3756,3761,3766,3771],{"type":30,"tag":1135,"props":3744,"children":3745},{"style":3539},[3746],{"type":39,"value":3747},"        update-types",{"type":30,"tag":1135,"props":3749,"children":3750},{"style":1339},[3751],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3753,"children":3754},{"style":1163},[3755],{"type":39,"value":3729},{"type":30,"tag":1135,"props":3757,"children":3758},{"style":2629},[3759],{"type":39,"value":3760},"\"minor\"",{"type":30,"tag":1135,"props":3762,"children":3763},{"style":1163},[3764],{"type":39,"value":3765},",",{"type":30,"tag":1135,"props":3767,"children":3768},{"style":2629},[3769],{"type":39,"value":3770}," \"patch\"",{"type":30,"tag":1135,"props":3772,"children":3773},{"style":1163},[3774],{"type":39,"value":3739},{"type":30,"tag":1135,"props":3776,"children":3777},{"class":1137,"line":1446},[3778,3783,3787,3791,3796,3800,3805],{"type":30,"tag":1135,"props":3779,"children":3780},{"style":3539},[3781],{"type":39,"value":3782},"    labels",{"type":30,"tag":1135,"props":3784,"children":3785},{"style":1339},[3786],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3788,"children":3789},{"style":1163},[3790],{"type":39,"value":3729},{"type":30,"tag":1135,"props":3792,"children":3793},{"style":2629},[3794],{"type":39,"value":3795},"\"dependencies\"",{"type":30,"tag":1135,"props":3797,"children":3798},{"style":1163},[3799],{"type":39,"value":3765},{"type":30,"tag":1135,"props":3801,"children":3802},{"style":2629},[3803],{"type":39,"value":3804}," \"auto-review\"",{"type":30,"tag":1135,"props":3806,"children":3807},{"style":1163},[3808],{"type":39,"value":3739},{"type":30,"tag":1135,"props":3810,"children":3811},{"class":1137,"line":1467},[3812,3817,3821,3825,3830],{"type":30,"tag":1135,"props":3813,"children":3814},{"style":3539},[3815],{"type":39,"value":3816},"    reviewers",{"type":30,"tag":1135,"props":3818,"children":3819},{"style":1339},[3820],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3822,"children":3823},{"style":1163},[3824],{"type":39,"value":3729},{"type":30,"tag":1135,"props":3826,"children":3827},{"style":2629},[3828],{"type":39,"value":3829},"\"kamanga\"",{"type":30,"tag":1135,"props":3831,"children":3832},{"style":1163},[3833],{"type":39,"value":3739},{"type":30,"tag":1135,"props":3835,"children":3836},{"class":1137,"line":1487},[3837,3842],{"type":30,"tag":1135,"props":3838,"children":3839},{"style":3539},[3840],{"type":39,"value":3841},"    ignore",{"type":30,"tag":1135,"props":3843,"children":3844},{"style":1339},[3845],{"type":39,"value":3564},{"type":30,"tag":1135,"props":3847,"children":3848},{"class":1137,"line":1521},[3849,3854,3859,3863],{"type":30,"tag":1135,"props":3850,"children":3851},{"style":1163},[3852],{"type":39,"value":3853},"      -",{"type":30,"tag":1135,"props":3855,"children":3856},{"style":3539},[3857],{"type":39,"value":3858}," dependency-name",{"type":30,"tag":1135,"props":3860,"children":3861},{"style":1339},[3862],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3864,"children":3865},{"style":2629},[3866],{"type":39,"value":3867}," \"next\"\n",{"type":30,"tag":1135,"props":3869,"children":3870},{"class":1137,"line":1564},[3871,3875,3879,3883,3888],{"type":30,"tag":1135,"props":3872,"children":3873},{"style":3539},[3874],{"type":39,"value":3747},{"type":30,"tag":1135,"props":3876,"children":3877},{"style":1339},[3878],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3880,"children":3881},{"style":1163},[3882],{"type":39,"value":3729},{"type":30,"tag":1135,"props":3884,"children":3885},{"style":2629},[3886],{"type":39,"value":3887},"\"version-update:semver-major\"",{"type":30,"tag":1135,"props":3889,"children":3890},{"style":1163},[3891],{"type":39,"value":3739},{"type":30,"tag":1135,"props":3893,"children":3894},{"class":1137,"line":1613},[3895],{"type":30,"tag":1135,"props":3896,"children":3897},{"emptyLinePlaceholder":13},[3898],{"type":39,"value":1396},{"type":30,"tag":1135,"props":3900,"children":3902},{"class":1137,"line":3901},20,[3903,3907,3911,3915],{"type":30,"tag":1135,"props":3904,"children":3905},{"style":1163},[3906],{"type":39,"value":3572},{"type":30,"tag":1135,"props":3908,"children":3909},{"style":3539},[3910],{"type":39,"value":3577},{"type":30,"tag":1135,"props":3912,"children":3913},{"style":1339},[3914],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3916,"children":3917},{"style":2629},[3918],{"type":39,"value":3919}," \"docker\"\n",{"type":30,"tag":1135,"props":3921,"children":3923},{"class":1137,"line":3922},21,[3924,3928,3932],{"type":30,"tag":1135,"props":3925,"children":3926},{"style":3539},[3927],{"type":39,"value":3599},{"type":30,"tag":1135,"props":3929,"children":3930},{"style":1339},[3931],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3933,"children":3934},{"style":2629},[3935],{"type":39,"value":3608},{"type":30,"tag":1135,"props":3937,"children":3939},{"class":1137,"line":3938},22,[3940,3944],{"type":30,"tag":1135,"props":3941,"children":3942},{"style":3539},[3943],{"type":39,"value":3616},{"type":30,"tag":1135,"props":3945,"children":3946},{"style":1339},[3947],{"type":39,"value":3564},{"type":30,"tag":1135,"props":3949,"children":3951},{"class":1137,"line":3950},23,[3952,3956,3960],{"type":30,"tag":1135,"props":3953,"children":3954},{"style":3539},[3955],{"type":39,"value":3628},{"type":30,"tag":1135,"props":3957,"children":3958},{"style":1339},[3959],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3961,"children":3962},{"style":2629},[3963],{"type":39,"value":3637},{"type":30,"tag":1135,"props":3965,"children":3967},{"class":1137,"line":3966},24,[3968],{"type":30,"tag":1135,"props":3969,"children":3970},{"emptyLinePlaceholder":13},[3971],{"type":39,"value":1396},{"type":30,"tag":1135,"props":3973,"children":3975},{"class":1137,"line":3974},25,[3976,3980,3984,3988],{"type":30,"tag":1135,"props":3977,"children":3978},{"style":1163},[3979],{"type":39,"value":3572},{"type":30,"tag":1135,"props":3981,"children":3982},{"style":3539},[3983],{"type":39,"value":3577},{"type":30,"tag":1135,"props":3985,"children":3986},{"style":1339},[3987],{"type":39,"value":1182},{"type":30,"tag":1135,"props":3989,"children":3990},{"style":2629},[3991],{"type":39,"value":3992}," \"github-actions\"\n",{"type":30,"tag":1135,"props":3994,"children":3996},{"class":1137,"line":3995},26,[3997,4001,4005],{"type":30,"tag":1135,"props":3998,"children":3999},{"style":3539},[4000],{"type":39,"value":3599},{"type":30,"tag":1135,"props":4002,"children":4003},{"style":1339},[4004],{"type":39,"value":1182},{"type":30,"tag":1135,"props":4006,"children":4007},{"style":2629},[4008],{"type":39,"value":3608},{"type":30,"tag":1135,"props":4010,"children":4012},{"class":1137,"line":4011},27,[4013,4017],{"type":30,"tag":1135,"props":4014,"children":4015},{"style":3539},[4016],{"type":39,"value":3616},{"type":30,"tag":1135,"props":4018,"children":4019},{"style":1339},[4020],{"type":39,"value":3564},{"type":30,"tag":1135,"props":4022,"children":4024},{"class":1137,"line":4023},28,[4025,4029,4033],{"type":30,"tag":1135,"props":4026,"children":4027},{"style":3539},[4028],{"type":39,"value":3628},{"type":30,"tag":1135,"props":4030,"children":4031},{"style":1339},[4032],{"type":39,"value":1182},{"type":30,"tag":1135,"props":4034,"children":4035},{"style":2629},[4036],{"type":39,"value":3637},{"type":30,"tag":31,"props":4038,"children":4039},{},[4040,4042,4048,4050,4056,4058,4063,4065,4070,4072,4076,4078,4083],{"type":39,"value":4041},"Trois choses comptent dans cette configuration. D'abord le ",{"type":30,"tag":262,"props":4043,"children":4045},{"className":4044},[],[4046],{"type":39,"value":4047},"groups",{"type":39,"value":4049}," qui rassemble minor et patch en une seule PR : c'est ce qui fait passer un repo de 30 PR par semaine à 3. Ensuite le ",{"type":30,"tag":262,"props":4051,"children":4053},{"className":4052},[],[4054],{"type":39,"value":4055},"open-pull-requests-limit: 5",{"type":39,"value":4057}," qui force le réalisme, parce que personne ne traite 15 PR Dependabot en parallèle. Enfin le ",{"type":30,"tag":262,"props":4059,"children":4061},{"className":4060},[],[4062],{"type":39,"value":3448},{"type":39,"value":4064}," ciblé sur les majors risquées (ici les montées majeures de Next.js, que je veux préparer avec un ADR et une fenêtre de migration avant d'accepter), avec une règle stricte : tout ",{"type":30,"tag":262,"props":4066,"children":4068},{"className":4067},[],[4069],{"type":39,"value":3448},{"type":39,"value":4071}," doit être documenté dans un commentaire qui dit ",{"type":30,"tag":42,"props":4073,"children":4074},{},[4075],{"type":39,"value":163},{"type":39,"value":4077}," il existe et ",{"type":30,"tag":42,"props":4079,"children":4080},{},[4081],{"type":39,"value":4082},"jusqu'à quand",{"type":39,"value":4084}," il reste valide.",{"type":30,"tag":31,"props":4086,"children":4087},{},[4088,4090,4096,4098,4104,4106,4111,4113,4118],{"type":39,"value":4089},"En mission sur une codebase Java/Maven, le quotidien du secteur bancaire, je remplace simplement ",{"type":30,"tag":262,"props":4091,"children":4093},{"className":4092},[],[4094],{"type":39,"value":4095},"npm",{"type":39,"value":4097}," par ",{"type":30,"tag":262,"props":4099,"children":4101},{"className":4100},[],[4102],{"type":39,"value":4103},"maven",{"type":39,"value":4105}," et l'",{"type":30,"tag":262,"props":4107,"children":4109},{"className":4108},[],[4110],{"type":39,"value":3448},{"type":39,"value":4112}," Next.js par un ",{"type":30,"tag":262,"props":4114,"children":4116},{"className":4115},[],[4117],{"type":39,"value":3448},{"type":39,"value":4119}," sur un bump de Spring Boot que je veux préparer avec un ADR. Le reste de la structure (groups, limit, schedule, labels) ne change pas. C'est ce qui fait qu'une fois la discipline acquise sur un repo, vous la portez en 10 minutes sur le suivant, quel que soit l'écosystème.",{"type":30,"tag":3499,"props":4121,"children":4123},{"id":4122},"étape-2-le-pipeline-dauto-merge-intelligent",[4124],{"type":39,"value":4125},"Étape 2 : le pipeline d'auto-merge intelligent",{"type":30,"tag":31,"props":4127,"children":4128},{},[4129,4131,4137],{"type":39,"value":4130},"Dependabot seul, c'est 50% du travail. Sans auto-merge, vous gardez la charge mentale de chaque PR. Voici ce que j'ajoute systématiquement, sous forme de GitHub Action ",{"type":30,"tag":262,"props":4132,"children":4134},{"className":4133},[],[4135],{"type":39,"value":4136},".github/workflows/dependabot-auto-merge.yml",{"type":39,"value":1926},{"type":30,"tag":3379,"props":4139,"children":4140},{},[4141,4151,4161],{"type":30,"tag":3383,"props":4142,"children":4143},{},[4144,4149],{"type":30,"tag":35,"props":4145,"children":4146},{},[4147],{"type":39,"value":4148},"Patch",{"type":39,"value":4150}," : auto-merge si la CI est verte. Pas de discussion. Une mise à jour de patch ne casse rien, sauf si la CI dit le contraire.",{"type":30,"tag":3383,"props":4152,"children":4153},{},[4154,4159],{"type":30,"tag":35,"props":4155,"children":4156},{},[4157],{"type":39,"value":4158},"Minor",{"type":39,"value":4160}," : review humaine obligatoire, mais rapide. 5 minutes pour lire le changelog et valider.",{"type":30,"tag":3383,"props":4162,"children":4163},{},[4164,4169,4171,4176],{"type":30,"tag":35,"props":4165,"children":4166},{},[4167],{"type":39,"value":4168},"Major",{"type":39,"value":4170}," : ADR obligatoire. Pas de bump de major sans une ",{"type":30,"tag":88,"props":4172,"children":4173},{"href":200},[4174],{"type":39,"value":4175},"décision documentée par ADR",{"type":39,"value":4177}," qui dit pourquoi, quel impact, et quel plan de rollback.",{"type":30,"tag":31,"props":4179,"children":4180},{},[4181,4183,4188],{"type":39,"value":4182},"Cette discipline tient parce qu'elle est asymétrique : on automatise le bas risque, on humanise le haut risque. C'est exactement ce que Martin Fowler décrit dans son article ",{"type":30,"tag":42,"props":4184,"children":4185},{},[4186],{"type":39,"value":4187},"ContinuousIntegration",{"type":39,"value":4189}," : automatiser ce qui doit l'être pour libérer du temps pour ce qui ne peut pas l'être.",{"type":30,"tag":3499,"props":4191,"children":4193},{"id":4192},"étape-3-la-métrique-qui-compte-vraiment",[4194],{"type":39,"value":4195},"Étape 3 : la métrique qui compte vraiment",{"type":30,"tag":31,"props":4197,"children":4198},{},[4199,4201,4206],{"type":39,"value":4200},"J'instaure une seule métrique de suivi : la ",{"type":30,"tag":262,"props":4202,"children":4204},{"className":4203},[],[4205],{"type":39,"value":3432},{"type":39,"value":4207}," sur les CVE critiques. Pas le nombre de PR mergées, pas le pourcentage de dépendances à jour. Juste : combien de temps entre la disclosure d'une CVE critique et son fix en prod.",{"type":30,"tag":31,"props":4209,"children":4210},{},[4211],{"type":39,"value":4212},"Sur crmcoaching, je suis à 3 jours en moyenne entre la disclosure d'une CVE critique et son fix en prod. Au démarrage, sans discipline, j'étais à plusieurs semaines. En mission, je vois régulièrement des équipes partir de 40 jours et plus. La baisse n'est jamais linéaire, elle vient des trois leviers ci-dessus combinés.",{"type":30,"tag":55,"props":4214,"children":4215},{},[],{"type":30,"tag":59,"props":4217,"children":4219},{"id":4218},"les-3-erreurs-à-éviter",[4220],{"type":39,"value":4221},"Les 3 erreurs à éviter",{"type":30,"tag":31,"props":4223,"children":4224},{},[4225],{"type":39,"value":4226},"Toutes les équipes que j'ai accompagnées sur ce sujet sont passées par au moins une de ces trois erreurs. Évitez-vous le détour.",{"type":30,"tag":31,"props":4228,"children":4229},{},[4230,4241],{"type":30,"tag":35,"props":4231,"children":4232},{},[4233,4235,4240],{"type":39,"value":4234},"Erreur 1 : laisser Dependabot ouvrir 30 PR par semaine sans ",{"type":30,"tag":262,"props":4236,"children":4238},{"className":4237},[],[4239],{"type":39,"value":4047},{"type":39,"value":205},{"type":39,"value":4242}," Le bruit tue le signal. Les développeurs commencent à fermer les PR sans lire. C'est pire que pas de Dependabot du tout, parce que vous avez l'illusion d'être protégé.",{"type":30,"tag":31,"props":4244,"children":4245},{},[4246,4251],{"type":30,"tag":35,"props":4247,"children":4248},{},[4249],{"type":39,"value":4250},"Erreur 2 : auto-merger les minor et les major.",{"type":39,"value":4252}," C'est tentant, ça soulage la charge mentale, mais une seule mise à jour cassante en prod détruit toute la confiance dans le pipeline. Auto-merge sur le patch uniquement, sauf si vous avez une couverture de tests acceptance-level qui couvre vos vrais comportements métier.",{"type":30,"tag":31,"props":4254,"children":4255},{},[4256,4261,4263,4268,4270,4276,4278,4284],{"type":30,"tag":35,"props":4257,"children":4258},{},[4259],{"type":39,"value":4260},"Erreur 3 : oublier les dépendances transitives.",{"type":39,"value":4262}," Dependabot scanne ce qui est dans votre ",{"type":30,"tag":262,"props":4264,"children":4266},{"className":4265},[],[4267],{"type":39,"value":3288},{"type":39,"value":4269}," ou votre ",{"type":30,"tag":262,"props":4271,"children":4273},{"className":4272},[],[4274],{"type":39,"value":4275},"pom.xml",{"type":39,"value":4277},". Mais les vulnérabilités se planquent souvent 3 ou 4 niveaux en dessous, dans des libs que vous n'avez jamais nommément ajoutées. C'est là que ",{"type":30,"tag":88,"props":4279,"children":4281},{"href":4280},"/fr/intelligence-artificielle/llm-securite-code-vulnerabilites",[4282],{"type":39,"value":4283},"les alertes de sécurité dédiées au code IA-généré",{"type":39,"value":4285}," complètent l'arsenal, pas en concurrent mais en complément.",{"type":30,"tag":55,"props":4287,"children":4288},{},[],{"type":30,"tag":59,"props":4290,"children":4291},{"id":639},[4292],{"type":39,"value":642},{"type":30,"tag":31,"props":4294,"children":4295},{},[4296],{"type":39,"value":4297},"Sur les 4 dernières missions où j'ai déployé cette discipline, voici les chiffres avant/après, mesurés sur 6 mois.",{"type":30,"tag":537,"props":4299,"children":4300},{},[4301,4320],{"type":30,"tag":541,"props":4302,"children":4303},{},[4304],{"type":30,"tag":545,"props":4305,"children":4306},{},[4307,4311,4316],{"type":30,"tag":549,"props":4308,"children":4309},{},[4310],{"type":39,"value":661},{"type":30,"tag":549,"props":4312,"children":4313},{},[4314],{"type":39,"value":4315},"Avant",{"type":30,"tag":549,"props":4317,"children":4318},{},[4319],{"type":39,"value":2959},{"type":30,"tag":560,"props":4321,"children":4322},{},[4323,4341,4359,4376],{"type":30,"tag":545,"props":4324,"children":4325},{},[4326,4331,4336],{"type":30,"tag":567,"props":4327,"children":4328},{},[4329],{"type":39,"value":4330},"Time-to-patch CVE critique",{"type":30,"tag":567,"props":4332,"children":4333},{},[4334],{"type":39,"value":4335},"32 jours en moyenne",{"type":30,"tag":567,"props":4337,"children":4338},{},[4339],{"type":39,"value":4340},"6 jours en moyenne",{"type":30,"tag":545,"props":4342,"children":4343},{},[4344,4349,4354],{"type":30,"tag":567,"props":4345,"children":4346},{},[4347],{"type":39,"value":4348},"Nombre de PR Dependabot ouvertes plus de 14 jours",{"type":30,"tag":567,"props":4350,"children":4351},{},[4352],{"type":39,"value":4353},"18 en moyenne",{"type":30,"tag":567,"props":4355,"children":4356},{},[4357],{"type":39,"value":4358},"2 en moyenne",{"type":30,"tag":545,"props":4360,"children":4361},{},[4362,4367,4372],{"type":30,"tag":567,"props":4363,"children":4364},{},[4365],{"type":39,"value":4366},"Incidents prod liés à une CVE supply chain",{"type":30,"tag":567,"props":4368,"children":4369},{},[4370],{"type":39,"value":4371},"2 par an",{"type":30,"tag":567,"props":4373,"children":4374},{},[4375],{"type":39,"value":746},{"type":30,"tag":545,"props":4377,"children":4378},{},[4379,4384,4389],{"type":30,"tag":567,"props":4380,"children":4381},{},[4382],{"type":39,"value":4383},"Heures dev consacrées à la gestion des dépendances",{"type":30,"tag":567,"props":4385,"children":4386},{},[4387],{"type":39,"value":4388},"6h par semaine",{"type":30,"tag":567,"props":4390,"children":4391},{},[4392],{"type":39,"value":4393},"1h30 par semaine",{"type":30,"tag":31,"props":4395,"children":4396},{},[4397],{"type":39,"value":4398},"Le gain n'est pas que technique, il est économique. Une heure de dev senior coûte entre 80 et 150 euros chargée. Économiser 4 heures et demie par semaine, c'est 18 000 à 35 000 euros par an. Pour une équipe de 5 développeurs, cette discipline financière paie son installation en 3 semaines.",{"type":30,"tag":31,"props":4400,"children":4401},{},[4402],{"type":39,"value":4403},"C'est ce que je dis aux CTOs qui hésitent : Dependabot n'est pas un sujet d'engineering, c'est un sujet d'allocation de capital.",{"type":30,"tag":55,"props":4405,"children":4406},{},[],{"type":30,"tag":59,"props":4408,"children":4409},{"id":801},[4410],{"type":39,"value":804},{"type":30,"tag":31,"props":4412,"children":4413},{},[4414],{"type":39,"value":4415},"Ce que je veux que vous reteniez de cet article, c'est que la gestion de dépendances n'est pas une tâche d'hygiène que vous traitez quand vous aurez le temps. C'est un processus craft, au même titre que la code review ou les tests. Et comme tout processus craft, il a besoin d'un squelette automatisé pour tenir dans la durée.",{"type":30,"tag":31,"props":4417,"children":4418},{},[4419],{"type":39,"value":4420},"L'IA accélère la production de code. Elle accélère aussi la production de dette de dépendances. Dependabot est un des rares outils où l'automatisation ne remplace pas le jugement : elle libère du temps pour l'exercer là où il compte vraiment, sur les majors, les CVE critiques, les choix architecturaux. C'est exactement ce que je cherche dans une bonne discipline craft.",{"type":30,"tag":31,"props":4422,"children":4423},{},[4424,4426,4431],{"type":39,"value":4425},"Si en lisant ces lignes vous avez reconnu votre situation, vous avez deux choix. Vous pouvez attendre votre prochain Log4Shell. Ou vous pouvez commencer lundi matin, par un seul fichier ",{"type":30,"tag":262,"props":4427,"children":4429},{"className":4428},[],[4430],{"type":39,"value":3296},{"type":39,"value":4432}," versionné, et bâtir la suite.",{"type":30,"tag":392,"props":4434,"children":4436},{"cta":833,"href":834,"title":4435,"type":836},"La gestion de dépendances n'est qu'une des 100 pratiques qui font un code de senior",[4437],{"type":30,"tag":31,"props":4438,"children":4439},{},[4440],{"type":39,"value":4441},"Configurer Dependabot en craft, c'est une seule pratique parmi celles qui séparent un dev qui subit sa dette d'un dev qui la pilote. Le Craft Bundle réunit les 100 pratiques que j'applique pour coder propre, de la gestion de dépendances aux ADR en passant par la review : exactement celles que l'IA ne vous apprendra jamais, parce qu'elle ne les a jamais vues tenir en prod.",{"type":30,"tag":55,"props":4443,"children":4444},{},[],{"type":30,"tag":59,"props":4446,"children":4448},{"id":4447},"faq-sur-dependabot-et-la-gestion-de-dépendances",[4449],{"type":39,"value":4450},"FAQ sur Dependabot et la gestion de dépendances",{"type":30,"tag":853,"props":4452,"children":4453},{},[4454,4459],{"type":30,"tag":857,"props":4455,"children":4456},{},[4457],{"type":39,"value":4458},"1. Dependabot ou Renovate : lequel choisir ?",{"type":30,"tag":31,"props":4460,"children":4461},{},[4462],{"type":39,"value":4463},"Dependabot est gratuit, intégré nativement à GitHub, et largement suffisant pour la majorité des équipes. Renovate est plus puissant (règles plus fines, plus d'écosystèmes, monorepo natif) mais demande plus de temps de configuration. Mon conseil : commencez par Dependabot. Si au bout de 6 mois vous trouvez ses limites (vous le saurez), passez à Renovate. Mais ne commencez pas par Renovate, vous perdrez 2 semaines avant la première PR utile.",{"type":30,"tag":853,"props":4465,"children":4466},{},[4467,4472],{"type":30,"tag":857,"props":4468,"children":4469},{},[4470],{"type":39,"value":4471},"2. Faut-il auto-merger les patch updates ?",{"type":30,"tag":31,"props":4473,"children":4474},{},[4475],{"type":39,"value":4476},"Oui, à une condition : votre CI doit être verte, complète, et fiable. Si votre couverture de tests est faible (moins de 60% sur les chemins critiques), n'auto-mergez rien. Renforcez d'abord les tests, puis activez l'auto-merge sur patch uniquement. Jamais sur minor ou major sans review humaine.",{"type":30,"tag":853,"props":4478,"children":4479},{},[4480,4485],{"type":30,"tag":857,"props":4481,"children":4482},{},[4483],{"type":39,"value":4484},"3. Comment gérer les dépendances qu'on ne peut pas mettre à jour (lock sur une vieille version) ?",{"type":30,"tag":31,"props":4486,"children":4487},{},[4488,4490,4495,4497,4502,4504,4509,4511,4516,4518,4524],{"type":39,"value":4489},"Utilisez le bloc ",{"type":30,"tag":262,"props":4491,"children":4493},{"className":4492},[],[4494],{"type":39,"value":3448},{"type":39,"value":4496}," du ",{"type":30,"tag":262,"props":4498,"children":4500},{"className":4499},[],[4501],{"type":39,"value":3296},{"type":39,"value":4503},", mais avec une règle stricte : tout ",{"type":30,"tag":262,"props":4505,"children":4507},{"className":4506},[],[4508],{"type":39,"value":3448},{"type":39,"value":4510}," doit être documenté (commentaire YAML expliquant pourquoi et jusqu'à quand) et révisé tous les 3 mois. Un ",{"type":30,"tag":262,"props":4512,"children":4514},{"className":4513},[],[4515],{"type":39,"value":3448},{"type":39,"value":4517}," non documenté devient une dette technique cachée. Vous remplacez un problème de sécurité par un problème d'oubli, ce qui est exactement le mécanisme décrit dans cet article sur ",{"type":30,"tag":88,"props":4519,"children":4521},{"href":4520},"/fr/dette-technique/legacy-code-evaluer-risque",[4522],{"type":39,"value":4523},"l'évaluation du risque legacy",{"type":39,"value":205},{"type":30,"tag":853,"props":4526,"children":4527},{},[4528,4533],{"type":30,"tag":857,"props":4529,"children":4530},{},[4531],{"type":39,"value":4532},"4. Dependabot crée trop de PR, comment réduire le bruit ?",{"type":30,"tag":31,"props":4534,"children":4535},{},[4536,4538,4543,4545,4550,4552,4558,4560,4566,4568,4574],{"type":39,"value":4537},"Trois leviers, dans cet ordre. Premièrement, regroupez les minor et patch via la clé ",{"type":30,"tag":262,"props":4539,"children":4541},{"className":4540},[],[4542],{"type":39,"value":4047},{"type":39,"value":4544},". C'est ce qui divise le bruit par 10. Deuxièmement, limitez avec ",{"type":30,"tag":262,"props":4546,"children":4548},{"className":4547},[],[4549],{"type":39,"value":4055},{"type":39,"value":4551},". Troisièmement, espacez le ",{"type":30,"tag":262,"props":4553,"children":4555},{"className":4554},[],[4556],{"type":39,"value":4557},"schedule",{"type":39,"value":4559}," à ",{"type":30,"tag":262,"props":4561,"children":4563},{"className":4562},[],[4564],{"type":39,"value":4565},"weekly",{"type":39,"value":4567}," plutôt que ",{"type":30,"tag":262,"props":4569,"children":4571},{"className":4570},[],[4572],{"type":39,"value":4573},"daily",{"type":39,"value":4575},". Avec ces trois réglages, vous passez de 30 PR par semaine à 3 ou 4.",{"type":30,"tag":853,"props":4577,"children":4578},{},[4579,4584],{"type":30,"tag":857,"props":4580,"children":4581},{},[4582],{"type":39,"value":4583},"5. Et le code IA-généré qui pull des dépendances obsolètes ?",{"type":30,"tag":31,"props":4585,"children":4586},{},[4587],{"type":39,"value":4588},"C'est exactement le scénario contre lequel Dependabot protège. Claude pulle des libs qu'il connaît depuis son training data, souvent en retard de 12 à 18 mois sur la version courante. Dependabot rattrape ces écarts à la PR suivante. La discipline craft à ajouter : auditer chaque dépendance que Claude propose avant de l'accepter dans le code. C'est un réflexe à 30 secondes qui évite des heures de remédiation.",{"type":30,"tag":853,"props":4590,"children":4591},{},[4592,4597],{"type":30,"tag":857,"props":4593,"children":4594},{},[4595],{"type":39,"value":4596},"6. Quel est le ROI réel d'une bonne configuration Dependabot ?",{"type":30,"tag":31,"props":4598,"children":4599},{},[4600],{"type":39,"value":4601},"Sur les 4 missions où j'ai mesuré, le ROI se situe entre 18 000 et 35 000 euros par an pour une équipe de 5 développeurs. Le calcul est simple : 4 à 5 heures de dev économisées par semaine, à un coût chargé de 80 à 150 euros l'heure. Sans compter les incidents évités, dont le coût unitaire peut dépasser 50 000 euros pour une CVE critique en prod.",{"type":30,"tag":55,"props":4603,"children":4604},{},[],{"type":30,"tag":392,"props":4606,"children":4607},{"cta":944,"href":945,"title":946,"type":947},[4608],{"type":30,"tag":31,"props":4609,"children":4610},{},[4611],{"type":39,"value":4612},"L'EMA est l'outil que je propose au début de chaque mission. Il mesure la maturité de votre équipe sur plusieurs axes engineering, dont la dette technique, le delivery, la gouvernance IA et l'architecture. La gestion de dépendances en est un sous-axe. Quelques minutes pour avoir une vision claire de votre passif engineering, et savoir où concentrer vos efforts en priorité.",{"type":30,"tag":3232,"props":4614,"children":4615},{},[4616],{"type":39,"value":3236},{"title":8,"searchDepth":955,"depth":955,"links":4618},[4619,4620,4621,4627,4628,4629,4630],{"id":3304,"depth":955,"text":3307},{"id":3369,"depth":955,"text":3372},{"id":3489,"depth":955,"text":3492,"children":4622},[4623,4625,4626],{"id":3501,"depth":1169,"text":4624},"Étape 1 : le dependabot.yml craft",{"id":4122,"depth":1169,"text":4125},{"id":4192,"depth":1169,"text":4195},{"id":4218,"depth":955,"text":4221},{"id":639,"depth":955,"text":642},{"id":801,"depth":955,"text":804},{"id":4447,"depth":955,"text":4450},"content:fr:dette-technique:dependabot-craft-gestion-dependances.md","fr/dette-technique/dependabot-craft-gestion-dependances.md","fr/dette-technique/dependabot-craft-gestion-dependances",1782669248269]