Claude Code in produzione: flusso di lavoro reale per sviluppatori PHP senior
Da aprile 2025 uso Claude Code, il CLI ufficiale di Anthropic per sviluppo assistito da AI documentato su docs.claude.com, come strumento quotidiano nel mio lavoro di consulenza su codebase PHP legacy e moderne di aziende italiane. Sei mesi di uso intensivo, tre progetti clienti diversi con caratteristiche molto differenti fra loro, e circa 850 task delegati completamente o parzialmente all'assistente AI mi hanno dato un quadro molto concreto di cosa funziona e cosa no. Questo articolo non è un'introduzione generale a Claude Code - per quella c'è la documentazione ufficiale - ma è la descrizione dettagliata del mio flusso reale: quali task delego completamente con fiducia misurata, quali richiedono supervisione stretta al 100%, dove l'AI sbaglia sistematicamente in modi riconoscibili, e come ho costruito i guardrail operativi che rendono il mio workflow più veloce del 30-40% rispetto al pre-Claude Code, senza regressione nella qualità del codice prodotto.
La premessa onesta da cui parto: Claude Code non sostituisce il ragionamento del senior developer; amplifica la sua capacità di produzione. La distinzione è importante. Un junior che usa Claude Code senza disciplina produce codice peggiore di quello che produrrebbe senza - perché mancano i guardrail critici che separano l'output plausibile dall'output corretto. Un senior che usa Claude Code con disciplina produce codice migliore, perché delega task meccanici al sistema e dedica il proprio cervello al design e alle decisioni architetturali dove l'AI non aiuta davvero. La discriminante non è l'intelligenza di Claude - è la disciplina dell'operatore umano.
La tassonomia dei task: cosa delego, cosa supervisiono, cosa faccio a mano
Dopo sei mesi di uso, ho sviluppato una classificazione interna dei task basata su quanto mi fido di Claude Code con ciascuno. La tassonomia ha quattro livelli.
Livello 1 - delega completa. Task meccanici dove il rischio di errore dell'AI è basso e l'impatto dell'eventuale errore è trascurabile. Esempi: rinomina di variabili in un file, aggiunta di type hint a metodi che già funzionano, conversione di docblock PHPDoc da stile vecchio a stile nuovo, formatting consistente di un file, estrazione di costanti magic number in const esplicite, generazione di fixtures Pest da schema database. Su questi task lascio Claude Code lavorare in autonomia completa, rivedo il diff veloce, mergio. Il rischio peggiore è una variabile rinominata male, che compila e gira comunque - non c'è rischio di bug subtle.
Livello 2 - supervisione leggera. Task dove Claude Code fa il grosso del lavoro ma io rivedo i dettagli tecnici. Esempi: scrittura di test unitari per una classe esistente, refactoring di un metodo lungo in metodi privati più piccoli, implementazione di un'API REST con pattern già definito, traduzione di regex PHP da una sintassi a un'altra, conversione di un blocco di codice procedurale in un design pattern noto (Strategy, Observer, Factory). Qui Claude Code produce il codice, io leggo con attenzione, validi assumption che il modello ha fatto implicitamente, e accetto/modifico/rifiuto. Il tempo di produzione è il 30-50% del tempo manuale.
Livello 3 - collaborazione stretta. Task dove il codice nasce dalla conversazione iterativa fra me e Claude Code. Esempi: progettazione di un nuovo module di business, diagnosi di bug in codice complesso (come il debugging assistito che ho descritto in un altro articolo), modellazione di entità di dominio per un nuovo sottosistema, decisione architetturale su service layer vs direct controller, selezione di pattern di integrazione con API esterne. Qui il valore di Claude Code non è nella produzione di codice, è nell'esplorare rapidamente più alternative e nell'articolare trade-off. Io guido, Claude Code elabora.
Livello 4 - faccio a mano. Task dove Claude Code è inutile o pericoloso. Esempi: decisioni su security-critical code (autenticazione, autorizzazione, crittografia), modifiche a logica finanziaria con implicazioni fiscali/legali, migration database su dataset grandi, ottimizzazione di query SQL complesse, integrazione con sistemi proprietari senza documentazione pubblica. Qui il tempo di produzione con AI sarebbe magari identico al manuale, ma la probabilità di errore grave cresce troppo - e gli errori in questi ambiti hanno conseguenze che non sono "il codice non compila", sono "l'azienda perde dati" o "l'applicazione ha una vulnerabilità non rilevabile tramite testing".
Sul lavoro dell'ultimo trimestre, la distribuzione dei task è stata approssimativamente: 35% Livello 1, 40% Livello 2, 20% Livello 3, 5% Livello 4. Il tempo complessivo di sviluppo è stato ridotto del 32% rispetto al mio benchmark pre-Claude Code, principalmente grazie al guadagno sui Livelli 1 e 2 che sono la parte più meccanica e volumetrica del lavoro quotidiano.
Il flusso tipico su un task di Livello 2: scrittura test unitari
Per rendere concreto il discorso, descrivo il flusso reale su un caso d'uso che eseguo praticamente ogni giorno - la scrittura di test Pest per classi PHP esistenti sprovviste di test. Il contesto: una classe di business CalcolatoreSconti che applica logica commerciale ai totali di un carrello. La classe ha 250 righe, 8 metodi pubblici, nessun test. Il mio obiettivo è portarla a copertura >80% in 20-30 minuti.
Step 1 - briefing iniziale. Apro Claude Code nella directory del progetto e do un comando strutturato:
Leggi app/Services/CalcolatoreSconti.php e scrivi test Pest completi
in tests/Unit/Services/CalcolatoreScontiTest.php.
Requisiti: usa dataset() per coprire i diversi scenari di sconto.
Ogni metodo pubblico deve avere almeno 3 test: happy path con input
tipico, edge case (input vuoti, zero, estremi), error case se il metodo
puo' lanciare eccezione. Non usare Mockery o mock se non strettamente
necessario. Se il metodo richiede un Cliente, usa una data class minimale
invece. Segui il naming che usi negli altri test del progetto: guarda
tests/Unit/Services/OrdineServiceTest.php come reference.
Prima di scrivere i test, analizza la classe e dimmi:
1. quali metodi ritieni critici da testare per primi
2. se ci sono assumption implicite nel codice che potrebbero
nascondere bug
3. se ci sono parti non testabili senza refactoring (es: dipendenze
static, uso di Carbon::now senza inject)Step 2 - analisi preliminare. Claude Code legge il file e mi risponde con le tre analisi richieste. Tipicamente trova 2-3 issue (es: "il metodo applicaScontoFedeltà usa Carbon::now() direttamente, non è testabile in modo deterministic senza time mocking", oppure "il metodo calcolaMinimo ha un comportamento inconsistente quando l'input è null vs array vuoto"). Queste osservazioni sono spesso utili anche prima di scrivere i test - mi indicano piccoli refactoring che farò prima di testare.
Step 3 - scrittura test iniziale. Dopo aver deciso (io) se fare refactoring preliminari, dico a Claude Code di procedere. Il modello produce il file di test completo, tipicamente 100-200 righe di test strutturati correttamente.
Step 4 - review critica. Questa è la fase dove la mia disciplina umana è cruciale. Leggo i test con attenzione focalizzata su tre domande: i test passano davvero contro la versione attuale del codice? I test coprono davvero il comportamento che credo di voler testare, o ci sono assumption implicite che invalidano la copertura? Ci sono edge case che il modello ha saltato ma che io conosco dal business?
Step 5 - esecuzione e correzione. Eseguo vendor/bin/pest sui nuovi test. Tipicamente 1-2 test falliscono al primo run (il modello ha fatto un'assumption errata sulla logica interna). Discutiamo, Claude Code corregge, ri-eseguo. Dopo 2-3 iterazioni, tutti i test passano.
Il tempo totale del flusso è 15-25 minuti per una classe tipica, contro i 45-60 minuti che avrei impiegato a mano. Il risparmio cumulativo su un progetto dove serve aggiungere test a 30-40 classi è significativo.
Dove Claude Code sbaglia sistematicamente (e come riconoscerlo)
Dopo 850 task delegati, ho identificato pattern di errore ricorrenti di Claude Code. Conoscerli mi permette di applicare guardrail mirati invece di generica diffidenza. Cinque pattern principali.
Pattern di errore 1 - invenzione di API o metodi. Claude Code a volte chiama metodi che non esistono nel framework o nella libreria usata, producendo codice che compila (PHP è permissivo) ma fallisce al runtime. Il pattern tipico è quando il modello assume che una libreria abbia un metodo che sarebbe naturale averlo ma che in realtà non esiste. Difesa: verificare ogni chiamata di metodo meno comune in documentazione ufficiale o in test.
Pattern di errore 2 - import missing. Classi usate senza che il relativo use sia in cima al file. Il codice sembra corretto a prima vista ma PHP lancia Class Not Found al primo run. Difesa: PHPStan a livello alto cattura sempre questo, e ho PHPStan integrato nella CI. Il pattern di integrazione di PHPStan nelle pipeline CI/CD per analisi statica rigorosa è diventato ancora più importante dopo che ho iniziato a usare AI.
Pattern di errore 3 - allucinazione di business logic. Quando chiedo di implementare logica di business vaga ("scrivi la funzione che calcola lo sconto fedeltà"), il modello può inventarsi regole plausibili ma non corrispondenti al business reale dell'azienda. Difesa: mai chiedere implementazioni di business logic senza aver prima specificato le regole esatte (in docstring, commenti o prompt). Se le regole non sono scritte, Claude Code le inventerà.
Pattern di errore 4 - pattern inadatti al contesto. Il modello tende ad applicare pattern di design "universalmente buoni" anche quando il contesto specifico non li richiede. Ad esempio, refactorare una classe di 30 righe introducendo Strategy Pattern e Factory Pattern per "estendibilità futura" non richiesta, aggiungendo complessità senza beneficio. Difesa: nel prompt, specificare esplicitamente il trade-off ("keep it simple, no over-engineering, il progetto ha una sola implementazione e non ne avrà mai altre").
Pattern di errore 5 - test che non testano davvero. Occasionalmente, Claude Code produce test che "girano e passano" ma non verificano realmente il comportamento che dovrebbero verificare. Esempio classico: un test che chiama un metodo, verifica che $result !== null, ma non verifica che $result sia effettivamente il valore atteso. Il test passa sempre, non cattura regressioni. Difesa: rileggere ogni test con la domanda "cosa verifica davvero questo test? Se la logica del metodo si invertisse, questo test fallirebbe?". Se la risposta è no, il test va riscritto.
Il pattern complessivo è che gli errori di Claude Code sono spesso plausibili. Non sono errori sintattici grossolani (quelli li vedi subito), sono errori semantici sottili che possono passare una review superficiale. La difesa non è diffidenza generica - è sapere esattamente dove guardare con attenzione focalizzata.
Stai cercando un Consulente Informatico esperto per introdurre Claude Code come strumento produttivo nel tuo team PHP, con guardrail operativi e best practice calibrate sul tuo contesto di progetto senza sacrificare la qualità del codice prodotto? Nel mio profilo professionale trovi l'esperienza concreta su LLM automation, Claude Code, workflow AI-assisted per developer senior italiani.
I file di contesto: come "insegnare" a Claude Code il tuo progetto
Un elemento che fa enorme differenza nella qualità dell'output è il file CLAUDE.md al root del progetto - un file che Claude Code legge automaticamente a ogni sessione e che funge da "memoria persistente" del progetto. Il contenuto tipico di un CLAUDE.md per un progetto Laravel maturo include: convenzioni di naming e stile adottate dal team, pattern architetturali preferiti (repository vs direct Eloquent, service layer vs fat controllers, etc.), librerie preferite e librerie bannate, path dove è proibito fare modifiche senza autorizzazione, convenzioni di test (Pest vs PHPUnit, struttura directory test, naming convention), regole di security specifiche del progetto (segreti mai nel codice, validazione specifica per input user).
Un estratto del CLAUDE.md che uso su uno dei progetti clienti:
# Progetto [nome anonimizzato]
## Stack
- Laravel 11, PHP 8.3, MySQL 8, Redis 7
- Frontend: Inertia.js + Vue 3
- Testing: Pest 3
## Convenzioni di codice
- Tutti i controller ereditano da App\Http\Controllers\ApiController
- Eloquent model hanno sempre $fillable esplicito (mai $guarded)
- Ogni endpoint API usa una Form Request dedicata per validation
- I test usano in()->group() per organizzazione, mai describe()
## Architettura
- Business logic in Service layer in app/Services/
- Mai mettere business logic in controller
- Repository solo per query complesse, non per CRUD semplici
- Tutti i job usano la code in config/horizon.php (mai default queue)
## Security
- Mai loggare oggetti che possono contenere password (User, Session)
- Mai usare $request->all() - sempre validated
- Uploads file sempre validati tramite FileRule della Form Request
## Librerie preferite
- Gestione date: Carbon (no DateTime puro)
- HTTP client: Http facade di Laravel (no Guzzle diretto)
- Logging: Log facade (no Monolog diretto)
## Librerie bannate
NON usare doctrine/dbal (abbiamo Eloquent).
NON usare league/flysystem-aws-s3-v3 versione < 3.0.
## Directory off-limits
vendor/ e node_modules/ (dipendenze, mai modificare).
storage/app/encrypted/ (dati cifrati cliente).
tests/_fixtures/ (fixtures stabili, non modificare senza approvazione).
Fine del file CLAUDE.md.Con questo file di contesto, Claude Code rispetta automaticamente le convenzioni del progetto senza dover ripeterle a ogni prompt. Un developer junior che arriva nel team e non conosce queste convenzioni le imparerà in tempo; Claude Code le applica da subito. Il risultato è che il codice prodotto da Claude Code è immediatamente allineato allo stile esistente, senza bisogno di review massicce per riallinearlo. Il pattern si estende al contesto descritto nel mio articolo sulla costruzione di MCP server personalizzati per integrare Claude Code con strumenti aziendali - CLAUDE.md gestisce contesto statico, MCP server gestisce contesto dinamico da sistemi esterni.
Il pattern di code review con Claude Code come "secondo paio di occhi"
Un uso che ho adottato gradualmente nei sei mesi è l'uso di Claude Code come revisore del codice che scrivo io manualmente. Il pattern è: completo un pezzo di codice, lo committo su branch di feature, apro Claude Code e gli chiedo "rivedi questo diff, cerca potenziali bug, edge case non coperti, security issue, opportunità di semplificazione". Il modello produce una lista di osservazioni, alcune utili, altre rumorose. Il valore aggiunto è che forza me stesso a rileggere il codice con una prospettiva diversa - "cosa commentarebbe un code reviewer esigente?" - prima ancora di aprire la PR per review umana.
Il prompt che uso è strutturato:
Esegui code review del diff corrente vs main.
Cerca:
1. Potenziali bug (edge case non coperti, null handling mancante,
race conditions, resource leak)
2. Security issue (SQL injection, XSS, deserialize, missing auth)
3. Performance issue (N+1 Eloquent, loop con query dentro, memory leak)
4. Opportunita' di semplificazione (pattern overengineered per il caso)
5. Aderenza a convenzioni progetto (CLAUDE.md)
Per ogni osservazione, specificare: file:riga specifica, categoria
(bug/security/perf/simplicity/convention), severity (high/medium/low),
spiegazione concisa, suggerimento di fix concreto.
Sii rigoroso ma non pedante. Ignora questioni di stile puro.Sul mio lavoro, l'applicazione di questo pattern ha catturato 3-4 issue veri al mese che avrei potenzialmente mergiato senza accorgermene. Non è tantissimo in valore assoluto, ma è sufficiente a giustificare il tempo aggiuntivo - uno di quegli issue era un N+1 query in un endpoint critico che sotto carico avrebbe generato degrado di performance visibile. Il pattern complementare alla code review automatica AI è descritto nel mio articolo sulla costruzione di pipeline di code review automatizzata con LLM su GitHub/GitLab per aziende, che scala questo approccio a livello di team invece che individuale.
L'integrazione con gli altri strumenti del workflow
Claude Code non vive in isolamento - si integra con gli strumenti del mio workflow quotidiano. Due integrazioni specifiche meritano menzione.
Prima: integrazione con gli hook Git pre-commit. Ho uno script che si attiva prima di ogni commit e verifica che il diff non contenga pattern tipici di errori Claude Code (invenzione di metodi, import missing, test vuoti). Se rileva sospetti, blocca il commit e mi chiede conferma esplicita. Questo è un guardrail aggiuntivo oltre al PHPStan standard.
Seconda: integrazione con il mio sistema di note. Al termine di ogni sessione significativa, copio una sintesi della sessione in un file Obsidian locale (dove tengo le mie note di progetto). Questo mi permette di ricostruire decisioni prese settimane dopo, ripercorrendo il ragionamento che ha portato a una certa implementazione. Il pattern è simile a quello descritto nel mio articolo sull'AI-assisted debugging di Claude per analisi di stack trace e root cause in PHP - l'AI è utile se lascia tracce navigabili, inutile se le sessioni svaniscono senza lasciare persistent context.
L'onestà intellettuale: quanto del mio lavoro fa davvero Claude Code?
Una domanda che mi pongo periodicamente e che credo sia onesto articolare è: quanto del mio output attuale è "merito" mio e quanto è "merito" di Claude Code? La risposta non è semplice. Il codice che produco è mio nel senso che io sono responsabile per ogni linea - io ho definito il problema, io ho guidato la soluzione, io ho revisionato e corretto l'output, io firmo la PR. Ma il volume di codice che produco sarebbe significativamente inferiore senza Claude Code, e alcune soluzioni emergono dalla conversazione con il modello che probabilmente non avrei trovato in isolamento.
Il modello mentale che uso è quello di collaborazione strutturata con uno junior velocissimo. Un senior che collabora con un junior competente ma inesperto: il senior definisce il problema, il junior propone l'implementazione, il senior rivede e corregge, il junior impara dall'iterazione. Nessuno dubita che l'output finale sia "del senior" anche se il junior ha scritto righe di codice specifiche. Claude Code occupa questo ruolo - è un collaboratore la cui velocità sovracompensa la sua mancanza di contesto specifico, a patto che il senior esegua bene il proprio ruolo di definizione del problema e review critica.
Il rischio che vedo - e che segnalo onestamente ai clienti - è che un junior developer che adotta Claude Code senza avere ancora sviluppato il "radar" critico del senior rischia di produrre codice peggiore perché non ha i filtri per catturare gli errori tipici del modello. Paradossalmente, l'AI amplifica sia le competenze che i gap. Un senior diventa più veloce e produttivo; un junior impreparato si ritrova a mergiare bug che non ha capito. La disciplina di mentoring e review resta essenziale anche - o soprattutto - nell'era dell'AI.
Le metriche concrete sul mio lavoro nei sei mesi
Traccio le mie metriche con disciplina perché la mia professionalità dipende dal poter dimostrare valore oggettivo. Sul periodo aprile-ottobre 2025 su tre progetti clienti: circa 850 task delegati o co-eseguiti con Claude Code (40% Livello 1, 45% Livello 2, 15% Livello 3+4), tempo medio di sviluppo ridotto del 32% rispetto al benchmark pre-Claude Code (misurato su task comparabili), zero bug in produzione attribuibili a codice generato da AI (tutti i bug emersi erano su codice scritto a mano, paradossalmente), 11 issue di security o bug catturati in fase di review AI che avrei potuto mergiare senza. Il costo dell'abbonamento Claude Code Pro è trascurabile rispetto al guadagno produttività.
Il beneficio più interessante ma meno facilmente misurabile è la qualità dei test. Ho ora una quantità di test ~3x superiore rispetto ai progetti pre-Claude Code, perché la scrittura di test è stata enormemente facilitata dalla delega Livello 2. Codice meglio testato è codice con meno regressioni nel tempo - il beneficio si accumulerà nei mesi successivi al mio intervento, su clienti che continueranno a manutenere il codice autonomamente.
Se sei un developer PHP senior e stai valutando l'adozione seria di Claude Code nel tuo workflow quotidiano, oppure stai gestendo un team di sviluppo e vuoi introdurre AI-assisted development con guardrail strutturati invece di lasciarla proliferare senza disciplina, contattami per una consulenza di workflow: in due giornate di lavoro analizzo il tuo flusso attuale, identifico i task dove Claude Code può dare il massimo beneficio, definisco il CLAUDE.md calibrato sul tuo stack e convenzioni, imposto i guardrail pre-commit che riducono il rischio di errori tipici dell'AI, e formo te o il tuo team sulla disciplina operativa che trasforma uno strumento potente in un moltiplicatore di produttività stabile nel medio periodo.