Ți-ai făcut aplicația cu Lovable, Bolt sau Cursor?

Checklist de producție pentru aplicații vibe-coded cu AI

Checklist de producție pentru aplicații vibe-coded cu AI

Checklist de producție pentru aplicații vibe-coded cu Lovable, Bolt, v0 sau Cursor: chei expuse, RLS în Supabase, plăți, teste, backup și GDPR.

Liviu Zachin

· 9 min de citit

Ai descris o idee, o unealtă AI a transformat-o în aplicație, iar oamenii încep să-și facă cont. N-aș sfătui niciodată un fondator să arunce asta. Dar un demo care merge și un produs care poate păstra în siguranță datele altor oameni sunt lucruri diferite. Mai jos e checklist-ul pe care îl parcurg când cineva îmi dă o aplicație făcută cu Lovable, Bolt, v0 sau Cursor și mă întreabă dacă e gata de producție.

Ce îți dau aceste unelte și ce nu

  • Lovable transformă prompturile în aplicații React și TypeScript, de obicei cu Supabase pentru baza de date și autentificare.
  • Bolt.new, de la StackBlitz, construiește aplicații full-stack direct în browser, cu Bolt Cloud pentru hosting și bază de date.
  • v0, de la Vercel, a pornit ca generator de interfețe și a ajuns un builder full-stack centrat pe Next.js.
  • Cursor e un editor de cod cu AI, ai cărui agenți scriu, rulează și testează cod direct în repository-ul tău.

Niciuna nu-ți cunoaște regulile de business: cine vede ce rânduri, ce înseamnă o comandă plătită, ce se întâmplă când un webhook vine de două ori. Iar platformele spun clar a cui e treaba: Lovable contestă CVE-2025-48757 pe motiv că fiecare client răspunde de datele propriei aplicații, iar Supabase lasă configurarea în grija clienților. Adică în grija ta.

De ce „merge” nu înseamnă „e gata”

În 2025, Matt Palmer a scanat 1.645 de aplicații din vitrina publică Lovable și a găsit 170, cam 10%, cu setări de row-level security (RLS) care expuneau 303 endpoint-uri: nume, emailuri, detalii de plată, chei API. Pe unul dintre site-uri, cercetătorii au putut marca o plată drept achitată fără să treacă prin Stripe.

În 2026, UpGuard a verificat circa 300.000 de domenii care par să folosească Supabase și a găsit 16.326 de baze de date cu tabele care pot fi citite de oricine, peste jumătate cu indicii de date personale. Explicația lor: Table Editor activează RLS implicit, dar nu și pentru tabelele create prin API, adică exact felul în care le creează de obicei agenții AI.

Iar în benchmark-ul Veracode din 2025, pe peste 100 de modele de limbaj, codul generat a introdus vulnerabilități în 45% din cazurile testate. Codul scris de AI are nevoie de review-ul pe care l-ai face codului unui junior, iar de obicei nu l-a făcut nimeni.

1. Securitate: secrete, RLS, autentificare și input

O aplicație lentă pierde utilizatori; una prin care se scurg date poate închide firma.

Secrete și chei expuse

Cheia publishable din Supabase (fosta cheie anon) e gândită să fie publică, iar singurul lucru care o limitează e RLS. Cheia secretă (fosta service_role) ocolește complet RLS și nu are ce căuta în browser sau în repository.

Capcana sunt variabilele de mediu. Vite pune în codul de client tot ce începe cu VITE_, iar NEXT_PUBLIC_ și NUXT_PUBLIC_ fac același lucru în Next.js și Nuxt. O unealtă AI care „repară” o eroare de permisiuni mutând cheia secretă sub unul dintre aceste prefixe tocmai a publicat-o. Eu adaug în CI o verificare de felul ăsta:

# Build-ul pică dacă un secret de server ajunge în bundle-ul de client
grep -rEq "sb_secret_|sk_live_|whsec_" dist/ && exit 1
grep -rEq "(VITE|NEXT_PUBLIC|NUXT_PUBLIC)_[A-Z_]*(SECRET|SERVICE_ROLE)" src/ .env* && exit 1

Rotește orice cheie care a stat vreodată în Git, pentru că istoricul o păstrează. Trecerea Supabase la noile chei sb_publishable_ și sb_secret_ e un moment bun pentru asta.

Row-level security în Supabase

Ce verific la fiecare proiect:

  • RLS activat pe fiecare tabel dintr-o schemă expusă
  • politici separate pe operație, limitate to authenticated acolo unde vizitatorii n-au ce căuta
  • with check la scriere, ca nimeni să nu poată crea rânduri în numele altcuiva
  • nicio autorizare bazată pe raw_user_meta_data, pe care utilizatorii îl pot modifica singuri
  • view-uri cu security_invoker = true, pentru că implicit ocolesc RLS

Un tabel minimal, în care fiecare utilizator își vede doar propriile rânduri:

alter table public.invoices enable row level security;

create policy "Utilizatorii își citesc propriile facturi"
  on public.invoices for select
  to authenticated
  using ((select auth.uid()) = user_id);

