01 · Rezumat
Ce livrăm și cum
O platformă de cookie consent funcțională și vandabilă în 10 săptămâni, 335–390 de ore, cu un prototip care rulează pe site-ul dumneavoastră la finalul săptămânii 2.
Modul de lucru: sprinturi de o săptămână cu demo la final, cod în repository-ul dumneavoastră din prima zi, fiecare fază închisă cu criterii de acceptanță scrise. Vedeți progresul în fiecare vineri, nu la final.
02 · Scop
Ce construim
Scopul MVP-ului este fixat la 7 module. Fiecare are un criteriu de acceptanță măsurabil, pe care îl demonstrăm înainte de a trece mai departe.
| Modul | Ce face concret | Criteriu de acceptanță |
|---|---|---|
| 1. Scanner automat | Crawler Playwright care parcurge domeniul din sitemap și linkuri interne, numără paginile unice, capturează cookie-urile setate (nume, domeniu emitent, durată, first/third-party) și le clasifică după o bază de cunoștințe: Strict necesare, Analiză, Marketing. Rescanare lunară din coadă. | Scanarea unui site de 1.000 de pagini se încheie în sub 20 de minute și detectează cookie-urile Google Analytics, Meta Pixel și YouTube; un domeniu care indică spre o adresă internă este respins. |
| 2. Încadrare automată pe nivel | Numărul de pagini unice din ultima scanare stabilește nivelul: Tier 1 până la 500 de pagini, Tier 2 de la 501 la 5.000, Tier 3 peste 5.000. Până la prima scanare completă, domeniul rulează pe un nivel provizoriu. La schimbarea nivelului se actualizează abonamentul Stripe la următoarea factură. Ce se numără ca pagină (propunere, de confirmat la scoping): un URL unic, public, care răspunde cu o pagină HTML validă. Nu se numără separat variantele aceleiași pagini create de parametri care nu schimbă conținutul (utm_*, sortare, sesiune, paginare de filtre). Nu intră în număr paginile după login, cele cu erori, redirecționările și cele excluse prin robots.txt; excluderile se afișează în raportul de scanare. Fiecare subdomeniu se scanează ca domeniu separat; dacă se tarifează separat sau în același pachet se stabilește la scoping. | Un domeniu care trece de 500 de pagini apare în dashboard cu nivelul nou și factura următoare reflectă schimbarea. |
| 3. Editor vizual de banner | Culori, font, rază colțuri, poziție (jos, sus, centru), logo, texte în mai multe limbi, previzualizare live pe un cadru al site-ului. Demo-ul din antet este o versiune în miniatură. | Clientul reproduce stilul site-ului său fără să scrie CSS. |
| 4. Widget JS | Vanilla JS, fără dependențe, încărcat async de pe Cloudflare; configurația bannerului vine ca JSON din CDN; scripturile marcate neesențiale sunt ținute ca type="text/plain" până la consimțământ. | Sub 10 KB gzip. Pe 3 site-uri de test agreate (WordPress, Shopify, HTML static), 3 rulări Lighthouse fiecare: LCP și INP în marja de ±100 ms și CLS în marja de ±0,02 față de măsurătoarea fără widget. |
| 5. Motor de conformitate | Consimțământ pe categorii, refuz pe primul strat, retragere din footer, jurnal cu marcaj temporal și versiunea bannerului, semnale Google Consent Mode v2 (ad_storage, analytics_storage, ad_user_data, ad_personalization). | Pe site-urile de test, niciun cookie din categoriile Analiză și Marketing nu apare înainte de opt-in pentru scripturile integrate conform ghidului (marcate direct sau declanșate prin Google Tag Manager pe consimțământ); scripturile neintegrate sunt semnalate de scanner ca neconforme. Jurnalul exportabil CSV conține fiecare decizie. |
| 6. Reguli pe jurisdicție | Profiluri de jurisdicție configurabile. Țara afacerii se declară la onboarding; țara vizitatorului vine din antetul CF-IPCountry (fără stocarea IP-ului); se aplică profilul cel mai strict dintre cele două: opt-in în UE/SEE, UK, Elveția; opt-out cu link „Do Not Sell or Share” și semnal GPC în SUA; banner informativ în rest. Profilurile, textele și configurarea fiecărui client se validează cu juristul lui pentru cazul concret; platforma livrează mecanismele, nu o garanție juridică. | Același site afișează banner GDPR unui vizitator din România și opt-out unui vizitator din California; fiecare profil poate fi modificat din admin fără deploy. |
| 7. Dashboard și facturare | Multi-tenant cu roluri (admin platformă, client, utilizator), domenii, scanări, bannere, jurnale; Stripe Billing cu abonamente lunare și anuale, facturi, Stripe Tax, webhooks pentru plăți eșuate. | Un client nou ajunge de la înregistrare la banner activ și abonament plătit în sub 15 minute, fără să aștepte finalul scanării: bannerul pornește pe nivelul provizoriu, iar nivelul definitiv se confirmă automat când scanarea se încheie. |
Demo: ce face scanner-ul cu un domeniu
Scanner-ul este modulul care face platforma să funcționeze fără intervenție umană: numără paginile, găsește cookie-urile și propune nivelul de abonament. Mai jos, o simulare a rezultatului pentru un magazin online obișnuit.
Declarația de cookie-uri, generată automat
| Cookie | Emitent | Durată | Categorie |
|---|
Simulare cu date fixe (1.240 de pagini, 12 cookie-uri tipice), indiferent de domeniul introdus. Scanarea reală, clasificarea și încadrarea pe nivel se construiesc în fazele 2 și 4; scanner-ul real rulează în Chromium headless și vede exact ce vede browserul vizitatorului.
03 · Tehnologie
Arhitectura tehnică
Tehnologii mature, cu care lucrăm curent, ca să nu pierdem timp pe experimente: Next.js, NestJS, PostgreSQL, Redis, Playwright, Stripe, Cloudflare, Docker.
Glisați lateral pentru a vedea întreaga diagramă.
8 componente. Site-ul clientului vorbește doar cu CDN-ul și trimite o singură cerere către API la fiecare decizie de consimțământ.
Dacă API-ul este indisponibil, bannerul funcționează în continuare, iar decizia se trimite la următoarea vizită. Crawler-ul rulează într-un container separat, ca să nu afecteze API-ul.
| Strat | Tehnologie | De ce o alegem |
|---|---|---|
| Widget | TypeScript compilat în Vanilla JS, fără framework, bundle cu esbuild | Singura cale de a sta sub 10 KB și de a nu intra în conflict cu codul site-ului gazdă. |
| CDN | Cloudflare (R2 + cache), antetul CF-IPCountry pentru țara vizitatorului | Latență mică oriunde, geolocație gratuită, fără stocare de IP. |
| Dashboard | Next.js (React), Tailwind, autentificare cu sesiuni și roluri | Dezvoltare rapidă a interfeței, randare server-side pentru pagini publice. |
| API | NestJS (Node.js, TypeScript), validare cu class-validator, OpenAPI generat | Structură modulară pe domenii (tenants, domains, scans, consents, billing), testabilă unitar. |
| Bază de date | PostgreSQL 16, Prisma, izolare pe tenant_id + row-level security | Jurnal de consimțământ auditabil, migrări versionate, backup standard. |
| Cozi și cache | Redis 7 + BullMQ | Scanările rulează în fundal, cu reîncercare și prioritate; configurația bannerului în cache. |
| Crawler | Playwright cu Chromium headless, worker Node separat | Vede cookie-urile așa cum le vede browserul real, inclusiv cele setate de JavaScript. |
| Facturare | Stripe Billing + Stripe Tax + webhooks | Abonamente, facturi, TVA și recuperarea plăților fără cod propriu de plată. |
| Infrastructură | Docker Compose pe Linux (Ubuntu / Rocky) în UE, GitHub Actions pentru CI/CD, Caddy pentru TLS | Reproductibil pe orice server, deploy automat la fiecare merge pe main. |
| Observabilitate | Loguri structurate (pino), Sentry pentru erori, uptime monitoring | Aflăm de o problemă înainte să o raporteze clientul. |
04 · Calendar
Planul pe săptămâni
10 săptămâni, 5 faze, 3 jaloane pe care le vedeți funcționând: prototip în săptămâna 2, beta internă în săptămâna 7, go-live în săptămâna 10.
Glisați lateral pentru a vedea întreaga diagramă.
5 faze, 3 jaloane, săptămâni de la start. Orele fiecărei faze sunt notate lângă bară.
Fazele 2 și 3 încep înainte ca precedenta să se încheie complet, pentru că nu depind una de alta: crawler-ul are nevoie doar de schema de date, iar widgetul doar de contractul API al configurației. Dacă o fază întârzie, jalonul următor se mută explicit, cu acordul dumneavoastră, niciodată în tăcere.
Ce vedeți la demo-ul de vineri, săptămână cu săptămână
| Săpt. | Ce vă arătăm | Ce puteți verifica singuri |
|---|---|---|
| S1 | Staging online, login cu rolul dumneavoastră de administrator, structura bazei de date. | Vă conectați în dashboard de pe propriul calculator. |
| S2 | Prototipul: bannerul stilizat după identitatea dumneavoastră, instalat pe un site real al dumneavoastră, cu un script de test blocat până la acord. | Deschideți site-ul, refuzați cookie-urile, verificați în browser că scriptul de test nu s-a încărcat. |
| S3 | Prima scanare a site-ului dumneavoastră: numărul de pagini și lista brută de cookie-uri. | Comparați numărul de pagini cu ce știți despre site. |
| S4 | Scanare completă cu clasificare pe categorii, raport descărcabil, nivelul de abonament propus, rescanare programată. | Lansați o scanare pe un al doilea domeniu și citiți raportul. |
| S5 | Widgetul final: blocare prealabilă a scripturilor, consimțământ pe categorii, Consent Mode v2, link de retragere. | Verificați semnalele în Google Tag Assistant. |
| S6 | Editorul vizual cu previzualizare live, teme, texte multilingve, publicare pe CDN. | Stilizați singuri bannerul și publicați-l pe site-ul de test. |
| S7 | Beta internă: regulile pe jurisdicție demonstrate cu VPN din România, UK, Elveția și California. | Alegeți țara, vedeți bannerul schimbându-se. |
| S8 | Facturare: înregistrare client, plată de test în Stripe, factură emisă, încadrare automată pe nivel. | Parcurgeți fluxul de client nou cu un card de test, de la zero la banner activ. |
| S9 | Dashboard-ul de administrare complet: clienți, abonamente, prețuri, șabloane, export CSV al jurnalului. | Modificați un preț sau un șablon și vedeți efectul fără deploy. |
| S10 | Checklist de lansare parcurs împreună, producție live, instruire de 2 ore, predarea documentației. | Semnați acceptanța finală; încep cele 30 de zile de corecții. |
05 · Efort
Detaliul pe faze
Total: 335–390 de ore, din care 265–305 dezvoltare, 45–55 testare și 25–30 deployment și lansare. Fiecare fază se încheie cu un livrabil pe care îl puteți verifica singuri.
| Fază | Săpt. | Ce facem, în ordine | Livrabil verificabil | Ore |
|---|---|---|---|---|
| 1. Arhitectură și bază de date | 1–2 | Repository în contul dumneavoastră, Docker Compose (api, web, worker, postgres, redis), schema Prisma multi-tenant (tenants, users, domains, scans, cookies, banners, consents, subscriptions), autentificare și roluri, CI cu lint + teste + build, deploy automat pe staging, scheletul widgetului. | Staging accesibil, login funcțional, un banner minimal afișat pe site-ul dumneavoastră, cu un script de test blocat până la acord (prototip). | 40–45 |
| 2. Crawler și scanner | 2–4 | Validarea domeniului la adăugare și protecție SSRF (doar DNS public, fără IP-uri private sau rezervate, doar porturile 80 și 443, worker în container izolat de rețeaua internă); worker Playwright: descoperire pagini din sitemap și linkuri, limită de adâncime și de pagini, regula de numărare a paginilor (parametri, subdomenii, excluderi), respectare robots.txt, captură cookie-uri și local storage, detecție first/third-party, bază de cunoștințe cu 500 de cookie-uri cunoscute, clasificare, raport de scanare, programare lunară în BullMQ, pagină de rezultate în dashboard. | Scanarea unui site real de 1.000 de pagini cu raport complet în sub 20 de minute, inclusiv lista paginilor excluse; un domeniu care indică spre o adresă internă este respins. | 80–90 |
| 3. Widget, editor de stil și jurisdicții | 4–7 | Widget TypeScript: încărcare config din CDN, randare banner și modal pe categorii, blocare scripturi (type="text/plain" + rescriere la consimțământ), cookie de stare, API de consimțământ, Consent Mode v2, link de retragere; motor de jurisdicție (țara afacerii × țara vizitatorului, șabloane UE/UK/CH/US editabile); editor vizual cu previzualizare live, teme, texte multilingve; publicare config pe CDN cu invalidare cache. | Bannerul stilizat de dumneavoastră rulează pe site-ul dumneavoastră, sub 10 KB, GDPR în UE și CCPA în SUA, verificat cu VPN. | 105–125 |
| 4. Facturare și dashboard | 6–9 | Produse și prețuri în Stripe, Checkout și Customer Portal, webhooks (plată reușită, eșuată, anulare), încadrare automată pe nivel după scanare, upgrade/downgrade, Stripe Tax, pagini client (domenii, scanări, banner, jurnal, facturi), pagini admin (clienți, abonamente, prețuri, șabloane, bază de cookie-uri), export CSV al jurnalului. | Un client nou plătește și are bannerul activ în sub 15 minute, cu nivelul provizoriu până la finalul scanării; factura apare în Stripe. | 65–75 |
| 5. QA, securitate, lansare | 8–10 | Teste end-to-end (Playwright) pe fluxurile principale, teste cross-browser și mobil ale widgetului, audit Lighthouse pe 3 site-uri reale, verificare OWASP de bază (autentificare, autorizare pe tenant, rate limiting, CSP, headers), backup zilnic cu test de restaurare, monitorizare și alerte, documentație tehnică și ghid de administrare, instruire 2 ore, go-live pe producție. | Checklist de lansare semnat, producție live cu domeniul dumneavoastră și primul abonament de test. | 45–55 |
| Total | 335–390 | |||
| Tip de efort | Ore |
|---|---|
| Dezvoltare | 265–305 |
| Testare și QA | 45–55 |
| Deployment și lansare | 25–30 |
06 · Metodă
Cum lucrăm
Vedeți software funcțional în fiecare săptămână și puteți opri sau redirecționa proiectul la orice demo, pentru că tot ce am construit până atunci este deja în repository-ul dumneavoastră.
| Practică | Concret |
|---|---|
| Sprinturi de o săptămână | Luni: obiectivele săptămânii în scris (3–5 puncte). Vineri: demo de 30 de minute pe staging și lista a ce urmează. |
| Cod în repository-ul dumneavoastră | GitHub sau GitLab pe contul dumneavoastră din ziua 1; lucrăm pe branch-uri, fiecare merge trece prin CI (lint, teste, build). |
| Staging permanent | Un mediu identic cu producția, actualizat automat la fiecare merge; îl puteți deschide oricând, nu doar la demo. |
| Definition of done | O funcție este gata când: criteriul de acceptanță trece, are teste automate, este documentată în README sau în ghidul de administrare și rulează pe staging. |
| Teste | Unitare pe motorul de jurisdicție, clasificare și încadrare pe nivel; end-to-end (Playwright) pe onboarding, plată și consimțământ; widgetul testat pe Chrome, Safari, Firefox, Edge, iOS și Android. |
| Acceptanță pe fază | La finalul fiecărei faze verificați livrabilul după criteriul scris și confirmați în scris; abia apoi trecem la faza următoare. |
| Schimbări de scop | Orice cerință nouă primește o estimare în ore în maximum 2 zile și intră în plan doar cu acordul dumneavoastră. |
| Documentație | README tehnic, diagrame actualizate, ghid de administrare cu capturi de ecran, specificație OpenAPI generată automat, runbook de operațiuni (backup, restaurare, actualizare). |
| Comunicare | Un canal dedicat (Slack, Teams sau e-mail, la alegerea dumneavoastră); răspundem în aceeași zi lucrătoare; blocajele le semnalăm în ziua în care apar. |
07 · Legal și tehnic
Cerințe tehnice de conformitate
Implementăm mecanismele pe care legea și Google le cer de la un CMP; textele legale rămân ale dumneavoastră și ale juristului dumneavoastră, iar șabloanele pe care le livrăm sunt doar punct de plecare.
| Cerință | Unde o implementăm | Cum verificăm |
|---|---|---|
| Niciun script neesențial înainte de opt-in (GDPR, ePrivacy) | Widget: scripturile marcate data-category stau ca text/plain până la consimțământ; editorul generează instrucțiunile de marcare și snippet-ul pentru Google Tag Manager. Limită: Consent Mode transmite semnale, nu blochează singur scripturi terțe; scripturile încărcate dinamic sau neintegrate conform ghidului nu sunt blocate și apar în raportul de scanare ca neconforme. | Inspectarea cookie-urilor în DevTools înainte și după opt-in; test automat; raport de scanare post-integrare pe fiecare site. |
| Refuz la fel de ușor ca acceptarea | Widget: butonul „Respinge tot” pe primul strat, cu același stil ca „Acceptă tot”; editorul nu permite ascunderea lui. | Captură de ecran la acceptanță. |
| Consimțământ pe categorii și retragere | Widget + API: modal cu Strict necesare (blocat pe activ), Analiză, Marketing; link permanent de redeschidere; retragerea șterge cookie-urile categoriilor dezactivate pe cât permite browserul. | Test end-to-end. |
| Dovada consimțământului | API + PostgreSQL: identificator pseudonim, marcaj temporal, versiunea bannerului și a textelor, categorii alese, jurisdicție aplicată; păstrat 12 luni, export CSV. | Export din dashboard. |
| Google Consent Mode v2 | Widget: gtag('consent','default',…) înainte de orice tag, apoi update cu ad_storage, analytics_storage, ad_user_data, ad_personalization. | Google Tag Assistant arată semnalele. |
| Profil pe jurisdicție | API: motor de reguli (țara afacerii, țara vizitatorului din CF-IPCountry) care alege profilul; widget: opt-out cu link „Do Not Sell or Share” și respectarea antetului Global Privacy Control acolo unde legea aplicabilă afacerii o cere. Profilurile sunt un punct de plecare tehnic, validat de juristul clientului; Elveția și UK au nuanțe proprii (informare vs. consimțământ explicit, excepțiile PECR) pe care profilul le acoperă prin configurare, nu automat. | Test cu VPN din RO, UK, CH, US-California; profilurile revizuite de jurist înainte de go-live. |
| Protecția datelor în platformă | Fără stocarea IP-ului vizitatorilor, TLS peste tot, parole cu argon2, izolare pe tenant prin row-level security, backup criptat în UE. | Checklist de securitate la faza 5. |
| Roluri și responsabilități GDPR | Contract + platformă. Propunerea de pornire: dumneavoastră sunteți operator pentru datele propriilor clienți și persoană împuternicită pentru jurnalele de consimțământ ale site-urilor lor; rolurile se confirmă cu juristul, în funcție de scopurile și responsabilitățile reale ale fiecărei părți. Acord de prelucrare (DPA) ca anexă la contractul cu fiecare client, retenție a jurnalelor de 12 luni (configurabilă), procedură de incident scrisă (runbook livrat în faza 5, cu termenul de notificare stabilit contractual), lista subprocesatorilor (hosting, Cloudflare, Stripe) publicată în dashboard. | Anexele semnate, runbook-ul de incident testat o dată și pagina de subprocesatori publicată înainte de go-live. |
08 · Riscuri
Riscuri tehnice și cum le tratăm
Riscurile reale ale acestui proiect sunt în crawler și în widget; le atacăm primele, în săptămânile 2–4, ca să nu rămână surprize la final.
| Risc | Unde apare | Cum îl tratăm |
|---|---|---|
| Crawler-ul folosit ca vector de atac (SSRF): un client adaugă un „domeniu” care indică spre adrese interne, metadata cloud sau porturi private | Crawler | Validarea domeniului la adăugare (DNS public, fără IP-uri private sau rezervate), re-verificarea rezolvării DNS la fiecare cerere, doar porturile 80 și 443, worker Playwright în container izolat, fără acces la rețeaua internă, limită de cereri pe domeniu și timeout global; criteriu de acceptanță al scanner-ului: domeniile interne sunt respinse cu mesaj clar. |
| Site-uri greu de scanat (protecție anti-bot, zone după login, aplicații single-page) | Crawler | User-agent declarat, IP static pe care clientul îl poate pune pe lista albă, limită de pagini și timeout, scanare cu sesiune autentificată ca opțiune, corecție manuală a numărului de pagini din admin. |
| Cookie-uri necunoscute, neclasificate | Scanner | Bază de cunoștințe cu 500 de cookie-uri la lansare, categoria „Neclasificat” vizibilă în dashboard, clientul le încadrează cu un clic; lista se îmbogățește din toate scanările platformei. |
| Conflict între widget și codul site-ului gazdă | Widget | Fără variabile globale în afara unui singur namespace, CSS izolat prin Shadow DOM, fără dependențe; testat pe WordPress, Shopify, Next.js și HTML static. |
| Scripturi încărcate prin Google Tag Manager care ocolesc blocarea | Widget | Consent Mode v2 ca semnal principal pentru GTM, plus instrucțiuni de configurare a declanșatoarelor pe consimțământ în ghidul de administrare. |
| Depășirea limitei de 10 KB | Widget | Buget de dimensiune verificat în CI la fiecare build; textele și temele vin din configurația JSON, nu din bundle. |
| Webhooks Stripe pierdute sau duplicate | Facturare | Procesare idempotentă după id-ul evenimentului, coadă cu reîncercare, reconciliere zilnică cu API-ul Stripe. |
| Amestec de date între clienți | Dashboard, API | tenant_id obligatoriu pe fiecare tabel, row-level security în PostgreSQL, teste automate care încearcă accesul încrucișat. |
| Schimbări la Google (Consent Mode, TCF) sau în legislație | Widget, șabloane | Widget versionat și actualizat pe CDN fără intervenție la clienți; șabloanele de jurisdicție se editează din admin fără deploy. |
| Estimarea depășită | Plan | Fazele cu cea mai mare incertitudine (2 și 3) au intervalul cel mai larg; dacă la mijlocul unei faze consumul depășește 60% din ore, anunțăm și propunem opțiuni, nu așteptăm finalul. |
09 · Angajament
De ce noi
Nu vindem o idee, ci un plan în care fiecare săptămână are un rezultat verificabil, iar riscul de a continua este decizia dumneavoastră, nu a noastră.
10 · Decizie
Pașii următori
Un singur pas cerut acum: o întâlnire de scoping de 60 de minute, după care primiți planul final și criteriile de acceptanță anexate contractului.
- Întâlnire de scoping (60 min). Confirmăm cele 7 module, regula de numărare a paginilor, site-ul pentru prototip și accesele necesare.
- Planul final și contractul. Scopul, orele, jaloanele și criteriile de acceptanță din acest document, anexate, împreună cu acordul de prelucrare a datelor și clauza de transfer al drepturilor asupra codului; condițiile comerciale separat.
- Start săptămâna 1. Repository, infrastructură, scheletul aplicației.
- Săptămâna 2. Prototipul rulează pe site-ul dumneavoastră; decizia de a continua.
- Săptămâna 10. Go-live, instruire, începutul celor 30 de zile de garanție.