Approfondimenti e Trend sull'Intelligenza Artificiale

Architettura di un progetto vibe-coded da zero: dal prompt al deploy

11 min di lettura
Tre livelli astratti su fondo charcoal con accento terracotta: contesto, codice e runtime
Windows macOS Linux
Foto: Alex Lunalbi · ai riparo · Proprietario

Prima del primo prompt: cartelle, moduli, interfacce e file di contesto. Architettura pratica di un progetto vibe-coded, fino al deploy, senza caos.

Apri Cursor, apri il Composer, scrivi «creami un’app per la gestione delle spese con login e dashboard» e premi Invio. Dopo pochi minuti hai qualcosa che sembra funzionare. Dopo tre ore di modifiche, l’IA può aver sovrascritto il routing, rotto la connessione al database da un componente UI, lasciato API key nel sorgente — e ogni nuovo prompt genera due errori per ogni bug che sistemi.

Questo è il ciclo tipico del single-prompt mess: caos da prompt unico.

Il vibe coding aiuta a scrivere codice; non progetta l’architettura al posto tuo. Se deleghi struttura dei file, confini tra moduli e gestione dei segreti, accumuli debito tecnico prima ancora del deploy.

In questa guida ti mostro come costruire l’impalcatura prima del primo prompt: albero cartelle, file di contesto, ordine dei prompt e checklist pre-deploy. Per i rischi tipici del codice generato resta utile (lettura opzionale) Vibe coding: rischi che non vedi.

Il modello mentale: separare per governare

Per evitare che l’IA mescoli business logic e UI in un god-file da migliaia di righe, ragiona a compartimenti. Nei miei test con assistenti attuali, i modelli lavorano meglio in un perimetro ristretto e possono fallire quando devono inventarsi da soli le relazioni di tutto il progetto.

Tre livelli pratici:

Livello Accesso IA Cosa contiene e a cosa serve
Contesto Regole d’ingaggio Lettura fissa File statici (SPEC.md, regole editor) che fissano stack, vincoli e convenzioni. L’IA li legge; non dovrebbe riscriverli da sola.
Codice Logica e UI Scrittura mirata Moduli isolati (src/api, src/ui…). L’IA scrive qui, preferibilmente un file/modulo alla volta, rispettando i contratti del Contesto.
Runtime & segreti Dati reali Nessun accesso File .env reali, credenziali, DB di produzione. L’IA genera al massimo .env.example. I valori veri non vanno nel prompt.

Passaggio 0 — Decisioni prima del prompt

Prima della chat, rispondi a cinque domande. Se non le hai, l’IA può scegliere pattern generici (a volte datati) dai suoi dati di addestramento.

  1. Cosa sto costruendo? CLI, SPA, API backend…
  2. Chi sono gli utenti? Solo tu in locale (rischio più basso) o web pubblico (rate limit, CORS, auth serie)?
  3. Quali dati tratto? Personali, password, pagamenti? L’auth non è un’area da lasciare alla sola creatività del modello.
  4. Qual è lo stack? Scegli tu linguaggio e framework. Non chiedere «qual è il migliore?»: decidi (es. FastAPI, Express) e vincola l’IA a quello.
  5. Andrà online? Se sì, niente segreti hardcoded — nemmeno «solo per la bozza».

ℹ️ Nota / Prerequisito operativo
Scegli uno stack che conosci almeno a livello concettuale. Il vibe coding riduce la fatica sulla sintassi, non sull’architettura.

Passaggio 1 — L’albero delle cartelle

Non lasciare che l’editor crei file a caso nella root. Prima crea i contenitori vuoti: l’IA è costretta a riempire i cassetti giusti.

Scheletro neutro (web/API generico):

mio-progetto/
├── .cursor/            # regole editor (se usi Cursor)
├── docs/               # SPEC.md e note di progetto
├── src/
│   ├── api/            # endpoint / controller
│   ├── core/           # business logic e tipi
│   ├── config/         # env, costanti, setup
│   └── ui/             # componenti (se presenti)
├── tests/              # smoke / unit
├── .env.example
├── .gitignore
└── README.md

Per uno scaffold Python più «ai riparo», vedi anche (opzionale) Struttura minima di un progetto Python.

Creazione rapida da terminale

Windows (PowerShell):

mkdir mio-progetto; cd mio-progetto
mkdir .cursor, docs, src\api, src\core, src\config, src\ui, tests
New-Item .env.example, .gitignore, README.md, docs\SPEC.md -ItemType File

macOS / Linux (bash/zsh):

mkdir -p mio-progetto/{.cursor,docs,src/{api,core,config,ui},tests}
cd mio-progetto
touch .env.example .gitignore README.md docs/SPEC.md

Messaggio implicito all’IA: l’ordine esiste già; riempi, non inventare la topologia.

Passaggio 2 — Moduli e contratti in prosa

I modelli possono perdere il filo su file lunghi. Se chiedi «aggiungi il login», rischi modifiche simultanee a bottone, router e DB.

Definisci boundary con contratti in prosa: una frase che dice come due moduli parlano, nei file di contesto.

