[{"data":1,"prerenderedAt":4001},["ShallowReactive",2],{"search-api":-1,"listing-tag-documentation-page-1":3},[4,972,3210],{"_path":5,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":9,"description":10,"id":11,"date":12,"listed":13,"nocomments":7,"hidden":7,"categories":14,"tags":15,"cover":19,"readingTime":20,"body":25,"_type":966,"_id":967,"_source":968,"_file":969,"_stem":970,"_extension":971},"\u002Ffr\u002Fdette-technique\u002F5-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],[16,17,18],"software-craftsmanship","ddd","documentation","covers\u002Farticles\u002F5-raisons-app-meurt-18-mois.jpg",{"text":21,"minutes":22,"time":23,"words":24},"15 min read",14.865,891900,2973,{"type":26,"children":27,"toc":953},"root",[28,48,53,57,64,76,81,95,117,139,142,148,165,175,192,205,210,213,219,228,237,255,333,338,341,347,356,365,382,387,390,403,406,412,421,430,440,453,456,462,471,480,490,495,508,511,517,522,530,535,628,633,636,642,647,782,795,798,804,809,814,819,830,842,845,851,866,879,892,905,925,938,941],{"type":29,"tag":30,"props":31,"children":32},"element","p",{},[33],{"type":29,"tag":34,"props":35,"children":36},"strong",{},[37,40,46],{"type":38,"value":39},"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":29,"tag":41,"props":42,"children":43},"em",{},[44],{"type":38,"value":45},"\"on repart de zéro, c'est moins cher.\"",{"type":38,"value":47}," 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":29,"tag":30,"props":49,"children":50},{},[51],{"type":38,"value":52},"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":29,"tag":54,"props":55,"children":56},"hr",{},[],{"type":29,"tag":58,"props":59,"children":61},"h2",{"id":60},"le-mythe-de-lappli-qui-meurt-parce-quelle-vieillit",[62],{"type":38,"value":63},"Le mythe de l'appli qui meurt parce qu'elle vieillit",{"type":29,"tag":30,"props":65,"children":66},{},[67,69,74],{"type":38,"value":68},"On parle de ",{"type":29,"tag":41,"props":70,"children":71},{},[72],{"type":38,"value":73},"\"code legacy\"",{"type":38,"value":75}," 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":29,"tag":30,"props":77,"children":78},{},[79],{"type":38,"value":80},"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":29,"tag":30,"props":82,"children":83},{},[84,86,93],{"type":38,"value":85},"Le facteur âge n'est pas la variable explicative. Le facteur discipline craft l'est. Selon la classification du ",{"type":29,"tag":87,"props":88,"children":90},"a",{"href":89},"\u002Ffr\u002Fdette-technique\u002Fintroduction-maturite-engineering-5-niveaux",[91],{"type":38,"value":92},"niveau de maturité engineering",{"type":38,"value":94}," 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":29,"tag":96,"props":97,"children":98},"blockquote",{},[99],{"type":29,"tag":30,"props":100,"children":101},{},[102,107,109,115],{"type":29,"tag":34,"props":103,"children":104},{},[105],{"type":38,"value":106},"Ce que j'ai observé",{"type":38,"value":108}," : 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":29,"tag":87,"props":110,"children":112},{"href":111},"\u002Ffr\u002Fdette-technique\u002Fclean-code-software-craftsmanship-principes-java",[113],{"type":38,"value":114},"principes Clean Code et software craftsmanship",{"type":38,"value":116}," que je rappelle systématiquement.",{"type":29,"tag":30,"props":118,"children":119},{},[120,122,130,132,137],{"type":38,"value":121},"Cet article s'appuie aussi sur ce que je vois revenir dans les Reels storytelling que je publie sur ",{"type":29,"tag":87,"props":123,"children":127},{"href":124,"rel":125},"https:\u002F\u002Fwww.instagram.com\u002Fkamangacode\u002F",[126],"nofollow",[128],{"type":38,"value":129},"mon profil Instagram kamangacode",{"type":38,"value":131},". Le cas n°1 du ",{"type":29,"tag":41,"props":133,"children":134},{},[135],{"type":38,"value":136},"\"projet que j'ai vu mourir à 18 mois\"",{"type":38,"value":138}," est celui-ci. Et il est rejouable autant de fois qu'on veut. Voici comment ne plus jamais le rejouer.",{"type":29,"tag":54,"props":140,"children":141},{},[],{"type":29,"tag":58,"props":143,"children":145},{"id":144},"raison-1-aucun-pourquoi-tracé-et-la-pratique-adr",[146],{"type":38,"value":147},"Raison #1 : aucun POURQUOI tracé (et la pratique ADR)",{"type":29,"tag":30,"props":149,"children":150},{},[151,156,158,163],{"type":29,"tag":34,"props":152,"children":153},{},[154],{"type":38,"value":155},"Symptôme",{"type":38,"value":157}," : à 12 mois, plus personne dans l'équipe ne sait ",{"type":29,"tag":41,"props":159,"children":160},{},[161],{"type":38,"value":162},"pourquoi",{"type":38,"value":164}," 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":29,"tag":30,"props":166,"children":167},{},[168,173],{"type":29,"tag":34,"props":169,"children":170},{},[171],{"type":38,"value":172},"Mécanisme",{"type":38,"value":174}," : 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":29,"tag":30,"props":176,"children":177},{},[178,183,185,190],{"type":29,"tag":34,"props":179,"children":180},{},[181],{"type":38,"value":182},"Pratique craft : ADR (Architecture Decision Records).",{"type":38,"value":184}," Michael Nygard a écrit en 2011 l'article fondateur ",{"type":29,"tag":41,"props":186,"children":187},{},[188],{"type":38,"value":189},"\"Documenting Architecture Decisions\"",{"type":38,"value":191}," 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":29,"tag":30,"props":193,"children":194},{},[195,197,203],{"type":38,"value":196},"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":29,"tag":87,"props":198,"children":200},{"href":199},"\u002Ffr\u002Farchitecture-craft\u002Fadr-architecture-decision-record",[201],{"type":38,"value":202},"la pratique des ADR pour les décisions structurantes",{"type":38,"value":204},".",{"type":29,"tag":30,"props":206,"children":207},{},[208],{"type":38,"value":209},"Sur les missions où j'installe cette discipline, le ratio ADR \u002F 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":29,"tag":54,"props":211,"children":212},{},[],{"type":29,"tag":58,"props":214,"children":216},{"id":215},"raison-2-pas-de-frontières-métier-et-la-pratique-bounded-contexts",[217],{"type":38,"value":218},"Raison #2 : pas de frontières métier (et la pratique Bounded Contexts)",{"type":29,"tag":30,"props":220,"children":221},{},[222,226],{"type":29,"tag":34,"props":223,"children":224},{},[225],{"type":38,"value":155},{"type":38,"value":227}," : 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":29,"tag":30,"props":229,"children":230},{},[231,235],{"type":29,"tag":34,"props":232,"children":233},{},[234],{"type":38,"value":172},{"type":38,"value":236}," : 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":29,"tag":30,"props":238,"children":239},{},[240,245,247,253],{"type":29,"tag":34,"props":241,"children":242},{},[243],{"type":38,"value":244},"Pratique craft : Bounded Contexts",{"type":38,"value":246}," issus du ",{"type":29,"tag":87,"props":248,"children":250},{"href":249},"\u002Ffr\u002Farchitecture-craft\u002Fdecouvrir-domain-driven-design-ddd-avantages-exemples-java",[251],{"type":38,"value":252},"Domain-Driven Design d'Eric Evans",{"type":38,"value":254}," (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":29,"tag":30,"props":256,"children":257},{},[258,260,267,269,275,276,282,283,289,290,296,297,303,304,310,311,317,319,324,326,331],{"type":38,"value":259},"Sur le crmcoaching, j'ai défini 8 bounded contexts dès le démarrage : ",{"type":29,"tag":261,"props":262,"children":264},"code",{"className":263},[],[265],{"type":38,"value":266},"booking",{"type":38,"value":268},", ",{"type":29,"tag":261,"props":270,"children":272},{"className":271},[],[273],{"type":38,"value":274},"lead",{"type":38,"value":268},{"type":29,"tag":261,"props":277,"children":279},{"className":278},[],[280],{"type":38,"value":281},"calendar",{"type":38,"value":268},{"type":29,"tag":261,"props":284,"children":286},{"className":285},[],[287],{"type":38,"value":288},"payment",{"type":38,"value":268},{"type":29,"tag":261,"props":291,"children":293},{"className":292},[],[294],{"type":38,"value":295},"notification",{"type":38,"value":268},{"type":29,"tag":261,"props":298,"children":300},{"className":299},[],[301],{"type":38,"value":302},"audit",{"type":38,"value":268},{"type":29,"tag":261,"props":305,"children":307},{"className":306},[],[308],{"type":38,"value":309},"auth",{"type":38,"value":268},{"type":29,"tag":261,"props":312,"children":314},{"className":313},[],[315],{"type":38,"value":316},"tenant",{"type":38,"value":318},". 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":29,"tag":261,"props":320,"children":322},{"className":321},[],[323],{"type":38,"value":266},{"type":38,"value":325},", je sais que ",{"type":29,"tag":261,"props":327,"children":329},{"className":328},[],[330],{"type":38,"value":288},{"type":38,"value":332}," 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":29,"tag":30,"props":334,"children":335},{},[336],{"type":38,"value":337},"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":29,"tag":54,"props":339,"children":340},{},[],{"type":29,"tag":58,"props":342,"children":344},{"id":343},"raison-3-tests-qui-testent-des-mocks-et-la-pratique-ac-level-coverage",[345],{"type":38,"value":346},"Raison #3 : tests qui testent des mocks (et la pratique AC-level coverage)",{"type":29,"tag":30,"props":348,"children":349},{},[350,354],{"type":29,"tag":34,"props":351,"children":352},{},[353],{"type":38,"value":155},{"type":38,"value":355}," : 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":29,"tag":30,"props":357,"children":358},{},[359,363],{"type":29,"tag":34,"props":360,"children":361},{},[362],{"type":38,"value":172},{"type":38,"value":364}," : 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":29,"tag":30,"props":366,"children":367},{},[368,373,375,381],{"type":29,"tag":34,"props":369,"children":370},{},[371],{"type":38,"value":372},"Pratique craft : Acceptance Criteria + couverture AC-level.",{"type":38,"value":374}," Dan North a posé les bases dans ses articles BDD fondateurs de 2006. Format Given\u002FWhen\u002FThen. 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":29,"tag":87,"props":376,"children":378},{"href":377},"\u002Ffr\u002Fpratiques-agiles\u002Fadopter-behaviour-driven-development-bdd-guide-agile",[379],{"type":38,"value":380},"l'adoption du Behaviour-Driven Development",{"type":38,"value":204},{"type":29,"tag":30,"props":383,"children":384},{},[385],{"type":38,"value":386},"Sur le crmcoaching, j'ai 47 acceptance criteria explicites, chacun couvert par un test behavior-level. Mon ratio \"tests utiles \u002F 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":29,"tag":54,"props":388,"children":389},{},[],{"type":29,"tag":391,"props":392,"children":397},"cta",{"cta":393,"href":394,"title":395,"type":396},"Coder comme un senior →","https:\u002F\u002Fapp.kamanga.fr\u002Fforms\u002Fmentoring","Vous voulez prendre les réflexes craft qui font tenir une codebase 10 ans ?","call",[398],{"type":29,"tag":30,"props":399,"children":400},{},[401],{"type":38,"value":402},"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":29,"tag":54,"props":404,"children":405},{},[],{"type":29,"tag":58,"props":407,"children":409},{"id":408},"raison-4-pas-de-discipline-de-refacto-et-la-pratique-strangler-fig",[410],{"type":38,"value":411},"Raison #4 : pas de discipline de refacto (et la pratique Strangler Fig)",{"type":29,"tag":30,"props":413,"children":414},{},[415,419],{"type":29,"tag":34,"props":416,"children":417},{},[418],{"type":38,"value":155},{"type":38,"value":420}," : 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":29,"tag":30,"props":422,"children":423},{},[424,428],{"type":29,"tag":34,"props":425,"children":426},{},[427],{"type":38,"value":172},{"type":38,"value":429}," : 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":29,"tag":30,"props":431,"children":432},{},[433,438],{"type":29,"tag":34,"props":434,"children":435},{},[436],{"type":38,"value":437},"Pratique craft : Strangler Fig Application (Martin Fowler, 2004).",{"type":38,"value":439}," 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":29,"tag":30,"props":441,"children":442},{},[443,445,451],{"type":38,"value":444},"Sur les missions où j'installe cette discipline, je couple le Strangler Fig avec ",{"type":29,"tag":87,"props":446,"children":448},{"href":447},"\u002Ffr\u002Fdette-technique\u002Fprogramme-refactoring-approuve-business",[449],{"type":38,"value":450},"un programme de refacto approuvé business",{"type":38,"value":452},". 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":29,"tag":54,"props":454,"children":455},{},[],{"type":29,"tag":58,"props":457,"children":459},{"id":458},"raison-5-tout-est-dans-une-seule-tête-et-la-pratique-docs-as-code",[460],{"type":38,"value":461},"Raison #5 : tout est dans une seule tête (et la pratique Docs as code)",{"type":29,"tag":30,"props":463,"children":464},{},[465,469],{"type":29,"tag":34,"props":466,"children":467},{},[468],{"type":38,"value":155},{"type":38,"value":470}," : 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":29,"tag":30,"props":472,"children":473},{},[474,478],{"type":29,"tag":34,"props":475,"children":476},{},[477],{"type":38,"value":172},{"type":38,"value":479}," : 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":29,"tag":30,"props":481,"children":482},{},[483,488],{"type":29,"tag":34,"props":484,"children":485},{},[486],{"type":38,"value":487},"Pratique craft : Docs as code, artifacts vivants versionnés.",{"type":38,"value":489}," 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":29,"tag":30,"props":491,"children":492},{},[493],{"type":38,"value":494},"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 \u002F 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":29,"tag":30,"props":496,"children":497},{},[498,500,506],{"type":38,"value":499},"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":29,"tag":87,"props":501,"children":503},{"href":502},"\u002Ffr\u002Fintelligence-artificielle\u002Fia-documentation-technique-cas-usage",[504],{"type":38,"value":505},"l'usage de l'IA pour la documentation technique",{"type":38,"value":507},", où l'IA devient un amplificateur d'écriture craft plutôt qu'un raccourci.",{"type":29,"tag":54,"props":509,"children":510},{},[],{"type":29,"tag":58,"props":512,"children":514},{"id":513},"synthèse-le-code-qui-tient-à-10-ans",[515],{"type":38,"value":516},"Synthèse : le code qui tient à 10 ans",{"type":29,"tag":30,"props":518,"children":519},{},[520],{"type":38,"value":521},"Voici la phrase signature que j'utilise en mission, en conférence, en stand-up :",{"type":29,"tag":30,"props":523,"children":524},{},[525],{"type":29,"tag":41,"props":526,"children":527},{},[528],{"type":38,"value":529},"\"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":29,"tag":30,"props":531,"children":532},{},[533],{"type":38,"value":534},"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":29,"tag":536,"props":537,"children":538},"table",{},[539,558],{"type":29,"tag":540,"props":541,"children":542},"thead",{},[543],{"type":29,"tag":544,"props":545,"children":546},"tr",{},[547,553],{"type":29,"tag":548,"props":549,"children":550},"th",{},[551],{"type":38,"value":552},"Raison de la mort à 18 mois",{"type":29,"tag":548,"props":554,"children":555},{},[556],{"type":38,"value":557},"Pratique craft de survie 10 ans",{"type":29,"tag":559,"props":560,"children":561},"tbody",{},[562,576,589,602,615],{"type":29,"tag":544,"props":563,"children":564},{},[565,571],{"type":29,"tag":566,"props":567,"children":568},"td",{},[569],{"type":38,"value":570},"#1 Aucun POURQUOI tracé",{"type":29,"tag":566,"props":572,"children":573},{},[574],{"type":38,"value":575},"ADRs versionnées dans le repo",{"type":29,"tag":544,"props":577,"children":578},{},[579,584],{"type":29,"tag":566,"props":580,"children":581},{},[582],{"type":38,"value":583},"#2 Pas de frontières métier",{"type":29,"tag":566,"props":585,"children":586},{},[587],{"type":38,"value":588},"Bounded Contexts (DDD)",{"type":29,"tag":544,"props":590,"children":591},{},[592,597],{"type":29,"tag":566,"props":593,"children":594},{},[595],{"type":38,"value":596},"#3 Tests qui testent des mocks",{"type":29,"tag":566,"props":598,"children":599},{},[600],{"type":38,"value":601},"Acceptance Criteria + tests behavior-level",{"type":29,"tag":544,"props":603,"children":604},{},[605,610],{"type":29,"tag":566,"props":606,"children":607},{},[608],{"type":38,"value":609},"#4 Pas de discipline de refacto",{"type":29,"tag":566,"props":611,"children":612},{},[613],{"type":38,"value":614},"Strangler Fig + 20% temps équipe",{"type":29,"tag":544,"props":616,"children":617},{},[618,623],{"type":29,"tag":566,"props":619,"children":620},{},[621],{"type":38,"value":622},"#5 Tout est dans une tête",{"type":29,"tag":566,"props":624,"children":625},{},[626],{"type":38,"value":627},"Docs as code, artifacts vivants versionnés",{"type":29,"tag":30,"props":629,"children":630},{},[631],{"type":38,"value":632},"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":29,"tag":54,"props":634,"children":635},{},[],{"type":29,"tag":58,"props":637,"children":639},{"id":638},"ce-que-ça-change-concrètement",[640],{"type":38,"value":641},"Ce que ça change concrètement",{"type":29,"tag":30,"props":643,"children":644},{},[645],{"type":38,"value":646},"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\u002Faprès.",{"type":29,"tag":536,"props":648,"children":649},{},[650,671],{"type":29,"tag":540,"props":651,"children":652},{},[653],{"type":29,"tag":544,"props":654,"children":655},{},[656,661,666],{"type":29,"tag":548,"props":657,"children":658},{},[659],{"type":38,"value":660},"Métrique",{"type":29,"tag":548,"props":662,"children":663},{},[664],{"type":38,"value":665},"Avant audit",{"type":29,"tag":548,"props":667,"children":668},{},[669],{"type":38,"value":670},"Après 12 mois",{"type":29,"tag":559,"props":672,"children":673},{},[674,692,710,728,746,764],{"type":29,"tag":544,"props":675,"children":676},{},[677,682,687],{"type":29,"tag":566,"props":678,"children":679},{},[680],{"type":38,"value":681},"Coût moyen d'une feature simple",{"type":29,"tag":566,"props":683,"children":684},{},[685],{"type":38,"value":686},"4,2 jours",{"type":29,"tag":566,"props":688,"children":689},{},[690],{"type":38,"value":691},"1,6 jour",{"type":29,"tag":544,"props":693,"children":694},{},[695,700,705],{"type":29,"tag":566,"props":696,"children":697},{},[698],{"type":38,"value":699},"Onboarding nouveau dev (1ère PR mergée)",{"type":29,"tag":566,"props":701,"children":702},{},[703],{"type":38,"value":704},"7 semaines",{"type":29,"tag":566,"props":706,"children":707},{},[708],{"type":38,"value":709},"3,5 semaines",{"type":29,"tag":544,"props":711,"children":712},{},[713,718,723],{"type":29,"tag":566,"props":714,"children":715},{},[716],{"type":38,"value":717},"Bugs régression par release",{"type":29,"tag":566,"props":719,"children":720},{},[721],{"type":38,"value":722},"5-7",{"type":29,"tag":566,"props":724,"children":725},{},[726],{"type":38,"value":727},"0-1",{"type":29,"tag":544,"props":729,"children":730},{},[731,736,741],{"type":29,"tag":566,"props":732,"children":733},{},[734],{"type":38,"value":735},"Discussions \"et si on réécrivait tout ?\"",{"type":29,"tag":566,"props":737,"children":738},{},[739],{"type":38,"value":740},"1 par trimestre",{"type":29,"tag":566,"props":742,"children":743},{},[744],{"type":38,"value":745},"0",{"type":29,"tag":544,"props":747,"children":748},{},[749,754,759],{"type":29,"tag":566,"props":750,"children":751},{},[752],{"type":38,"value":753},"Ratio docs \u002F code",{"type":29,"tag":566,"props":755,"children":756},{},[757],{"type":38,"value":758},"4%",{"type":29,"tag":566,"props":760,"children":761},{},[762],{"type":38,"value":763},"16%",{"type":29,"tag":544,"props":765,"children":766},{},[767,772,777],{"type":29,"tag":566,"props":768,"children":769},{},[770],{"type":38,"value":771},"ADRs créées dans l'année",{"type":29,"tag":566,"props":773,"children":774},{},[775],{"type":38,"value":776},"3",{"type":29,"tag":566,"props":778,"children":779},{},[780],{"type":38,"value":781},"47",{"type":29,"tag":30,"props":783,"children":784},{},[785,787,793],{"type":38,"value":786},"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":29,"tag":87,"props":788,"children":790},{"href":789},"\u002Ffr\u002Fdette-technique\u002Fingenierie-logicielle-avantage-concurrentiel",[791],{"type":38,"value":792},"l'ingénierie logicielle comme avantage concurrentiel",{"type":38,"value":794},". Le craft n'est pas une dépense engineering, c'est un levier business avec ROI mesurable.",{"type":29,"tag":54,"props":796,"children":797},{},[],{"type":29,"tag":58,"props":799,"children":801},{"id":800},"conclusion",[802],{"type":38,"value":803},"Conclusion",{"type":29,"tag":30,"props":805,"children":806},{},[807],{"type":38,"value":808},"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":29,"tag":30,"props":810,"children":811},{},[812],{"type":38,"value":813},"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":29,"tag":30,"props":815,"children":816},{},[817],{"type":38,"value":818},"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":29,"tag":30,"props":820,"children":821},{},[822,824,829],{"type":38,"value":823},"Pour la suite des patterns de durabilité que je documente chaque semaine en mission, retrouvez-moi sur ",{"type":29,"tag":87,"props":825,"children":827},{"href":124,"rel":826},[126],[828],{"type":38,"value":129},{"type":38,"value":204},{"type":29,"tag":391,"props":831,"children":836},{"cta":832,"href":833,"title":834,"type":835},"Les 100 pratiques que l'IA n'enseigne pas →","https:\u002F\u002Fkamanga.fr\u002Freferentiel-craft","Ces 5 piliers craft font partie d'un référentiel de 100 pratiques","product",[837],{"type":29,"tag":30,"props":838,"children":839},{},[840],{"type":38,"value":841},"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":29,"tag":54,"props":843,"children":844},{},[],{"type":29,"tag":58,"props":846,"children":848},{"id":847},"faq-sur-le-code-durable-et-les-5-piliers-craft",[849],{"type":38,"value":850},"FAQ sur le code durable et les 5 piliers craft",{"type":29,"tag":852,"props":853,"children":854},"details",{},[855,861],{"type":29,"tag":856,"props":857,"children":858},"summary",{},[859],{"type":38,"value":860},"1. Faut-il installer les 5 piliers en même temps ou séquentiellement ?",{"type":29,"tag":30,"props":862,"children":863},{},[864],{"type":38,"value":865},"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":29,"tag":852,"props":867,"children":868},{},[869,874],{"type":29,"tag":856,"props":870,"children":871},{},[872],{"type":38,"value":873},"2. Combien coûte cette discipline en charge supplémentaire pour l'équipe ?",{"type":29,"tag":30,"props":875,"children":876},{},[877],{"type":38,"value":878},"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":29,"tag":852,"props":880,"children":881},{},[882,887],{"type":29,"tag":856,"props":883,"children":884},{},[885],{"type":38,"value":886},"3. Le DDD n'est-il pas trop lourd pour une équipe de 3-5 personnes ?",{"type":29,"tag":30,"props":888,"children":889},{},[890],{"type":38,"value":891},"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":29,"tag":852,"props":893,"children":894},{},[895,900],{"type":29,"tag":856,"props":896,"children":897},{},[898],{"type":38,"value":899},"4. Comment vendre cette discipline à un COMEX qui veut \"livrer plus vite\" ?",{"type":29,"tag":30,"props":901,"children":902},{},[903],{"type":38,"value":904},"Avec le tableau avant\u002Faprè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":29,"tag":852,"props":906,"children":907},{},[908,913],{"type":29,"tag":856,"props":909,"children":910},{},[911],{"type":38,"value":912},"5. Les 5 piliers fonctionnent-ils avec du code IA-généré massivement ?",{"type":29,"tag":30,"props":914,"children":915},{},[916,918,924],{"type":38,"value":917},"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":29,"tag":87,"props":919,"children":921},{"href":920},"\u002Ffr\u002Fintelligence-artificielle\u002Frecap-5-pieges-claude-semaine-1",[922],{"type":38,"value":923},"pièges Claude et leurs contre-patterns craft",{"type":38,"value":204},{"type":29,"tag":852,"props":926,"children":927},{},[928,933],{"type":29,"tag":856,"props":929,"children":930},{},[931],{"type":38,"value":932},"6. Que faire si mon équipe résiste à installer les ADR (raison #1) ?",{"type":29,"tag":30,"props":934,"children":935},{},[936],{"type":38,"value":937},"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":29,"tag":54,"props":939,"children":940},{},[],{"type":29,"tag":391,"props":942,"children":947},{"cta":943,"href":944,"title":945,"type":946},"Évaluer la maturité de mon équipe →","\u002Fmes-ressources","Ressource gratuite : Engineering Maturity Assessment","resource",[948],{"type":29,"tag":30,"props":949,"children":950},{},[951],{"type":38,"value":952},"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":954,"depth":954,"links":955},2,[956,957,958,959,960,961,962,963,964,965],{"id":60,"depth":954,"text":63},{"id":144,"depth":954,"text":147},{"id":215,"depth":954,"text":218},{"id":343,"depth":954,"text":346},{"id":408,"depth":954,"text":411},{"id":458,"depth":954,"text":461},{"id":513,"depth":954,"text":516},{"id":638,"depth":954,"text":641},{"id":800,"depth":954,"text":803},{"id":847,"depth":954,"text":850},"markdown","content:fr:dette-technique:5-raisons-app-meurt-18-mois.md","content","fr\u002Fdette-technique\u002F5-raisons-app-meurt-18-mois.md","fr\u002Fdette-technique\u002F5-raisons-app-meurt-18-mois","md",{"_path":502,"_dir":973,"_draft":7,"_partial":7,"_locale":8,"title":974,"description":975,"id":976,"date":977,"listed":13,"nocomments":7,"hidden":7,"categories":978,"tags":979,"cover":982,"readingTime":983,"body":988,"_type":966,"_id":3207,"_source":968,"_file":3208,"_stem":3209,"_extension":971},"intelligence-artificielle","IA et documentation technique : les cas d'usage qui marchent vraiment","L'IA peut automatiser 60% de la documentation technique, mais pas les 60% auxquels on pense en premier. Les cas d'usage validés et ceux à éviter.",28,"2026-03-09",[973],[18,980,981,16],"ia","ci-cd","covers\u002Farticles\u002Fia-documentation-technique.jpg",{"text":984,"minutes":985,"time":986,"words":987},"11 min read",10.575,634500,2115,{"type":26,"children":989,"toc":3196},[990,995,1000,1008,1011,1017,1022,1032,1042,1047,1050,1056,1066,1076,1085,1098,1106,1109,1115,1124,1133,2563,2576,2585,2588,2594,2603,2612,2617,2625,2635,2645,2648,2654,2663,2672,2677,2930,2935,2938,2944,2953,2962,2966,2974,2979,2982,2988,3003,3013,3023,3026,3032,3050,3060,3070,3075,3078,3087,3090,3096,3109,3138,3151,3164,3177,3180,3190],{"type":29,"tag":30,"props":991,"children":992},{},[993],{"type":38,"value":994},"Je construis crmcoaching seul : un CRM SaaS pour coachs professionnels, avec une quarantaine de use cases répartis en une dizaine de bounded contexts (lead, client, offre, mentoring, calendar, notification, audit...). La base de code grossit vite. Sans documentation, je perds du temps à me réorienter dans mon propre code entre deux sessions. J'ai donc intégré Claude directement dans mon workflow de documentation : READMEs de bounded contexts, docstrings sur les use cases NestJS, résumés de PR, ADRs. Le gain est réel, et les limites le sont aussi.",{"type":29,"tag":30,"props":996,"children":997},{},[998],{"type":38,"value":999},"Claude Code génère les READMEs des modules en quelques minutes. La révision humaine prend 15 à 30 minutes par bounded context. L'onboarding dans une partie du code que je n'ai pas touchée depuis trois semaines passe de 45 minutes de relecture à 10 minutes avec un README à jour.",{"type":29,"tag":30,"props":1001,"children":1002},{},[1003],{"type":29,"tag":34,"props":1004,"children":1005},{},[1006],{"type":38,"value":1007},"L'IA peut automatiser 60% de la documentation technique. Mais pas les 60% auxquels on pense en premier. Ceux qui espèrent que l'IA va écrire leurs ADRs et leur documentation d'architecture sont déçus. Ceux qui l'utilisent pour les bons cas d'usage gagnent des heures par semaine.",{"type":29,"tag":54,"props":1009,"children":1010},{},[],{"type":29,"tag":58,"props":1012,"children":1014},{"id":1013},"ce-que-lia-documente-bien-et-ce-quelle-documente-mal",[1015],{"type":38,"value":1016},"Ce que l'IA documente bien, et ce qu'elle documente mal",{"type":29,"tag":30,"props":1018,"children":1019},{},[1020],{"type":38,"value":1021},"Après plusieurs mois à documenter crmcoaching avec Claude, une règle simple s'est dégagée :",{"type":29,"tag":30,"props":1023,"children":1024},{},[1025,1030],{"type":29,"tag":34,"props":1026,"children":1027},{},[1028],{"type":38,"value":1029},"L'IA documente bien le \"quoi\" :",{"type":38,"value":1031}," ce que le code fait, comment appeler un endpoint, quels paramètres un use case accepte, quelle est la structure d'un DTO. Ces informations sont dans le code, Claude les extrait et les formate.",{"type":29,"tag":30,"props":1033,"children":1034},{},[1035,1040],{"type":29,"tag":34,"props":1036,"children":1037},{},[1038],{"type":38,"value":1039},"L'IA documente mal le \"pourquoi\" :",{"type":38,"value":1041}," pourquoi ce découpage hexagonal, pourquoi ce timeout, pourquoi cette contrainte métier sur le slot-hold. Ces informations ne sont pas dans le code, elles sont dans ma tête au moment où j'ai pris la décision.",{"type":29,"tag":30,"props":1043,"children":1044},{},[1045],{"type":38,"value":1046},"La règle d'usage : utiliser Claude pour documenter le \"quoi\" ; investir le temps humain sur le \"pourquoi\".",{"type":29,"tag":54,"props":1048,"children":1049},{},[],{"type":29,"tag":58,"props":1051,"children":1053},{"id":1052},"cas-dusage-1-génération-de-documentation-dapi-roi-élevé",[1054],{"type":38,"value":1055},"Cas d'usage 1 : Génération de documentation d'API (ROI élevé)",{"type":29,"tag":30,"props":1057,"children":1058},{},[1059,1064],{"type":29,"tag":34,"props":1060,"children":1061},{},[1062],{"type":38,"value":1063},"Le problème :",{"type":38,"value":1065}," les controllers NestJS ne sont souvent pas documentés. Chaque fois que je reprends un bounded context après quelques semaines, je perds du temps à relire les endpoints, les paramètres et les formats de réponse.",{"type":29,"tag":30,"props":1067,"children":1068},{},[1069,1074],{"type":29,"tag":34,"props":1070,"children":1071},{},[1072],{"type":38,"value":1073},"Ce que Claude fait :",{"type":38,"value":1075}," à partir du code d'un controller NestJS et de ses DTOs Zod\u002Fclass-validator, Claude génère une documentation structurée (Markdown ou OpenAPI) avec les endpoints, les paramètres, les types, et des exemples de requête\u002Fréponse.",{"type":29,"tag":1077,"props":1078,"children":1080},"pre",{"code":1079},"Prompt pour Claude :\n\nVoici le controller NestJS du module \"mentoring\" et les DTOs associés.\nGénère une documentation OpenAPI complète avec description de chaque endpoint,\nparamètres, types de retour, et exemples de requête\u002Fréponse.\nMentionne les guards d'authentification et les scopes de permission quand ils\nsont présents dans les décorateurs.\n\n[coller le code du controller + DTOs]\n",[1081],{"type":29,"tag":261,"props":1082,"children":1083},{"__ignoreMap":8},[1084],{"type":38,"value":1079},{"type":29,"tag":30,"props":1086,"children":1087},{},[1088,1090,1096],{"type":38,"value":1089},"Avec NestJS, les décorateurs ",{"type":29,"tag":261,"props":1091,"children":1093},{"className":1092},[],[1094],{"type":38,"value":1095},"@ApiProperty()",{"type":38,"value":1097}," (Swagger) et les schémas Zod servent de source de vérité pour la génération : Claude les lit et produit une doc cohérente avec le contrat de l'API réelle. Résultat typique : une documentation utilisable en 5 minutes de génération + 15 minutes de révision pour vérifier l'exactitude et ajouter le contexte métier (quel flux business appelle cet endpoint, quelles sont les contraintes de rate limiting).",{"type":29,"tag":30,"props":1099,"children":1100},{},[1101],{"type":29,"tag":34,"props":1102,"children":1103},{},[1104],{"type":38,"value":1105},"Gain : 3 à 4 heures de documentation manuelle ramenées à 20 minutes.",{"type":29,"tag":54,"props":1107,"children":1108},{},[],{"type":29,"tag":58,"props":1110,"children":1112},{"id":1111},"cas-dusage-2-commentaires-et-docstrings-dans-le-code-roi-moyen",[1113],{"type":38,"value":1114},"Cas d'usage 2 : Commentaires et docstrings dans le code (ROI moyen)",{"type":29,"tag":30,"props":1116,"children":1117},{},[1118,1122],{"type":29,"tag":34,"props":1119,"children":1120},{},[1121],{"type":38,"value":1063},{"type":38,"value":1123}," le code existant n'a pas de commentaires. Les use cases complexes sont difficiles à comprendre sans connaître le contexte de leur création.",{"type":29,"tag":30,"props":1125,"children":1126},{},[1127,1131],{"type":29,"tag":34,"props":1128,"children":1129},{},[1130],{"type":38,"value":1073},{"type":38,"value":1132}," il génère des docstrings TSDoc pour les classes et méthodes existantes en TypeScript.",{"type":29,"tag":1077,"props":1134,"children":1138},{"code":1135,"language":1136,"meta":8,"className":1137,"style":8},"\u002F\u002F Avant\n@Injectable()\nexport class CreateSlotHoldUseCase {\n  constructor(\n    private readonly slotHoldRepository: ISlotHoldRepository,\n    private readonly offerRepository: IOfferRepository,\n  ) {}\n\n  async execute(command: CreateSlotHoldCommand): Promise\u003CSlotHold> {\n    const offer = await this.offerRepository.findById(command.offerId);\n    if (!offer) throw new OfferNotFoundException(command.offerId);\n    if (offer.userId !== command.userId)\n      throw new UnauthorizedSlotHoldException();\n    return this.slotHoldRepository.create({\n      offerId: command.offerId,\n      userId: command.userId,\n      expiresAt: new Date(Date.now() + 15 * 60 * 1000),\n    });\n  }\n}\n\n\u002F\u002F Après génération par Claude\n\u002F**\n * Use case : réserver temporairement un slot d'offre pour un utilisateur.\n *\n * Vérifie que l'offre existe et appartient bien à l'utilisateur demandeur,\n * puis crée un slot-hold avec une expiration de 15 minutes.\n * Ce hold est libéré automatiquement si le paiement n'aboutit pas.\n *\n * @throws {OfferNotFoundException} si l'offre n'existe pas en base\n * @throws {UnauthorizedSlotHoldException} si l'offre appartient à un autre userId\n *\u002F\n@Injectable()\nexport class CreateSlotHoldUseCase {\n  constructor(\n    private readonly slotHoldRepository: ISlotHoldRepository,\n    private readonly offerRepository: IOfferRepository,\n  ) {}\n\n  \u002F**\n   * Exécute la réservation temporaire du slot.\n   *\n   * @param command - Commande contenant `offerId` et `userId`\n   * @returns Le slot-hold créé avec sa date d'expiration\n   *\u002F\n  async execute(command: CreateSlotHoldCommand): Promise\u003CSlotHold> {\n    const offer = await this.offerRepository.findById(command.offerId);\n    if (!offer) throw new OfferNotFoundException(command.offerId);\n    if (offer.userId !== command.userId)\n      throw new UnauthorizedSlotHoldException();\n    return this.slotHoldRepository.create({\n      offerId: command.offerId,\n      userId: command.userId,\n      expiresAt: new Date(Date.now() + 15 * 60 * 1000),\n    });\n  }\n}\n","typescript","language-typescript shiki shiki-themes catppuccin-frappe github-dark",[1139],{"type":29,"tag":261,"props":1140,"children":1141},{"__ignoreMap":8},[1142,1154,1175,1202,1216,1252,1282,1296,1305,1372,1442,1498,1539,1566,1606,1636,1666,1745,1762,1771,1780,1788,1797,1806,1815,1824,1833,1842,1850,1858,1898,1932,1941,1957,1977,1989,2017,2045,2057,2065,2074,2083,2092,2120,2142,2151,2207,2263,2311,2347,2371,2407,2435,2463,2531,2547,2555],{"type":29,"tag":1143,"props":1144,"children":1147},"span",{"class":1145,"line":1146},"line",1,[1148],{"type":29,"tag":1143,"props":1149,"children":1151},{"style":1150},"--shiki-default:#737994;--shiki-default-font-style:italic;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit",[1152],{"type":38,"value":1153},"\u002F\u002F Avant\n",{"type":29,"tag":1143,"props":1155,"children":1156},{"class":1145,"line":954},[1157,1163,1169],{"type":29,"tag":1143,"props":1158,"children":1160},{"style":1159},"--shiki-default:#8CAAEE;--shiki-default-font-style:italic;--shiki-dark:#E1E4E8;--shiki-dark-font-style:inherit",[1161],{"type":38,"value":1162},"@",{"type":29,"tag":1143,"props":1164,"children":1166},{"style":1165},"--shiki-default:#8CAAEE;--shiki-default-font-style:italic;--shiki-dark:#B392F0;--shiki-dark-font-style:inherit",[1167],{"type":38,"value":1168},"Injectable",{"type":29,"tag":1143,"props":1170,"children":1172},{"style":1171},"--shiki-default:#EF9F76;--shiki-dark:#E1E4E8",[1173],{"type":38,"value":1174},"()\n",{"type":29,"tag":1143,"props":1176,"children":1178},{"class":1145,"line":1177},3,[1179,1185,1190,1196],{"type":29,"tag":1143,"props":1180,"children":1182},{"style":1181},"--shiki-default:#CA9EE6;--shiki-dark:#F97583",[1183],{"type":38,"value":1184},"export",{"type":29,"tag":1143,"props":1186,"children":1187},{"style":1181},[1188],{"type":38,"value":1189}," class",{"type":29,"tag":1143,"props":1191,"children":1193},{"style":1192},"--shiki-default:#E5C890;--shiki-default-font-style:italic;--shiki-dark:#B392F0;--shiki-dark-font-style:inherit",[1194],{"type":38,"value":1195}," CreateSlotHoldUseCase",{"type":29,"tag":1143,"props":1197,"children":1199},{"style":1198},"--shiki-default:#949CBB;--shiki-dark:#E1E4E8",[1200],{"type":38,"value":1201}," {\n",{"type":29,"tag":1143,"props":1203,"children":1205},{"class":1145,"line":1204},4,[1206,1211],{"type":29,"tag":1143,"props":1207,"children":1208},{"style":1181},[1209],{"type":38,"value":1210},"  constructor",{"type":29,"tag":1143,"props":1212,"children":1213},{"style":1198},[1214],{"type":38,"value":1215},"(\n",{"type":29,"tag":1143,"props":1217,"children":1219},{"class":1145,"line":1218},5,[1220,1225,1230,1236,1242,1247],{"type":29,"tag":1143,"props":1221,"children":1222},{"style":1181},[1223],{"type":38,"value":1224},"    private",{"type":29,"tag":1143,"props":1226,"children":1227},{"style":1181},[1228],{"type":38,"value":1229}," readonly",{"type":29,"tag":1143,"props":1231,"children":1233},{"style":1232},"--shiki-default:#EA999C;--shiki-default-font-style:italic;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit",[1234],{"type":38,"value":1235}," slotHoldRepository",{"type":29,"tag":1143,"props":1237,"children":1239},{"style":1238},"--shiki-default:#81C8BE;--shiki-dark:#F97583",[1240],{"type":38,"value":1241},":",{"type":29,"tag":1143,"props":1243,"children":1244},{"style":1192},[1245],{"type":38,"value":1246}," ISlotHoldRepository",{"type":29,"tag":1143,"props":1248,"children":1249},{"style":1198},[1250],{"type":38,"value":1251},",\n",{"type":29,"tag":1143,"props":1253,"children":1255},{"class":1145,"line":1254},6,[1256,1260,1264,1269,1273,1278],{"type":29,"tag":1143,"props":1257,"children":1258},{"style":1181},[1259],{"type":38,"value":1224},{"type":29,"tag":1143,"props":1261,"children":1262},{"style":1181},[1263],{"type":38,"value":1229},{"type":29,"tag":1143,"props":1265,"children":1266},{"style":1232},[1267],{"type":38,"value":1268}," offerRepository",{"type":29,"tag":1143,"props":1270,"children":1271},{"style":1238},[1272],{"type":38,"value":1241},{"type":29,"tag":1143,"props":1274,"children":1275},{"style":1192},[1276],{"type":38,"value":1277}," IOfferRepository",{"type":29,"tag":1143,"props":1279,"children":1280},{"style":1198},[1281],{"type":38,"value":1251},{"type":29,"tag":1143,"props":1283,"children":1285},{"class":1145,"line":1284},7,[1286,1291],{"type":29,"tag":1143,"props":1287,"children":1288},{"style":1198},[1289],{"type":38,"value":1290},"  )",{"type":29,"tag":1143,"props":1292,"children":1293},{"style":1198},[1294],{"type":38,"value":1295}," {}\n",{"type":29,"tag":1143,"props":1297,"children":1299},{"class":1145,"line":1298},8,[1300],{"type":29,"tag":1143,"props":1301,"children":1302},{"emptyLinePlaceholder":13},[1303],{"type":38,"value":1304},"\n",{"type":29,"tag":1143,"props":1306,"children":1308},{"class":1145,"line":1307},9,[1309,1314,1319,1324,1329,1333,1338,1343,1347,1352,1358,1363,1368],{"type":29,"tag":1143,"props":1310,"children":1311},{"style":1181},[1312],{"type":38,"value":1313},"  async",{"type":29,"tag":1143,"props":1315,"children":1316},{"style":1165},[1317],{"type":38,"value":1318}," execute",{"type":29,"tag":1143,"props":1320,"children":1321},{"style":1198},[1322],{"type":38,"value":1323},"(",{"type":29,"tag":1143,"props":1325,"children":1326},{"style":1232},[1327],{"type":38,"value":1328},"command",{"type":29,"tag":1143,"props":1330,"children":1331},{"style":1238},[1332],{"type":38,"value":1241},{"type":29,"tag":1143,"props":1334,"children":1335},{"style":1192},[1336],{"type":38,"value":1337}," CreateSlotHoldCommand",{"type":29,"tag":1143,"props":1339,"children":1340},{"style":1198},[1341],{"type":38,"value":1342},")",{"type":29,"tag":1143,"props":1344,"children":1345},{"style":1238},[1346],{"type":38,"value":1241},{"type":29,"tag":1143,"props":1348,"children":1349},{"style":1192},[1350],{"type":38,"value":1351}," Promise",{"type":29,"tag":1143,"props":1353,"children":1355},{"style":1354},"--shiki-default:#99D1DB;--shiki-dark:#E1E4E8",[1356],{"type":38,"value":1357},"\u003C",{"type":29,"tag":1143,"props":1359,"children":1360},{"style":1192},[1361],{"type":38,"value":1362},"SlotHold",{"type":29,"tag":1143,"props":1364,"children":1365},{"style":1354},[1366],{"type":38,"value":1367},">",{"type":29,"tag":1143,"props":1369,"children":1370},{"style":1198},[1371],{"type":38,"value":1201},{"type":29,"tag":1143,"props":1373,"children":1375},{"class":1145,"line":1374},10,[1376,1381,1387,1392,1397,1403,1408,1414,1418,1423,1428,1432,1437],{"type":29,"tag":1143,"props":1377,"children":1378},{"style":1181},[1379],{"type":38,"value":1380},"    const",{"type":29,"tag":1143,"props":1382,"children":1384},{"style":1383},"--shiki-default:#C6D0F5;--shiki-dark:#79B8FF",[1385],{"type":38,"value":1386}," offer",{"type":29,"tag":1143,"props":1388,"children":1389},{"style":1238},[1390],{"type":38,"value":1391}," =",{"type":29,"tag":1143,"props":1393,"children":1394},{"style":1181},[1395],{"type":38,"value":1396}," await",{"type":29,"tag":1143,"props":1398,"children":1400},{"style":1399},"--shiki-default:#E78284;--shiki-dark:#79B8FF",[1401],{"type":38,"value":1402}," this",{"type":29,"tag":1143,"props":1404,"children":1406},{"style":1405},"--shiki-default:#81C8BE;--shiki-dark:#E1E4E8",[1407],{"type":38,"value":204},{"type":29,"tag":1143,"props":1409,"children":1411},{"style":1410},"--shiki-default:#C6D0F5;--shiki-dark:#E1E4E8",[1412],{"type":38,"value":1413},"offerRepository",{"type":29,"tag":1143,"props":1415,"children":1416},{"style":1405},[1417],{"type":38,"value":204},{"type":29,"tag":1143,"props":1419,"children":1420},{"style":1165},[1421],{"type":38,"value":1422},"findById",{"type":29,"tag":1143,"props":1424,"children":1425},{"style":1410},[1426],{"type":38,"value":1427},"(command",{"type":29,"tag":1143,"props":1429,"children":1430},{"style":1405},[1431],{"type":38,"value":204},{"type":29,"tag":1143,"props":1433,"children":1434},{"style":1410},[1435],{"type":38,"value":1436},"offerId)",{"type":29,"tag":1143,"props":1438,"children":1439},{"style":1198},[1440],{"type":38,"value":1441},";\n",{"type":29,"tag":1143,"props":1443,"children":1445},{"class":1145,"line":1444},11,[1446,1451,1456,1461,1466,1471,1477,1482,1486,1490,1494],{"type":29,"tag":1143,"props":1447,"children":1448},{"style":1181},[1449],{"type":38,"value":1450},"    if",{"type":29,"tag":1143,"props":1452,"children":1453},{"style":1410},[1454],{"type":38,"value":1455}," (",{"type":29,"tag":1143,"props":1457,"children":1458},{"style":1238},[1459],{"type":38,"value":1460},"!",{"type":29,"tag":1143,"props":1462,"children":1463},{"style":1410},[1464],{"type":38,"value":1465},"offer) ",{"type":29,"tag":1143,"props":1467,"children":1468},{"style":1181},[1469],{"type":38,"value":1470},"throw",{"type":29,"tag":1143,"props":1472,"children":1474},{"style":1473},"--shiki-default:#CA9EE6;--shiki-default-font-weight:bold;--shiki-dark:#F97583;--shiki-dark-font-weight:inherit",[1475],{"type":38,"value":1476}," new",{"type":29,"tag":1143,"props":1478,"children":1479},{"style":1165},[1480],{"type":38,"value":1481}," OfferNotFoundException",{"type":29,"tag":1143,"props":1483,"children":1484},{"style":1410},[1485],{"type":38,"value":1427},{"type":29,"tag":1143,"props":1487,"children":1488},{"style":1405},[1489],{"type":38,"value":204},{"type":29,"tag":1143,"props":1491,"children":1492},{"style":1410},[1493],{"type":38,"value":1436},{"type":29,"tag":1143,"props":1495,"children":1496},{"style":1198},[1497],{"type":38,"value":1441},{"type":29,"tag":1143,"props":1499,"children":1501},{"class":1145,"line":1500},12,[1502,1506,1511,1515,1520,1525,1530,1534],{"type":29,"tag":1143,"props":1503,"children":1504},{"style":1181},[1505],{"type":38,"value":1450},{"type":29,"tag":1143,"props":1507,"children":1508},{"style":1410},[1509],{"type":38,"value":1510}," (offer",{"type":29,"tag":1143,"props":1512,"children":1513},{"style":1405},[1514],{"type":38,"value":204},{"type":29,"tag":1143,"props":1516,"children":1517},{"style":1410},[1518],{"type":38,"value":1519},"userId ",{"type":29,"tag":1143,"props":1521,"children":1522},{"style":1238},[1523],{"type":38,"value":1524},"!==",{"type":29,"tag":1143,"props":1526,"children":1527},{"style":1410},[1528],{"type":38,"value":1529}," command",{"type":29,"tag":1143,"props":1531,"children":1532},{"style":1405},[1533],{"type":38,"value":204},{"type":29,"tag":1143,"props":1535,"children":1536},{"style":1410},[1537],{"type":38,"value":1538},"userId)\n",{"type":29,"tag":1143,"props":1540,"children":1542},{"class":1145,"line":1541},13,[1543,1548,1552,1557,1562],{"type":29,"tag":1143,"props":1544,"children":1545},{"style":1181},[1546],{"type":38,"value":1547},"      throw",{"type":29,"tag":1143,"props":1549,"children":1550},{"style":1473},[1551],{"type":38,"value":1476},{"type":29,"tag":1143,"props":1553,"children":1554},{"style":1165},[1555],{"type":38,"value":1556}," UnauthorizedSlotHoldException",{"type":29,"tag":1143,"props":1558,"children":1559},{"style":1410},[1560],{"type":38,"value":1561},"()",{"type":29,"tag":1143,"props":1563,"children":1564},{"style":1198},[1565],{"type":38,"value":1441},{"type":29,"tag":1143,"props":1567,"children":1569},{"class":1145,"line":1568},14,[1570,1575,1579,1583,1588,1592,1597,1601],{"type":29,"tag":1143,"props":1571,"children":1572},{"style":1181},[1573],{"type":38,"value":1574},"    return",{"type":29,"tag":1143,"props":1576,"children":1577},{"style":1399},[1578],{"type":38,"value":1402},{"type":29,"tag":1143,"props":1580,"children":1581},{"style":1405},[1582],{"type":38,"value":204},{"type":29,"tag":1143,"props":1584,"children":1585},{"style":1410},[1586],{"type":38,"value":1587},"slotHoldRepository",{"type":29,"tag":1143,"props":1589,"children":1590},{"style":1405},[1591],{"type":38,"value":204},{"type":29,"tag":1143,"props":1593,"children":1594},{"style":1165},[1595],{"type":38,"value":1596},"create",{"type":29,"tag":1143,"props":1598,"children":1599},{"style":1410},[1600],{"type":38,"value":1323},{"type":29,"tag":1143,"props":1602,"children":1603},{"style":1198},[1604],{"type":38,"value":1605},"{\n",{"type":29,"tag":1143,"props":1607,"children":1609},{"class":1145,"line":1608},15,[1610,1615,1619,1623,1627,1632],{"type":29,"tag":1143,"props":1611,"children":1612},{"style":1410},[1613],{"type":38,"value":1614},"      offerId",{"type":29,"tag":1143,"props":1616,"children":1617},{"style":1405},[1618],{"type":38,"value":1241},{"type":29,"tag":1143,"props":1620,"children":1621},{"style":1410},[1622],{"type":38,"value":1529},{"type":29,"tag":1143,"props":1624,"children":1625},{"style":1405},[1626],{"type":38,"value":204},{"type":29,"tag":1143,"props":1628,"children":1629},{"style":1410},[1630],{"type":38,"value":1631},"offerId",{"type":29,"tag":1143,"props":1633,"children":1634},{"style":1198},[1635],{"type":38,"value":1251},{"type":29,"tag":1143,"props":1637,"children":1639},{"class":1145,"line":1638},16,[1640,1645,1649,1653,1657,1662],{"type":29,"tag":1143,"props":1641,"children":1642},{"style":1410},[1643],{"type":38,"value":1644},"      userId",{"type":29,"tag":1143,"props":1646,"children":1647},{"style":1405},[1648],{"type":38,"value":1241},{"type":29,"tag":1143,"props":1650,"children":1651},{"style":1410},[1652],{"type":38,"value":1529},{"type":29,"tag":1143,"props":1654,"children":1655},{"style":1405},[1656],{"type":38,"value":204},{"type":29,"tag":1143,"props":1658,"children":1659},{"style":1410},[1660],{"type":38,"value":1661},"userId",{"type":29,"tag":1143,"props":1663,"children":1664},{"style":1198},[1665],{"type":38,"value":1251},{"type":29,"tag":1143,"props":1667,"children":1669},{"class":1145,"line":1668},17,[1670,1675,1679,1683,1688,1693,1697,1702,1707,1712,1718,1723,1728,1732,1737,1741],{"type":29,"tag":1143,"props":1671,"children":1672},{"style":1410},[1673],{"type":38,"value":1674},"      expiresAt",{"type":29,"tag":1143,"props":1676,"children":1677},{"style":1405},[1678],{"type":38,"value":1241},{"type":29,"tag":1143,"props":1680,"children":1681},{"style":1473},[1682],{"type":38,"value":1476},{"type":29,"tag":1143,"props":1684,"children":1685},{"style":1165},[1686],{"type":38,"value":1687}," Date",{"type":29,"tag":1143,"props":1689,"children":1690},{"style":1410},[1691],{"type":38,"value":1692},"(Date",{"type":29,"tag":1143,"props":1694,"children":1695},{"style":1405},[1696],{"type":38,"value":204},{"type":29,"tag":1143,"props":1698,"children":1699},{"style":1165},[1700],{"type":38,"value":1701},"now",{"type":29,"tag":1143,"props":1703,"children":1704},{"style":1410},[1705],{"type":38,"value":1706},"() ",{"type":29,"tag":1143,"props":1708,"children":1709},{"style":1238},[1710],{"type":38,"value":1711},"+",{"type":29,"tag":1143,"props":1713,"children":1715},{"style":1714},"--shiki-default:#EF9F76;--shiki-dark:#79B8FF",[1716],{"type":38,"value":1717}," 15",{"type":29,"tag":1143,"props":1719,"children":1720},{"style":1238},[1721],{"type":38,"value":1722}," *",{"type":29,"tag":1143,"props":1724,"children":1725},{"style":1714},[1726],{"type":38,"value":1727}," 60",{"type":29,"tag":1143,"props":1729,"children":1730},{"style":1238},[1731],{"type":38,"value":1722},{"type":29,"tag":1143,"props":1733,"children":1734},{"style":1714},[1735],{"type":38,"value":1736}," 1000",{"type":29,"tag":1143,"props":1738,"children":1739},{"style":1410},[1740],{"type":38,"value":1342},{"type":29,"tag":1143,"props":1742,"children":1743},{"style":1198},[1744],{"type":38,"value":1251},{"type":29,"tag":1143,"props":1746,"children":1748},{"class":1145,"line":1747},18,[1749,1754,1758],{"type":29,"tag":1143,"props":1750,"children":1751},{"style":1198},[1752],{"type":38,"value":1753},"    }",{"type":29,"tag":1143,"props":1755,"children":1756},{"style":1410},[1757],{"type":38,"value":1342},{"type":29,"tag":1143,"props":1759,"children":1760},{"style":1198},[1761],{"type":38,"value":1441},{"type":29,"tag":1143,"props":1763,"children":1765},{"class":1145,"line":1764},19,[1766],{"type":29,"tag":1143,"props":1767,"children":1768},{"style":1198},[1769],{"type":38,"value":1770},"  }\n",{"type":29,"tag":1143,"props":1772,"children":1774},{"class":1145,"line":1773},20,[1775],{"type":29,"tag":1143,"props":1776,"children":1777},{"style":1198},[1778],{"type":38,"value":1779},"}\n",{"type":29,"tag":1143,"props":1781,"children":1783},{"class":1145,"line":1782},21,[1784],{"type":29,"tag":1143,"props":1785,"children":1786},{"emptyLinePlaceholder":13},[1787],{"type":38,"value":1304},{"type":29,"tag":1143,"props":1789,"children":1791},{"class":1145,"line":1790},22,[1792],{"type":29,"tag":1143,"props":1793,"children":1794},{"style":1150},[1795],{"type":38,"value":1796},"\u002F\u002F Après génération par Claude\n",{"type":29,"tag":1143,"props":1798,"children":1800},{"class":1145,"line":1799},23,[1801],{"type":29,"tag":1143,"props":1802,"children":1803},{"style":1150},[1804],{"type":38,"value":1805},"\u002F**\n",{"type":29,"tag":1143,"props":1807,"children":1809},{"class":1145,"line":1808},24,[1810],{"type":29,"tag":1143,"props":1811,"children":1812},{"style":1150},[1813],{"type":38,"value":1814}," * Use case : réserver temporairement un slot d'offre pour un utilisateur.\n",{"type":29,"tag":1143,"props":1816,"children":1818},{"class":1145,"line":1817},25,[1819],{"type":29,"tag":1143,"props":1820,"children":1821},{"style":1150},[1822],{"type":38,"value":1823}," *\n",{"type":29,"tag":1143,"props":1825,"children":1827},{"class":1145,"line":1826},26,[1828],{"type":29,"tag":1143,"props":1829,"children":1830},{"style":1150},[1831],{"type":38,"value":1832}," * Vérifie que l'offre existe et appartient bien à l'utilisateur demandeur,\n",{"type":29,"tag":1143,"props":1834,"children":1836},{"class":1145,"line":1835},27,[1837],{"type":29,"tag":1143,"props":1838,"children":1839},{"style":1150},[1840],{"type":38,"value":1841}," * puis crée un slot-hold avec une expiration de 15 minutes.\n",{"type":29,"tag":1143,"props":1843,"children":1844},{"class":1145,"line":976},[1845],{"type":29,"tag":1143,"props":1846,"children":1847},{"style":1150},[1848],{"type":38,"value":1849}," * Ce hold est libéré automatiquement si le paiement n'aboutit pas.\n",{"type":29,"tag":1143,"props":1851,"children":1853},{"class":1145,"line":1852},29,[1854],{"type":29,"tag":1143,"props":1855,"children":1856},{"style":1150},[1857],{"type":38,"value":1823},{"type":29,"tag":1143,"props":1859,"children":1861},{"class":1145,"line":1860},30,[1862,1867,1872,1877,1883,1888,1893],{"type":29,"tag":1143,"props":1863,"children":1864},{"style":1150},[1865],{"type":38,"value":1866}," * ",{"type":29,"tag":1143,"props":1868,"children":1870},{"style":1869},"--shiki-default:#949CBB;--shiki-dark:#F97583",[1871],{"type":38,"value":1162},{"type":29,"tag":1143,"props":1873,"children":1874},{"style":1181},[1875],{"type":38,"value":1876},"throws",{"type":29,"tag":1143,"props":1878,"children":1880},{"style":1879},"--shiki-default:#949CBB;--shiki-dark:#B392F0",[1881],{"type":38,"value":1882}," {",{"type":29,"tag":1143,"props":1884,"children":1885},{"style":1192},[1886],{"type":38,"value":1887},"OfferNotFoundException",{"type":29,"tag":1143,"props":1889,"children":1890},{"style":1879},[1891],{"type":38,"value":1892},"}",{"type":29,"tag":1143,"props":1894,"children":1895},{"style":1150},[1896],{"type":38,"value":1897}," si l'offre n'existe pas en base\n",{"type":29,"tag":1143,"props":1899,"children":1901},{"class":1145,"line":1900},31,[1902,1906,1910,1914,1918,1923,1927],{"type":29,"tag":1143,"props":1903,"children":1904},{"style":1150},[1905],{"type":38,"value":1866},{"type":29,"tag":1143,"props":1907,"children":1908},{"style":1869},[1909],{"type":38,"value":1162},{"type":29,"tag":1143,"props":1911,"children":1912},{"style":1181},[1913],{"type":38,"value":1876},{"type":29,"tag":1143,"props":1915,"children":1916},{"style":1879},[1917],{"type":38,"value":1882},{"type":29,"tag":1143,"props":1919,"children":1920},{"style":1192},[1921],{"type":38,"value":1922},"UnauthorizedSlotHoldException",{"type":29,"tag":1143,"props":1924,"children":1925},{"style":1879},[1926],{"type":38,"value":1892},{"type":29,"tag":1143,"props":1928,"children":1929},{"style":1150},[1930],{"type":38,"value":1931}," si l'offre appartient à un autre userId\n",{"type":29,"tag":1143,"props":1933,"children":1935},{"class":1145,"line":1934},32,[1936],{"type":29,"tag":1143,"props":1937,"children":1938},{"style":1150},[1939],{"type":38,"value":1940}," *\u002F\n",{"type":29,"tag":1143,"props":1942,"children":1944},{"class":1145,"line":1943},33,[1945,1949,1953],{"type":29,"tag":1143,"props":1946,"children":1947},{"style":1159},[1948],{"type":38,"value":1162},{"type":29,"tag":1143,"props":1950,"children":1951},{"style":1165},[1952],{"type":38,"value":1168},{"type":29,"tag":1143,"props":1954,"children":1955},{"style":1171},[1956],{"type":38,"value":1174},{"type":29,"tag":1143,"props":1958,"children":1960},{"class":1145,"line":1959},34,[1961,1965,1969,1973],{"type":29,"tag":1143,"props":1962,"children":1963},{"style":1181},[1964],{"type":38,"value":1184},{"type":29,"tag":1143,"props":1966,"children":1967},{"style":1181},[1968],{"type":38,"value":1189},{"type":29,"tag":1143,"props":1970,"children":1971},{"style":1192},[1972],{"type":38,"value":1195},{"type":29,"tag":1143,"props":1974,"children":1975},{"style":1198},[1976],{"type":38,"value":1201},{"type":29,"tag":1143,"props":1978,"children":1980},{"class":1145,"line":1979},35,[1981,1985],{"type":29,"tag":1143,"props":1982,"children":1983},{"style":1181},[1984],{"type":38,"value":1210},{"type":29,"tag":1143,"props":1986,"children":1987},{"style":1198},[1988],{"type":38,"value":1215},{"type":29,"tag":1143,"props":1990,"children":1992},{"class":1145,"line":1991},36,[1993,1997,2001,2005,2009,2013],{"type":29,"tag":1143,"props":1994,"children":1995},{"style":1181},[1996],{"type":38,"value":1224},{"type":29,"tag":1143,"props":1998,"children":1999},{"style":1181},[2000],{"type":38,"value":1229},{"type":29,"tag":1143,"props":2002,"children":2003},{"style":1232},[2004],{"type":38,"value":1235},{"type":29,"tag":1143,"props":2006,"children":2007},{"style":1238},[2008],{"type":38,"value":1241},{"type":29,"tag":1143,"props":2010,"children":2011},{"style":1192},[2012],{"type":38,"value":1246},{"type":29,"tag":1143,"props":2014,"children":2015},{"style":1198},[2016],{"type":38,"value":1251},{"type":29,"tag":1143,"props":2018,"children":2020},{"class":1145,"line":2019},37,[2021,2025,2029,2033,2037,2041],{"type":29,"tag":1143,"props":2022,"children":2023},{"style":1181},[2024],{"type":38,"value":1224},{"type":29,"tag":1143,"props":2026,"children":2027},{"style":1181},[2028],{"type":38,"value":1229},{"type":29,"tag":1143,"props":2030,"children":2031},{"style":1232},[2032],{"type":38,"value":1268},{"type":29,"tag":1143,"props":2034,"children":2035},{"style":1238},[2036],{"type":38,"value":1241},{"type":29,"tag":1143,"props":2038,"children":2039},{"style":1192},[2040],{"type":38,"value":1277},{"type":29,"tag":1143,"props":2042,"children":2043},{"style":1198},[2044],{"type":38,"value":1251},{"type":29,"tag":1143,"props":2046,"children":2048},{"class":1145,"line":2047},38,[2049,2053],{"type":29,"tag":1143,"props":2050,"children":2051},{"style":1198},[2052],{"type":38,"value":1290},{"type":29,"tag":1143,"props":2054,"children":2055},{"style":1198},[2056],{"type":38,"value":1295},{"type":29,"tag":1143,"props":2058,"children":2060},{"class":1145,"line":2059},39,[2061],{"type":29,"tag":1143,"props":2062,"children":2063},{"emptyLinePlaceholder":13},[2064],{"type":38,"value":1304},{"type":29,"tag":1143,"props":2066,"children":2068},{"class":1145,"line":2067},40,[2069],{"type":29,"tag":1143,"props":2070,"children":2071},{"style":1150},[2072],{"type":38,"value":2073},"  \u002F**\n",{"type":29,"tag":1143,"props":2075,"children":2077},{"class":1145,"line":2076},41,[2078],{"type":29,"tag":1143,"props":2079,"children":2080},{"style":1150},[2081],{"type":38,"value":2082},"   * Exécute la réservation temporaire du slot.\n",{"type":29,"tag":1143,"props":2084,"children":2086},{"class":1145,"line":2085},42,[2087],{"type":29,"tag":1143,"props":2088,"children":2089},{"style":1150},[2090],{"type":38,"value":2091},"   *\n",{"type":29,"tag":1143,"props":2093,"children":2095},{"class":1145,"line":2094},43,[2096,2101,2105,2110,2115],{"type":29,"tag":1143,"props":2097,"children":2098},{"style":1150},[2099],{"type":38,"value":2100},"   * ",{"type":29,"tag":1143,"props":2102,"children":2103},{"style":1869},[2104],{"type":38,"value":1162},{"type":29,"tag":1143,"props":2106,"children":2107},{"style":1181},[2108],{"type":38,"value":2109},"param",{"type":29,"tag":1143,"props":2111,"children":2113},{"style":2112},"--shiki-default:#EA999C;--shiki-dark:#E1E4E8",[2114],{"type":38,"value":1529},{"type":29,"tag":1143,"props":2116,"children":2117},{"style":1150},[2118],{"type":38,"value":2119}," - Commande contenant `offerId` et `userId`\n",{"type":29,"tag":1143,"props":2121,"children":2123},{"class":1145,"line":2122},44,[2124,2128,2132,2137],{"type":29,"tag":1143,"props":2125,"children":2126},{"style":1150},[2127],{"type":38,"value":2100},{"type":29,"tag":1143,"props":2129,"children":2130},{"style":1869},[2131],{"type":38,"value":1162},{"type":29,"tag":1143,"props":2133,"children":2134},{"style":1181},[2135],{"type":38,"value":2136},"returns",{"type":29,"tag":1143,"props":2138,"children":2139},{"style":1150},[2140],{"type":38,"value":2141}," Le slot-hold créé avec sa date d'expiration\n",{"type":29,"tag":1143,"props":2143,"children":2145},{"class":1145,"line":2144},45,[2146],{"type":29,"tag":1143,"props":2147,"children":2148},{"style":1150},[2149],{"type":38,"value":2150},"   *\u002F\n",{"type":29,"tag":1143,"props":2152,"children":2154},{"class":1145,"line":2153},46,[2155,2159,2163,2167,2171,2175,2179,2183,2187,2191,2195,2199,2203],{"type":29,"tag":1143,"props":2156,"children":2157},{"style":1181},[2158],{"type":38,"value":1313},{"type":29,"tag":1143,"props":2160,"children":2161},{"style":1165},[2162],{"type":38,"value":1318},{"type":29,"tag":1143,"props":2164,"children":2165},{"style":1198},[2166],{"type":38,"value":1323},{"type":29,"tag":1143,"props":2168,"children":2169},{"style":1232},[2170],{"type":38,"value":1328},{"type":29,"tag":1143,"props":2172,"children":2173},{"style":1238},[2174],{"type":38,"value":1241},{"type":29,"tag":1143,"props":2176,"children":2177},{"style":1192},[2178],{"type":38,"value":1337},{"type":29,"tag":1143,"props":2180,"children":2181},{"style":1198},[2182],{"type":38,"value":1342},{"type":29,"tag":1143,"props":2184,"children":2185},{"style":1238},[2186],{"type":38,"value":1241},{"type":29,"tag":1143,"props":2188,"children":2189},{"style":1192},[2190],{"type":38,"value":1351},{"type":29,"tag":1143,"props":2192,"children":2193},{"style":1354},[2194],{"type":38,"value":1357},{"type":29,"tag":1143,"props":2196,"children":2197},{"style":1192},[2198],{"type":38,"value":1362},{"type":29,"tag":1143,"props":2200,"children":2201},{"style":1354},[2202],{"type":38,"value":1367},{"type":29,"tag":1143,"props":2204,"children":2205},{"style":1198},[2206],{"type":38,"value":1201},{"type":29,"tag":1143,"props":2208,"children":2210},{"class":1145,"line":2209},47,[2211,2215,2219,2223,2227,2231,2235,2239,2243,2247,2251,2255,2259],{"type":29,"tag":1143,"props":2212,"children":2213},{"style":1181},[2214],{"type":38,"value":1380},{"type":29,"tag":1143,"props":2216,"children":2217},{"style":1383},[2218],{"type":38,"value":1386},{"type":29,"tag":1143,"props":2220,"children":2221},{"style":1238},[2222],{"type":38,"value":1391},{"type":29,"tag":1143,"props":2224,"children":2225},{"style":1181},[2226],{"type":38,"value":1396},{"type":29,"tag":1143,"props":2228,"children":2229},{"style":1399},[2230],{"type":38,"value":1402},{"type":29,"tag":1143,"props":2232,"children":2233},{"style":1405},[2234],{"type":38,"value":204},{"type":29,"tag":1143,"props":2236,"children":2237},{"style":1410},[2238],{"type":38,"value":1413},{"type":29,"tag":1143,"props":2240,"children":2241},{"style":1405},[2242],{"type":38,"value":204},{"type":29,"tag":1143,"props":2244,"children":2245},{"style":1165},[2246],{"type":38,"value":1422},{"type":29,"tag":1143,"props":2248,"children":2249},{"style":1410},[2250],{"type":38,"value":1427},{"type":29,"tag":1143,"props":2252,"children":2253},{"style":1405},[2254],{"type":38,"value":204},{"type":29,"tag":1143,"props":2256,"children":2257},{"style":1410},[2258],{"type":38,"value":1436},{"type":29,"tag":1143,"props":2260,"children":2261},{"style":1198},[2262],{"type":38,"value":1441},{"type":29,"tag":1143,"props":2264,"children":2266},{"class":1145,"line":2265},48,[2267,2271,2275,2279,2283,2287,2291,2295,2299,2303,2307],{"type":29,"tag":1143,"props":2268,"children":2269},{"style":1181},[2270],{"type":38,"value":1450},{"type":29,"tag":1143,"props":2272,"children":2273},{"style":1410},[2274],{"type":38,"value":1455},{"type":29,"tag":1143,"props":2276,"children":2277},{"style":1238},[2278],{"type":38,"value":1460},{"type":29,"tag":1143,"props":2280,"children":2281},{"style":1410},[2282],{"type":38,"value":1465},{"type":29,"tag":1143,"props":2284,"children":2285},{"style":1181},[2286],{"type":38,"value":1470},{"type":29,"tag":1143,"props":2288,"children":2289},{"style":1473},[2290],{"type":38,"value":1476},{"type":29,"tag":1143,"props":2292,"children":2293},{"style":1165},[2294],{"type":38,"value":1481},{"type":29,"tag":1143,"props":2296,"children":2297},{"style":1410},[2298],{"type":38,"value":1427},{"type":29,"tag":1143,"props":2300,"children":2301},{"style":1405},[2302],{"type":38,"value":204},{"type":29,"tag":1143,"props":2304,"children":2305},{"style":1410},[2306],{"type":38,"value":1436},{"type":29,"tag":1143,"props":2308,"children":2309},{"style":1198},[2310],{"type":38,"value":1441},{"type":29,"tag":1143,"props":2312,"children":2314},{"class":1145,"line":2313},49,[2315,2319,2323,2327,2331,2335,2339,2343],{"type":29,"tag":1143,"props":2316,"children":2317},{"style":1181},[2318],{"type":38,"value":1450},{"type":29,"tag":1143,"props":2320,"children":2321},{"style":1410},[2322],{"type":38,"value":1510},{"type":29,"tag":1143,"props":2324,"children":2325},{"style":1405},[2326],{"type":38,"value":204},{"type":29,"tag":1143,"props":2328,"children":2329},{"style":1410},[2330],{"type":38,"value":1519},{"type":29,"tag":1143,"props":2332,"children":2333},{"style":1238},[2334],{"type":38,"value":1524},{"type":29,"tag":1143,"props":2336,"children":2337},{"style":1410},[2338],{"type":38,"value":1529},{"type":29,"tag":1143,"props":2340,"children":2341},{"style":1405},[2342],{"type":38,"value":204},{"type":29,"tag":1143,"props":2344,"children":2345},{"style":1410},[2346],{"type":38,"value":1538},{"type":29,"tag":1143,"props":2348,"children":2350},{"class":1145,"line":2349},50,[2351,2355,2359,2363,2367],{"type":29,"tag":1143,"props":2352,"children":2353},{"style":1181},[2354],{"type":38,"value":1547},{"type":29,"tag":1143,"props":2356,"children":2357},{"style":1473},[2358],{"type":38,"value":1476},{"type":29,"tag":1143,"props":2360,"children":2361},{"style":1165},[2362],{"type":38,"value":1556},{"type":29,"tag":1143,"props":2364,"children":2365},{"style":1410},[2366],{"type":38,"value":1561},{"type":29,"tag":1143,"props":2368,"children":2369},{"style":1198},[2370],{"type":38,"value":1441},{"type":29,"tag":1143,"props":2372,"children":2374},{"class":1145,"line":2373},51,[2375,2379,2383,2387,2391,2395,2399,2403],{"type":29,"tag":1143,"props":2376,"children":2377},{"style":1181},[2378],{"type":38,"value":1574},{"type":29,"tag":1143,"props":2380,"children":2381},{"style":1399},[2382],{"type":38,"value":1402},{"type":29,"tag":1143,"props":2384,"children":2385},{"style":1405},[2386],{"type":38,"value":204},{"type":29,"tag":1143,"props":2388,"children":2389},{"style":1410},[2390],{"type":38,"value":1587},{"type":29,"tag":1143,"props":2392,"children":2393},{"style":1405},[2394],{"type":38,"value":204},{"type":29,"tag":1143,"props":2396,"children":2397},{"style":1165},[2398],{"type":38,"value":1596},{"type":29,"tag":1143,"props":2400,"children":2401},{"style":1410},[2402],{"type":38,"value":1323},{"type":29,"tag":1143,"props":2404,"children":2405},{"style":1198},[2406],{"type":38,"value":1605},{"type":29,"tag":1143,"props":2408,"children":2410},{"class":1145,"line":2409},52,[2411,2415,2419,2423,2427,2431],{"type":29,"tag":1143,"props":2412,"children":2413},{"style":1410},[2414],{"type":38,"value":1614},{"type":29,"tag":1143,"props":2416,"children":2417},{"style":1405},[2418],{"type":38,"value":1241},{"type":29,"tag":1143,"props":2420,"children":2421},{"style":1410},[2422],{"type":38,"value":1529},{"type":29,"tag":1143,"props":2424,"children":2425},{"style":1405},[2426],{"type":38,"value":204},{"type":29,"tag":1143,"props":2428,"children":2429},{"style":1410},[2430],{"type":38,"value":1631},{"type":29,"tag":1143,"props":2432,"children":2433},{"style":1198},[2434],{"type":38,"value":1251},{"type":29,"tag":1143,"props":2436,"children":2438},{"class":1145,"line":2437},53,[2439,2443,2447,2451,2455,2459],{"type":29,"tag":1143,"props":2440,"children":2441},{"style":1410},[2442],{"type":38,"value":1644},{"type":29,"tag":1143,"props":2444,"children":2445},{"style":1405},[2446],{"type":38,"value":1241},{"type":29,"tag":1143,"props":2448,"children":2449},{"style":1410},[2450],{"type":38,"value":1529},{"type":29,"tag":1143,"props":2452,"children":2453},{"style":1405},[2454],{"type":38,"value":204},{"type":29,"tag":1143,"props":2456,"children":2457},{"style":1410},[2458],{"type":38,"value":1661},{"type":29,"tag":1143,"props":2460,"children":2461},{"style":1198},[2462],{"type":38,"value":1251},{"type":29,"tag":1143,"props":2464,"children":2466},{"class":1145,"line":2465},54,[2467,2471,2475,2479,2483,2487,2491,2495,2499,2503,2507,2511,2515,2519,2523,2527],{"type":29,"tag":1143,"props":2468,"children":2469},{"style":1410},[2470],{"type":38,"value":1674},{"type":29,"tag":1143,"props":2472,"children":2473},{"style":1405},[2474],{"type":38,"value":1241},{"type":29,"tag":1143,"props":2476,"children":2477},{"style":1473},[2478],{"type":38,"value":1476},{"type":29,"tag":1143,"props":2480,"children":2481},{"style":1165},[2482],{"type":38,"value":1687},{"type":29,"tag":1143,"props":2484,"children":2485},{"style":1410},[2486],{"type":38,"value":1692},{"type":29,"tag":1143,"props":2488,"children":2489},{"style":1405},[2490],{"type":38,"value":204},{"type":29,"tag":1143,"props":2492,"children":2493},{"style":1165},[2494],{"type":38,"value":1701},{"type":29,"tag":1143,"props":2496,"children":2497},{"style":1410},[2498],{"type":38,"value":1706},{"type":29,"tag":1143,"props":2500,"children":2501},{"style":1238},[2502],{"type":38,"value":1711},{"type":29,"tag":1143,"props":2504,"children":2505},{"style":1714},[2506],{"type":38,"value":1717},{"type":29,"tag":1143,"props":2508,"children":2509},{"style":1238},[2510],{"type":38,"value":1722},{"type":29,"tag":1143,"props":2512,"children":2513},{"style":1714},[2514],{"type":38,"value":1727},{"type":29,"tag":1143,"props":2516,"children":2517},{"style":1238},[2518],{"type":38,"value":1722},{"type":29,"tag":1143,"props":2520,"children":2521},{"style":1714},[2522],{"type":38,"value":1736},{"type":29,"tag":1143,"props":2524,"children":2525},{"style":1410},[2526],{"type":38,"value":1342},{"type":29,"tag":1143,"props":2528,"children":2529},{"style":1198},[2530],{"type":38,"value":1251},{"type":29,"tag":1143,"props":2532,"children":2534},{"class":1145,"line":2533},55,[2535,2539,2543],{"type":29,"tag":1143,"props":2536,"children":2537},{"style":1198},[2538],{"type":38,"value":1753},{"type":29,"tag":1143,"props":2540,"children":2541},{"style":1410},[2542],{"type":38,"value":1342},{"type":29,"tag":1143,"props":2544,"children":2545},{"style":1198},[2546],{"type":38,"value":1441},{"type":29,"tag":1143,"props":2548,"children":2550},{"class":1145,"line":2549},56,[2551],{"type":29,"tag":1143,"props":2552,"children":2553},{"style":1198},[2554],{"type":38,"value":1770},{"type":29,"tag":1143,"props":2556,"children":2558},{"class":1145,"line":2557},57,[2559],{"type":29,"tag":1143,"props":2560,"children":2561},{"style":1198},[2562],{"type":38,"value":1779},{"type":29,"tag":30,"props":2564,"children":2565},{},[2566,2568,2574],{"type":38,"value":2567},"Limite importante : Claude génère des docstrings corrects sur la forme, mais peut se tromper sur la sémantique métier. Toujours réviser pour vérifier que la description correspond au comportement réel. La génération réduit le temps d'écriture de 80%, elle ne remplace pas la révision humaine. Voir comment intégrer l'",{"type":29,"tag":87,"props":2569,"children":2571},{"href":2570},"\u002Ffr\u002Fintelligence-artificielle\u002Fia-code-review-retour-experience",[2572],{"type":38,"value":2573},"IA dans la code review",{"type":38,"value":2575}," pour un workflow cohérent.",{"type":29,"tag":391,"props":2577,"children":2579},{"cta":393,"href":394,"title":2578,"type":396},"Vous voulez savoir où s'arrête l'IA et où votre jugement doit reprendre la main ?",[2580],{"type":29,"tag":30,"props":2581,"children":2582},{},[2583],{"type":38,"value":2584},"Distinguer le \"quoi\" que l'IA documente bien du \"pourquoi\" qu'elle invente, ça ne se lit pas, ça se travaille. En mentoring 1:1, je relis votre code et vos docstrings générés avec vous, et vous apprenez à repérer là où le modèle se trompe sur la sémantique métier. Vous montez en niveau sur ce que l'IA ne peut pas voir à votre place.",{"type":29,"tag":54,"props":2586,"children":2587},{},[],{"type":29,"tag":58,"props":2589,"children":2591},{"id":2590},"cas-dusage-3-readme-de-bounded-context-et-onboarding-roi-élevé",[2592],{"type":38,"value":2593},"Cas d'usage 3 : README de bounded context et onboarding (ROI élevé)",{"type":29,"tag":30,"props":2595,"children":2596},{},[2597,2601],{"type":29,"tag":34,"props":2598,"children":2599},{},[2600],{"type":38,"value":1063},{"type":38,"value":2602}," chaque bounded context d'un système hexagonal devrait avoir un README qui explique son rôle, ses use cases exposés, ses ports, et comment le tester. En pratique, ces READMEs sont absents ou obsolètes dès la deuxième itération.",{"type":29,"tag":30,"props":2604,"children":2605},{},[2606,2610],{"type":29,"tag":34,"props":2607,"children":2608},{},[2609],{"type":38,"value":1073},{"type":38,"value":2611}," à partir du code source (structure de dossiers, index de use cases, ports et adapters), Claude Code génère un README structuré.",{"type":29,"tag":30,"props":2613,"children":2614},{},[2615],{"type":38,"value":2616},"Prompt type :",{"type":29,"tag":1077,"props":2618,"children":2620},{"code":2619},"Voici la structure du bounded context \"mentoring\" de mon API NestJS hexagonale :\n- les fichiers de domain\u002F (entités, value objects, ports)\n- les fichiers d'application\u002F (use cases)\n- le module NestJS racine\n\nGénère un README.md complet incluant :\n- Rôle du bounded context et responsabilité métier\n- Liste des use cases exposés avec leur commande\u002Fquery d'entrée\n- Ports principaux (interfaces repository, services externes)\n- Variables d'environnement spécifiques à ce contexte\n- Comment lancer les tests unitaires et d'intégration de ce module\n",[2621],{"type":29,"tag":261,"props":2622,"children":2623},{"__ignoreMap":8},[2624],{"type":38,"value":2619},{"type":29,"tag":30,"props":2626,"children":2627},{},[2628,2633],{"type":29,"tag":34,"props":2629,"children":2630},{},[2631],{"type":38,"value":2632},"Ce que j'ajoute manuellement :",{"type":38,"value":2634}," les décisions d'architecture propres au contexte (pourquoi ce bounded context est isolé, quelles contraintes de données sont imposées par le métier), les dépendances avec les autres contextes (ex : mentoring dépend de slot-hold via un port explicite).",{"type":29,"tag":30,"props":2636,"children":2637},{},[2638,2643],{"type":29,"tag":34,"props":2639,"children":2640},{},[2641],{"type":38,"value":2642},"Gain pour la reprise de contexte :",{"type":38,"value":2644}," avec des READMEs à jour, reprendre un bounded context non touché depuis 3 semaines prend 10 minutes au lieu de 45.",{"type":29,"tag":54,"props":2646,"children":2647},{},[],{"type":29,"tag":58,"props":2649,"children":2651},{"id":2650},"cas-dusage-4-résumés-de-pr-et-commit-messages-roi-élevé",[2652],{"type":38,"value":2653},"Cas d'usage 4 : Résumés de PR et commit messages (ROI élevé)",{"type":29,"tag":30,"props":2655,"children":2656},{},[2657,2661],{"type":29,"tag":34,"props":2658,"children":2659},{},[2660],{"type":38,"value":1063},{"type":38,"value":2662}," les commit messages et descriptions de PR sont soit vides (\"fix bug\", \"update\"), soit trop longs pour être lus. L'historique git devient inutilisable comme journal de bord du projet.",{"type":29,"tag":30,"props":2664,"children":2665},{},[2666,2670],{"type":29,"tag":34,"props":2667,"children":2668},{},[2669],{"type":38,"value":1073},{"type":38,"value":2671}," à partir du diff d'une PR, Claude génère un résumé structuré (ce qui a changé, pourquoi, les impacts potentiels, le plan de test).",{"type":29,"tag":30,"props":2673,"children":2674},{},[2675],{"type":38,"value":2676},"Un script pre-commit qui appelle l'API Claude avec le diff en cours :",{"type":29,"tag":1077,"props":2678,"children":2682},{"code":2679,"language":2680,"meta":8,"className":2681,"style":8},"# Script pre-commit simplifié (hooks\u002Fprepare-commit-msg)\n#!\u002Fbin\u002Fbash\nDIFF=$(git diff --cached)\nif [ -z \"$DIFF\" ]; then\n  exit 0\nfi\nSUGGESTION=$(echo \"$DIFF\" | claude -p \"Génère un commit message Conventional Commits\nen anglais pour ce diff. Format : type(scope): description courte.\nTypes valides : feat \u002F fix \u002F refactor \u002F test \u002F docs \u002F chore.\nRéponds uniquement avec le message, sans explication.\")\necho \"# Suggestion Claude : $SUGGESTION\" >> \"$1\"\n","bash","language-bash shiki shiki-themes catppuccin-frappe github-dark",[2683],{"type":29,"tag":261,"props":2684,"children":2685},{"__ignoreMap":8},[2686,2694,2703,2743,2786,2800,2808,2861,2869,2877,2889],{"type":29,"tag":1143,"props":2687,"children":2688},{"class":1145,"line":1146},[2689],{"type":29,"tag":1143,"props":2690,"children":2691},{"style":1150},[2692],{"type":38,"value":2693},"# Script pre-commit simplifié (hooks\u002Fprepare-commit-msg)\n",{"type":29,"tag":1143,"props":2695,"children":2696},{"class":1145,"line":954},[2697],{"type":29,"tag":1143,"props":2698,"children":2700},{"style":2699},"--shiki-default:#F4B8E4;--shiki-default-font-style:italic;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit",[2701],{"type":38,"value":2702},"#!\u002Fbin\u002Fbash\n",{"type":29,"tag":1143,"props":2704,"children":2705},{"class":1145,"line":1177},[2706,2711,2716,2721,2726,2732,2738],{"type":29,"tag":1143,"props":2707,"children":2708},{"style":1410},[2709],{"type":38,"value":2710},"DIFF",{"type":29,"tag":1143,"props":2712,"children":2713},{"style":1238},[2714],{"type":38,"value":2715},"=",{"type":29,"tag":1143,"props":2717,"children":2718},{"style":1198},[2719],{"type":38,"value":2720},"$(",{"type":29,"tag":1143,"props":2722,"children":2723},{"style":1165},[2724],{"type":38,"value":2725},"git",{"type":29,"tag":1143,"props":2727,"children":2729},{"style":2728},"--shiki-default:#A6D189;--shiki-dark:#9ECBFF",[2730],{"type":38,"value":2731}," diff",{"type":29,"tag":1143,"props":2733,"children":2735},{"style":2734},"--shiki-default:#A6D189;--shiki-dark:#79B8FF",[2736],{"type":38,"value":2737}," --cached",{"type":29,"tag":1143,"props":2739,"children":2740},{"style":1198},[2741],{"type":38,"value":2742},")\n",{"type":29,"tag":1143,"props":2744,"children":2745},{"class":1145,"line":1204},[2746,2751,2756,2761,2766,2771,2776,2781],{"type":29,"tag":1143,"props":2747,"children":2748},{"style":1181},[2749],{"type":38,"value":2750},"if",{"type":29,"tag":1143,"props":2752,"children":2753},{"style":1198},[2754],{"type":38,"value":2755}," [",{"type":29,"tag":1143,"props":2757,"children":2758},{"style":1238},[2759],{"type":38,"value":2760}," -z",{"type":29,"tag":1143,"props":2762,"children":2763},{"style":2728},[2764],{"type":38,"value":2765}," \"",{"type":29,"tag":1143,"props":2767,"children":2768},{"style":1410},[2769],{"type":38,"value":2770},"$DIFF",{"type":29,"tag":1143,"props":2772,"children":2773},{"style":2728},[2774],{"type":38,"value":2775},"\"",{"type":29,"tag":1143,"props":2777,"children":2778},{"style":1198},[2779],{"type":38,"value":2780}," ];",{"type":29,"tag":1143,"props":2782,"children":2783},{"style":1181},[2784],{"type":38,"value":2785}," then\n",{"type":29,"tag":1143,"props":2787,"children":2788},{"class":1145,"line":1218},[2789,2795],{"type":29,"tag":1143,"props":2790,"children":2792},{"style":2791},"--shiki-default:#E78284;--shiki-default-font-style:italic;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit",[2793],{"type":38,"value":2794},"  exit",{"type":29,"tag":1143,"props":2796,"children":2797},{"style":1714},[2798],{"type":38,"value":2799}," 0\n",{"type":29,"tag":1143,"props":2801,"children":2802},{"class":1145,"line":1254},[2803],{"type":29,"tag":1143,"props":2804,"children":2805},{"style":1181},[2806],{"type":38,"value":2807},"fi\n",{"type":29,"tag":1143,"props":2809,"children":2810},{"class":1145,"line":1284},[2811,2816,2820,2824,2829,2833,2837,2841,2846,2851,2856],{"type":29,"tag":1143,"props":2812,"children":2813},{"style":1410},[2814],{"type":38,"value":2815},"SUGGESTION",{"type":29,"tag":1143,"props":2817,"children":2818},{"style":1238},[2819],{"type":38,"value":2715},{"type":29,"tag":1143,"props":2821,"children":2822},{"style":1198},[2823],{"type":38,"value":2720},{"type":29,"tag":1143,"props":2825,"children":2826},{"style":2791},[2827],{"type":38,"value":2828},"echo",{"type":29,"tag":1143,"props":2830,"children":2831},{"style":2728},[2832],{"type":38,"value":2765},{"type":29,"tag":1143,"props":2834,"children":2835},{"style":1410},[2836],{"type":38,"value":2770},{"type":29,"tag":1143,"props":2838,"children":2839},{"style":2728},[2840],{"type":38,"value":2775},{"type":29,"tag":1143,"props":2842,"children":2843},{"style":1238},[2844],{"type":38,"value":2845}," |",{"type":29,"tag":1143,"props":2847,"children":2848},{"style":1165},[2849],{"type":38,"value":2850}," claude",{"type":29,"tag":1143,"props":2852,"children":2853},{"style":2734},[2854],{"type":38,"value":2855}," -p",{"type":29,"tag":1143,"props":2857,"children":2858},{"style":2728},[2859],{"type":38,"value":2860}," \"Génère un commit message Conventional Commits\n",{"type":29,"tag":1143,"props":2862,"children":2863},{"class":1145,"line":1298},[2864],{"type":29,"tag":1143,"props":2865,"children":2866},{"style":2728},[2867],{"type":38,"value":2868},"en anglais pour ce diff. Format : type(scope): description courte.\n",{"type":29,"tag":1143,"props":2870,"children":2871},{"class":1145,"line":1307},[2872],{"type":29,"tag":1143,"props":2873,"children":2874},{"style":2728},[2875],{"type":38,"value":2876},"Types valides : feat \u002F fix \u002F refactor \u002F test \u002F docs \u002F chore.\n",{"type":29,"tag":1143,"props":2878,"children":2879},{"class":1145,"line":1374},[2880,2885],{"type":29,"tag":1143,"props":2881,"children":2882},{"style":2728},[2883],{"type":38,"value":2884},"Réponds uniquement avec le message, sans explication.\"",{"type":29,"tag":1143,"props":2886,"children":2887},{"style":1198},[2888],{"type":38,"value":2742},{"type":29,"tag":1143,"props":2890,"children":2891},{"class":1145,"line":1444},[2892,2896,2901,2906,2910,2915,2919,2925],{"type":29,"tag":1143,"props":2893,"children":2894},{"style":2791},[2895],{"type":38,"value":2828},{"type":29,"tag":1143,"props":2897,"children":2898},{"style":2728},[2899],{"type":38,"value":2900}," \"# Suggestion Claude : ",{"type":29,"tag":1143,"props":2902,"children":2903},{"style":1410},[2904],{"type":38,"value":2905},"$SUGGESTION",{"type":29,"tag":1143,"props":2907,"children":2908},{"style":2728},[2909],{"type":38,"value":2775},{"type":29,"tag":1143,"props":2911,"children":2912},{"style":1238},[2913],{"type":38,"value":2914}," >>",{"type":29,"tag":1143,"props":2916,"children":2917},{"style":2728},[2918],{"type":38,"value":2765},{"type":29,"tag":1143,"props":2920,"children":2922},{"style":2921},"--shiki-default:#EA999C;--shiki-default-font-style:italic;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit",[2923],{"type":38,"value":2924},"$1",{"type":29,"tag":1143,"props":2926,"children":2927},{"style":2728},[2928],{"type":38,"value":2929},"\"\n",{"type":29,"tag":30,"props":2931,"children":2932},{},[2933],{"type":38,"value":2934},"Bénéfice secondaire : des descriptions de PR de qualité améliorent le processus de relecture, le reviewer comprend rapidement l'intention du changement avant de lire le code.",{"type":29,"tag":54,"props":2936,"children":2937},{},[],{"type":29,"tag":58,"props":2939,"children":2941},{"id":2940},"cas-dusage-5-mise-à-jour-de-documentation-existante-roi-moyen",[2942],{"type":38,"value":2943},"Cas d'usage 5 : Mise à jour de documentation existante (ROI moyen)",{"type":29,"tag":30,"props":2945,"children":2946},{},[2947,2951],{"type":29,"tag":34,"props":2948,"children":2949},{},[2950],{"type":38,"value":1063},{"type":38,"value":2952}," la documentation existante se désynchronise du code. Un endpoint change, la documentation ne change pas. On suit la doc et on se retrouve avec des erreurs incompréhensibles.",{"type":29,"tag":30,"props":2954,"children":2955},{},[2956,2960],{"type":29,"tag":34,"props":2957,"children":2958},{},[2959],{"type":38,"value":1073},{"type":38,"value":2961}," comparer la documentation existante avec le code actuel et identifier les divergences.",{"type":29,"tag":30,"props":2963,"children":2964},{},[2965],{"type":38,"value":2616},{"type":29,"tag":1077,"props":2967,"children":2969},{"code":2968},"Voici la documentation actuelle de l'endpoint POST \u002Fmentoring\u002Fcheckout-intent :\n[documentation]\n\nVoici le code actuel du controller et du use case correspondant :\n[code]\n\nIdentifie les divergences entre la documentation et le code, et propose\nune documentation mise à jour.\n",[2970],{"type":29,"tag":261,"props":2971,"children":2972},{"__ignoreMap":8},[2973],{"type":38,"value":2968},{"type":29,"tag":30,"props":2975,"children":2976},{},[2977],{"type":38,"value":2978},"Limite : Claude identifie les divergences techniques (paramètres manquants, types incorrects) mais pas les divergences de logique métier. La révision humaine reste nécessaire.",{"type":29,"tag":54,"props":2980,"children":2981},{},[],{"type":29,"tag":58,"props":2983,"children":2985},{"id":2984},"ce-que-lia-ne-peut-pas-documenter",[2986],{"type":38,"value":2987},"Ce que l'IA ne peut pas documenter",{"type":29,"tag":30,"props":2989,"children":2990},{},[2991,3001],{"type":29,"tag":34,"props":2992,"children":2993},{},[2994,2999],{"type":29,"tag":87,"props":2995,"children":2996},{"href":199},[2997],{"type":38,"value":2998},"Décisions d'architecture",{"type":38,"value":3000}," :",{"type":38,"value":3002}," pourquoi l'architecture hexagonale plutôt que MVC classique, pourquoi PostgreSQL avec Prisma plutôt qu'un ORM plus léger, pourquoi ce découpage en bounded contexts. Ces décisions ont un contexte (contraintes techniques, état du projet, urgence du moment) que Claude ne peut pas reconstruire. Les ADRs restent un exercice humain.",{"type":29,"tag":30,"props":3004,"children":3005},{},[3006,3011],{"type":29,"tag":34,"props":3007,"children":3008},{},[3009],{"type":38,"value":3010},"Contraintes non-exprimées dans le code :",{"type":38,"value":3012}," un timeout à 3 secondes dans une config qui existe parce qu'un service tiers SLA garantit 99% de réponses en moins de 2,5 secondes. Sans commentaire humain, Claude ne peut pas savoir que cette valeur ne doit pas changer.",{"type":29,"tag":30,"props":3014,"children":3015},{},[3016,3021],{"type":29,"tag":34,"props":3017,"children":3018},{},[3019],{"type":38,"value":3020},"Le \"pourquoi ça ne marche pas\" :",{"type":38,"value":3022}," les runbooks de debugging, les solutions aux problèmes connus, les workarounds pour les bugs connus des dépendances. Ces informations viennent de l'expérience terrain, pas du code.",{"type":29,"tag":54,"props":3024,"children":3025},{},[],{"type":29,"tag":58,"props":3027,"children":3029},{"id":3028},"comment-intégrer-claude-dans-le-workflow-de-documentation",[3030],{"type":38,"value":3031},"Comment intégrer Claude dans le workflow de documentation",{"type":29,"tag":30,"props":3033,"children":3034},{},[3035,3040,3042,3048],{"type":29,"tag":34,"props":3036,"children":3037},{},[3038],{"type":38,"value":3039},"Option A : Documentation as part of PR :",{"type":38,"value":3041}," ajouter à la ",{"type":29,"tag":87,"props":3043,"children":3045},{"href":3044},"\u002Ffr\u002Fdette-technique\u002Fdefinition-of-done-qualite",[3046],{"type":38,"value":3047},"Definition of Done",{"type":38,"value":3049}," que toute nouvelle API ou bounded context doit avoir sa documentation générée par Claude et révisée par l'auteur. La doc est vérifiée en même temps que le code.",{"type":29,"tag":30,"props":3051,"children":3052},{},[3053,3058],{"type":29,"tag":34,"props":3054,"children":3055},{},[3056],{"type":38,"value":3057},"Option B : Session de documentation dédiée :",{"type":38,"value":3059}," une fois par mois, une session de 2 à 3 heures consacrée à la mise à jour de la documentation avec Claude. On génère, on révise, on merge.",{"type":29,"tag":30,"props":3061,"children":3062},{},[3063,3068],{"type":29,"tag":34,"props":3064,"children":3065},{},[3066],{"type":38,"value":3067},"Option C : Automatisation continue :",{"type":38,"value":3069}," un pipeline CI qui génère automatiquement la documentation OpenAPI à partir des décorateurs NestJS (Swagger module) et la déploie dans un portail de documentation. La doc est toujours synchronisée avec le code.",{"type":29,"tag":30,"props":3071,"children":3072},{},[3073],{"type":38,"value":3074},"La séquence que je recommande : commencer par les READMEs des bounded contexts critiques (impact reprise de contexte immédiat), puis la documentation des endpoints internes (impact developer experience), puis les résumés de PR (impact qualité de l'historique git).",{"type":29,"tag":54,"props":3076,"children":3077},{},[],{"type":29,"tag":391,"props":3079,"children":3081},{"cta":832,"href":833,"title":3080,"type":835},"Documenter le bon 60%, c'est une pratique : il en existe 99 autres",[3082],{"type":29,"tag":30,"props":3083,"children":3084},{},[3085],{"type":38,"value":3086},"Savoir ce que l'IA documente bien et ce qu'elle documente mal fait partie d'un référentiel plus large : le Craft Bundle, les 100 pratiques craft que j'applique pour coder propre et garder une base de code lisible dans le temps. Ce sont celles que l'IA ne vous apprendra jamais, parce qu'elle ne les a jamais vues tenir en production.",{"type":29,"tag":54,"props":3088,"children":3089},{},[],{"type":29,"tag":58,"props":3091,"children":3093},{"id":3092},"faq-sur-lia-et-la-documentation-technique",[3094],{"type":38,"value":3095},"FAQ sur l'IA et la documentation technique",{"type":29,"tag":852,"props":3097,"children":3098},{},[3099,3104],{"type":29,"tag":856,"props":3100,"children":3101},{},[3102],{"type":38,"value":3103},"1. La documentation générée par IA est-elle fiable ?",{"type":29,"tag":30,"props":3105,"children":3106},{},[3107],{"type":38,"value":3108},"Pour le \"quoi\" technique (paramètres, types, structure), oui, avec révision. Claude peut se tromper sur la sémantique d'une valeur de retour ou sur le comportement dans les cas d'erreur. La règle : toute documentation générée est relue par le développeur qui connaît le code avant d'être mergée. La génération réduit le temps d'écriture de 80%, elle ne remplace pas la révision humaine.",{"type":29,"tag":852,"props":3110,"children":3111},{},[3112,3117],{"type":29,"tag":856,"props":3113,"children":3114},{},[3115],{"type":38,"value":3116},"2. Quel outil IA utiliser pour la documentation ?",{"type":29,"tag":30,"props":3118,"children":3119},{},[3120,3122,3128,3130,3136],{"type":38,"value":3121},"Claude, dans tous les cas. Claude Code (le CLI officiel Anthropic) génère des docstrings directement depuis le terminal, produit des READMEs de modules à partir du code source, et résume les diffs de PR. Pour la documentation OpenAPI automatique sur NestJS, le module ",{"type":29,"tag":261,"props":3123,"children":3125},{"className":3124},[],[3126],{"type":38,"value":3127},"@nestjs\u002Fswagger",{"type":38,"value":3129}," combiné à des schémas Zod (via ",{"type":29,"tag":261,"props":3131,"children":3133},{"className":3132},[],[3134],{"type":38,"value":3135},"nestjs-zod",{"type":38,"value":3137},") fait le travail nativement, Claude vient en complément pour les descriptions textuelles et le contexte métier.",{"type":29,"tag":852,"props":3139,"children":3140},{},[3141,3146],{"type":29,"tag":856,"props":3142,"children":3143},{},[3144],{"type":38,"value":3145},"3. Comment éviter que la documentation générée soit obsolète dès le lendemain ?",{"type":29,"tag":30,"props":3147,"children":3148},{},[3149],{"type":38,"value":3150},"Deux stratégies : (1) Documentation automatique synchronisée avec le code (OpenAPI généré par NestJS\u002FSwagger, Storybook pour les composants frontend), toujours à jour par construction. (2) Documentation révisée par un humain, avec des tests de documentation qui vérifient que les exemples de code compilent et retournent les bons résultats. L'approche hybride : génération automatique pour les APIs, révision humaine pour les guides.",{"type":29,"tag":852,"props":3152,"children":3153},{},[3154,3159],{"type":29,"tag":856,"props":3155,"children":3156},{},[3157],{"type":38,"value":3158},"4. Comment se motiver à documenter quand on développe seul ?",{"type":29,"tag":30,"props":3160,"children":3161},{},[3162],{"type":38,"value":3163},"En changeant le cadre. La documentation n'est pas un effort pour les autres, c'est une réduction du coût de maintenance pour soi. Le code que tu documentes aujourd'hui, c'est celui que tu n'auras pas à relire pendant 45 minutes dans trois semaines. Calculez le coût réel du manque de doc : 3 reprises de contexte à 40 min par semaine = 2 heures perdues chaque semaine, contre 30 minutes de documentation avec Claude. L'argument est économique, pas moral.",{"type":29,"tag":852,"props":3165,"children":3166},{},[3167,3172],{"type":29,"tag":856,"props":3168,"children":3169},{},[3170],{"type":38,"value":3171},"5. Faut-il documenter en français ou en anglais ?",{"type":29,"tag":30,"props":3173,"children":3174},{},[3175],{"type":38,"value":3176},"Le code et les commentaires techniques dans la même langue que le reste du codebase (souvent anglais pour une portabilité maximale). Les READMEs et guides internes dans la langue de l'équipe (ou du projet solo). La règle pratique : si un document sera lu par des personnes externes au projet, anglais. Si interne, la langue du projet.",{"type":29,"tag":54,"props":3178,"children":3179},{},[],{"type":29,"tag":391,"props":3181,"children":3184},{"cta":3182,"href":944,"title":3183,"type":946},"Télécharger la checklist gratuite →","Ressource gratuite : AI-Ready Engineering Team Checklist",[3185],{"type":29,"tag":30,"props":3186,"children":3187},{},[3188],{"type":38,"value":3189},"La checklist AI-Ready inclut les cas d'usage IA validés par pilier (documentation, code review, tests, architecture) et le framework d'évaluation d'adoption pour votre équipe. Avec les métriques de ROI pour chaque cas d'usage.",{"type":29,"tag":3191,"props":3192,"children":3193},"style",{},[3194],{"type":38,"value":3195},"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":954,"depth":954,"links":3197},[3198,3199,3200,3201,3202,3203,3204,3205,3206],{"id":1013,"depth":954,"text":1016},{"id":1052,"depth":954,"text":1055},{"id":1111,"depth":954,"text":1114},{"id":2590,"depth":954,"text":2593},{"id":2650,"depth":954,"text":2653},{"id":2940,"depth":954,"text":2943},{"id":2984,"depth":954,"text":2987},{"id":3028,"depth":954,"text":3031},{"id":3092,"depth":954,"text":3095},"content:fr:intelligence-artificielle:ia-documentation-technique-cas-usage.md","fr\u002Fintelligence-artificielle\u002Fia-documentation-technique-cas-usage.md","fr\u002Fintelligence-artificielle\u002Fia-documentation-technique-cas-usage",{"_path":199,"_dir":3211,"_draft":7,"_partial":7,"_locale":8,"title":3212,"description":3213,"id":1218,"date":3214,"listed":13,"nocomments":7,"hidden":7,"categories":3215,"tags":3216,"cover":3218,"readingTime":3219,"body":3224,"_type":966,"_id":3998,"_source":968,"_file":3999,"_stem":4000,"_extension":971},"architecture-craft","Architecture décisionnelle : pourquoi les ADRs changent tout","Chaque équipe refait les mêmes débats architecturaux parce que personne ne documente les décisions passées. Les ADRs résolvent ça en 30 minutes de mise en place.","2026-01-14",[3211],[18,3217],"architecture","covers\u002Farticles\u002Fadr-architecture-decision.jpg",{"text":3220,"minutes":3221,"time":3222,"words":3223},"8 min read",7.395,443700,1479,{"type":26,"children":3225,"toc":3989},[3226,3231,3236,3241,3246,3249,3255,3267,3272,3277,3297,3302,3313,3316,3322,3327,3337,3347,3387,3397,3407,3622,3631,3634,3640,3645,3650,3668,3681,3684,3690,3695,3703,3708,3718,3728,3738,3751,3754,3760,3768,3773,3778,3781,3785,3859,3868,3871,3877,3890,3911,3937,3950,3971,3974,3985],{"type":29,"tag":30,"props":3227,"children":3228},{},[3229],{"type":38,"value":3230},"J'ai rejoint une équipe bancaire en mission où le même débat revenait toutes les deux semaines : \"Pourquoi on a choisi PostgreSQL plutôt que MongoDB ?\" La décision avait deux ans. Personne ne s'en souvenait. Et chaque fois, on reconstruisait le contexte de zéro, parfois en prenant une direction différente de la précédente.",{"type":29,"tag":30,"props":3232,"children":3233},{},[3234],{"type":38,"value":3235},"Ce n'était pas un manque d'intelligence. C'était un manque de mémoire organisationnelle.",{"type":29,"tag":30,"props":3237,"children":3238},{},[3239],{"type":38,"value":3240},"Les Architecture Decision Records (ADRs) sont la réponse à ce problème. Un document court (une à deux pages) qui répond à une seule question : \"Pourquoi avons-nous fait ce choix technique ?\" Le concept existe depuis les années 2000. La plupart des équipes ne l'utilisent toujours pas.",{"type":29,"tag":30,"props":3242,"children":3243},{},[3244],{"type":38,"value":3245},"Et ça leur coûte cher.",{"type":29,"tag":54,"props":3247,"children":3248},{},[],{"type":29,"tag":58,"props":3250,"children":3252},{"id":3251},"le-coût-réel-des-décisions-non-documentées",[3253],{"type":38,"value":3254},"Le coût réel des décisions non documentées",{"type":29,"tag":30,"props":3256,"children":3257},{},[3258,3260,3265],{"type":38,"value":3259},"Dans une équipe de 10 développeurs, si chaque développeur perd 2 heures par mois à reconstruire le contexte de décisions passées, ça représente ",{"type":29,"tag":34,"props":3261,"children":3262},{},[3263],{"type":38,"value":3264},"240 heures par an",{"type":38,"value":3266},", soit plus de 6 semaines-développeur perdues sur des débats déjà tranchés.",{"type":29,"tag":30,"props":3268,"children":3269},{},[3270],{"type":38,"value":3271},"Quand j'ai mené cet exercice chez un client dans le secteur assurance (60 développeurs, 8 équipes), les résultats étaient éloquents : 73% des développeurs n'avaient pas conscience des 3 dernières décisions architecturales majeures prises par leur propre équipe. Le coût en onboardings ratés, en refactorings inutiles, en duplications de solutions était supérieur à 400 heures par trimestre.",{"type":29,"tag":30,"props":3273,"children":3274},{},[3275],{"type":38,"value":3276},"J'ai demandé à chaque équipe de répondre par écrit à trois questions :",{"type":29,"tag":3278,"props":3279,"children":3280},"ul",{},[3281,3287,3292],{"type":29,"tag":3282,"props":3283,"children":3284},"li",{},[3285],{"type":38,"value":3286},"\"Pourquoi utilisez-vous cette technologie plutôt que l'alternative ?\"",{"type":29,"tag":3282,"props":3288,"children":3289},{},[3290],{"type":38,"value":3291},"\"Qui a pris la décision d'adopter ce pattern et quand ?\"",{"type":29,"tag":3282,"props":3293,"children":3294},{},[3295],{"type":38,"value":3296},"\"Avez-vous des décisions en cours avec lesquelles vous n'êtes pas d'accord mais que vous n'avez jamais remises en question ?\"",{"type":29,"tag":30,"props":3298,"children":3299},{},[3300],{"type":38,"value":3301},"La diversité des réponses (et surtout les \"je ne sais pas\") a suffi à convaincre les équipes de changer leurs pratiques.",{"type":29,"tag":30,"props":3303,"children":3304},{},[3305,3307,3311],{"type":38,"value":3306},"Michael Nygard, dans son billet fondateur de 2011 sur les ADRs, posait la même exigence : capturer les décisions architecturalement significatives et leur contexte, pas seulement leur résultat. Ce qui importe, c'est de comprendre ",{"type":29,"tag":41,"props":3308,"children":3309},{},[3310],{"type":38,"value":162},{"type":38,"value":3312}," une décision a été prise, pas seulement laquelle.",{"type":29,"tag":54,"props":3314,"children":3315},{},[],{"type":29,"tag":58,"props":3317,"children":3319},{"id":3318},"le-template-adr-en-5-sections",[3320],{"type":38,"value":3321},"Le template ADR en 5 sections",{"type":29,"tag":30,"props":3323,"children":3324},{},[3325],{"type":38,"value":3326},"Un ADR bien rédigé répond à 5 questions dans l'ordre :",{"type":29,"tag":30,"props":3328,"children":3329},{},[3330,3335],{"type":29,"tag":34,"props":3331,"children":3332},{},[3333],{"type":38,"value":3334},"Contexte",{"type":38,"value":3336}," : quelle situation nécessite cette décision ? Quelles contraintes s'appliquent ? Qui est impliqué ?",{"type":29,"tag":30,"props":3338,"children":3339},{},[3340,3345],{"type":29,"tag":34,"props":3341,"children":3342},{},[3343],{"type":38,"value":3344},"Décision",{"type":38,"value":3346}," : quelle est la décision prise, formulée comme une assertion active (\"Nous utilisons PostgreSQL comme base de données principale\") plutôt que comme une question ouverte.",{"type":29,"tag":30,"props":3348,"children":3349},{},[3350,3355,3357,3363,3365,3371,3372,3378,3379,3385],{"type":29,"tag":34,"props":3351,"children":3352},{},[3353],{"type":38,"value":3354},"Statut",{"type":38,"value":3356}," : ",{"type":29,"tag":261,"props":3358,"children":3360},{"className":3359},[],[3361],{"type":38,"value":3362},"proposed",{"type":38,"value":3364}," | ",{"type":29,"tag":261,"props":3366,"children":3368},{"className":3367},[],[3369],{"type":38,"value":3370},"accepted",{"type":38,"value":3364},{"type":29,"tag":261,"props":3373,"children":3375},{"className":3374},[],[3376],{"type":38,"value":3377},"deprecated",{"type":38,"value":3364},{"type":29,"tag":261,"props":3380,"children":3382},{"className":3381},[],[3383],{"type":38,"value":3384},"superseded",{"type":38,"value":3386},". Le statut évolue dans le temps : une décision peut être remplacée par une nouvelle ADR.",{"type":29,"tag":30,"props":3388,"children":3389},{},[3390,3395],{"type":29,"tag":34,"props":3391,"children":3392},{},[3393],{"type":38,"value":3394},"Conséquences",{"type":38,"value":3396}," : implications positives et négatives. Qu'est-ce qui devient plus simple ? Qu'est-ce qui devient plus difficile ?",{"type":29,"tag":30,"props":3398,"children":3399},{},[3400,3405],{"type":29,"tag":34,"props":3401,"children":3402},{},[3403],{"type":38,"value":3404},"Alternatives considérées",{"type":38,"value":3406}," : quelles autres options ont été évaluées et pourquoi ont-elles été écartées ?",{"type":29,"tag":1077,"props":3408,"children":3411},{"code":3409,"language":966,"meta":8,"className":3410,"style":8},"# ADR-0001 : Utilisation de PostgreSQL comme base de données principale\n\n## Contexte\nNotre service de gestion des commandes nécessite une base de données relationnelle\navec support des transactions ACID. L'équipe a de l'expérience avec PostgreSQL et MySQL.\nContrainte : déploiement sur AWS, budget infrastructure limité.\n\n## Décision\nNous utilisons PostgreSQL 15 comme base de données principale pour tous les services\nqui nécessitent une persistance relationnelle.\n\n## Statut\nAccepté (2026-01-14)\n\n## Conséquences\n- Positives : ACID garanti, support JSON natif, extensions riches (PostGIS si besoin)\n- Négatives : scaling vertical nécessaire avant sharding ; expertise spécifique requise\n- Impact sur l'équipe : formation nécessaire pour 3 développeurs juniors\n\n## Alternatives considérées\n- MySQL 8.0 : écarté car support JSON moins mature et licensing Oracle\n- MongoDB : écarté car nos données sont relationnelles\n- DynamoDB : écarté car coût à l'usage imprévisible et expertise absente\n","language-markdown shiki shiki-themes catppuccin-frappe github-dark",[3412],{"type":29,"tag":261,"props":3413,"children":3414},{"__ignoreMap":8},[3415,3424,3431,3440,3448,3456,3464,3471,3479,3487,3495,3502,3510,3518,3525,3533,3547,3559,3571,3578,3586,3598,3610],{"type":29,"tag":1143,"props":3416,"children":3417},{"class":1145,"line":1146},[3418],{"type":29,"tag":1143,"props":3419,"children":3421},{"style":3420},"--shiki-default:#E78284;--shiki-default-font-weight:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold",[3422],{"type":38,"value":3423},"# ADR-0001 : Utilisation de PostgreSQL comme base de données principale\n",{"type":29,"tag":1143,"props":3425,"children":3426},{"class":1145,"line":954},[3427],{"type":29,"tag":1143,"props":3428,"children":3429},{"emptyLinePlaceholder":13},[3430],{"type":38,"value":1304},{"type":29,"tag":1143,"props":3432,"children":3433},{"class":1145,"line":1177},[3434],{"type":29,"tag":1143,"props":3435,"children":3437},{"style":3436},"--shiki-default:#EF9F76;--shiki-default-font-weight:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold",[3438],{"type":38,"value":3439},"## Contexte\n",{"type":29,"tag":1143,"props":3441,"children":3442},{"class":1145,"line":1204},[3443],{"type":29,"tag":1143,"props":3444,"children":3445},{"style":1410},[3446],{"type":38,"value":3447},"Notre service de gestion des commandes nécessite une base de données relationnelle\n",{"type":29,"tag":1143,"props":3449,"children":3450},{"class":1145,"line":1218},[3451],{"type":29,"tag":1143,"props":3452,"children":3453},{"style":1410},[3454],{"type":38,"value":3455},"avec support des transactions ACID. L'équipe a de l'expérience avec PostgreSQL et MySQL.\n",{"type":29,"tag":1143,"props":3457,"children":3458},{"class":1145,"line":1254},[3459],{"type":29,"tag":1143,"props":3460,"children":3461},{"style":1410},[3462],{"type":38,"value":3463},"Contrainte : déploiement sur AWS, budget infrastructure limité.\n",{"type":29,"tag":1143,"props":3465,"children":3466},{"class":1145,"line":1284},[3467],{"type":29,"tag":1143,"props":3468,"children":3469},{"emptyLinePlaceholder":13},[3470],{"type":38,"value":1304},{"type":29,"tag":1143,"props":3472,"children":3473},{"class":1145,"line":1298},[3474],{"type":29,"tag":1143,"props":3475,"children":3476},{"style":3436},[3477],{"type":38,"value":3478},"## Décision\n",{"type":29,"tag":1143,"props":3480,"children":3481},{"class":1145,"line":1307},[3482],{"type":29,"tag":1143,"props":3483,"children":3484},{"style":1410},[3485],{"type":38,"value":3486},"Nous utilisons PostgreSQL 15 comme base de données principale pour tous les services\n",{"type":29,"tag":1143,"props":3488,"children":3489},{"class":1145,"line":1374},[3490],{"type":29,"tag":1143,"props":3491,"children":3492},{"style":1410},[3493],{"type":38,"value":3494},"qui nécessitent une persistance relationnelle.\n",{"type":29,"tag":1143,"props":3496,"children":3497},{"class":1145,"line":1444},[3498],{"type":29,"tag":1143,"props":3499,"children":3500},{"emptyLinePlaceholder":13},[3501],{"type":38,"value":1304},{"type":29,"tag":1143,"props":3503,"children":3504},{"class":1145,"line":1500},[3505],{"type":29,"tag":1143,"props":3506,"children":3507},{"style":3436},[3508],{"type":38,"value":3509},"## Statut\n",{"type":29,"tag":1143,"props":3511,"children":3512},{"class":1145,"line":1541},[3513],{"type":29,"tag":1143,"props":3514,"children":3515},{"style":1410},[3516],{"type":38,"value":3517},"Accepté (2026-01-14)\n",{"type":29,"tag":1143,"props":3519,"children":3520},{"class":1145,"line":1568},[3521],{"type":29,"tag":1143,"props":3522,"children":3523},{"emptyLinePlaceholder":13},[3524],{"type":38,"value":1304},{"type":29,"tag":1143,"props":3526,"children":3527},{"class":1145,"line":1608},[3528],{"type":29,"tag":1143,"props":3529,"children":3530},{"style":3436},[3531],{"type":38,"value":3532},"## Conséquences\n",{"type":29,"tag":1143,"props":3534,"children":3535},{"class":1145,"line":1638},[3536,3542],{"type":29,"tag":1143,"props":3537,"children":3539},{"style":3538},"--shiki-default:#81C8BE;--shiki-dark:#FFAB70",[3540],{"type":38,"value":3541},"-",{"type":29,"tag":1143,"props":3543,"children":3544},{"style":1410},[3545],{"type":38,"value":3546}," Positives : ACID garanti, support JSON natif, extensions riches (PostGIS si besoin)\n",{"type":29,"tag":1143,"props":3548,"children":3549},{"class":1145,"line":1668},[3550,3554],{"type":29,"tag":1143,"props":3551,"children":3552},{"style":3538},[3553],{"type":38,"value":3541},{"type":29,"tag":1143,"props":3555,"children":3556},{"style":1410},[3557],{"type":38,"value":3558}," Négatives : scaling vertical nécessaire avant sharding ; expertise spécifique requise\n",{"type":29,"tag":1143,"props":3560,"children":3561},{"class":1145,"line":1747},[3562,3566],{"type":29,"tag":1143,"props":3563,"children":3564},{"style":3538},[3565],{"type":38,"value":3541},{"type":29,"tag":1143,"props":3567,"children":3568},{"style":1410},[3569],{"type":38,"value":3570}," Impact sur l'équipe : formation nécessaire pour 3 développeurs juniors\n",{"type":29,"tag":1143,"props":3572,"children":3573},{"class":1145,"line":1764},[3574],{"type":29,"tag":1143,"props":3575,"children":3576},{"emptyLinePlaceholder":13},[3577],{"type":38,"value":1304},{"type":29,"tag":1143,"props":3579,"children":3580},{"class":1145,"line":1773},[3581],{"type":29,"tag":1143,"props":3582,"children":3583},{"style":3436},[3584],{"type":38,"value":3585},"## Alternatives considérées\n",{"type":29,"tag":1143,"props":3587,"children":3588},{"class":1145,"line":1782},[3589,3593],{"type":29,"tag":1143,"props":3590,"children":3591},{"style":3538},[3592],{"type":38,"value":3541},{"type":29,"tag":1143,"props":3594,"children":3595},{"style":1410},[3596],{"type":38,"value":3597}," MySQL 8.0 : écarté car support JSON moins mature et licensing Oracle\n",{"type":29,"tag":1143,"props":3599,"children":3600},{"class":1145,"line":1790},[3601,3605],{"type":29,"tag":1143,"props":3602,"children":3603},{"style":3538},[3604],{"type":38,"value":3541},{"type":29,"tag":1143,"props":3606,"children":3607},{"style":1410},[3608],{"type":38,"value":3609}," MongoDB : écarté car nos données sont relationnelles\n",{"type":29,"tag":1143,"props":3611,"children":3612},{"class":1145,"line":1799},[3613,3617],{"type":29,"tag":1143,"props":3614,"children":3615},{"style":3538},[3616],{"type":38,"value":3541},{"type":29,"tag":1143,"props":3618,"children":3619},{"style":1410},[3620],{"type":38,"value":3621}," DynamoDB : écarté car coût à l'usage imprévisible et expertise absente\n",{"type":29,"tag":391,"props":3623,"children":3625},{"cta":393,"href":394,"title":3624,"type":396},"Vous voulez savoir formuler une décision d'archi qui tienne la route six mois plus tard ?",[3626],{"type":29,"tag":30,"props":3627,"children":3628},{},[3629],{"type":38,"value":3630},"Rédiger un ADR qui capture vraiment le contexte, les contraintes et les alternatives, ça ne s'improvise pas : un développeur senior sait quelles décisions méritent d'être tracées et comment les écrire pour qu'elles servent. En mentoring 1:1, on travaille vos décisions techniques réelles ensemble, je vous montre comment raisonner sur les conséquences et les compromis. Vous gagnez le réflexe de documenter ce qui compte, sans noyer l'essentiel.",{"type":29,"tag":54,"props":3632,"children":3633},{},[],{"type":29,"tag":58,"props":3635,"children":3637},{"id":3636},"les-3-premières-adrs-à-rédiger",[3638],{"type":38,"value":3639},"Les 3 premières ADRs à rédiger",{"type":29,"tag":30,"props":3641,"children":3642},{},[3643],{"type":38,"value":3644},"Ne commencez pas par les décisions les plus anciennes ni les plus complexes. Commencez par les 3 décisions qui génèrent le plus de questions récurrentes.",{"type":29,"tag":30,"props":3646,"children":3647},{},[3648],{"type":38,"value":3649},"Pour identifier lesquelles, je pose toujours ces questions :",{"type":29,"tag":3278,"props":3651,"children":3652},{},[3653,3658,3663],{"type":29,"tag":3282,"props":3654,"children":3655},{},[3656],{"type":38,"value":3657},"Quelle décision technique revient en débat à chaque onboarding d'un nouveau développeur ?",{"type":29,"tag":3282,"props":3659,"children":3660},{},[3661],{"type":38,"value":3662},"Quelle décision architecturale génère des \"oui mais pourquoi ?\" récurrents en code review ?",{"type":29,"tag":3282,"props":3664,"children":3665},{},[3666],{"type":38,"value":3667},"Quelle décision récente mérite d'être documentée pendant que le contexte est encore frais ?",{"type":29,"tag":30,"props":3669,"children":3670},{},[3671,3673,3679],{"type":38,"value":3672},"Pour les décisions prises sans documentation, je recommande d'écrire l'ADR avec ce qu'on sait, même imparfaitement. Un ADR incomplet vaut mieux que pas d'ADR. Le statut ",{"type":29,"tag":261,"props":3674,"children":3676},{"className":3675},[],[3677],{"type":38,"value":3678},"reconstructed",{"type":38,"value":3680}," signale que le document a été rédigé après-coup.",{"type":29,"tag":54,"props":3682,"children":3683},{},[],{"type":29,"tag":58,"props":3685,"children":3687},{"id":3686},"organisation-et-rituels-de-maintenance",[3688],{"type":38,"value":3689},"Organisation et rituels de maintenance",{"type":29,"tag":30,"props":3691,"children":3692},{},[3693],{"type":38,"value":3694},"Je recommande cette structure dans le dépôt Git :",{"type":29,"tag":1077,"props":3696,"children":3698},{"code":3697},"docs\u002F\n  architecture\u002F\n    decisions\u002F\n      0001-postgresql-base-de-donnees.md\n      0002-event-driven-architecture.md\n      0003-monorepo-structure.md\n    README.md  ← index des ADRs avec titre et statut\n",[3699],{"type":29,"tag":261,"props":3700,"children":3701},{"__ignoreMap":8},[3702],{"type":38,"value":3697},{"type":29,"tag":30,"props":3704,"children":3705},{},[3706],{"type":38,"value":3707},"Trois règles de maintenance que j'impose à toutes les équipes que j'accompagne :",{"type":29,"tag":30,"props":3709,"children":3710},{},[3711,3716],{"type":29,"tag":34,"props":3712,"children":3713},{},[3714],{"type":38,"value":3715},"Numérotation séquentielle.",{"type":38,"value":3717}," ADR-0001, ADR-0002... La chronologie fait partie de l'information.",{"type":29,"tag":30,"props":3719,"children":3720},{},[3721,3726],{"type":29,"tag":34,"props":3722,"children":3723},{},[3724],{"type":38,"value":3725},"Ne jamais modifier ni supprimer une ADR.",{"type":38,"value":3727}," Seulement la superseder avec une nouvelle. La trace historique a de la valeur : comprendre pourquoi une décision a changé est aussi utile que la décision actuelle.",{"type":29,"tag":30,"props":3729,"children":3730},{},[3731,3736],{"type":29,"tag":34,"props":3732,"children":3733},{},[3734],{"type":38,"value":3735},"Rituel de PR.",{"type":38,"value":3737}," À chaque pull request contenant un changement architectural significatif, vérifier si une ADR doit être créée ou mise à jour. Ce check peut être intégré dans le template de PR.",{"type":29,"tag":30,"props":3739,"children":3740},{},[3741,3743,3749],{"type":38,"value":3742},"L'outil ",{"type":29,"tag":261,"props":3744,"children":3746},{"className":3745},[],[3747],{"type":38,"value":3748},"adr-tools",{"type":38,"value":3750}," (CLI open source) génère et gère les ADRs depuis le terminal. Pour les équipes sur Confluence, l'intégration est possible, mais je garde toujours le dépôt Git comme source de vérité.",{"type":29,"tag":54,"props":3752,"children":3753},{},[],{"type":29,"tag":58,"props":3755,"children":3757},{"id":3756},"le-piège-de-la-rétro-documentation-exhaustive",[3758],{"type":38,"value":3759},"Le piège de la rétro-documentation exhaustive",{"type":29,"tag":96,"props":3761,"children":3762},{},[3763],{"type":29,"tag":30,"props":3764,"children":3765},{},[3766],{"type":38,"value":3767},"Ne pas essayer de documenter toutes les décisions passées d'un coup. La rétro-documentation exhaustive est un projet qui ne se termine pas et qui décourage l'équipe avant qu'elle prenne le pli.",{"type":29,"tag":30,"props":3769,"children":3770},{},[3771],{"type":38,"value":3772},"Ma recommandation : documenter toutes les nouvelles décisions systématiquement à partir d'aujourd'hui, et rattraper les décisions passées au fil des besoins : lors des onboardings, des débats récurrents, ou des refactorings qui remettent en question des choix passés.",{"type":29,"tag":30,"props":3774,"children":3775},{},[3776],{"type":38,"value":3777},"En 3 mois à ce rythme, les équipes que j'accompagne ont entre 15 et 25 ADRs actives. C'est suffisant pour changer la culture.",{"type":29,"tag":54,"props":3779,"children":3780},{},[],{"type":29,"tag":58,"props":3782,"children":3783},{"id":638},[3784],{"type":38,"value":641},{"type":29,"tag":536,"props":3786,"children":3787},{},[3788,3804],{"type":29,"tag":540,"props":3789,"children":3790},{},[3791],{"type":29,"tag":544,"props":3792,"children":3793},{},[3794,3799],{"type":29,"tag":548,"props":3795,"children":3796},{},[3797],{"type":38,"value":3798},"Action",{"type":29,"tag":548,"props":3800,"children":3801},{},[3802],{"type":38,"value":3803},"Résultat",{"type":29,"tag":559,"props":3805,"children":3806},{},[3807,3820,3833,3846],{"type":29,"tag":544,"props":3808,"children":3809},{},[3810,3815],{"type":29,"tag":566,"props":3811,"children":3812},{},[3813],{"type":38,"value":3814},"Calculer le coût des décisions non documentées",{"type":29,"tag":566,"props":3816,"children":3817},{},[3818],{"type":38,"value":3819},"Conviction de l'équipe",{"type":29,"tag":544,"props":3821,"children":3822},{},[3823,3828],{"type":29,"tag":566,"props":3824,"children":3825},{},[3826],{"type":38,"value":3827},"Adopter le template en 5 sections",{"type":29,"tag":566,"props":3829,"children":3830},{},[3831],{"type":38,"value":3832},"Format standardisé",{"type":29,"tag":544,"props":3834,"children":3835},{},[3836,3841],{"type":29,"tag":566,"props":3837,"children":3838},{},[3839],{"type":38,"value":3840},"Rédiger les 3 premières ADRs prioritaires",{"type":29,"tag":566,"props":3842,"children":3843},{},[3844],{"type":38,"value":3845},"Premières ADRs dans le dépôt",{"type":29,"tag":544,"props":3847,"children":3848},{},[3849,3854],{"type":29,"tag":566,"props":3850,"children":3851},{},[3852],{"type":38,"value":3853},"Setup le registre et les rituels de PR",{"type":29,"tag":566,"props":3855,"children":3856},{},[3857],{"type":38,"value":3858},"Processus pérenne",{"type":29,"tag":391,"props":3860,"children":3862},{"cta":832,"href":833,"title":3861,"type":835},"Documenter ses décisions, c'est une pratique parmi les 100 qui séparent un dev d'un artisan",[3863],{"type":29,"tag":30,"props":3864,"children":3865},{},[3866],{"type":38,"value":3867},"Cet article détaille une seule pratique : tracer ses décisions d'architecture avec des ADRs. Le Craft Bundle réunit les 100 pratiques que j'applique au quotidien pour coder propre et raisonner comme un senior, depuis la conception jusqu'à la maintenance. Ce sont les réflexes qu'on acquiert sur le terrain, ceux que l'IA ne vous apprendra jamais parce qu'elle ne les a jamais vus tourner en prod.",{"type":29,"tag":54,"props":3869,"children":3870},{},[],{"type":29,"tag":58,"props":3872,"children":3874},{"id":3873},"faq-sur-les-adrs",[3875],{"type":38,"value":3876},"FAQ sur les ADRs",{"type":29,"tag":852,"props":3878,"children":3879},{},[3880,3885],{"type":29,"tag":856,"props":3881,"children":3882},{},[3883],{"type":38,"value":3884},"1. Où stocker les ADRs : dans le dépôt Git ou dans Confluence\u002FNotion ?",{"type":29,"tag":30,"props":3886,"children":3887},{},[3888],{"type":38,"value":3889},"Dans le dépôt Git, si possible. Les ADRs sont du code de documentation : elles doivent versionner avec le code qu'elles documentent. Une ADR dans Git est visible dans les PR, peut être liée aux commits concernés, et survit aux migrations d'outils. Si votre organisation exige Confluence pour la documentation, utilisez-le en complément, mais gardez le dépôt Git comme source de vérité. J'ai vu trop d'ADRs perdues lors de migrations Confluence.",{"type":29,"tag":852,"props":3891,"children":3892},{},[3893,3898],{"type":29,"tag":856,"props":3894,"children":3895},{},[3896],{"type":38,"value":3897},"2. Faut-il un ADR pour chaque décision technique ou seulement les grandes décisions d'architecture ?",{"type":29,"tag":30,"props":3899,"children":3900},{},[3901,3903,3909],{"type":38,"value":3902},"Seulement les décisions significatives : choix de technologie, choix d'architecture (microservices vs monolithe, synchrone vs asynchrone), patterns de design appliqués à l'ensemble du système, décisions de sécurité ou de conformité. Pas besoin d'ADR pour les décisions de code quotidiennes : quel nom de variable, quelle structure de fichier dans un composant. La règle empirique que j'utilise : si la décision fera débat dans 6 mois, elle mérite une ADR. Par exemple, le choix d'adopter un ",{"type":29,"tag":87,"props":3904,"children":3906},{"href":3905},"\u002Ffr\u002Farchitecture-craft\u002Fdatabase-per-service-microservices",[3907],{"type":38,"value":3908},"pattern Database per Service dans une architecture microservices",{"type":38,"value":3910}," est typiquement le genre de décision qui doit être documentée dans une ADR.",{"type":29,"tag":852,"props":3912,"children":3913},{},[3914,3919],{"type":29,"tag":856,"props":3915,"children":3916},{},[3917],{"type":38,"value":3918},"3. Que faire quand une ADR ancienne devient obsolète ?",{"type":29,"tag":30,"props":3920,"children":3921},{},[3922,3924,3929,3931,3935],{"type":38,"value":3923},"Créer une nouvelle ADR qui supersede l'ancienne. L'ancienne garde son statut ",{"type":29,"tag":261,"props":3925,"children":3927},{"className":3926},[],[3928],{"type":38,"value":3384},{"type":38,"value":3930}," avec une référence vers la nouvelle. Jamais modifier l'ADR originale : la trace historique des décisions a de la valeur, même quand elles sont remplacées. Comprendre ",{"type":29,"tag":41,"props":3932,"children":3933},{},[3934],{"type":38,"value":162},{"type":38,"value":3936}," une décision a changé est souvent aussi utile que comprendre la décision actuelle.",{"type":29,"tag":852,"props":3938,"children":3939},{},[3940,3945],{"type":29,"tag":856,"props":3941,"children":3942},{},[3943],{"type":38,"value":3944},"4. Comment introduire les ADRs dans une équipe qui n'a jamais documenté ses décisions ?",{"type":29,"tag":30,"props":3946,"children":3947},{},[3948],{"type":38,"value":3949},"Je commence toujours par l'exemple. Je rédige les 3 premières ADRs moi-même, les présente en réunion d'équipe, et explique la valeur qu'elles auraient eue lors de situations passées concrètes, des situations que l'équipe reconnaît. Ensuite, j'invite les développeurs à rédiger les ADRs pour leurs prochaines décisions avec du support. Après 3 cycles, la pratique s'installe naturellement.",{"type":29,"tag":852,"props":3951,"children":3952},{},[3953,3958],{"type":29,"tag":856,"props":3954,"children":3955},{},[3956],{"type":38,"value":3957},"5. Est-ce que les ADRs ralentissent le processus de décision ?",{"type":29,"tag":30,"props":3959,"children":3960},{},[3961,3963,3969],{"type":38,"value":3962},"Non, et c'est le contrepoint que j'entends toujours. Rédiger une ADR prend 30 minutes. Refaire le même débat dans 6 mois prend 3 heures, mobilise 5 personnes, et produit parfois une décision différente de la précédente sans raison valable. Le retour sur investissement est immédiat après la première ADR utilisée pour clore un débat récurrent. C'est d'autant plus vrai pour un CTO en début de mandat : parmi les ",{"type":29,"tag":87,"props":3964,"children":3966},{"href":3965},"\u002Ffr\u002Fmanagement\u002Fcto-premiere-annee-90-jours",[3967],{"type":38,"value":3968},"90 premiers jours d'un CTO",{"type":38,"value":3970},", poser les bases de la gouvernance architecturale (dont les ADRs) est l'une des décisions structurantes les plus durables.",{"type":29,"tag":54,"props":3972,"children":3973},{},[],{"type":29,"tag":391,"props":3975,"children":3979},{"cta":3976,"href":3977,"title":3978,"type":946},"Faire mon auto-évaluation →","\u002Fema","Ressource gratuite : Engineering Maturity Self-Assessment",[3980],{"type":29,"tag":30,"props":3981,"children":3982},{},[3983],{"type":38,"value":3984},"L'Engineering Maturity Self-Assessment couvre le domaine Gouvernance & Documentation : évaluez votre maturité sur les pratiques de décision architecturale, la documentation, et la cohérence du système. Score et plan d'action en 10 minutes.",{"type":29,"tag":3191,"props":3986,"children":3987},{},[3988],{"type":38,"value":3195},{"title":8,"searchDepth":954,"depth":954,"links":3990},[3991,3992,3993,3994,3995,3996,3997],{"id":3251,"depth":954,"text":3254},{"id":3318,"depth":954,"text":3321},{"id":3636,"depth":954,"text":3639},{"id":3686,"depth":954,"text":3689},{"id":3756,"depth":954,"text":3759},{"id":638,"depth":954,"text":641},{"id":3873,"depth":954,"text":3876},"content:fr:architecture-craft:adr-architecture-decision-record.md","fr\u002Farchitecture-craft\u002Fadr-architecture-decision-record.md","fr\u002Farchitecture-craft\u002Fadr-architecture-decision-record",1784113937346]