De la Google Sheets la un dashboard custom
Am finalizat recent un proiect destul de intens: un dashboard intern pentru o agenție locală de marketing cu vreo 40 de angajați și peste 120 de clienți activi. Oamenii își pierdeau diminețile copiind date din Facebook Ads și Google Ads în niște Google Sheets gigantice, care se blocau de trei ori pe zi.
Planul a fost simplu pe hârtie. Trei luni de dezvoltare, un singur dev (eu) și un stack modern: Next.js (App Router), Prisma cu PostgreSQL pe Supabase și NextAuth pentru securitate. Am vrut ceva rapid, ușor de întreținut și, cel mai important, ieftin de rulat.
După 90 de zile și vreo 400 de commit-uri, aplicația e în producție. Am învățat pe pielea mea ce funcționează de minune și unde te lovește de te lasă lat.
Ce a mers ca pe roate (The Good)
NextAuth (acum Auth.js) este pur și simplu genial pentru tool-uri interne. Agenția folosește Google Workspace, așa că am activat doar 'GoogleProvider'. Mi-a luat exact 20 de minute să configurez totul, inclusiv restricția ca doar utilizatorii cu domeniul agenției să se poată autentifica. Fără baze de date de parole, fără e-mailuri de resetare, zero bătăi de cap cu securitatea.
Prisma, de asemenea, rămâne preferata mea pentru prototipare rapidă și CRUD de bază. Autocomplete-ul din editor și migrațiile automate mi-au salvat probabil 30% din timpul de development pe partea de backend. Am putut defini schemele pentru clienți, campanii și bugete în câteva ore.
Unde am dat de pereți (The Bad & The Ugly)
Dacă vrei să faci un dashboard interactiv în Next.js App Router, pregătește-te de luptă cu cache-ul. Implicit, Next.js vrea să facă cache la tot ce prinde.
La un moment dat, managerii de cont modificau bugetele în UI, dar pe ecran apăreau tot datele vechi. Am avut zeci de tichete în prima săptămână pentru că rapoartele erau 'stale'. Am rezolvat-o doar după ce am pus 'export const dynamic = force-dynamic' pe rutele de API și am început să folosesc 'revalidatePath' agresiv. Next.js e promovat ca fiind excelent pentru site-uri de prezentare sau e-commerce, dar pentru dashboard-uri dinamice unde datele se schimbă la secundă, comportamentul de caching implicit este un coșmar administrativ.
Al doilea compromis major a fost performanța Prisma la agregări mari. Agenția importă zilnic în baza de date zeci de mii de rânduri de metrics din API-uri externe. Când am încercat să facem un raport anual agregat pe 5 tabele relaționate, Prisma genera niște query-uri SQL atât de complexe încât baza de date dădea timeout după 30 de secunde.
Am fost nevoit să renunț la ORM-ul curat și să scriu SQL brut folosind 'prisma.$queryRaw'. Am optimizat query-urile manual, am adăugat indexuri pe coloanele de date și ID-uri de clienți și am redus timpul de execuție de la 12 secunde la doar 150ms.
Concluzia mea după 3 luni
Next.js cu Prisma e un combo excelent dacă vrei să livrezi repede. Am reușit singur să ridic o platformă stabilă pe care acum o folosesc zilnic 40 de oameni.
Totuși, dacă aș lua proiectul de la capăt, aș separa complet backend-ul de frontend. Aș face un API simplu în Go sau Node direct cu Fastify, iar Next.js l-aș păstra strict ca SPA (Single Page Application) pe client-side, fără să mă mai bat cu Server Components și caching-ul lor ciudat.
Voi cum gestionați cache-ul în App Router pentru aplicații de tip dashboard? Mergeți pe SPA clasic sau forțați dynamic rendering peste tot?