[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-it-claude-code-review-automatica-pr":3},{"id":4,"title":5,"author":6,"body":7,"cover":476,"description":477,"draft":478,"extension":479,"locale":480,"meta":481,"navigation":80,"path":482,"publishedAt":483,"seo":484,"seoTitle":485,"slug":486,"stem":487,"tags":488,"__hash__":491},"blog\u002Fit\u002Fblog\u002Fclaude-code-review-automatica-pr.md","Code review automatica su PR con Claude Code: comandi custom e regole di progetto","Manuel Tardivo",{"type":8,"value":9,"toc":467},"minimark",[10,24,29,32,44,48,55,58,181,188,192,199,339,346,350,353,359,382,388,398,404,408,414,417,424,428,431,434,438,463],[11,12,13,17,18,23],"p",{},[14,15,16],"strong",{},"Claude Code"," può fare un primo passaggio sistematico su ogni pull request prima del reviewer umano, non per sostituire la revisione, ma per filtrare problemi ovvi e liberare attenzione per quelli che contano. È l’utilizzo con il ritorno più immediato nei team piccoli, ed è quello che configuriamo per primo quando integriamo Claude Code in un flusso esistente in Snowinch. Parte dalla ",[19,20,22],"a",{"href":21},"\u002Fit\u002Fblog\u002Fclaude-code-guida-pratica-italia","guida pratica al cluster Claude Code","; qui entriamo nel dettaglio operativo sulla review.",[25,26,28],"h2",{"id":27},"il-problema-della-code-review-in-team-piccoli","Il problema della code review in team piccoli",[11,30,31],{},"In un team di 3–5 persone, la code review è spesso il collo di bottiglia più sottovalutato. Chi fa review è lo stesso che sta sviluppando qualcos’altro, l’attenzione è divisa, i problemi ovvi passano perché ci si concentra sulla logica di business, e i commenti si accumulano in modo non uniforme a seconda di chi fa la review quel giorno.",[11,33,34,35,38,39,43],{},"Il risultato è review di qualità variabile, non per mancanza di competenza ma per mancanza di tempo e contesto costante. Claude Code non risolve il problema della review umana, risolve il problema del ",[14,36,37],{},"rumore",": i tipi non gestiti, i ",[40,41,42],"code",{},"console.log"," dimenticati, le funzioni che violano le convenzioni del progetto, i casi limite non coperti. Quegli errori non dovrebbero arrivare al reviewer umano.",[25,45,47],{"id":46},"la-configurazione-che-fa-la-differenza-claudemd","La configurazione che fa la differenza: CLAUDE.md",[11,49,50,51,54],{},"Il file ",[40,52,53],{},"CLAUDE.md"," nella root del progetto è il documento che trasforma Claude Code da assistente generico ad assistente contestuale. Senza di esso, la review è basata su convenzioni generali. Con esso, è basata sulle regole specifiche del tuo progetto.",[11,56,57],{},"Per la code review, le sezioni più importanti da includere:",[59,60,65],"pre",{"className":61,"code":62,"language":63,"meta":64,"style":64},"language-markdown shiki shiki-themes github-light github-dark","# Convenzioni di progetto\n\n## Architettura\n- I controller non contengono logica di business: delegano ai service layer\n- Le query al database passano sempre attraverso il repository layer, mai direttamente dai controller\n- I tipi nullable vanno gestiti esplicitamente, no optional chaining senza fallback dichiarato\n\n## Pattern proibiti\n- Niente `any` esplicito in TypeScript, usa `unknown` e narrowing\n- Niente `console.log` in produzione, usa il logger interno (`src\u002Flib\u002Flogger`)\n- Niente side-effect nelle funzioni pure, separare sempre query da mutation\n\n## Naming\n- I file di test seguono il pattern `*.test.ts` nella stessa directory del file testato\n- Le variabili di ambiente vengono lette solo da `src\u002Fconfig\u002Fenv.ts`, mai direttamente da `process.env`\n\n## Aree critiche\n- `src\u002Fbilling\u002F`, ogni modifica richiede attenzione particolare ai casi di concorrenza\n- `src\u002Fauth\u002F`, le modifiche ai middleware di autenticazione vanno verificate contro tutti i ruoli\n","markdown","",[40,66,67,75,82,88,94,100,106,111,117,123,129,135,140,146,152,158,163,169,175],{"__ignoreMap":64},[68,69,72],"span",{"class":70,"line":71},"line",1,[68,73,74],{},"# Convenzioni di progetto\n",[68,76,78],{"class":70,"line":77},2,[68,79,81],{"emptyLinePlaceholder":80},true,"\n",[68,83,85],{"class":70,"line":84},3,[68,86,87],{},"## Architettura\n",[68,89,91],{"class":70,"line":90},4,[68,92,93],{},"- I controller non contengono logica di business: delegano ai service layer\n",[68,95,97],{"class":70,"line":96},5,[68,98,99],{},"- Le query al database passano sempre attraverso il repository layer, mai direttamente dai controller\n",[68,101,103],{"class":70,"line":102},6,[68,104,105],{},"- I tipi nullable vanno gestiti esplicitamente, no optional chaining senza fallback dichiarato\n",[68,107,109],{"class":70,"line":108},7,[68,110,81],{"emptyLinePlaceholder":80},[68,112,114],{"class":70,"line":113},8,[68,115,116],{},"## Pattern proibiti\n",[68,118,120],{"class":70,"line":119},9,[68,121,122],{},"- Niente `any` esplicito in TypeScript, usa `unknown` e narrowing\n",[68,124,126],{"class":70,"line":125},10,[68,127,128],{},"- Niente `console.log` in produzione, usa il logger interno (`src\u002Flib\u002Flogger`)\n",[68,130,132],{"class":70,"line":131},11,[68,133,134],{},"- Niente side-effect nelle funzioni pure, separare sempre query da mutation\n",[68,136,138],{"class":70,"line":137},12,[68,139,81],{"emptyLinePlaceholder":80},[68,141,143],{"class":70,"line":142},13,[68,144,145],{},"## Naming\n",[68,147,149],{"class":70,"line":148},14,[68,150,151],{},"- I file di test seguono il pattern `*.test.ts` nella stessa directory del file testato\n",[68,153,155],{"class":70,"line":154},15,[68,156,157],{},"- Le variabili di ambiente vengono lette solo da `src\u002Fconfig\u002Fenv.ts`, mai direttamente da `process.env`\n",[68,159,161],{"class":70,"line":160},16,[68,162,81],{"emptyLinePlaceholder":80},[68,164,166],{"class":70,"line":165},17,[68,167,168],{},"## Aree critiche\n",[68,170,172],{"class":70,"line":171},18,[68,173,174],{},"- `src\u002Fbilling\u002F`, ogni modifica richiede attenzione particolare ai casi di concorrenza\n",[68,176,178],{"class":70,"line":177},19,[68,179,180],{},"- `src\u002Fauth\u002F`, le modifiche ai middleware di autenticazione vanno verificate contro tutti i ruoli\n",[11,182,183,184,187],{},"L’esempio sopra è ",[14,185,186],{},"strutturale",", adatta path e regole al tuo codebase. Questo file va trattato come documentazione viva: si aggiorna ogni volta che il team prende una decisione architetturale rilevante. Se una convenzione non è scritta qui, Claude Code non può applicarla.",[25,189,191],{"id":190},"comandi-custom-per-la-review","Comandi custom per la review",[11,193,194,195,198],{},"Claude Code supporta comandi custom definiti nella directory ",[40,196,197],{},".claude\u002Fcommands\u002F"," del progetto. Sono file Markdown che definiscono istruzioni specifiche per un task ricorrente, la review di una PR è il caso d’uso ideale.",[59,200,202],{"className":61,"code":201,"language":63,"meta":64,"style":64},"\u003C!-- .claude\u002Fcommands\u002Freview-pr.md -->\n# Review PR\n\nAnalizza le modifiche nella staging area o nel diff fornito e produci una review strutturata.\n\n## Cosa verificare\n\n1. **Violazioni delle convenzioni** definite in CLAUDE.md, segnala ogni deviazione con il file e la riga\n2. **Tipi non gestiti**, variabili nullable senza fallback, cast espliciti senza verifica\n3. **Casi limite mancanti**, input vuoti, array vuoti, valori zero, concorrenza\n4. **Side-effect non dichiarati**, funzioni che modificano stato esterno senza che sia evidente dalla firma\n5. **Sicurezza di base**, input utente non sanitizzato, query costruite con concatenazione di stringhe\n\n## Cosa non segnalare\n\n- Preferenze stilistiche non coperte da CLAUDE.md\n- Suggerimenti architetturali che richiederebbero refactoring significativo, aprire issue separata\n- Problemi già presenti nel codice pre-esistente non toccato da questa PR\n\n## Formato output\n\nPer ogni problema trovato:\n- File e riga\n- Descrizione del problema\n- Suggerimento concreto di fix (non generico)\n\nSe non ci sono problemi, dillo esplicitamente, non inventare commenti per sembrare utile.\n",[40,203,204,209,214,218,223,227,232,236,241,246,251,256,261,265,270,274,279,284,289,293,299,304,310,316,322,328,333],{"__ignoreMap":64},[68,205,206],{"class":70,"line":71},[68,207,208],{},"\u003C!-- .claude\u002Fcommands\u002Freview-pr.md -->\n",[68,210,211],{"class":70,"line":77},[68,212,213],{},"# Review PR\n",[68,215,216],{"class":70,"line":84},[68,217,81],{"emptyLinePlaceholder":80},[68,219,220],{"class":70,"line":90},[68,221,222],{},"Analizza le modifiche nella staging area o nel diff fornito e produci una review strutturata.\n",[68,224,225],{"class":70,"line":96},[68,226,81],{"emptyLinePlaceholder":80},[68,228,229],{"class":70,"line":102},[68,230,231],{},"## Cosa verificare\n",[68,233,234],{"class":70,"line":108},[68,235,81],{"emptyLinePlaceholder":80},[68,237,238],{"class":70,"line":113},[68,239,240],{},"1. **Violazioni delle convenzioni** definite in CLAUDE.md, segnala ogni deviazione con il file e la riga\n",[68,242,243],{"class":70,"line":119},[68,244,245],{},"2. **Tipi non gestiti**, variabili nullable senza fallback, cast espliciti senza verifica\n",[68,247,248],{"class":70,"line":125},[68,249,250],{},"3. **Casi limite mancanti**, input vuoti, array vuoti, valori zero, concorrenza\n",[68,252,253],{"class":70,"line":131},[68,254,255],{},"4. **Side-effect non dichiarati**, funzioni che modificano stato esterno senza che sia evidente dalla firma\n",[68,257,258],{"class":70,"line":137},[68,259,260],{},"5. **Sicurezza di base**, input utente non sanitizzato, query costruite con concatenazione di stringhe\n",[68,262,263],{"class":70,"line":142},[68,264,81],{"emptyLinePlaceholder":80},[68,266,267],{"class":70,"line":148},[68,268,269],{},"## Cosa non segnalare\n",[68,271,272],{"class":70,"line":154},[68,273,81],{"emptyLinePlaceholder":80},[68,275,276],{"class":70,"line":160},[68,277,278],{},"- Preferenze stilistiche non coperte da CLAUDE.md\n",[68,280,281],{"class":70,"line":165},[68,282,283],{},"- Suggerimenti architetturali che richiederebbero refactoring significativo, aprire issue separata\n",[68,285,286],{"class":70,"line":171},[68,287,288],{},"- Problemi già presenti nel codice pre-esistente non toccato da questa PR\n",[68,290,291],{"class":70,"line":177},[68,292,81],{"emptyLinePlaceholder":80},[68,294,296],{"class":70,"line":295},20,[68,297,298],{},"## Formato output\n",[68,300,302],{"class":70,"line":301},21,[68,303,81],{"emptyLinePlaceholder":80},[68,305,307],{"class":70,"line":306},22,[68,308,309],{},"Per ogni problema trovato:\n",[68,311,313],{"class":70,"line":312},23,[68,314,315],{},"- File e riga\n",[68,317,319],{"class":70,"line":318},24,[68,320,321],{},"- Descrizione del problema\n",[68,323,325],{"class":70,"line":324},25,[68,326,327],{},"- Suggerimento concreto di fix (non generico)\n",[68,329,331],{"class":70,"line":330},26,[68,332,81],{"emptyLinePlaceholder":80},[68,334,336],{"class":70,"line":335},27,[68,337,338],{},"Se non ci sono problemi, dillo esplicitamente, non inventare commenti per sembrare utile.\n",[11,340,341,342,345],{},"Il comando si invoca dalla sessione Claude Code con ",[40,343,344],{},"\u002Freview-pr",". Puoi passargli il diff direttamente o lasciarlo leggere i file modificati nella working directory.",[25,347,349],{"id":348},"workflow-pratico","Workflow pratico",[11,351,352],{},"Il flusso che funziona in team piccoli senza introdurre overhead:",[11,354,355,358],{},[14,356,357],{},"Prima del push:"," il dev invoca la review localmente sul branch prima di aprire la PR. Corregge i problemi ovvi, poi apre la PR.",[59,360,364],{"className":361,"code":362,"language":363,"meta":64,"style":64},"language-bash shiki shiki-themes github-light github-dark","# Nella working directory con le modifiche staged\nclaude \u002Freview-pr\n","bash",[40,365,366,372],{"__ignoreMap":64},[68,367,368],{"class":70,"line":71},[68,369,371],{"class":370},"sJ8bj","# Nella working directory con le modifiche staged\n",[68,373,374,378],{"class":70,"line":77},[68,375,377],{"class":376},"sScJk","claude",[68,379,381],{"class":380},"sZZnC"," \u002Freview-pr\n",[11,383,384,387],{},[14,385,386],{},"Come check opzionale in CI:"," puoi integrare Claude Code in CI passandogli il diff della PR tramite la CLI. Non è un gate obbligatorio, è un commento automatico sulla PR che il reviewer umano può leggere prima di iniziare la propria review.",[11,389,390,391,397],{},"L’integrazione CI dipende dalla piattaforma e dalla versione della CLI disponibile, verifica la documentazione ufficiale di Claude Code per le opzioni di automazione aggiornate: ",[19,392,396],{"href":393,"rel":394},"https:\u002F\u002Fdocs.anthropic.com\u002Fen\u002Fdocs\u002Fclaude-code\u002Foverview",[395],"nofollow","docs.anthropic.com\u002Fclaude-code",".",[11,399,400,403],{},[14,401,402],{},"Come primo step della review umana:"," il reviewer legge prima il report di Claude Code, verifica i problemi segnalati, poi fa la propria review concentrandosi sulla logica di business e sulle decisioni architetturali. I problemi meccanici sono già stati filtrati.",[25,405,407],{"id":406},"cosa-claude-code-trova-bene-e-cosa-no","Cosa Claude Code trova bene e cosa no",[11,409,410,411,413],{},"Trova bene: violazioni di convenzioni esplicite, tipi non gestiti, pattern proibiti definiti nel ",[40,412,53],{},", casi limite evidenti, codice duplicato che viola il DRY in modo esplicito.",[11,415,416],{},"Trova meno bene: problemi di concorrenza sottili che richiedono ragionamento sull’ordine di esecuzione, bug che emergono solo con combinazioni specifiche di stato, problemi architetturali che richiedono contesto di dominio non documentato nel codice.",[11,418,419,420,423],{},"La regola pratica: se il problema si può descrivere come una regola esplicita («non usare ",[40,421,422],{},"any","», «i controller non contengono logica di business»), Claude Code lo trova. Se richiede intuizione sul dominio o ragionamento su scenari non documentati, non è affidabile.",[25,425,427],{"id":426},"il-rischio-da-evitare","Il rischio da evitare",[11,429,430],{},"Trattare l’output della review come definitivo senza leggerlo. Succede quando il team inizia a fidarsi ciecamente dello strumento, i falsi negativi (problemi non segnalati) passano inosservati perché si assume che se Claude Code non li ha trovati, non esistono.",[11,432,433],{},"La review automatica filtra il rumore, non garantisce la correttezza. Il reviewer umano resta responsabile, con meno rumore da gestire, ma con la stessa responsabilità di giudizio.",[25,435,437],{"id":436},"sintesi-operativa","Sintesi operativa",[439,440,441,447,454,457,460],"ul",{},[442,443,50,444,446],"li",{},[40,445,53],{}," è la configurazione fondamentale: senza regole esplicite di progetto, la review è generica e di scarso valore.",[442,448,449,450,453],{},"I comandi custom in ",[40,451,452],{},".claude\u002Fcommands\u002Freview-pr.md"," definiscono cosa verificare, cosa ignorare e il formato dell’output, riducono la variabilità tra sessioni.",[442,455,456],{},"Il workflow più sostenibile: review locale prima del push, non come gate CI obbligatorio.",[442,458,459],{},"Claude Code trova violazioni di regole esplicite, non sostituisce il giudizio su logica di business e architettura.",[442,461,462],{},"Leggere sempre l’output prima di agire su di esso: i falsi negativi esistono e non sono segnalati.",[464,465,466],"style",{},"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);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":64,"searchDepth":77,"depth":77,"links":468},[469,470,471,472,473,474,475],{"id":27,"depth":77,"text":28},{"id":46,"depth":77,"text":47},{"id":190,"depth":77,"text":191},{"id":348,"depth":77,"text":349},{"id":406,"depth":77,"text":407},{"id":426,"depth":77,"text":427},{"id":436,"depth":77,"text":437},"\u002Fblog\u002F11_claude_code_review_automatica_pr_1x.webp","Review automatica delle PR con Claude Code: CLAUDE.md, comando \u002Freview-pr, workflow locale prima del push, e limiti rispetto alla review umana.",false,"md","it",{},"\u002Fit\u002Fblog\u002Fclaude-code-review-automatica-pr","2026-07-07",{"title":5,"description":477},"Claude Code: review automatica su pull request","claude-code-review-automatica-pr","it\u002Fblog\u002Fclaude-code-review-automatica-pr",[489,490],"mvp","automation","x-eQp-sHPooulbJqYHCx_OenQhdjJfW3BRDIL-eH3Aw"]