modulo 08 / lezione 64

Pubblicare con responsabilità: sicurezza e progetto integrato

Capstone — generazione iterativa con commit piccoli

Costruire il prototipo in sequenza controllata, mantenendo cronologia, rollback e revisioni leggibili.

90 min Vibe Coding

Capstone — generazione iterativa con commit piccoli

Setup pronto, architettura scritta. Ora costruisci. Non in un colpo: in passi piccoli, ognuno verificabile, con commit leggibile. La sequenza ben ordinata trasforma il progetto da “una grande sessione AI” a “30 piccole iterazioni” — ogni una rivedibile, rollbackabile, dimostrabile.

Perché questa lezione conta

Generazione monolitica = nessun controllo + nessun apprendimento. Generazione iterativa = controllo a ogni passo + apprendimento incrementale + rollback sicuro. La prima è veloce solo apparentemente: se va male, riinizi tutto. La seconda è più disciplinata ma converge.

Obiettivo operativo

Alla fine della sessione devi avere:

  1. 3-5 commit del capstone in branch dedicato;
  2. ogni commit verificato (test/manuale);
  3. cronologia leggibile (commit message Conventional);
  4. piano per i prossimi passi.

Nucleo della lezione

1. Ordine raccomandato

Sequenza tipica per app capstone (basata su lezione 20):

1. Setup minimo (commit “chore: initial setup”): scaffolding, config base. Già fatto in lezione 61.

2. Schema dati (commit “feat(db): add habits and entries schemas”): schema IndexedDB, tipi TS. Niente UI ancora.

3. UI statica (commit “feat(ui): add HabitList and HabitForm components”): componenti che mostrano dati hardcoded. Click non fanno niente.

4. Stato locale (commit “feat(ui): connect components to local state”): form invia dati, lista mostra dati locali. Persistenza no.

5. Persistenza (commit “feat(db): wire HabitList and HabitForm to IndexedDB”): aggiungi/modifica/leggi da IndexedDB.

6. Flusso principale (commit “feat: complete main flow add habit + toggle today”): caso normale end-to-end funziona.

7. Casi limite (commit “fix: handle empty state and edge cases”): stati vuoti, errori, casi limite.

8. Test (commit “test: add unit tests for db wrapper”): test minimi su logica core.

9. Polish UX (commit “polish: improve mobile and accessibility”): mobile, tastiera, contrasto.

Ogni commit:

  • è verificabile (puoi eseguire e vedere che funziona);
  • è committabile da solo;
  • è reversibile (revert isolato).

Idealmente 8-15 commit per MVP. Più di 30 = stai dividendo troppo. Meno di 5 = stai dividendo poco.

2. Prompt per ogni passo

Pattern ripetibile (dalla lezione 17 + 18):

Stiamo lavorando al capstone [nome]. Riferimenti:
- AGENTS.md
- docs/architettura.md
- docs/decisions.md
- docs/capstone-brief.md

Branch corrente: feat/passo-N
Ultimo commit: [hash o messaggio]

Task corrente: [passo N specifico]

File ammessi: [lista esplicita]
File vietati: tutto il resto + config + .env*
No nuove dipendenze. No refactor laterale.

Procedura:
1. Conferma e parafrasa il task.
2. Lista assunzioni.
3. Piano in 3-5 punti.
4. Aspetta mio OK.
5. Implementa.
6. Mostra diff.
7. Esegui [comando di verifica].
8. Spiega cosa hai fatto, cosa non hai verificato, rischi residui.

Aspetto autorizzazione esplicita prima di iniziare.

Riusabile per ogni passo, sostituisci solo “task corrente” e “file ammessi”.

3. Verifica passo per passo

Dopo ogni generazione:

Diff: leggi tutto. Cerca segnali pericolosi (lezione 35).

Verifica funzionale: comando di test passa? Manuale: caso normale funziona?

Coerenza con architettura: il modello ha rispettato il diagramma? File nel posto giusto? Pattern coerenti?

Aggiungi al decision log se durante il passo è emersa decisione nuova.

Commit se ok.

Se non ok: git reset --hard, riformula. Non patchare.

Sequenza guidata di tre commit

Per il capstone “registro spese”, non chiedere “costruisci tutta l’app”. Procedi così:

Commit 1 — dominio

Implementa solo tipi e funzioni pure:
- Expense
- Category
- validateExpenseInput
- calculateMonthlyTotal
Niente UI, niente storage, niente librerie.
Aggiungi esempi o test minimi.

Review: le regole sono leggibili? Gli errori sono espliciti? I test coprono importo negativo e data mancante?

Commit 2 — storage

Aggiungi repository IndexedDB dietro interfaccia ExpenseRepository.
Non modificare funzioni dominio.
Aggiungi fallback errore e smoke test manuale.

Review: la UI ancora non c’è, ma persistenza è isolata.

Commit 3 — UI flusso principale

Crea form + lista usando funzioni e repository esistenti.
Niente grafici, niente filtri avanzati.
Gestisci vuoto, loading, errore.

Ora hai una verticale funzionante. Ogni commit ha un comportamento verificabile e un rollback chiaro. Se il commit 3 fallisce, dominio e storage restano buoni.

Controllo dopo ogni commit

Dopo ogni commit, compila una riga:

Commit:
Obiettivo:
File modificati:
Verifica eseguita:
Rischi rimasti:
Prossimo passo:

Esempio:

Commit: feat(expenses): add domain validation
Obiettivo: validare importo, data e categoria.
File modificati: src/lib/expenses/domain.ts, domain.test.ts.
Verifica eseguita: test unitari su importo negativo, data mancante, categoria vuota.
Rischi rimasti: parsing valuta localizzata non deciso.
Prossimo passo: repository IndexedDB dietro interfaccia.

Questa mini scheda impedisce di procedere per inerzia. Se non sai scrivere “verifica eseguita”, il commit non è pronto. Se “rischi rimasti” è vuoto per dieci commit, probabilmente non stai guardando abbastanza.

Il ritmo corretto è: prompt piccolo, diff piccolo, verifica piccola, commit piccolo. Quando uno di questi quattro diventa grande, fermati e spezza il lavoro prima di chiedere altro codice.

Procedura pratica

90 minuti = 3-5 passi:

  1. Branch (1 min): git checkout -b feat/passo-1.
  2. Prompt (5 min): scrivi seguendo il pattern.
  3. Generazione + interazione (15-20 min): piano, autorizza, modifica, mostra diff.
  4. Verifica (5 min): comando + manuale.
  5. Commit (1 min): messaggio Conventional.
  6. Aggiorna AGENTS.md/decisions.md se serve (5 min).
  7. Pausa (3 min): rilettura passo, decisione su passo successivo.
  8. Ripeti per altri 2-4 passi.

Laboratorio guidato

Capstone: tracker abitudini.

Passo 1: Schema dati.

Prompt:

Task: definire tipi TypeScript e wrapper IndexedDB per Habits e HabitEntries.

File ammessi: src/lib/db.ts, src/types.ts.

Schema (da architettura):
- Habits: id, name, color, createdAt
- HabitEntries: id, habitId, date (YYYY-MM-DD), done

Wrapper deve esporre:
- listHabits(): Promise<Habit[]>
- createHabit(input): Promise<Habit>
- updateHabit(id, patch): Promise<Habit>
- deleteHabit(id): Promise<void>
- getEntriesForDate(date): Promise<HabitEntry[]>
- toggleEntry(habitId, date): Promise<HabitEntry>

Vincoli:
- usa libreria `idb` (è in package.json)
- gestione errori con Result<T, AppError>
- niente componenti UI ancora

Verifica: bun run astro check passa.

Procedura: piano → OK → implementazione → diff → verifica.

Output dell’AI: piano in 4 step, conferma assunzioni, propone codice.

Tu: leggi piano, OK. Modello implementa. Tu leggi diff (~80 righe), tutto coerente, in posti giusti. Type check passa.

Commit: feat(db): add Habit and HabitEntry types with IndexedDB wrapper.

Passo 2: UI statica HabitList.

(replica pattern, file ammessi src/components/HabitList.astro o .tsx, dati hardcoded di 3 abitudini fittizie)

Commit: feat(ui): add HabitList component with hardcoded data.

Passo 3: connetti UI a DB.

(prompt che mostra HabitList ora, chiede di sostituire dati hardcoded con chiamate a listHabits())

Commit: feat(ui): connect HabitList to IndexedDB.

A 90 minuti hai 3 commit, base solida. Prossima sessione continua da qui.

Output atteso

3-5 commit del capstone in branch dedicato. Cronologia leggibile. Cliente può clonare repo e seguire.

Studio passo passo

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

  1. Prima lettura: chiarisci l’obiettivo: costruire il prototipo in sequenza controllata, mantenendo cronologia, rollback e revisioni leggibili. Se non riesci a riscriverlo in una frase tua, rileggi il nucleo della lezione.
  2. Seconda lettura: trasforma i contenuti in domande operative:
  • Ordine consigliato: setup, modello dati, UI statica, flusso principale, persistenza, errori, test, rifinitura.
  • Prompt per ogni micro-step: obiettivo, file ammessi, cosa non toccare, verifica richiesta.
  • Commit come checkpoint: salvare ogni passaggio funzionante prima di chiedere il successivo.
  1. Applicazione: svolgi il laboratorio: implementare tre passi del capstone con tre commit separati e revisione del diff dopo ciascuno. L’output da ottenere è: una prima versione funzionante del prototipo con cronologia leggibile e task successivi chiari.

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

  • branch dedicato per la sessione;
  • ogni commit ha messaggio Conventional;
  • ogni commit è verificato (test o manuale);
  • diff letti prima di accettare;
  • nessuna nuova dipendenza non approvata;
  • AGENTS.md/decisions.md aggiornati se necessario.

Errori comuni

Saltare il piano. Vai diretto al codice. Modello sceglie scelte non condivise.

Commit gigante. “Tutta la feature in un commit”. Storia inutilizzabile.

Niente verifica fra commit. Cinque commit, alla fine “rotto”, non sai dove.

Patchare invece di reset. Se diff è cattivo, git reset --hard e ricomincia.

Dimenticare AGENTS.md updates. Convenzioni emerse durante il passo non finiscono nel file. Prossima sessione il modello le ignora.

Sessioni troppo lunghe. Dopo 90-120 minuti, attenzione cala. Pausa.

Prompt di lavoro

(vedi sezione 2 sopra: pattern riusabile)

Esercizio finale

Sessione di 90 min sul tuo capstone. Misura: numero di commit, righe modificate per commit (target ≤100), tempo medio per passo, quante volte hai fatto reset. Se hai 3-5 commit puliti e zero reset, ritmo è sostenibile. Se hai 1 commit gigante o 5 reset, rivedi taglia dei task.