modulo 03 / lezione 20

Dal problema al prompt

Decomposizione: spezzare richieste grandi in passi piccoli

Evitare generazioni monolitiche e costruire una sequenza di modifiche leggibili, testabili e reversibili.

75 min Vibe Coding

Decomposizione: spezzare richieste grandi in passi piccoli

Una richiesta da 5 ore al modello produce un disastro. Cinque richieste da un’ora producono cinque cose verificabili e quattro punti di reset se qualcosa va male. La decomposizione non è una tecnica avanzata: è il modo in cui costruisci controllo sull’AI.

Perché questa lezione conta

Il modello non si stanca, non dimentica nel mezzo di una generazione, può davvero produrre 1000 righe in un colpo. Ma tu non puoi leggerle tutte. E quando 1000 righe contengono 3 errori sottili, trovarli costa più che riscrivere. Decomposizione in passi piccoli sposta il costo dal “riparare disastri” al “verificare ogni passo”.

Obiettivo operativo

Alla fine devi saper:

  1. distinguere feature verticale e orizzontale;
  2. scomporre una richiesta grande in 5-10 passi atomici;
  3. scegliere l’ordine dei passi in base a rischio e dipendenze.

Nucleo della lezione

1. Verticale vs orizzontale

Feature verticale: un piccolo flusso utente completo end-to-end. Tocca UI, logica, dati, ma fa solo una cosa.

Esempio: “utente può registrare email con conferma via link”. Tocca form (frontend), endpoint /register (backend), tabella users (DB), invio email (servizio esterno), pagina conferma. Cinque pezzi, ma tutti per UN flusso.

Feature orizzontale: infrastruttura larga ma non chiude un flusso utente.

Esempio: “implementare sistema di autenticazione”. Setup auth provider, schema DB, middleware, decoratori, helper. Niente di questo è usabile da utente finale fino a integrazione completa.

Verticale è sempre meglio quando possibile. Vantaggi:

  • ogni passo produce qualcosa di osservabile;
  • demo possibile a metà strada;
  • feedback utente più rapido;
  • abbandono possibile dopo passo 1 senza buttare tutto.

Orizzontale serve solo quando un’infrastruttura comune va costruita prima di tre o più verticali futuri. In dubbio: verticale.

2. Passi atomici tipici

Sequenza standard per una feature verticale (adatta a quasi tutto):

  1. Setup minimo: file, route, struttura iniziale. Non funziona ancora ma scaffolding c’è.
  2. Modello dati: schema DB / tipo TypeScript / Pydantic / etc. Niente UI ancora.
  3. UI statica: layout, componenti, niente stato. Click non fanno nulla.
  4. Stato locale: gestione form, toggle, dropdown. UI reattiva ma non persiste.
  5. Persistenza: chiamata API + scrittura DB. Dati sopravvivono al refresh.
  6. Validazione: lato client (UX) + lato server (sicurezza).
  7. Gestione errori: rete, server, validazione, edge case.
  8. Test: unit test logica + smoke test flusso.
  9. Pulizia: nomi, dead code, commenti, documentazione.

Ogni passo:

  • è verificabile (puoi eseguire e vedere qualcosa);
  • è committabile (commit message ha senso);
  • è reversibile (revert isolato non distrugge altro).

3. Scegliere l’ordine

Non è sempre 1→2→3. Tre criteri per scegliere il prossimo passo:

  • Rischio: parti dal passo più incerto. Se “non so se la libreria X funziona col mio caso”, testala in un mini-passo prima di costruirci sopra.
  • Dipendenze: passo Y richiede output di passo X? Y dopo X.
  • Valore dimostrabile: in stallo? Fai il passo che produce demo visibile, mantiene motivazione.
  • Facilità di verifica: dubbio fra due passi simili? Quello più facile da testare prima.

Errore frequente: ordine “naturale” 1→9 quando in realtà passo 5 è il più rischioso e dovrebbe essere fatto subito (con scaffold minimo) per ridurre incertezza.

Procedura pratica

Per ogni richiesta grande:

  1. Scrivi richiesta intera come prima formulata.
  2. Identifica tipo: verticale o orizzontale? Se orizzontale, prova a tagliare in verticali.
  3. Decomponi: lista numerata 5-10 passi seguendo schema atomico.
  4. Per ogni passo: cosa fa, file toccati, criterio di “fatto”, rischio (basso/medio/alto).
  5. Riordina: priorità a rischi alti per ridurre incertezza presto.
  6. Esegui un passo per volta, commit a ogni passo.

Tempo decomposizione: 15-20 min. Tempo recuperato: ore.

Laboratorio guidato

Richiesta grande: “aggiungi al sito personale una sezione blog con autore, post, commenti, ricerca, RSS”.

