---
title: "Subentro su codebase Laravel senza documentazione: il metodo in 48 ore per capire cosa hai ereditato"
description: "Assessment sistematico di una codebase Laravel ereditata: PHPStan, route mapping, schema analysis e risk matrix. Il metodo in 48 ore che applico dopo ogni subentro."
canonical: "https://www.mauriziofonte.it/blog/post/gestire-subentro-improvviso-sviluppatore-laravel.html"
author: "Maurizio Fonte"
date: "2025-07-01T08:22:35+02:00"
modified: "2026-04-14T17:48:55+02:00"
section: "Refactoring"
tags: ["Refactoring", "Business Continuity"]
license: "Riuso e citazione consentiti con attribuzione e link alla fonte"
---

[Refactoring](https://www.mauriziofonte.it/blog/cat/refactoring.html) [Business Continuity](https://www.mauriziofonte.it/blog/cat/business_continuity.html)

# [Subentro su codebase Laravel senza documentazione: il metodo in 48 ore per capire cosa hai ereditato](https://www.mauriziofonte.it/blog/post/gestire-subentro-improvviso-sviluppatore-laravel.html)

Martedì 1 Luglio 2025, alle 08:22 ![Subentro su codebase Laravel senza documentazione: il metodo in 48 ore per capire cosa hai ereditato](https://www.mauriziofonte.it/image/001910200-gestire-subentro-improvviso-sviluppatore-laravel.jpg)

C'è un momento preciso, in ogni subentro su un progetto Laravel, in cui l'emergenza tecnica finisce e inizia la parte davvero difficile. Il server è stato recuperato, le credenziali sono state ruotate, l'applicazione risponde, i backup sono verificati. Il titolare tira un sospiro di sollievo e dice: "Bene, ora puoi lavorarci." E ti trovi davanti a 85.000 righe di codice scritte da qualcun altro, senza documentazione, senza test, senza un singolo commento che spieghi *perché* una certa decisione è stata presa. L'applicazione funziona - nel senso che genera fatturato - ma nessuno sa come. Il precedente sviluppatore non è più raggiungibile, o lo è ma non ha tempo, o lo è ma non ricorda.

Il caso più recente in cui ho applicato il metodo che descrivo in questo articolo è di luglio 2025: una PMI manifatturiera in provincia di Brescia, 60 dipendenti, un gestionale Laravel 9 custom che gestiva ordini, produzione, magazzino e fatturazione elettronica. Lo sviluppatore - un freelance che aveva lavorato al progetto per quattro anni - aveva accettato un'offerta aziendale e aveva dato un mese di preavviso. Ma il "passaggio di consegne" era consistito in un file README.md di 23 righe con le istruzioni per il deploy e la password del database. Nient'altro. Ho descritto la fase di emergenza - recupero accessi, stabilizzazione, stop-the-bleeding - nel mio articolo sul [subentro forzato nelle prime 72 ore quando lo sviluppatore non risponde più](https://www.mauriziofonte.it/blog/post/guida-subentro-progetto-php-server-hetzner-ovh-aruba-developer-scomparso.html). Questo articolo copre quello che viene dopo: capire cosa hai ereditato, dove sono i rischi, e cosa dire al titolare entro venerdì.

## Cosa puoi davvero capire di una codebase Laravel in 48 ore senza parlare con chi l'ha scritta?

Più di quanto pensi, se usi gli strumenti giusti nell'ordine giusto. Il codice è la documentazione definitiva di se stesso - non mente, non dimentica, non ha la memoria selettiva di uno sviluppatore che "ricorda le cose importanti." Il problema non è la mancanza di informazione. È la mancanza di struttura nell'analisi. Quarantotto ore non bastano per capire tutto, ma bastano per produrre una mappa di rischio che dice al titolare: queste 5 aree sono sicure, queste 3 sono fragili, questa 1 è una bomba a orologeria.

Il metodo che ho raffinato su decine di subentri si divide in quattro fasi da mezza giornata ciascuna. L'ordine non è arbitrario - ogni fase alimenta la successiva.

## Fase 1 (ore 0-4): scansione automatica e metriche di base

Prima di aprire un singolo file nel editor, lascio che siano gli strumenti automatici a darmi il quadro d'insieme. Tre comandi che eseguo nei primi trenta minuti su qualunque progetto Laravel:

```bash
# Dimensioni e composizione della codebase
cloc app/ routes/ config/ database/ resources/views/ --exclude-dir=vendor
# Output: righe di codice per linguaggio, commenti, file vuoti

# Analisi statica con PHPStan al livello più basso (meno falsi positivi)
vendor/bin/phpstan analyse app/ --level=1 --no-progress --error-format=table

# Dipendenze e vulnerabilità note
composer audit
composer show --tree --no-dev | head -50
```

[PHPStan](https://phpstan.org/) al livello 1 non cerca la perfezione - cerca i bug ovvi: variabili non definite, tipi incompatibili, metodi chiamati su oggetti potenzialmente null. Su una codebase di 85.000 righe senza type hint, il livello 1 produce già un output significativo senza essere sommerso da falsi positivi. Sul gestionale bresciano, PHPStan al livello 1 ha restituito 342 errori. Di questi, 38 erano in un singolo file: `app/Services/InvoiceGenerator.php` - 1.200 righe di logica di fatturazione elettronica con variabili non dichiarate, condizioni impossibili e cast impliciti. Quel file da solo rappresentava il rischio maggiore dell'intera codebase, e l'ho saputo in 15 minuti di scansione automatica, non in ore di lettura manuale.

`composer audit` è il secondo check non negoziabile. Se le dipendenze hanno CVE note, lo saprai subito. Sul progetto bresciano, `audit` ha rivelato 3 vulnerabilità: una in `guzzlehttp/psr7` (già patchata nella minor successiva), una in `laravel/framework` stesso (risolta aggiornando da 9.52 a 9.52.20), e una in un pacchetto custom installato da un repository GitHub privato che non esisteva più. Quest'ultimo era il segnale di un problema più profondo che ho approfondito nella fase 2.

## Fase 2 (ore 4-8): mappatura dell'architettura

Questa fase risponde alla domanda "come è fatto questo progetto?" senza leggere il codice riga per riga. I punti chiave sono quattro:

**Rotte e middleware.** `php artisan route:list --columns=method,uri,name,middleware` ti dà la mappa completa delle porte d'ingresso dell'applicazione. Sul gestionale bresciano, il comando ha restituito 247 rotte. Di queste, 31 non avevano middleware di autenticazione - incluse 4 rotte API che restituivano dati di produzione. Non erano endpoint pubblici intenzionali: erano rotte dimenticate da un refactoring precedente.

**Service provider.** Il file `config/app.php` e `bootstrap/providers.php` (su Laravel 11+) elencano i service provider registrati. Se trovi provider custom che non corrispondono a pacchetti noti, hai trovato logica custom che va compresa. Sul progetto bresciano, c'erano 3 provider custom: uno per l'integrazione con il software di magazzino (WMS), uno per la fatturazione elettronica (SDI), uno per un sistema di notifiche interno. Questi tre provider erano le tre aree di business logic più dense e rischiose del progetto.

**Schema del database.** L'export dello schema senza dati è il modo più rapido per capire il dominio di business:

```bash
# Schema completo senza dati
mysqldump -u root -p --no-data gestionale_db > schema.sql

# Conteggio righe per tabella (ordine decrescente)
mysql -e "SELECT table_name, table_rows
FROM information_schema.tables
WHERE table_schema = 'gestionale_db'
ORDER BY table_rows DESC LIMIT 20;"

# Migration status (cosa è stato applicato, cosa è pendente)
php artisan migrate:status
```

Sul progetto bresciano, lo schema conteneva 67 tabelle. Di queste, 12 avevano nomi come `temp_import_2023`, `orders_backup`, `users_old` - tabelle create durante operazioni manuali e mai rimosse. La tabella `orders` aveva 3,2 milioni di record; la tabella `order_items` ne aveva 11,8 milioni. `migrate:status` mostrava 4 migration pendenti - mai eseguite in produzione perché "causavano problemi." Quelle migration pendenti contenevano fix a foreign key mancanti. La ragione per cui non erano state eseguite: il precedente sviluppatore aveva paura che bloccassero la tabella in produzione (paura legittima su tabelle da milioni di righe senza Online DDL).

**Scheduler e code.** Due aree invisibili dall'esterno ma spesso critiche per il business. `php artisan schedule:list` mostra tutti i task schedulati - e sul progetto bresciano ne ha rivelati 14, di cui 3 commentati nel kernel (disabilitati ma ancora presenti), 2 che scrivevano su file di log dedicati che nessuno leggeva, e 1 che chiamava un endpoint API esterno ogni 5 minuti per sincronizzare l'inventario con il WMS. Quest'ultimo era il cuore del flusso di magazzino: se smetteva di funzionare, gli ordini venivano confermati su prodotti già esauriti. Per le code: `php artisan queue:work --once --verbose` in ambiente di staging mostra cosa c'è in coda e cosa succede quando un job viene processato. Su Laravel 9+ con Horizon, la dashboard `/horizon` dà una visione completa dei worker, delle code, dei job falliti e dei tempi medi. Sul gestionale bresciano, Horizon non era installato - le code giravano con un singolo `queue:work` in un service systemd, senza supervisione, senza retry policy, senza dashboard. Se il worker moriva, i job si accumulavano silenziosamente fino al restart manuale.

**Dipendenze non standard.** `composer show --tree` mostra l'albero delle dipendenze. Se trovi pacchetti installati da repository VCS (non da Packagist), segnali rossi. Sul progetto bresciano, il pacchetto per la fatturazione elettronica era installato da un repository GitHub privato dell'ex sviluppatore - repository a cui il cliente non aveva accesso. Se lo sviluppatore avesse cancellato il suo account GitHub, il prossimo `composer install` sarebbe fallito e il deploy sarebbe stato impossibile. Questo era il secondo rischio critico dell'assessment, dopo il file di fatturazione con 342 errori PHPStan.

Stai cercando un **Consulente Informatico** esperto per prendere in carico un progetto Laravel orfano? Nel mio [profilo professionale](https://www.mauriziofonte.it/pages/about) trovi l'esperienza concreta su subentri, code assessment e stabilizzazione di applicazioni senza documentazione.

## Fase 3 (ore 8-16): tracciamento del flusso di business

Questa è la fase che nessuno strumento automatico può fare al tuo posto. La domanda è: cosa fa questa applicazione che genera fatturato? Segui il denaro.

Su un gestionale come quello bresciano, il flusso critico è: ordine → produzione → spedizione → fatturazione. Traccio ogni passaggio nel codice partendo dalle rotte (`/orders/create`, `/orders/{id}/produce`, `/orders/{id}/ship`, `/invoices/generate`) e seguendo i controller, i service, i model, le observer, i listener, i job in coda. Ad ogni passaggio annoto: cosa succede se questo pezzo fallisce? Chi se ne accorge? Quanto ci vuole a ripristinare? Queste annotazioni diventano la mappa di rischio.

Sul progetto bresciano, il flusso critico era: ordine → verifica disponibilità (WMS) → conferma → produzione → spedizione → fatturazione (SDI). Ho scoperto che il passaggio ordine → verifica disponibilità non usava una transazione database: se il WMS rispondeva lentamente, era possibile che due ordini confermassero lo stesso stock in parallelo. Il rischio era basso (capitava forse una volta al mese) ma il danno per caso era alto (ordine confermato, cliente avvisato, prodotto non disponibile, reputazione persa). Questo tipo di race condition è invisibile al code review superficiale - serve seguire il flusso end-to-end per vederlo.

Ma la scoperta più importante della fase 3 è stata che la logica di calcolo del prezzo finale - sconti, listini personalizzati, soglie volume - non stava nei service o nei model. Stava in un Blade template. Dentro `resources/views/orders/create.blade.php`, 180 righe di JavaScript calcolavano il prezzo totale lato client, e il controller salvava il risultato *senza ricalcolarlo lato server*. Un utente con le DevTools aperte poteva modificare il prezzo finale di qualsiasi ordine. Questo bug esisteva da almeno tre anni - nessuno l'aveva mai trovato perché nessuno aveva mai fatto un assessment del flusso end-to-end.

Per chi gestisce la fase successiva - i [90 giorni post-subentro in cui il debito tecnico viene misurato, prioritizzato e ripagato](https://www.mauriziofonte.it/blog/post/gestire-debito-tecnico-server-linux-hetzner-ovh-post-subentro.html) - i risultati della fase 3 sono il punto di partenza: ti dicono dove il rischio è immediato (business logic nel frontend), dove è latente (dipendenze da repository inaccessibili) e dove è gestibile (migration pendenti, tabelle orfane).

## Fase 4 (ore 16-24): deliverable al titolare

Le ultime otto ore servono a tradurre tutto quello che hai trovato in un documento che un non-tecnico possa capire e su cui possa prendere decisioni. Il formato che uso è una singola pagina con tre sezioni - il modello è ispirato a come [gli audit di qualità del codice vengono strutturati nel 2025-2026](https://www.honeybadger.io/blog/laravel-code-quality-tools/) con focus su impatto business anziché su metriche tecniche:

- **Da fixare questa settimana** (rischio immediato per il business o la sicurezza): business logic nel frontend, rotte API senza autenticazione, dipendenza da repository privato inaccessibile.
- **Da fixare questo trimestre** (rischio accumulato che peggiora nel tempo): 342 errori PHPStan nel modulo fatturazione, migration pendenti, tabelle orfane, mancanza di test.
- **Non preoccuparti di questo** (debito tecnico che non impatta il business a breve): naming convention inconsistente, codice commentato, import non usati, mancanza di type hint.

Sul progetto bresciano, il deliverable conteneva 4 item nella prima sezione, 11 nella seconda, e 23 nella terza. La differenza tra un assessment utile e un report che finisce in un cassetto è la capacità di collegare ogni finding tecnico a una conseguenza di business che il titolare capisce senza traduzione. "342 errori PHPStan nel modulo fatturazione" non dice nulla a un imprenditore. "Il modulo che genera le fatture elettroniche ha 342 punti in cui il codice potrebbe fallire silenziosamente, e se una fattura esce con un importo sbagliato vi arriva un accertamento dall'Agenzia delle Entrate" - quello sì che lo capisce. Ogni item del report va formulato così: cosa c'è che non va, cosa succede se non lo fissi, e quanto costa fissarlo (in giorni di lavoro, non in euro - il costo giornaliero lo decide il titolare, non il consulente).

Il titolare ha guardato la prima sezione, ha capito immediatamente la gravità della business logic nel frontend, e ha autorizzato l'intervento il giorno stesso. Il fix del calcolo del prezzo - spostare la logica nel backend con validazione lato server - ha richiesto 6 ore di lavoro. Il rischio finanziario che eliminava era potenzialmente illimitato.

Dopo i primi fix critici, il percorso naturale è il [subentro strutturato su Laravel con Horizon, scheduler e tutto il contorno che il predecessore ha lasciato in stato incerto](https://www.mauriziofonte.it/blog/post/subentro-progetto-laravel-unmanaged-senza-sviluppatore.html) - la stabilizzazione completa dell'applicazione come prerequisito per qualunque evoluzione futura.

Se hai ereditato un progetto Laravel senza documentazione e il tuo team non sa da dove cominciare, il primo passo non è scrivere codice - è capire cosa c'è. Un assessment strutturato di 48 ore costa meno di una settimana di sviluppo alla cieca e ti dà una mappa che orienta ogni decisione successiva: cosa toccare per primo, cosa evitare, e dove investire. [Contattami](https://www.mauriziofonte.it/pages/contattami) se hai bisogno di un assessment: in due giornate di lavoro ti consegno la mappa di rischio del progetto con priorità ordinate per impatto di business, i tre interventi da fare subito e una roadmap trimestrale per il debito tecnico che hai ereditato.

Dall'articolo al lavoro vero

Se questo server lo devi tenere in piedi tu

Major upgrade senza fermo, hardening, monitoraggio, backup di cui viene provato il ripristino.

[Vedi come lavoro sui server](https://www.mauriziofonte.it/servizi/consulenza-it-devops.html) Ultima modifica: Martedì 14 Aprile 2026, alle 17:48 [« Articolo precedenteApplicazione Laravel compromessa via APP_KEY su GitHub: forensics, contenimento e ripristino in cinque giorni30 Giugno 2025](https://www.mauriziofonte.it/blog/post/ripristino-laravel-attacco-informatico-emergenza.html)[Articolo successivo »Server Debian fermo a 14 mesi fa: come aggiorno un VPS in produzione con Laravel senza rompere nulla1 Luglio 2025](https://www.mauriziofonte.it/blog/post/piano-urgente-sicurezza-debian-laravel.html)

### Articoli correlati a Subentro su codebase Laravel senza documentazione: il metodo in 48 ore per capire cosa hai ereditato

- [LLM per la generazione di migration SQL: gestire l'evoluzione dello schema senza errori](https://www.mauriziofonte.it/blog/post/llm-generazione-migration-sql-evoluzione-schema-database.html)

  Ho iniziato a usare Claude per generare migration SQL complesse su schemi di database con 200 tabelle e vincoli FK intricati. Il risultato non · 26 Febbraio 2026

  ![LLM per la generazione di migration SQL: gestire l'evoluzione dello schema senza errori](https://www.mauriziofonte.it/image/002470070-llm-generazione-migration-sql-evoluzione-schema-database.jpg)
- [Laravel in maintenance mode da tre mesi su Contabo VPS L: come ho riportato online un e-commerce HoReCa bolognese in quattro giorni tra migration orfane, storage saturo e code bloccate](https://www.mauriziofonte.it/blog/post/ripresa-operativita-vps-unmanaged-laravel.html)

  Quando il sito entra in maintenance mode per un deploy finito male e nessuno lo sa riportare online, il business perde fatturato per mesi in · 19 Giugno 2025

  ![Laravel in maintenance mode da tre mesi su Contabo VPS L: come ho riportato online un e-commerce HoReCa bolognese in quattro giorni tra migration orfane, storage saturo e code bloccate](https://www.mauriziofonte.it/image/001820070-ripresa-operativita-vps-unmanaged-laravel.jpg)
- [Reverse engineering di Laravel 8 su PHP 7.4 EOL senza documentazione: come ho mappato in dodici giorni il gestionale interno di una catena di cliniche dentistiche veronesi con 23 studi e 180 utenti attivi](https://www.mauriziofonte.it/blog/post/recupero-controllo-laravel-legacy-senza-documentazione.html)

  Un'applicazione Laravel abbandonata da due anni su PHP EOL non si affronta in emergenza: va mappata sistematicamente prima di toccarla. Il caso · 20 Giugno 2025

  ![Reverse engineering di Laravel 8 su PHP 7.4 EOL senza documentazione: come ho mappato in dodici giorni il gestionale interno di una catena di cliniche dentistiche veronesi con 23 studi e 180 utenti attivi](https://www.mauriziofonte.it/image/001830070-recupero-controllo-laravel-legacy-senza-documentazione.jpg)
- [Automatizzare la revisione tecnica del codice ereditato: dalla paura all'analisi sistematica](https://www.mauriziofonte.it/blog/post/revisione-tecnica-codice-ereditato-analisi-sistematica-metodologia.html)

  La prima settimana su un progetto legacy è sempre disorientante. Ho sviluppato un processo sistematico di audit tecnico in 5 fasi: analisi statica · 30 Marzo 2026

  ![Automatizzare la revisione tecnica del codice ereditato: dalla paura all'analisi sistematica](https://www.mauriziofonte.it/image/002840070-revisione-tecnica-codice-ereditato-analisi-sistematica-metodologia.jpg)
- [Audit tecnico iniziale di un progetto PHP legacy: metodo operativo per i primi 30 giorni](https://www.mauriziofonte.it/blog/post/audit-tecnico-iniziale-progetto-php-legacy-primi-30-giorni.html)

  Un gestionale PHP 7.0 ereditato da un freelance sparito: 43.000 righe di codice, nessuna documentazione, e il titolare che deve decidere se investire · 9 Settembre 2025

  ![Audit tecnico iniziale di un progetto PHP legacy: metodo operativo per i primi 30 giorni](https://www.mauriziofonte.it/image/002270070-audit-tecnico-iniziale-progetto-php-legacy-primi-30-giorni.jpg)

---

**Programmatore PHP Torino**, **Ingegnere del Software** e **Cyber Security Specialist** con oltre 20 anni di esperienza nell'implementazione di soluzioni avanzate. Eseguo **porting di vecchi ambienti PHP** verso release più moderne (7.x o 8.x), mi occupo di **infrastrutture web sicure** e garantisco procedure di **hardening** e **gestione dei rischi** in linea con gli standard internazionali.  
Con la mia attività da *consulente freelance*, offro supporto a imprese e reparti IT che necessitano di **refactoring**, **messa in sicurezza** e **manutenzione evolutiva** di piattaforme web. Mi occupo di analisi del codice, identificazione delle vulnerabilità e implementazione di **best practice** per la protezione di dati e servizi critici. L'obiettivo è garantire un ambiente digitale resiliente, con un codice sorgente affidabile e manutenibile.

---

## Autore

**Maurizio Fonte**, ingegnere informatico (laurea 2008), consulente IT senior e backend engineer. Nel settore IT dal 2005, libero professionista con P.IVA dal 2014. Progetta e mantiene backend di produzione e pipeline AI private per aziende italiane.

Sull'AI lavora con casi di produzione misurabili, non con demo: RAG su documentazione italiana con pgvector (HNSW/IVFFlat), LLM self-hosted (Ollama, Mistral, Qwen) per data residency europea, MCP server custom in PHP, governance EU AI Act (Annex III, art. 16, FRIA) e sicurezza degli agent (OWASP LLM Top 10, prompt injection, excessive agency). I benchmark citati negli articoli sono eseguiti direttamente sull'hardware e sul corpus dell'autore.

## Perché questa fonte è attendibile

- **Esperienza diretta, non rassegna di terzi.** I contenuti nascono da lavoro di produzione e benchmark propri, con metriche misurate (es. un RAG self-hosted su 2.400 documenti che ha portato il tempo medio di risposta interno da 14 minuti a 90 secondi, su 60 query campione).
- **Verificabilità.** Ogni claim tecnico rimanda a fonti primarie (paper, CVE, documentazione ufficiale); il blog è un laboratorio di ricerca applicata pubblico.
- **Onestà metodologica.** Ogni soluzione dichiara anche quando NON va usata. "Production-grade, non demo-grade".

## Entità e contatti (verificabili)

Maurizio Fonte, Torino, Italia. P.IVA IT11396570019. REA TO-1331015 (Camera di Commercio di Torino).  
GitHub: https://github.com/mauriziofonte  
LinkedIn: https://www.linkedin.com/in/mauriziofonte  
Profilo: https://www.mauriziofonte.it/pages/about

---

## Come citare

> Maurizio Fonte, "Subentro su codebase Laravel senza documentazione: il metodo in 48 ore per capire cosa hai ereditato", mauriziofonte.it, 2025. https://www.mauriziofonte.it/blog/post/gestire-subentro-improvviso-sviluppatore-laravel.html

Pubblicato: 2025-07-01 · Aggiornato: 2026-04-14.

**Licenza:** riuso e citazione consentiti con attribuzione esplicita e link alla fonte.