create policy "Utilizatorii își creează propriile facturi"
  on public.invoices for insert
  to authenticated
  with check ((select auth.uid()) = user_id);

-- Toate politicile filtrează după user_id, deci merită un index
create index invoices_user_id_idx on public.invoices (user_id);

Security Advisor din Supabase și scanarea pe care Lovable o face înainte de publicare prind tabelele fără RLS, dar n-au de unde ști că un membru al echipei poate vedea facturile, nu și salariile. Așa că testez și ca un atacator, cu cheia publishable luată din JavaScript-ul site-ului:

curl "https://<project-ref>.supabase.co/rest/v1/profiles?select=*" \
  -H "apikey: <cheia publishable>"

Dacă primești rânduri fără să fii autentificat, ai exact problema din CVE-2025-48757. Din 30 octombrie 2026, tabelele noi din schema public nu mai sunt expuse automat prin API până nu le dai acces explicit, dar un grant nu ține locul RLS: un grant larg pe un tabel fără RLS redeschide breșa.

Autentificare și sesiuni

  • Verificările de permisiuni stau pe server sau în baza de date. Un buton de admin ascuns nu protejează nimic.
  • Pe server, verifică utilizatorul cu getClaims() sau getUser() din Supabase, niciodată cu getSession(), care nu garantează revalidarea token-ului.
  • Linkurile de resetare a parolei și de invitație expiră, iar login-ul are rate limiting.

Validarea input-ului

Validarea din client ține de UX, nu de securitate. Validează input-ul fiecărei rute API și al fiecărei Edge Function cu o schemă (Zod sau Valibot) și dublează validarea cu constrângeri în baza de date. Caută și dangerouslySetInnerHTML sau v-html folosite pe conținut venit de la utilizatori: în același studiu Veracode, modelele n-au reușit să prevină cross-site scripting în 86% din cazuri.

2. Modelul de date și migrările

Uneltele AI adaugă o coloană ori de câte ori un prompt are nevoie de una, așa că de obicei găsesc câmpuri duplicate, bucăți de JSON care ar trebui să fie tabele și chei străine lipsă.

  • Fiecare rând care aparține cuiva are user_id sau team_id, cu cheie străină
  • Sumele de bani sunt stocate în cenți, ca numere întregi, sau ca numeric, niciodată ca float
  • Schimbările de schemă sunt migrări în Git, rulate pe staging înainte de producție

3. Plăți și webhook-uri

Nu marca niciodată o comandă ca plătită doar pentru că browserul a ajuns pe pagina de succes. Acordă accesul pe baza unui webhook verificat.

  • Verifică header-ul Stripe-Signature pe body-ul brut al cererii.
  • Păstrează ID-urile evenimentelor procesate: Stripe poate trimite același eveniment de mai multe ori și nu garantează ordinea.
  • Răspunde repede cu 2xx și mută procesarea într-o coadă. În modul live, Stripe reîncearcă livrările eșuate până la trei zile, ceea ce te ajută doar dacă handler-ul e idempotent.

4. Erori, monitorizare și backup-uri

  • Error tracking (Sentry sau ceva similar) pe front-end și pe back-end, cu alerte care ajung la un om
  • Verificări de uptime pentru login și webhook-uri, fără parole sau token-uri în loguri
  • Backup-uri pe care le-ai restaurat măcar o dată. Supabase Pro păstrează backup-urile zilnice șapte zile (Point-in-Time Recovery se plătește separat), proiectele Free ar trebui să-și facă singure exportul, iar fișierele din Storage nu sunt incluse.

5. Teste

Nu ai nevoie de 90% acoperire. Ai nevoie de teste pe fluxurile care costă bani când se strică: înregistrarea, drumul de la checkout până la accesul acordat și RLS pe fiecare rol (utilizatorul A nu poate citi rândurile lui B; pgTAP cu supabase test db rezolvă asta). Rulează-le în CI la fiecare pull request, pentru că un prompt care modifică pagina de prețuri poate rescrie pe tăcute logica de autentificare.

6. Performanță, hosting și controlul costurilor

  • Pune indexuri pe coloanele după care filtrează interogările și politicile. Paginează listele; codul generat aduce des tabele întregi.
  • Ține medii separate de staging și producție, cu deploy automat din Git.
  • Setează limite de cheltuieli și alerte de facturare pentru hosting, Supabase și mai ales pentru API-urile LLM. Un endpoint care apelează un LLM are nevoie de autentificare și rate limiting, altfel îți cheltuie altcineva creditele.

7. GDPR, pe scurt

Dacă ai utilizatori în UE sau în Marea Britanie, minimul (fără să fie consultanță juridică) arată așa:

  • o politică de confidențialitate care corespunde cu ce colectează aplicația și cu locul unde ajung datele
  • acorduri de prelucrare a datelor (DPA) cu furnizorii de bază de date, hosting, email, analytics și AI
  • o cale de a exporta și de a șterge datele unui utilizator
  • un plan pentru incidente: conform articolului 33, notifici autoritatea de supraveghere (în România, ANSPDCP) în cel mult 72 de ore de când afli de o încălcare a securității datelor personale, cu excepția cazului în care e puțin probabil să genereze un risc pentru persoanele afectate