Decomposizione in 8 passi atomici:

  1. Schema dati: tipi Post, Author, Comment. Solo definizioni, niente DB ancora. Verifica: typecheck passa. Rischio: basso.
  2. Routing: route /blog, /blog/[slug]. Pagine vuote con titolo. Verifica: URL navigabili. Rischio: basso.
  3. Lista post statica: dati hardcoded in array. Componente PostList. Verifica: vede 3 post finti. Rischio: basso.
  4. Pagina singolo post: legge slug da URL, mostra post. Verifica: click su post → pagina dettaglio. Rischio: basso.
  5. Sorgente dati reale: file markdown locali con frontmatter. Verifica: posti finti rimossi, post veri caricati. Rischio: medio (parsing, frontmatter).
  6. Commenti: commenti come thread, persistenza locale (per ora). Verifica: aggiunta, visualizzazione, refresh persiste. Rischio: medio.
  7. Ricerca: input nella pagina blog, filtra per titolo+contenuto. Verifica: digito → lista filtra. Rischio: basso.
  8. RSS: endpoint /blog/rss.xml. Verifica: feed validator passa. Rischio: medio (specifica RSS).

Ordine raccomandato: 1, 2, 3, 4, 5, 7, 6, 8. Commenti spostati dopo perché meno critici di “vedere i post”. Posso fermarmi a 5 e avere già un blog funzionante.

Stima ore per passo: 30 min - 2 ore. 6 commit reversibili. 2 punti dove posso fermarmi e considerare “pronto” (passo 4 = blog statico, passo 5 = blog reale).

Output atteso

Per la prossima feature reale, una scheda di decomposizione con: passi numerati, file toccati, criterio “fatto”, rischio. Salva e usa come piano operativo.

Studio passo passo

Studia questa lezione in tre passaggi, senza correre subito al prompt o al codice.

  1. Prima lettura: chiarisci l’obiettivo: evitare generazioni monolitiche e costruire una sequenza di modifiche leggibili, testabili e reversibili. Se non riesci a riscriverlo in una frase tua, rileggi il nucleo della lezione.
  2. Seconda lettura: trasforma i contenuti in domande operative:
  • Feature verticali e orizzontali: differenza tra completare un piccolo flusso e preparare infrastruttura larga.
  • Passi atomici: setup, modello dati, UI statica, stato, persistenza, validazione, test, pulizia.
  • Criteri per scegliere il prossimo passo: rischio, dipendenze, valore dimostrabile, facilità di verifica.
  1. Applicazione: svolgi il laboratorio: prendere una richiesta grande e dividerla in otto task ordinati con confini chiari. L’output da ottenere è: una roadmap di implementazione a micro-commit da usare con un agente o un IDE AI.

Prima di passare alla lezione successiva, controlla di avere un artefatto concreto: una tabella, un prompt, una checklist, un mini report, un diff commentato o una decisione scritta. Nel vibe coding la comprensione resta astratta finché non produce una traccia verificabile.

Checklist di verifica

  • so distinguere feature verticale e orizzontale;
  • ho un esempio recente in cui ho decomposto una richiesta grande;
  • ogni mio passo ha criterio “fatto” osservabile;
  • ho almeno una volta riordinato i passi per fare prima il rischioso, non il facile.

Errori comuni

Decomposizione finta. “1: aggiungi blog. 2: aggiungi commenti.” Non sono passi, sono titoli. Passo deve avere file e criterio.

Solo passi facili in cima. Ti senti produttivo, accumuli debito su passi rischiosi che esploderanno alla fine.

Passo troppo grande. “Implementa autenticazione” è una mezza feature. Decomponi ulteriormente: schema, signup, login, sessione, logout.

Niente commit fra passi. Tutto in un unico commit gigante. Se passo 7 fallisce, non puoi tornare a passo 5 perché tutto è insieme. Commit per passo.

Decomposizione che ignora dipendenze. Passo 5 richiede passo 3 ma viene messo prima. Verifica grafico dipendenze.

Sovra-decomposizione. 50 passi per feature piccola. Diventa burocrazia. Idealmente 5-12 passi per feature media.

Prompt di lavoro

Devo implementare questa feature: [descrizione]

Aiutami a decomporre. Prima di tutto:
1. Identifica se è verticale o orizzontale.
2. Se orizzontale, suggerisci come trasformarla in 1+ verticali.

Poi proponi 5-10 passi atomici. Per ogni passo:
- Cosa fa (1 riga)
- File toccati
- Criterio di "fatto" osservabile
- Rischio (basso/medio/alto) con motivazione
- Dipendenze da altri passi

Riordina i passi per:
- ridurre incertezza presto (rischi alti prima, con scaffold minimo);
- rispettare dipendenze;
- avere almeno un punto intermedio dimostrabile;
- accettare di fermarsi prima della fine se il valore basta.

Output: tabella dei passi nell'ordine raccomandato.
Non scrivere codice. Aspetta che io approvi la decomposizione e ti chieda di iniziare passo 1.

Esercizio finale

Riguarda l’ultima feature grande che hai chiuso. Ricostruisci a posteriori la decomposizione “ideale” in 5-10 passi atomici. Confronta con come hai effettivamente lavorato: hai fatto passi grandi? hai mescolato passi senza commit fra loro? hai saltato il passo rischioso e te lo sei trovato in faccia alla fine? Quasi sempre sì. La decomposizione non si improvvisa, si applica come metodo.