[{"data":1,"prerenderedAt":841},["ShallowReactive",2],{"article-alternates":3,"article-\u002Ffr\u002Flifestyle\u002Fculture-de-revue-de-code-qualite-mesurable":13},{"i18nKey":4,"paths":5},"lifestyle-003-2026-06",{"de":6,"en":7,"es":8,"fr":9,"it":10,"ru":11,"tr":12},"\u002Fde\u002Flifestyle\u002Fcode-review-kultur-messbare-qualitat","\u002Fen\u002Flifestyle\u002Fcode-review-culture-measurable-quality","\u002Fes\u002Flifestyle\u002Fcultura-de-revision-de-codigo-calidad-medible-sin-conflictos-personales","\u002Ffr\u002Flifestyle\u002Fculture-examen-code-revue-qualite-mesurable","\u002Fit\u002Flifestyle\u002Fcultura-di-code-review-qualita-misurabile-senza-conflitti-personali","\u002Fru\u002Flifestyle\u002Fkod-inceleme-kulturu-olculebilir-kalite","\u002Ftr\u002Flifestyle\u002Fcode-review-kulturu-olculebilir-kalite-kisisel-catisma-yok",{"_path":14,"_dir":15,"_draft":16,"_partial":16,"_locale":17,"title":18,"description":19,"publishedAt":20,"modifiedAt":20,"category":15,"i18nKey":4,"tags":21,"readingTime":27,"author":28,"body":29,"_type":522,"_id":836,"_source":837,"_file":838,"_stem":839,"_extension":840},"\u002Ffr\u002Flifestyle\u002Fculture-de-revue-de-code-qualite-mesurable","lifestyle",false,"","Culture de Revue de Code : Qualité Mesurable, Aucun Conflit Personnel","Établir la qualité d'équipe sur des critères numériques — time-to-review, comment density, PR size — plutôt que sur le jugement personnel. Discipline systémique, pas arbitraire.","2026-06-20",[22,23,24,25,26],"revue-de-code","culture-engineering","pr-metrics","workflow-equipe","async-first",9,"Roibase",{"type":30,"children":31,"toc":824},"root",[32,40,47,52,57,62,69,74,80,93,98,103,347,353,358,491,503,508,514,519,685,690,696,701,706,729,735,740,745,750,758,763,769,774,804,809,813,818],{"type":33,"tag":34,"props":35,"children":36},"element","p",{},[37],{"type":38,"value":39},"text","Les processus de revue de code commencent généralement par « contrôle qualité » et finissent par « guerre d'egos ». À mesure que l'équipe grandit, deux pièges deviennent évidents : les PR languissent pendant des semaines, ou chaque commentaire est perçu comme une critique personnelle. Les deux proviennent du même problème fondamental — l'absence de règles mesurables. Chez Roibase, après 8 ans avec des équipes pluridisciplinaires de plus de 15 personnes, nous avons appris une leçon simple : tant que vous n'ancrez pas la culture de revue sur des critères numériques, le jugement personnel devient inévitable. Quand vous systématisez les métriques — time-to-review, comment density, PR size — la qualité augmente et les conflits diminuent.",{"type":33,"tag":41,"props":42,"children":44},"h2",{"id":43},"vitesse-de-revue-sla-time-to-review",[45],{"type":38,"value":46},"Vitesse de Revue : SLA Time-to-Review",{"type":33,"tag":34,"props":48,"children":49},{},[50],{"type":38,"value":51},"Chaque PR a un cycle de vie. Le délai entre son ouverture et le premier commentaire — time-to-first-review — est le premier indicateur de la discipline d'équipe. Chez Roibase, nous avons plafonné ce délai à 4 heures maximum (pendant les heures de travail). Pourquoi 4 heures ? C'est le point d'équilibre dans un modèle de travail asynchrone qui préserve les blocs de deep work tout en accélérant la boucle de rétroaction.",{"type":33,"tag":34,"props":53,"children":54},{},[55],{"type":38,"value":56},"La règle est simple : dans les 4 heures suivant l'ouverture d'une PR, au moins un reviewer doit la consulter. Le mécanisme d'application n'est pas une notification Slack — c'est un workflow GitHub Actions. Quand une PR est ouverte, elle reçoit automatiquement une étiquette ; après 4 heures, les reviewers assignés reçoivent une mention Slack. Ce rappel discret élimine les reviews oubliées.",{"type":33,"tag":34,"props":58,"children":59},{},[60],{"type":38,"value":61},"La métrique time-to-merge est encore plus critique. Le délai total entre l'ouverture et la fusion dans la branche principale — par exemple, les modifications backend ne doivent pas dépasser 24 heures. Pour le frontend, 48 heures. Pourquoi cette différence ? Les fusions backend nécessitent généralement moins de validation visuelle et peuvent être déployées derrière des feature flags. Le frontend exige des vérifications de design et des tests multi-appareils.",{"type":33,"tag":63,"props":64,"children":66},"h3",{"id":65},"tableau-de-bord-métrique-intégration-linear",[67],{"type":38,"value":68},"Tableau de Bord Métrique : Intégration Linear",{"type":33,"tag":34,"props":70,"children":71},{},[72],{"type":38,"value":73},"Nous intégrons Linear à GitHub, liant automatiquement chaque PR à un ticket Linear. Le statut du ticket se met à jour selon le cycle de vie de la PR. À la fin du sprint, nous examinons : le time-to-merge moyen. Si la moyenne d'équipe dépasse 36 heures, c'est un problème à discuter en rétrospective — généralement lié à la taille des PR ou à la charge de reviewers.",{"type":33,"tag":41,"props":75,"children":77},{"id":76},"taille-de-pr-la-règle-des-400-lignes",[78],{"type":38,"value":79},"Taille de PR : La Règle des 400 Lignes",{"type":33,"tag":34,"props":81,"children":82},{},[83,85,91],{"type":38,"value":84},"Les grandes PR ne peuvent pas être révisées correctement. C'est le consensus le plus large du secteur, mais rarement traduit en règle mesurable. Notre standard chez Roibase : ",{"type":33,"tag":86,"props":87,"children":88},"strong",{},[89],{"type":38,"value":90},"400 lignes maximum de changements",{"type":38,"value":92}," (additions + suppressions combinées). D'où vient ce chiffre ? C'est le volume de code qu'un reviewer peut raisonnablement conserver en contexte pendant une revue de 30 minutes focalisée.",{"type":33,"tag":34,"props":94,"children":95},{},[96],{"type":38,"value":97},"Pour enforcer cette règle, une GitHub branch protection rule ajoute automatiquement le label « needs-split » aux PR dépassant 400 lignes — la fusion est impossible. Les exceptions existent — mises à jour de dépendances, scripts de migration. Elles nécessitent une validation manuelle, mais même cela exige un commentaire GitHub justifiant le dépassement.",{"type":33,"tag":34,"props":99,"children":100},{},[101],{"type":38,"value":102},"Comment effectuer les grands refactors ? Via des PR empilées. Première PR : modifications d'interface ; deuxième : implémentation ; troisième : suppression du code ancien. Chacune sous 400 lignes, chacune peut être révisée indépendamment. Cette approche est-elle chronophage ? Oui. Augmente-t-elle le risque de conflits de fusion ? Légèrement. Mais la qualité des revues s'améliore exponentiellement — parce que le reviewer peut réfléchir à chaque changement dans sa pleine capacité mentale.",{"type":33,"tag":104,"props":105,"children":109},"pre",{"code":106,"language":107,"meta":17,"className":108,"style":17},"# GitHub Actions — PR size check\nname: PR Size Check\non: pull_request\n\njobs:\n  size_check:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Check PR size\n        run: |\n          ADDITIONS=$(jq '.pull_request.additions' \"$GITHUB_EVENT_PATH\")\n          DELETIONS=$(jq '.pull_request.deletions' \"$GITHUB_EVENT_PATH\")\n          TOTAL=$((ADDITIONS + DELETIONS))\n          if [ $TOTAL -gt 400 ]; then\n            echo \"PR too large: $TOTAL lines\"\n            gh pr edit --add-label needs-split\n            exit 1\n          fi\n","yaml","language-yaml shiki shiki-themes github-dark",[110],{"type":33,"tag":111,"props":112,"children":113},"code",{"__ignoreMap":17},[114,126,148,167,177,191,204,222,235,256,275,284,293,302,311,320,329,338],{"type":33,"tag":115,"props":116,"children":119},"span",{"class":117,"line":118},"line",1,[120],{"type":33,"tag":115,"props":121,"children":123},{"style":122},"--shiki-default:#6A737D",[124],{"type":38,"value":125},"# GitHub Actions — PR size check\n",{"type":33,"tag":115,"props":127,"children":129},{"class":117,"line":128},2,[130,136,142],{"type":33,"tag":115,"props":131,"children":133},{"style":132},"--shiki-default:#85E89D",[134],{"type":38,"value":135},"name",{"type":33,"tag":115,"props":137,"children":139},{"style":138},"--shiki-default:#E1E4E8",[140],{"type":38,"value":141},": ",{"type":33,"tag":115,"props":143,"children":145},{"style":144},"--shiki-default:#9ECBFF",[146],{"type":38,"value":147},"PR Size Check\n",{"type":33,"tag":115,"props":149,"children":151},{"class":117,"line":150},3,[152,158,162],{"type":33,"tag":115,"props":153,"children":155},{"style":154},"--shiki-default:#79B8FF",[156],{"type":38,"value":157},"on",{"type":33,"tag":115,"props":159,"children":160},{"style":138},[161],{"type":38,"value":141},{"type":33,"tag":115,"props":163,"children":164},{"style":144},[165],{"type":38,"value":166},"pull_request\n",{"type":33,"tag":115,"props":168,"children":170},{"class":117,"line":169},4,[171],{"type":33,"tag":115,"props":172,"children":174},{"emptyLinePlaceholder":173},true,[175],{"type":38,"value":176},"\n",{"type":33,"tag":115,"props":178,"children":180},{"class":117,"line":179},5,[181,186],{"type":33,"tag":115,"props":182,"children":183},{"style":132},[184],{"type":38,"value":185},"jobs",{"type":33,"tag":115,"props":187,"children":188},{"style":138},[189],{"type":38,"value":190},":\n",{"type":33,"tag":115,"props":192,"children":194},{"class":117,"line":193},6,[195,200],{"type":33,"tag":115,"props":196,"children":197},{"style":132},[198],{"type":38,"value":199},"  size_check",{"type":33,"tag":115,"props":201,"children":202},{"style":138},[203],{"type":38,"value":190},{"type":33,"tag":115,"props":205,"children":207},{"class":117,"line":206},7,[208,213,217],{"type":33,"tag":115,"props":209,"children":210},{"style":132},[211],{"type":38,"value":212},"    runs-on",{"type":33,"tag":115,"props":214,"children":215},{"style":138},[216],{"type":38,"value":141},{"type":33,"tag":115,"props":218,"children":219},{"style":144},[220],{"type":38,"value":221},"ubuntu-latest\n",{"type":33,"tag":115,"props":223,"children":225},{"class":117,"line":224},8,[226,231],{"type":33,"tag":115,"props":227,"children":228},{"style":132},[229],{"type":38,"value":230},"    steps",{"type":33,"tag":115,"props":232,"children":233},{"style":138},[234],{"type":38,"value":190},{"type":33,"tag":115,"props":236,"children":237},{"class":117,"line":27},[238,243,247,251],{"type":33,"tag":115,"props":239,"children":240},{"style":138},[241],{"type":38,"value":242},"      - ",{"type":33,"tag":115,"props":244,"children":245},{"style":132},[246],{"type":38,"value":135},{"type":33,"tag":115,"props":248,"children":249},{"style":138},[250],{"type":38,"value":141},{"type":33,"tag":115,"props":252,"children":253},{"style":144},[254],{"type":38,"value":255},"Check PR size\n",{"type":33,"tag":115,"props":257,"children":259},{"class":117,"line":258},10,[260,265,269],{"type":33,"tag":115,"props":261,"children":262},{"style":132},[263],{"type":38,"value":264},"        run",{"type":33,"tag":115,"props":266,"children":267},{"style":138},[268],{"type":38,"value":141},{"type":33,"tag":115,"props":270,"children":272},{"style":271},"--shiki-default:#F97583",[273],{"type":38,"value":274},"|\n",{"type":33,"tag":115,"props":276,"children":278},{"class":117,"line":277},11,[279],{"type":33,"tag":115,"props":280,"children":281},{"style":144},[282],{"type":38,"value":283},"          ADDITIONS=$(jq '.pull_request.additions' \"$GITHUB_EVENT_PATH\")\n",{"type":33,"tag":115,"props":285,"children":287},{"class":117,"line":286},12,[288],{"type":33,"tag":115,"props":289,"children":290},{"style":144},[291],{"type":38,"value":292},"          DELETIONS=$(jq '.pull_request.deletions' \"$GITHUB_EVENT_PATH\")\n",{"type":33,"tag":115,"props":294,"children":296},{"class":117,"line":295},13,[297],{"type":33,"tag":115,"props":298,"children":299},{"style":144},[300],{"type":38,"value":301},"          TOTAL=$((ADDITIONS + DELETIONS))\n",{"type":33,"tag":115,"props":303,"children":305},{"class":117,"line":304},14,[306],{"type":33,"tag":115,"props":307,"children":308},{"style":144},[309],{"type":38,"value":310},"          if [ $TOTAL -gt 400 ]; then\n",{"type":33,"tag":115,"props":312,"children":314},{"class":117,"line":313},15,[315],{"type":33,"tag":115,"props":316,"children":317},{"style":144},[318],{"type":38,"value":319},"            echo \"PR too large: $TOTAL lines\"\n",{"type":33,"tag":115,"props":321,"children":323},{"class":117,"line":322},16,[324],{"type":33,"tag":115,"props":325,"children":326},{"style":144},[327],{"type":38,"value":328},"            gh pr edit --add-label needs-split\n",{"type":33,"tag":115,"props":330,"children":332},{"class":117,"line":331},17,[333],{"type":33,"tag":115,"props":334,"children":335},{"style":144},[336],{"type":38,"value":337},"            exit 1\n",{"type":33,"tag":115,"props":339,"children":341},{"class":117,"line":340},18,[342],{"type":33,"tag":115,"props":343,"children":344},{"style":144},[345],{"type":38,"value":346},"          fi\n",{"type":33,"tag":41,"props":348,"children":350},{"id":349},"densité-de-commentaires-le-seuil-nitpick",[351],{"type":38,"value":352},"Densité de Commentaires : Le Seuil Nitpick",{"type":33,"tag":34,"props":354,"children":355},{},[356],{"type":38,"value":357},"Tous les commentaires n'ont pas le même poids. Il existe une différence critique entre « ceci pourrait être refactorisé » et « cela provoque une exception null pointer ». Le template de revue Roibase exige une catégorisation des commentaires :",{"type":33,"tag":359,"props":360,"children":361},"table",{},[362,386],{"type":33,"tag":363,"props":364,"children":365},"thead",{},[366],{"type":33,"tag":367,"props":368,"children":369},"tr",{},[370,376,381],{"type":33,"tag":371,"props":372,"children":373},"th",{},[374],{"type":38,"value":375},"Catégorie",{"type":33,"tag":371,"props":377,"children":378},{},[379],{"type":38,"value":380},"Étiquette",{"type":33,"tag":371,"props":382,"children":383},{},[384],{"type":38,"value":385},"Exemple",{"type":33,"tag":387,"props":388,"children":389},"tbody",{},[390,416,441,466],{"type":33,"tag":367,"props":391,"children":392},{},[393,402,411],{"type":33,"tag":394,"props":395,"children":396},"td",{},[397],{"type":33,"tag":86,"props":398,"children":399},{},[400],{"type":38,"value":401},"Blocker",{"type":33,"tag":394,"props":403,"children":404},{},[405],{"type":33,"tag":111,"props":406,"children":408},{"className":407},[],[409],{"type":38,"value":410},"🔴 BLOCKER",{"type":33,"tag":394,"props":412,"children":413},{},[414],{"type":38,"value":415},"Faille de sécurité, crash runtime",{"type":33,"tag":367,"props":417,"children":418},{},[419,427,436],{"type":33,"tag":394,"props":420,"children":421},{},[422],{"type":33,"tag":86,"props":423,"children":424},{},[425],{"type":38,"value":426},"Major",{"type":33,"tag":394,"props":428,"children":429},{},[430],{"type":33,"tag":111,"props":431,"children":433},{"className":432},[],[434],{"type":38,"value":435},"🟠 MAJOR",{"type":33,"tag":394,"props":437,"children":438},{},[439],{"type":38,"value":440},"Régression de performance, erreur logique",{"type":33,"tag":367,"props":442,"children":443},{},[444,452,461],{"type":33,"tag":394,"props":445,"children":446},{},[447],{"type":33,"tag":86,"props":448,"children":449},{},[450],{"type":38,"value":451},"Minor",{"type":33,"tag":394,"props":453,"children":454},{},[455],{"type":33,"tag":111,"props":456,"children":458},{"className":457},[],[459],{"type":38,"value":460},"🟡 MINOR",{"type":33,"tag":394,"props":462,"children":463},{},[464],{"type":38,"value":465},"Convention de nommage, couverture de test",{"type":33,"tag":367,"props":467,"children":468},{},[469,477,486],{"type":33,"tag":394,"props":470,"children":471},{},[472],{"type":33,"tag":86,"props":473,"children":474},{},[475],{"type":38,"value":476},"Nitpick",{"type":33,"tag":394,"props":478,"children":479},{},[480],{"type":33,"tag":111,"props":481,"children":483},{"className":482},[],[484],{"type":38,"value":485},"🔵 NITPICK",{"type":33,"tag":394,"props":487,"children":488},{},[489],{"type":38,"value":490},"Préférence, subjectif",{"type":33,"tag":34,"props":492,"children":493},{},[494,496,501],{"type":38,"value":495},"La règle : ",{"type":33,"tag":86,"props":497,"children":498},{},[499],{"type":38,"value":500},"le ratio nitpick ne doit pas dépasser 30 %",{"type":38,"value":502},". Sur 10 commentaires, 3 peuvent être des nitpicks ; les 7 autres doivent être blocker\u002Fmajor\u002Fminor. Pourquoi ? Parce que les revues dominées par les nitpicks démotivent l'auteur et créent une perception de pointillisme excessif.",{"type":33,"tag":34,"props":504,"children":505},{},[506],{"type":38,"value":507},"La métrique comment density : nombre moyen de commentaires par PR. Chez Roibase, ce chiffre se situe entre 3 et 5. Au-delà de 10, c'est généralement un signal que la PR devrait être divisée. Zéro commentaire ? C'est un symptôme de rubber stamp review — indésirable aussi.",{"type":33,"tag":63,"props":509,"children":511},{"id":510},"utilisation-du-template",[512],{"type":38,"value":513},"Utilisation du Template",{"type":33,"tag":34,"props":515,"children":516},{},[517],{"type":38,"value":518},"Chaque reviewer commence par un template GitHub PR :",{"type":33,"tag":104,"props":520,"children":524},{"code":521,"language":522,"meta":17,"className":523,"style":17},"## Revue Checklist\n- [ ] La logique du code est-elle correcte ?\n- [ ] La couverture de test dépasse-t-elle 80 % ?\n- [ ] Y a-t-il un breaking change ? (CHANGELOG mis à jour ?)\n- [ ] L'impact performance a-t-il été mesuré ? (benchmarks\u002F)\n\n## Commentaires\n**🔴 BLOCKER :**\n-\n\n**🟠 MAJOR :**\n-\n\n**🟡 MINOR :**\n-\n\n**🔵 NITPICK :**\n-\n","markdown","language-markdown shiki shiki-themes github-dark",[525],{"type":33,"tag":111,"props":526,"children":527},{"__ignoreMap":17},[528,537,551,563,575,587,594,602,611,619,626,634,641,648,656,663,670,678],{"type":33,"tag":115,"props":529,"children":530},{"class":117,"line":118},[531],{"type":33,"tag":115,"props":532,"children":534},{"style":533},"--shiki-default:#79B8FF;--shiki-default-font-weight:bold",[535],{"type":38,"value":536},"## Revue Checklist\n",{"type":33,"tag":115,"props":538,"children":539},{"class":117,"line":128},[540,546],{"type":33,"tag":115,"props":541,"children":543},{"style":542},"--shiki-default:#FFAB70",[544],{"type":38,"value":545},"-",{"type":33,"tag":115,"props":547,"children":548},{"style":138},[549],{"type":38,"value":550}," [ ] La logique du code est-elle correcte ?\n",{"type":33,"tag":115,"props":552,"children":553},{"class":117,"line":150},[554,558],{"type":33,"tag":115,"props":555,"children":556},{"style":542},[557],{"type":38,"value":545},{"type":33,"tag":115,"props":559,"children":560},{"style":138},[561],{"type":38,"value":562}," [ ] La couverture de test dépasse-t-elle 80 % ?\n",{"type":33,"tag":115,"props":564,"children":565},{"class":117,"line":169},[566,570],{"type":33,"tag":115,"props":567,"children":568},{"style":542},[569],{"type":38,"value":545},{"type":33,"tag":115,"props":571,"children":572},{"style":138},[573],{"type":38,"value":574}," [ ] Y a-t-il un breaking change ? (CHANGELOG mis à jour ?)\n",{"type":33,"tag":115,"props":576,"children":577},{"class":117,"line":179},[578,582],{"type":33,"tag":115,"props":579,"children":580},{"style":542},[581],{"type":38,"value":545},{"type":33,"tag":115,"props":583,"children":584},{"style":138},[585],{"type":38,"value":586}," [ ] L'impact performance a-t-il été mesuré ? (benchmarks\u002F)\n",{"type":33,"tag":115,"props":588,"children":589},{"class":117,"line":193},[590],{"type":33,"tag":115,"props":591,"children":592},{"emptyLinePlaceholder":173},[593],{"type":38,"value":176},{"type":33,"tag":115,"props":595,"children":596},{"class":117,"line":206},[597],{"type":33,"tag":115,"props":598,"children":599},{"style":533},[600],{"type":38,"value":601},"## Commentaires\n",{"type":33,"tag":115,"props":603,"children":604},{"class":117,"line":224},[605],{"type":33,"tag":115,"props":606,"children":608},{"style":607},"--shiki-default:#E1E4E8;--shiki-default-font-weight:bold",[609],{"type":38,"value":610},"**🔴 BLOCKER :**\n",{"type":33,"tag":115,"props":612,"children":613},{"class":117,"line":27},[614],{"type":33,"tag":115,"props":615,"children":616},{"style":138},[617],{"type":38,"value":618},"-\n",{"type":33,"tag":115,"props":620,"children":621},{"class":117,"line":258},[622],{"type":33,"tag":115,"props":623,"children":624},{"emptyLinePlaceholder":173},[625],{"type":38,"value":176},{"type":33,"tag":115,"props":627,"children":628},{"class":117,"line":277},[629],{"type":33,"tag":115,"props":630,"children":631},{"style":607},[632],{"type":38,"value":633},"**🟠 MAJOR :**\n",{"type":33,"tag":115,"props":635,"children":636},{"class":117,"line":286},[637],{"type":33,"tag":115,"props":638,"children":639},{"style":138},[640],{"type":38,"value":618},{"type":33,"tag":115,"props":642,"children":643},{"class":117,"line":295},[644],{"type":33,"tag":115,"props":645,"children":646},{"emptyLinePlaceholder":173},[647],{"type":38,"value":176},{"type":33,"tag":115,"props":649,"children":650},{"class":117,"line":304},[651],{"type":33,"tag":115,"props":652,"children":653},{"style":607},[654],{"type":38,"value":655},"**🟡 MINOR :**\n",{"type":33,"tag":115,"props":657,"children":658},{"class":117,"line":313},[659],{"type":33,"tag":115,"props":660,"children":661},{"style":138},[662],{"type":38,"value":618},{"type":33,"tag":115,"props":664,"children":665},{"class":117,"line":322},[666],{"type":33,"tag":115,"props":667,"children":668},{"emptyLinePlaceholder":173},[669],{"type":38,"value":176},{"type":33,"tag":115,"props":671,"children":672},{"class":117,"line":331},[673],{"type":33,"tag":115,"props":674,"children":675},{"style":607},[676],{"type":38,"value":677},"**🔵 NITPICK :**\n",{"type":33,"tag":115,"props":679,"children":680},{"class":117,"line":340},[681],{"type":33,"tag":115,"props":682,"children":683},{"style":138},[684],{"type":38,"value":618},{"type":33,"tag":34,"props":686,"children":687},{},[688],{"type":38,"value":689},"Ce template sert deux objectifs : forcer le reviewer à catégoriser, et permettre à l'auteur de voir rapidement quels commentaires sont critiques.",{"type":33,"tag":41,"props":691,"children":693},{"id":692},"revue-asynchrone-piège-des-réunions-sync",[694],{"type":38,"value":695},"Revue Asynchrone : Piège des Réunions Sync",{"type":33,"tag":34,"props":697,"children":698},{},[699],{"type":38,"value":700},"La revue de code ne doit pas se faire en réunion synchrone. Chez Roibase, il n'existe pas de concept de « review call » — toute revue est asynchrone, sur GitHub. Pourquoi ? L'équipe travaille dans 3 fuseau horaires différents, et préserver les blocs de deep work est critique.",{"type":33,"tag":34,"props":702,"children":703},{},[704],{"type":38,"value":705},"La discipline de revue asynchrone fonctionne ainsi : le reviewer examine la PR pendant ses heures de focus profond (généralement 09:00-12:00). Il rédige ses commentaires, approuve ou demande des modifications. Quand l'auteur reçoit la notification (selon son calendrier), il apporte les changements et redemande une revue. Ce cycle se répète 2 à 3 fois en moyenne.",{"type":33,"tag":34,"props":707,"children":708},{},[709,711,716,718,727],{"type":38,"value":710},"Exception : ",{"type":33,"tag":86,"props":712,"children":713},{},[714],{"type":38,"value":715},"deadlock de revue",{"type":38,"value":717}," — si l'auteur et le reviewer ne parviennent pas à s'entendre après 3 allers-retours, alors on ouvre un appel sync de 15 minutes. Mais cela se produit 5 à 6 fois par an — ce sont des exceptions. L'approche ",{"type":33,"tag":719,"props":720,"children":724},"a",{"href":721,"rel":722},"https:\u002F\u002Fwww.roibase.com.tr\u002Ffr\u002Fbranding",[723],"nofollow",[725],{"type":38,"value":726},"branding",{"type":38,"value":728}," de Roibase reflète aussi cette culture de travail async-first — documentation-first, meetings-last.",{"type":33,"tag":41,"props":730,"children":732},{"id":731},"propriété-vs-gatekeeping",[733],{"type":38,"value":734},"Propriété vs. Gatekeeping",{"type":33,"tag":34,"props":736,"children":737},{},[738],{"type":38,"value":739},"L'objectif de la revue est l'assurance qualité, mais son effet secondaire ne devrait pas être le gatekeeping. Chez Roibase, chaque PR nécessite 1 à 2 reviewers minimum. Pourquoi 2 comme plafond ? Attendre l'approbation de 3+ reviewers coûte plus en temps qu'il n'économise en qualité de code.",{"type":33,"tag":34,"props":741,"children":742},{},[743],{"type":38,"value":744},"La sélection des reviewers n'est pas automatique — c'est l'auteur qui choisit. Règle : au moins un code owner (du fichier CODEOWNERS), l'autre peut être n'importe qui. Cette approche maintient la propriété chez l'auteur. La question « qui doit approuver ? » relève de la responsabilité de l'auteur, pas du leader d'équipe.",{"type":33,"tag":34,"props":746,"children":747},{},[748],{"type":38,"value":749},"Le fichier CODEOWNERS ressemble à ceci :",{"type":33,"tag":104,"props":751,"children":753},{"code":752},"# Backend\n\u002Fbackend\u002F @backend-team\n\u002Fapi\u002F @backend-team\n\n# Frontend\n\u002Fweb\u002F @frontend-team\n\u002Fmobile\u002F @mobile-team\n\n# Infrastructure\n\u002Fterraform\u002F @devops-team\n\u002F.github\u002F @devops-team\n",[754],{"type":33,"tag":111,"props":755,"children":756},{"__ignoreMap":17},[757],{"type":38,"value":752},{"type":33,"tag":34,"props":759,"children":760},{},[761],{"type":38,"value":762},"Chaque modification de fichier doit être révisée par quelqu'un du team concerné — mais l'auteur choisit encore cette personne.",{"type":33,"tag":41,"props":764,"children":766},{"id":765},"rétrospective-métriques-de-revue",[767],{"type":38,"value":768},"Rétrospective : Métriques de Revue",{"type":33,"tag":34,"props":770,"children":771},{},[772],{"type":38,"value":773},"À la fin de chaque sprint (toutes les 2 semaines), nous examinons les métriques de revue. Tableau de bord Linear :",{"type":33,"tag":775,"props":776,"children":777},"ul",{},[778,784,789,794,799],{"type":33,"tag":779,"props":780,"children":781},"li",{},[782],{"type":38,"value":783},"Time-to-merge moyen (cible : 36 heures)",{"type":33,"tag":779,"props":785,"children":786},{},[787],{"type":38,"value":788},"Distribution des tailles de PR (cible : 90 % sous 400 lignes)",{"type":33,"tag":779,"props":790,"children":791},{},[792],{"type":38,"value":793},"Comment density (cible : 3-5 par PR)",{"type":33,"tag":779,"props":795,"children":796},{},[797],{"type":38,"value":798},"Ratio nitpick (cible : \u003C30 %)",{"type":33,"tag":779,"props":800,"children":801},{},[802],{"type":38,"value":803},"Goulot d'étranglement : quel reviewer attend le plus ?",{"type":33,"tag":34,"props":805,"children":806},{},[807],{"type":38,"value":808},"Ces chiffres alimentent la rétrospective, mais sans blâme personnel. Au lieu de « Ali est lent en revue », on demande : « Les PR backend attendent en moyenne 48 heures ; devrions-nous élargir le pool de reviewers ? »",{"type":33,"tag":810,"props":811,"children":812},"hr",{},[],{"type":33,"tag":34,"props":814,"children":815},{},[816],{"type":38,"value":817},"Transformer la culture de revue de code du jugement personnel à la discipline systémique n'est pas difficile — mais cela demande des règles mesurables. L'SLA time-to-review, la règle des 400 lignes, la catégorisation des commentaires, l'approche async-first — ce sont les outils concrets qui nous permettent de maintenir la qualité à mesure que Roibase grandit depuis 8 ans. Si vos processus de revue sont encore « instinctifs » et « selon les circonstances », introduisez les chiffres et systématisez. La qualité augmentera pendant que les conflits diminueront.",{"type":33,"tag":819,"props":820,"children":821},"style",{},[822],{"type":38,"value":823},"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);}",{"title":17,"searchDepth":150,"depth":150,"links":825},[826,829,830,833,834,835],{"id":43,"depth":128,"text":46,"children":827},[828],{"id":65,"depth":150,"text":68},{"id":76,"depth":128,"text":79},{"id":349,"depth":128,"text":352,"children":831},[832],{"id":510,"depth":150,"text":513},{"id":692,"depth":128,"text":695},{"id":731,"depth":128,"text":734},{"id":765,"depth":128,"text":768},"content:fr:lifestyle:culture-de-revue-de-code-qualite-mesurable.md","content","fr\u002Flifestyle\u002Fculture-de-revue-de-code-qualite-mesurable.md","fr\u002Flifestyle\u002Fculture-de-revue-de-code-qualite-mesurable","md",1782079493317]