⚠️ Attenzione — God-file
Un file che fa UI + SQL + formattazione date è un god-file. L’IA li propone spesso perché è più semplice stampare tutto di seguito. Rifiutali: chiedi una funzione esportata e un modulo alla volta. Approfondimento: disaccoppiare business logic e UI.

Esempio di contratto:

Il modulo src/core/auth esporta verifyUser(token): stringa in ingresso, booleano in uscita. src/api/routes può solo chiamare questa funzione; non valida i token in proprio.

Così, quando generi l’API, l’IA sa già di non reinventare la validazione.

Passaggio 3 — File di contesto per l’IA

docs/SPEC.md

La mappa del progetto. All’inizio di una sessione, ancora l’assistente qui.

Deve contenere:

  • obiettivo dell’app (3 righe);
  • stack obbligatorio (es. «moduli ES, niente CommonJS»);
  • strutture dati / tabelle (qui, non solo nel prompt);
  • cosa non fare (niente porte cambiate di nascosta, niente dati random non richiesti).

Skeleton minimo da adattare:

# SPEC — nome-progetto

## Obiettivo
[3 righe: chi lo usa, che problema risolve, cosa è fuori scope]

## Stack obbligatorio
- Runtime: …
- Framework: …
- DB (se c’è): …
- Divieti: es. niente ORM X, niente CommonJS

## Dati
- Entità / tabelle: …
- Cosa NON salvare in chiaro: password, token, PII inutili

## Non fare
- Non cambiare porte senza dirlo
- Non hardcodare secret
- Non generare UI finché core + config non passano lo smoke test

Regole editor (es. .cursorrules)

Snippet utile (adatta allo stack):

Regole di progetto:
1. Niente log di segreti o credenziali in console.
2. Leggi env da src/config — non spargere process.env / os.environ ovunque.
3. Se modifichi un file, restituisci quel modulo completo; non toccare i vicini se non richiesto.
4. Ogni chiamata di rete gestisce un timeout.

💡 Consiglio pratico — Contesto pulito
Non mettere chiavi, password o dump enormi di errori nei file di contesto. Restano immutabili e leggibili.

Passaggio 4 — Ordine dei prompt

Costruisci dal basso verso l’alto: un pezzo, un test, poi avanti.

  1. Dati / schema — «Leggi docs/SPEC.md. Crea src/core/db-schema con sole strutture, niente UI.»
  2. Config e fail-fast — «Carica env in src/config. Se manca una variabile vitale, errori all’avvio.»
  3. Smoke test — «In tests/ uno script che carica config + core e stampa OK.»
  4. API — «Endpoint in src/api che usa lo schema; JSON puro; stub ok se il DB non c’è.»
  5. UI per ultima — «Componente in src/ui che chiama l’endpoint; gestisci loading ed error.»

Se l’errore arriva al passo 2, lo isoli. Un mega-prompt 1→5 propaga il guasto fino alla UI.

Dopo ogni prompt: tre controlli da 60 secondi

  1. Diff — leggi cosa ha toccato (path inattesi = stop).
  2. Run locale — avvia lo smoke / il server; niente «compila nella mia testa».
  3. Confini — il nuovo codice importa solo ciò che il contratto permette? Se ui parla col DB, rifai il pezzo.

Confronto utile:

  • Debole: «Fammi l’app con login e dashboard» → monolite, confini assenti.
    Meglio: «Leggi SPEC.md. Crea solo src/core/auth con verifyUser(token) → bool. Niente UI, niente DB reale.»
  • Debole: «Sistemami gli errori» → fix opachi.
    Meglio: «Mostra la diff del fix. Non allargare i tipi e non spegnere i check di sicurezza.»

Passaggio 5 — Igiene del repository dal giorno zero

.gitignore obbligatorio

Non affidarti alla memoria del modello. Includi almeno:

  • node_modules/, __pycache__/, dist/, .venv/
  • .env, .env.local, *.pem, *.key
  • *.log, .DS_Store

.env.example

Chiedi all’IA un template con chiavi vuote:

API_KEY=
DATABASE_URL=

I valori reali stanno solo nel .env locale (e nei secret del provider in produzione).

Passaggio 6 — Checklist pre-deploy

L’impulso «deploya su Vercel/Render» va frenato. L’IA può proporre CORS *, bind su 0.0.0.0 o debug acceso solo per far sparire l’errore.

Checklist minima:

  1. Build locale di produzione — npm run build (o equivalente) deve passare sul tuo PC.
  2. Niente path assoluti personali — tipo C:\Users\Nome\… o /Users/nome/….
  3. HTTPS e header — in produzione: CSP/HSTS di base, niente HTTP in chiaro se puoi. Approfondimento opzionale: Configurare CSP, HSTS e X-Frame-Options.
  4. Debug spento — DEBUG=false (o equivalente) legato all’env di produzione.
  5. Caccia ai segreti — cerca nel progetto secret, password, sk-, bearer. Se trovi una chiave nel sorgente, spostala in env.
  6. CORS e bind — niente Access-Control-Allow-Origin: * «per far sparire l’errore» su API con dati; niente 0.0.0.0 esposto senza bisogno (vedi anche CORS e asterisco).
  7. Smoke post-deploy — login/health check, una chiamata API, un giro DevTools Network senza surprise.

