Am terminat recent un dashboard intern pentru o agenție de marketing locală, după trei luni de muncă destul de intensă cu Next.js, Prisma și NextAuth. Vreau să vă povestesc ce a mers uns, unde ne-am blocat și de ce unele decizii tehnice ne-au mușcat de fund mai târziu. Dacă aveți în plan un proiect de genul ăsta, s-ar putea să economisiți niște săptămâni de research.
De la ce am plecat și stack-ul ales
Clientul, o agenție cu vreo 45 de oameni, folosea patru tool-uri diferite pentru activitatea de zi cu zi: Google Sheets pentru bugete, Trello pentru task-uri, Notion pentru proceduri și un tool obscur de time tracking. Haosul era complet. Scopul nostru a fost să adunăm totul într-un singur loc.
Am ales Next.js (App Router), Prisma cu PostgreSQL găzduit pe Supabase și NextAuth pentru autentificare. Am vrut un stack modern, rapid de ridicat, unde să nu pierdem timpul cu configurarea Webpack-ului sau cu boilerplate de backend.
Ce a mers excelent (și unde am economisit timp)
Prisma a fost de departe MVP-ul acestui proiect. Relațiile dintre tabele, cum ar fi campanii, utilizatori, task-uri și bugete istorice, s-au scris aproape singure în schemă. Am economisit probabil 30% din timpul de backend doar pentru că n-am stat să scriem SQL chior sau migrații manuale complexe. Autocomplete-ul pe tipurile generate ne-a salvat de zeci de bug-uri de tipul „undefined” în UI.
NextAuth s-a integrat și el destul de repede cu Google Workspace-ul lor. În doar două zile am avut un flux de autentificare securizat, limitat strict la domeniul lor de e-mail (@agentie.ro). Nimeni din exterior nu putea să își facă cont, lucru esențial pentru datele financiare pe care le gestionam acolo.
Părțile dureroase și trade-off-urile
Dar nu totul a fost roz. Next.js App Router și caching-ul lui implicit ne-au mâncat zilele.
Am pățit-o chiar în prima săptămână de testare internă. Operatorii modificau bugetul unei campanii de Facebook Ads, dar pe dashboard-ul managerului apăreau tot datele vechi, din cache. Am rezolvat-o până la urmă cu revalidatePath și unstable_noStore, însă codul a devenit destul de fragmentat și greu de urmărit. Uneori aveam senzația că mă lupt cu framework-ul doar ca să obțin un comportament banal de aplicație dinamică.
O altă problemă a fost legată de baza de date. NextAuth cu adaptorul de Prisma tinde să facă foarte multe interogări la fiecare request dacă folosești sesiuni salvate în baza de date. Pe tier-ul inițial de Supabase, conexiunile se epuizau instant. Am fost nevoiți să trecem rapid pe sesiuni bazate pe JWT-uri ca să nu omorâm baza de date.
Ce am învățat după 3 luni în tranșee
Dacă aș lua proiectul de la capăt, aș schimba două lucruri majore.
În primul rând, nu totul trebuie să fie Server Component. Pentru ecrane extrem de interactive, cum este cel de alocare a bugetelor pe săptămâni, un use client clasic cu state local și un simplu API de fetch este mult mai curat și mai performant decât să te chinui cu Server Actions pentru fiecare input modificat.
În al doilea rând, optimizarea bazei de date nu se face la final. Prisma e comodă, dar generează uneori niște query-uri cu include care fac join-uri masive în spate. Când am trecut de 10.000 de înregistrări în istoric, dashboard-ul începuse să se miște vizibil mai greu până când am adăugat indexi manuali în baza de date.
Aplicația este acum în producție și rulează stabil. Timpul de raportare săptămânal al managerilor a scăzut de la 6 ore la sub o oră.
Voi ce folosiți pentru dashboard-urile interne rapide? Rămâneți la clasicul React SPA separat de API sau ați trecut complet pe framework-uri full-stack gen Next/Remix?