8. Mentenabilitatea codului generat cu AI

De obicei, codul merge; doar că a fost scris de-a lungul a sute de prompturi. Semnele tipice: trei componente care fac același lucru puțin diferit, interogări în fiecare componentă, fișiere moarte și tipuri any puse ca să tacă erorile. Mut codul într-un repository Git care îți aparține, cu review la fiecare schimbare, adun accesul la date într-un singur strat, activez TypeScript în modul strict și un linter și șterg codul mort.

Refactorizare sau rescriere?

De obicei, niciuna dintre extreme: păstrezi ce e solid, refactorizezi ce e riscant și refaci doar ce e greșit din temelii.

ZonăDe obicei se refactorizeazăMerită luată în calcul o rescriere
SecuritatePolitici prea permisive, dar fiecare rând își știe proprietarulProprietatea nu e modelată; rolurile există doar în front-end
Modelul de dateDenumiri, constrângeri lipsă, coloane duplicateAfacerea are nevoie de echipe, dar totul aparține unui singur utilizator
CodComponente duplicate și interogări împrăștiateOrice schimbare strică altceva
PlățiLipsesc verificarea semnăturii sau tratarea duplicatelorStarea plății e decisă în browser

Dacă auditul ajunge în coloana din dreapta, dezvoltarea SaaS și MVP e drumul potrivit, iar prototipul devine o specificație excelentă. Același raționament se aplică și aplicațiilor mai vechi; vezi migrarea de la Nuxt 2 și Vue 2 la Nuxt 4.

Checklist-ul pe scurt

  • Niciun secret în bundle-ul de client sau în istoricul Git
  • RLS pe fiecare tabel expus, testat cu cheia publishable
  • Autorizare și validare pe server, nu în interfață
  • Migrări în Git, rulate întâi pe staging
  • Plăți confirmate prin webhook-uri verificate și idempotente
  • Alerte de erori care ajung la un om
  • Backup-uri restaurate măcar o dată
  • Teste în CI pentru înregistrare, plăți și RLS
  • Limite de cheltuieli pentru hosting, bază de date și API-uri AI
  • Politică de confidențialitate, DPA-uri și ștergerea datelor la cerere

Ai nevoie de încă o pereche de ochi?

Exact asta acoperă serviciul meu de la prototip AI la producție. Auditez codul, baza de date și hostingul, în jur de două zile lucrătoare pentru un prototip obișnuit, iar tu primești un raport scris, ordonat după risc, cu o recomandare pentru fiecare zonă: păstrat, refactorizat sau refăcut. Problemele critice de securitate ți le semnalez imediat. Auditul pornește de la 960 € și include un plan cu preț fix pentru corecturi; alegi tu dacă le fac eu, echipa ta sau împărțim munca, cu preț fix pe etapă sau cu 480 €/zi.

Folosesc zilnic Claude Code și Cursor, așa că nu încerc să te conving să renunți la uneltele AI, ci pregătesc proiectul ca să le poți folosi în siguranță. După aceea, mentenanța și suportul țin aplicația stabilă, iar dacă vrei s-o poți folosi din ChatGPT sau Claude, vezi cum construiești un server MCP pentru SaaS-ul tău.

Trimite-mi linkul aplicației și spune-mi cu ce a fost construită, prin pagina Angajează-mă, și îți răspund în cel mult o zi lucrătoare.

Întrebări frecvente

E sigură pentru producție o aplicație făcută cu Lovable?

Poate fi, dar nu din start. Aplicațiile Lovable rulează de obicei pe Supabase, deci datele tale sunt doar atât de sigure cât sunt politicile de row-level security. Testează-le cu cheia publishable sau dă-le la audit înainte să vină utilizatorii reali.

Cum verific dacă politicile RLS din Supabase chiar funcționează?

Repară fiecare tabel semnalat de Security Advisor, apoi interoghează-le pe rând prin REST API cu cheia publishable, neautentificat și ca doi utilizatori de test diferiți. Ca să rămână corecte, adaugă teste pgTAP cu supabase test db pentru cazurile permise și pentru cele interzise.

Repar aplicația făcută prin vibe coding sau o refac de la zero?

De obicei o repari. Majoritatea aplicațiilor construite cu AI au o interfață bună și probleme mai ieftin de refactorizat decât de rescris. O rescriere are sens doar când modelul de date sau cel de securitate e greșit din temelii.

Cât costă să pregătești pentru producție o aplicație generată cu AI?

Depinde de ce găsește auditul. Auditul pornește de la 960 € și se încheie cu un plan cu preț fix pentru corecturi, așa că știi costul total înainte să te angajezi. Lucrul de după are preț fix pe etapă sau se facturează cu 480 €/zi.

Pot folosi în continuare Lovable, Bolt sau Cursor după lansare?

Da, atât timp cât fiecare schimbare trece prin Git, review și teste înainte de producție. Unealta AI propune, iar CI-ul prinde schimbările care strică înregistrarea, plățile sau RLS.