Ricerca segreti (esempi):

Windows (PowerShell), dalla root del progetto:

Select-String -Path .\src\*,.\*.js,.\*.ts,.\*.py -Pattern "sk-|Bearer |password\s*=" -SimpleMatch:$false -ErrorAction SilentlyContinue

macOS / Linux:

rg -n "sk-|Bearer |password\s*=" src || true

🚨 Avviso critico — Commit di chiavi
Se una chiave reale è finita in Git (anche solo locale poi pushato), considerala compromessa: ruotala dal pannello del provider. Riscrivere la storia non basta se il remote l’ha già vista.

Per un giro di controlli free sul sito online, vedi (opzionale) Audit di sicurezza gratuito.

Esempio di sessione (45 minuti, senza monolite)

Scenario: mini API di note personali (solo tu, poi magari online).

  1. Minuti 0–10 — rispondi alle cinque domande del Passaggio 0; crea cartelle; scrivi SPEC.md (stack: es. FastAPI o Express; dati: titolo + testo; divieto: niente auth «finta» in UI).
  2. Minuti 10–15 — regole editor + .gitignore + .env.example (DATABASE_URL=, SECRET_KEY=).
  3. Minuti 15–25 — prompt schema/core + config fail-fast; lancia smoke: deve stampare OK.
  4. Minuti 25–35 — un endpoint GET/POST note in memoria o SQLite locale; JSON solo.
  5. Minuti 35–45 — solo se l’API risponde: una UI minima oppure stop e commit. UI il giorno dopo.

Se al minuto 25 lo smoke fallisce, non aprire la UI. È esattamente il punto in cui il prompt unico ti avrebbe già mescolato tre layer.

Errori comuni nel vibe coding

  1. «Fix» cieco — l’IA toglie l’errore allargando i tipi o spegnendo un check. Leggi la diff.
  2. UI + query nello stesso prompt — accoppiamento forte, difficile da riusare.
  3. Dipendenze fantasma — import senza package.json / requirements.txt. Verifica install e, in JS, anche npm audit (guida opzionale: Dipendenze e supply chain).
  4. Saltare lo SPEC — alla sessione dopo, senza mappa, le allucinazioni divergono.

Domande Frequenti (FAQ)

Cosa fare prima del primo prompt in Cursor?

Fissa stack e perimetro, crea l’albero cartelle, poi SPEC.md e le regole editor. Solo dopo generi codice.

Quali cartelle servono in un progetto vibe-coded minimo?

Almeno config/, api/ (o equivalente), core/, ui/ se c’è interfaccia, più tests/, .env.example e .gitignore. Adatta i nomi allo stack, non al contrario.

Cosa sono i file di contesto per l’IA?

Documenti locali (SPEC.md, regole editor) con obiettivo, stack e divieti. L’assistente li usa per restare coerente tra una sessione e l’altra.

Meglio un prompt unico o tanti prompt per modulo?

Tanti prompt mirati, con verifica dopo ciascuno. Il monolite da un solo prompt è più difficile da manutenere e da auditare.

Dove metto le API key in questo flusso?

Solo in .env (o secret del hosting), mai nel prompt e mai commitate. Nel codice: lettura centralizzata da src/config.

Questa guida sostituisce le checklist di sicurezza?

No. Organizza il cantiere per ridurre caos e debito. XSS, SQL injection, CORS aperti e cookie restano da verificare a parte — parti da Vibe coding: rischi e dall’audit gratuito.

Dal cantiere al deploy

Venti minuti di cartelle, regole e contratti ti risparmiano ore di debugging opaco. Quando la struttura regge, il deploy è logistica: secret in dashboard, HTTPS, debug off, niente chiavi nel repo.

Secret sul provider (senza passarli all’IA)

  1. Copia le chiavi da .env.example (nomi, non valori).
  2. Nel pannello del host (Vercel, Render, VPS, Aruba…) crea le stesse variabili con i valori reali.
  3. Verifica un restart / un deploy che l’app parta in fail-fast se manca una variabile.
  4. Non chiedere all’IA «ecco la mia sk-…, mettila tu»: anche in chat restano log e history.

Su Windows, se i comandi node / python «non esistono», sistema il PATH prima di dare colpa al modello: è prerequisito operativo, non un bug di Cursor. Su macOS/Linux vale lo stesso per python3 e permessi della cartella progetto.

Se parti da Python locale, allinea anche lo scaffold a struttura minima ai riparo e, per gli script CLI, ad argparse senza dolore.

Letture opzionali

Alex Lunalbi

Alex Lunalbi

Security & privacy

Dona su PayPal

Scrivo di sicurezza digitale pratica e codice IA. Su ai riparo ogni procedura è verificata su macchine reali.

Tag
  • vibe coding,
  • architettura,
  • cursor,
  • deploy,
  • intelligenza artificiale