Fase 5: Sincronizzazione dei progressi con UUID
Obiettivo: Persistire lo stato di completamento di ciascun utente e ridipingere la sidebar al reload, il tutto senza account utente. ACU consumati: 2,7 (previsti 2–3). Esito: Una piccola hook React ora salva un UUID generato dal browser, chiama l’API GraphQL a ogni passaggio dei test e precarica i progressi all’avvio del playground.
Cosa ha fatto davvero Devin
Per la quinta fase, Devin ha:
- Integrato Apollo Client per la comunicazione GraphQL tra frontend e backend
- Implementato la gestione di sessioni anonime con UUID memorizzati in localStorage
- Sincronizzato i dati di progresso in tempo reale e gli indicatori visivi sia a livello di categoria che di esercizio
- Rilevato il completamento dell’esercizio agganciandosi al test runner Vitest nel browser
- Aggiunto supporto offline, aggiornamenti ottimistici e gestione robusta degli errori con retry (che non avevo richiesto).
Uno dei vantaggi è che Devin ha aggiunto l’aggiornamento ottimistico della UI, così i badge passano a ✅ all’istante. È importante perché mantiene l’interfaccia scattante anche con connessioni ad alta latenza.
Lezioni apprese
I miei takeaway sono:
- Ambito ridotto = pochi errori: era un task piuttosto piccolo e ben delimitato, quindi Devin l’ha eseguito bene e in tempi buoni.
- Di’ cosa vuoi, ma anche cosa non vuoi: ho notato che Devin tende a estendere lo scope e, ancora una volta, mi ha dato più di quanto avessi chiesto. In questo caso non mi ha disturbato, ma se c’è qualcosa che davvero non vuoi che faccia, dillo esplicitamente. Per esempio, in ogni singolo prompt ho specificato “niente login” perché immaginavo avrebbe provato ad arrivarci.
Ora abbiamo la prova che la pipeline delle sessioni anonime funziona end-to-end. È il momento di farla sembrare bella nell’ultima fase di finitura.
Fase 6: Finitura UI & dashboard dei progressi
Obiettivo: Trasformare l’interfaccia utilitaristica in un’esperienza “pastello e ariosa” e aggiungere un dashboard che visualizzi la streak di ciascun utente, la scala di difficoltà e l’attività settimanale. ACU consumati: 11 (previsti ≈ 3). Esito: Temi pastello chiaro/scuro, card degli esercizi ridisegnate e un dashboard live con anelli, barre e contatori di streak. Devin ha centrato le linee generali, ma sono intervenuto per salvare incongruenze nei nomi e sostituzioni di dipendenze non richieste.
In questa fase ho volutamente ampliato lo scope per vedere come Devin avrebbe gestito un set più ampio di richieste. Pensavo fosse molto più facile per Devin rispetto alla fase 3, con tutta l’implementazione del backend. Spoiler: mi sbagliavo.
Cosa ha affrontato Devin dal prompt
Questa è la ripartizione delle mie richieste e dell’output di Devin:
|
Requisito |
Output di Devin |
|
Design system pastello |
Aggiunte variabili Tailwind CSS per primario azzurro soft, success menta, accenti lavanda. Angoli |
|
Tipografia & spaziatura |
Introdotta una classe |
|
Dashboard dei progressi |
Nuova route
|
|
Card migliorate |
Sostituito |
|
Espansione del catalogo |
Generate altre 10 bozze di esercizi con nomi narrativi e template placeholder. I metadata includono difficoltà, tempo stimato e categoria. |
Dove Devin ha sbagliato
Non tutto è andato liscio — Devin:
- Ha cambiato i nomi dei file del pacchetto degli esercizi senza aggiornare wrapper o resolver → 500 a runtime; patch +1 ACU.
- Ha sostituito silenziosamente Postgres con SQLite “per semplificare lo sviluppo locale” senza chiedere il mio ok. Non l’avrei saputo se non stessi guardando.
- Ha lasciato decine di
console.lognei componenti React, e i lint check continuavano a riprovare.
Lezioni apprese
I miei takeaway:
- La logica del dashboard ha ancora bisogno di lavoro: Devin ha cablato i contatori di streak e tempo trascorso ma li ha lasciati non funzionanti. Le metriche di back-end dovrebbero avere almeno un test di integrazione, così la UI “happy path” non viene mergiata prematuramente.
- L’uso degli ACU accelera nelle sessioni lunghe: dopo ~8 ACU, la sessione è rallentata sensibilmente. Sessioni brevi e con limite (< 5 ACU) mantengono il contesto nitido e l’agente reattivo.
- Devin “aiuterà” a scambiare dipendenze: ha sostituito Postgres con SQLite senza chiedere. Fissa i servizi critici nel prompt: “Non cambiare il motore del database; resta su Postgres.”
- I task di design innescano churn da hot-reload: ogni refresh di Tailwind/Vite conta come tempo dell’agente. Forse è meglio mettere in pausa la sessione prima di modifiche massive agli stili e risvegliare Devin quando il progetto compila pulito.
Questo task è stato lungo e costoso rispetto al resto del lavoro. Almeno Devin è consapevole di dove sono nati i problemi:

Qualcosa di carino c’è, ma ha richiesto tempo e non è del tutto funzionale. Alcune metriche del dashboard sono hardcodate — due esercizi nella nostra categoria option? Ne abbiamo 10. Anche le metriche di streak e tempo trascorso non sono collegate a nulla, e la UI nelle pagine dei singoli esercizi è piuttosto scadente.
Retrospettiva su costi & tempi
Come sono andati i numeri
Ecco un riepilogo di com’è andata:
|
Fase |
ACU previsti |
ACU effettivi |
Delta |
Note |
|
1 – Workspace & impalcatura |
1 – 2 |
3,66 |
▲ ≈ 1,7 |
Loop extra su |
|
2 – Pacchetto esercizi |
2 |
0,60 |
▼ 1,4 |
Spostamenti semplici di file; nessuna installazione pesante |
|
3 – API & Prisma |
4 |
4,20 |
▲ 0,2 |
Grane di configurazione (mancava |
|
4 – Playground & test |
3 – 4 |
7,20 |
▲ ≈ 3,5 |
Cicli di hot-reload, stallo del merge-editor |
|
5 – Sincronizzazione progressi |
2 – 3 |
2,70 |
▼ ≈ 0,3 |
Hook + query lineari |
|
6 – Finitura UI & dashboard |
2 – 3 |
11,00 |
▲ ≈ 8 |
Re-installazioni, swap DB silenzioso, grossi reload CSS |
|
Totale |
18 – 24 |
29,36 |
▲ ≈ 6 – 11 |
Circa il 35% oltre la stima iniziale |
|
Costo: 29,36 ACU × $2,25 ≈ $66 | ||||
Tempo risparmiato vs lavoro manuale
Questa è la mia stima del tempo risparmiato:
|
Task |
Stima umana |
Devin (+ fix) |
Netto |
|
Bootstrap di NestJS + GraphQL + Prisma |
4 ore |
1 ora (incl. fix) |
−3 ore |
|
Collegare Sandpack + Vitest nel browser |
3 ore |
1 ora 20 min |
−1 h 40 min |
|
Redesign completo pastello & dashboard |
6 ore |
2 ore (ma ancora non funzionale) |
−4 h |
|
Tempo totale |
~13 ore |
~4 ore 20 min |
-8 ore 40 min |
Punti chiave
Queste sono le cose che consiglio:
|
Tema |
Cosa fare |
Perché conta |
|
Tieni le sessioni brevi |
• Limita ogni esecuzione a ≤ 5 ACU. • Spezza grandi obiettivi in ticket masticabili. |
Le sessioni > 8 ACU sono lente, e i tassi di errore saltano a ≈35%. Raffiche brevi restano reattive e più economiche. |
|
Sollecita presto, metti spesso in pausa |
• Guarda la scheda Timelapse; se Devin entra in loop, digita “Continua” o “Dormi”. • Metti in pausa mentre fai mass-edit di CSS o documenti, poi riattiva Devin quando il codice compila. |
I loop inattivi continuano a far correre il contatore; il churn da hot-reload durante il design è puro consumo di ACU. |
|
Tratta la config come lavoro manuale |
• Sposta/rinomina grandi alberi di file tu stesso (drag & drop batte script da 0,8 ACU). • Correggi manualmente gli errori di pacchetti al primo avvio, i retry sono pozzi di ACU. |
I/O su file e installazioni ripetute rappresentano ~30% dei crediti sprecati. |
|
Esegui lint & type-check in locale |
• Esegui sempre gli script di test (nel nostro caso, lint e typecheck) prima del merge. • Aggiungi questi comandi alla tua CI (ne parleremo nel prossimo tutorial!). |
Devin può dichiarare successo anche quando la pipeline fallisce. |
|
Fissa le tecnologie critiche |
• Indica ciò che non deve cambiare: “Resta su Postgres, niente login, tieni Tailwind”. • Elenca le env richieste in |
Devin “aiuterà” a scambiare Postgres con SQLite o ad aggiungere nuovi runner di test se non gli dici di non farlo. |
|
Gestisci tu i segreti |
• Rimuovi i file • Pianifica uno step con un secret manager per i prossimi tutorial. |
Devin non distingue necessariamente le credenziali finte da quelle reali. |
|
Elimina gli stalli del merge editor |
• Intervieni per aiutare con i merge commit e l’uscita dai processi. |
I blocchi in Vim fanno sprecare minuti e ACU. |
|
Elimina presto il codice morto |
• Dopo gli spostamenti, fai |
File ridondanti confondono l’agente e gonfiano i tempi di build. |
|
Aggiungi unit test per la nuova logica |
• I contatori di streak, i timer o le metriche richiedono test di backend; non fidarti solo della UI. Ancora un po’ di pazienza: lo vedremo nel prossimo tutorial. |
Devin ha cablato il dashboard ma ha lasciato i contatori non funzionanti finché i test non hanno evidenziato il gap. |
|
Di’ cosa vuoi e cosa non vuoi |
• Negativi espliciti (“Niente auth per ora”) prevengono l’allargamento di scope. • Rivedi il piano proposto da Devin e taglia gli extra. |
L’agente tende a “sovra-consegnare”: ottimo per le demo, pessimo per i budget. |
E adesso?
Ora abbiamo:
- Un playground rifinito in pastello che esegue i test fp-ts nel browser
- Un’API NestJS + PostgreSQL che ricorda i progressi con nient’altro che un UUID
- Un dashboard dei progressi che è anche divertente da usare
Nel prossimo tutorial, sposteremo il focus dalle funzionalità al workflow e alla collaborazione con:
- Test continui: aggiungi suite Jest e Playwright, poi lascia che Devin le tenga entrambe verdi a ogni PR.
- Pipeline CI/CD: genera GitHub Actions che buildano le app web e API ed eseguono i test in Chrome headless.
- Integrazioni di team: collega Devin a Jira per gli aggiornamenti dei ticket, invia i riepiloghi di build su Slack e sperimenta con la nuova funzione Wiki in-product di Devin per la documentazione leggera.
Se sei pronto a continuare, fai clic sul terzo elemento dell’elenco qui sotto per andare al prossimo tutorial:
- Setup e prima Pull Request (Parte 1)
- Consegnare una vertical slice con Devin (Parte 2)
- Integrazioni, test e CI/CD (Parte 3)
- Sicurezza, deployment, manutenzione (Parte 4)

Autore
Marie Fayard
Sono una tech lead orientata al prodotto, specializzata nel far crescere startup nelle fasi iniziali, dal primo prototipo al product-market fit e oltre. Sono instancabilmente curiosa di come le persone usano la tecnologia e adoro lavorare a stretto contatto con founder e team cross‑funzionali per dare vita a idee ambiziose. Quando non costruisco prodotti, inseguo l’ispirazione in angoli nuovi del mondo o scarico le tensioni in una sala yoga.


Bentornato! Nel primo tutorial di questa serie, Devin ha rispolverato il mio vecchio repo fp-ts-exercises e ha aperto una PR pulita per l’aggiornamento delle dipendenze. In questa seconda parte, alziamo l’asticella e costruiamo funzionalità full-stack.
Puoi accedere a tutti i tutorial della serie su Devin qui:
Quando arriverai in fondo a questa seconda parte, avrai:
Lungo il percorso, lasceremo che Devin generi la sua lista di task, lo guarderemo destreggiarsi tra ticket front-end e back-end, e interverremo quando inciampa su gremlin di configurazione. Ti mostrerò dove ho speso (e risparmiato) ACU, cosa ho corretto a mano e come mantenere le sessioni efficienti.
Requisiti e ripasso
In tutta la serie, lavoriamo sul mio (un tempo) abbandonato repo di esercizi fp-ts.
Il progetto è una raccolta di piccole sfide pensate per insegnare concetti di programmazione funzionale (come Option, Either, ecc.) in TypeScript. Al momento è un repo “clona e avvia”: chi impara lo clona, modifica i file in locale ed esegue i test nel proprio terminale.
L’obiettivo è trasformare quegli esercizi in un playground interattivo nel browser, dove si può leggere una spiegazione, modificare il codice in un editor in pagina e vedere i test passare (o fallire) all’istante. Inoltre, chi impara potrà anche effettuare l’accesso per salvare i propri progressi.
Cosa abbiamo fatto nella prima parte
Ricorda che nel primo tutorial abbiamo:
Strumenti locali necessari per la seconda parte
Per questo secondo tutorial, ci serviranno:
Impostazioni consigliate per Devin
Ti consiglio le seguenti impostazioni per Devin:
Lascia che Devin scriva il piano di gioco
Ho pensato che sarebbe stato interessante iniziare testando la capacità di pianificazione di Devin. Ho creato un prompt e ho chiesto a Devin, usando la funzione “Ask” (attualmente gratuita in Beta), di aiutarmi a pianificare il lavoro che faremo oggi.
Prompt:
Voglio trasformare il mio repo Node + TypeScript fp-ts-exercises esistente (attualmente esercizi CLI “clona e avvia”) in una piattaforma di apprendimento basata sul browser che tenga traccia dei progressi.
Esperienza target:
- Chi impara apre un’app web Next.js, sceglie un esercizio, modifica il codice nel browser e vede i test Vitest passare o fallire all’istante.
- I progressi (gli slug completati) sono salvati lato server e ricaricati alle visite successive, ma per ora non aggiungiamo account utente (usa un UUID anonimo salvato nel browser).
Scelte tecniche verso cui propendo:
- Frontend: Next.js 14 (React 18, App Router)
- Editor e runner del codice: Sandpack + @vitest/browser
- API: NestJS 13 con @nestjs/graphql (Apollo Driver)
- Database: Prisma 5 con PostgreSQL
- Workspace: semplici npm workspaces (apps/web, apps/api, packages/exercises)
Proponi un piano di implementazione passo-passo (lista di task) che dia vita a questa vertical slice. Stima il costo relativo in ACU per ciascun task ed evidenzia eventuali passaggi lunghi (es. grandi migrazioni o installazioni pesanti di dipendenze).
Devin ha restituito utilmente una lista di task in sei fasi con stime ACU per ciascuna, ed ha segnalato i passaggi di “installazione dipendenze pesanti”.
Risposta di Devin:
Fase 1: Setup del workspace (2–3 ACU)
Fase 2: Migrazione del pacchetto esercizi (3–4 ACU)
Fase 3: Backend API (4–5 ACU)
Fase 4: Funzionalità core del frontend (5–6 ACU)
Fase 5: Tracciamento dei progressi (2–3 ACU)
Fase 6: Finiture & Deployment (2–3 ACU)
Costo stimato totale: 18–24 ACU
Il piano era complessivamente buono. Ho cambiato alcune cose, in particolare nella sesta fase, dato che affronteremo il deployment nel quarto tutorial.
Fase 1: Workspace & impalcatura del front-end
Obiettivo: Avviare npm workspaces, spostare i file legacy e bootstrap di un guscio Next.js 14 vuoto. ACU consumati: 3,66 (previsti 1–2). Esito: Il repo ora ha
/apps/web, il pacchetto condivisopackages/exercisese un’app Next.js pronta per Tailwind in esecuzione sulocalhost:3000.Il prompt
Ho chiesto a Devin di costruire il piano che aveva proposto per la prima fase. Devin in modalità agent non ha contesto di quanto potresti aver chiesto prima nella funzione “Ask Devin”, quindi devi creare un prompt separato e fornire il contesto.
Non incollerò tutti i prompt in questo articolo, ma ecco il primo:
Prompt:
Task: Inizializzare la struttura degli npm workspaces e il frontend Next.js per la piattaforma browser di fp-ts-exercisesContesto:
Sto convertendo il mio sistema di apprendimento basato su CLI fp-ts-exercises esistente in una piattaforma basata sul browser. L’attuale sistema ha esercizi organizzati in 10-from-either.exercise.ts:1-3 con configurazione TypeScript in tsconfig.json:88 e setup di Vitest in vitest.config.ts:7.
Requisiti:
Deliverable:
Stack tecnico:
Consegna:
Tutti i prompt che ho scritto in seguito hanno seguito lo stesso schema: evidenziazione del task, contesto, requisiti, deliverable, stack tecnico e dettagli di consegna.
Cosa ha fatto davvero Devin
Ci ha messo abbastanza a decidere il da farsi (circa quattro minuti), ma ha:
packages/exercises/src.Perché il costo in ACU è salito
Il costo in ACU è salito perché:
npm installdopo un timeout dello specchio.qin Vim, poi conCtrl-C, e entrambi sono falliti. Gli ho dato un po’ di tempo per provare a sistemare da solo, ma alla fine sono intervenuto manualmente e ho chiuso i processi entrambe le volte. Ogni minuto extra significava ACU extra, e non avrei colto il problema rapidamente se non avessi seguito da vicino le azioni di Devin.Interventi umani e lezioni apprese
Ecco un riepilogo delle correzioni che ho dovuto fare:
Correzione
Tempo
Come l’ho fatta
Terminato task node watch bloccato
15 s
Ucciso il processo dalla shell della VM.
Reinstallato Tailwind
90 s
npm install tailwindcss postcss autoprefixer --workspace=apps/web e rieseguito tailwind init.
Aggiunto .next/ a .gitignore
10 s
Commit manuale per evitare PR appesantite.
Spostare grandi alberi di file è più veloce a mano, e molto meno costoso dato che Devin addebita per tempo/task. Ho trascinato le cartelle, fatto commit e lasciato che l’agente rilevasse la nuova struttura. È riuscito a prendere le mie modifiche e a fare un merge da solo!
Detto ciò, ho dovuto sollecitarlo a eseguire gli script di lint e typecheck, anche se l’avevo specificato nel prompt iniziale. Alla fine li ha eseguiti entrambi, ma sono falliti. Devin ha comunque considerato il tutto un successo ed è andato avanti con la PR.
Ho corretto entrambi i problemi in locale, eseguito io stesso gli script, avviato il nuovo server di sviluppo web per assicurarmi che partisse come previsto e pushato il commit.
Fase 2: Impacchettare gli esercizi
Obiettivo: Estrarre tutti i file delle challenge in un pacchetto riutilizzabile
packages/exercisese generare metadata per ogni esercizio. ACU consumati: 0,6 (previsti 2+). Esito: Il pacchetto condiviso esporta metadata tipizzati che l’app web e la futura API possono importare conimport { exercises } from '@exercises/registry'.Cosa ha fatto davvero Devin
Devin ha creato:
fp-ts.exercise.tse.solution.tsoption-01)getExercises(),getExerciseBySlug(),getExercisesByCategory(),getCategories(),getCategoryBySlug()Perché Devin è rimasto sotto budget
Devin è riuscito a tenere basso il costo in ACU — ecco come:
git mv(economico) invece di copia-incolla più diffInterventi umani
Questa volta nessuno!
Facendo tesoro della volta precedente, ho fatto checkout del branch di Devin ed eseguito gli script in locale. Tutto ha compilato e il registry esporta definizioni di tipo pulite, perfette come input per la UI e l’API che costruiremo dopo.
Fase 3: API NestJS + GraphQL
Obiettivo: Alzare un servizio NestJS 13 che espone i progressi degli esercizi via GraphQL e persiste i dati in PostgreSQL con Prisma. ACU consumati: 4,2 (previsti 4). Esito:
apps/apisi avvia sulocalhost:4000/graphql. Puoi interrogare e mutare i record di progresso indicizzati da un ID di sessione anonimo.Cosa ha fatto davvero Devin
Per la terza fase, Devin ha:
apps/apicon TypeScript e Apollo GraphQLSessioneCompletedExercisepackages/exercises) per la discovery dei datiDove Devin ha inciampato
Questi sono i problemi incontrati durante la terza fase e le correzioni che ho dovuto fare:
Problema
Fix
Tempo
Dimenticato l’import di
reflect-metadata→ app in crash all’avvioHo sollecitato Devin: “Sto riscontrando questo errore quando provo a eseguire
"npm run dev":La meta-proprietà 'import.meta' è consentita solo quando l’opzione
--moduleè 'es2020', 'es2022', 'esnext', 'system', 'node16', 'node18' o 'nodenext'.”1 ACU, 5 minuti
Script di lint mancante
Ho chiesto a Devin: “Aggiungi lo script di lint al pacchetto api e assicurati che passi.”
1 ACU, 4 minuti
Commit involontario di
.envgit rm --cached apps/api/.env && echo '.env' >> apps/api/.gitignore20 s
Lezioni apprese
Questi sono i miei takeaway:
npm run devandava in crash finché non è stato aggiuntoreflect-metadata..envcon una variabileDATABASE_URL, che conteneva username e password fittizi. Una volta pullato in locale, ho cambiato username e password con quelli del mio database locale e mi sono assicurato di rimuovere il file dal tracciamento git e aggiungerlo a.gitignore. Vedremo nei prossimi tutorial come gestire in sicurezza i segreti.Fase 4: Playground Sandpack & test live
Obiettivo: Fornire a chi impara un editor nel browser che esegue soluzioni fp-ts e controlli Vitest in tempo reale. ACU consumati: 7,2 (previsti 3-4). Esito: Visitando
/exercises/option-01si apre una vista divisa: editor Sandpack a sinistra, “tunnel” dei test a destra, e compare un messaggio di successo nel momento in cui tutti gli spec passano.Cosa ha fatto davvero Devin
Ecco cosa ha fatto Devin per la quarta fase:
Dove Devin ha bruciato ACU extra
Devin ha consumato più ACU del previsto per questa fase — ecco perché:
Causa
Come ho risolto / mitigato
Codice del runner CLI obsoleto rimasto in
apps/web– Sandpack ha provato a compilare entrambe le copie ed è andato in crash.Eliminato
pages/index.tsxdallo scaffold originale, fatto commit e rieseguito Devin.Aspettava feedback ma non l’ha chiesto esplicitamente → loop inattivo.
Ho scritto “Sembra ok, continua.” in chat dopo tre minuti di silenzio.
Lezioni apprese
I miei takeaway stavolta sono:
Qui Devin ha impiegato un po’ di tempo. Ha fatto loop su loop, tentando di risolvere gli stessi problemi, non collegando correttamente backend e frontend, facendo modifiche, riavviando i server, controllando nel browser se funzionava, ecc. Insomma, proprio come il normale lavoro di sviluppo, suppongo…
Ora abbiamo un’app funzionale. Sono riuscito ad avviare sia l’API sia il server web, navigare su localhost, modificare la funzione stub, premere Salva e guardare il pannello dei test passare da rosso a verde. Poi mi sono accorto che il lavoro era solo a metà: aveva hardcodato i test e la soluzione del primo esercizio su ogni pagina esercizio. L’ho fatto notare e, dopo altri loop, è riuscito a correggerlo e pushare le fix.