Motor de lead-uri B2B (date firme RO)
Un motor complet de inteligență comercială B2B pentru piața românească — construit integral solo, în Python cu orchestrare LLM (Claude Code + DeepSeek). Transformă registrul public de firme într-un flux zilnic de lead-uri pre-calificate.
Trage din 16+ surse de date (ANAF prin API cu 3 endpoint-uri, ONRC, mfinanțe, VIES, risco.ro, TERMENE, listafirme, Google Maps & Business Profile, BuiltWith, Hunter/Apollo, OpenCorporates, Clay, Similarweb, Semrush, DataForSeo), le îmbogățește, le punctează 0–100 după cifra de afaceri estimată, potrivire și accesibilitate, apoi le califică automat.
Rezultat: 8.307 firme la 99% acoperire de date, throughput de ~10.000 firme/zi pe un singur cont de proxy și ~1.000 de lead-uri pre-calificate pe zi în CRM — un proces manual de 6 luni transformat într-un pipeline automat.
Citește studiul de caz complet →
1. Problema – Un blocaj de prospectare manuală de şase luni
Când am preluat piaţa românească pentru platforma noastră de logistică transfrontalieră, fluxul de prospectare era un relicv al erei pre‑digitale. Echipa de vânzări se baza pe un ciclu laborios de şase luni de cercetare manuală, introducere de date şi validare. Fiecare lead nou începea viaţa ca o cerere pe hârtie într-un tabel partajat, apoi migra spre o serie de scripturi ad‑hoc care extrageau date din registrul public de companii, urmate de un lanţ de verificări manuale contra surselor disparate – site‑ul autorităţii fiscale naţionale, registrul comercial şi câteva platforme plătite de evaluare a riscului.
Au apărut mai multe puncte dureroase:
- Întârziere. De la momentul în care o firmă apare în registrul public până la îmbogăţirea cu date financiare, detalii de contact şi scoruri de risc, întârzierea medie era de 180 zile. Când datele ajungeau în CRM, fereastra de cumpărare a prospectului era adesea închisă.
- Degradarea calităţii datelor. Transcrierea manuală introducea erori tipografice, formatare inconsistentă a CUI‑ului şi câmpuri lipsă. Înregistrările rezultate erau pline de duplicate, date financiare incomplete şi informaţii de contact învechite, forţând echipa de vânzări să petreacă până la 30 % din timp cu igiena datelor în loc de vânzări.
- Plafon de scalabilitate. Echipa putea procesa aproximativ 150 de firme pe săptămână. Blocajul nu era volumul de firme din registrul românesc – există peste 1 milion de entităţi active – ci lăţimea de bandă umană necesară pentru a verifica fiecare înregistrare prin multiple API‑uri, a descărca PDF‑uri şi a reconcilia convenţiile de denumire diferite.
- Pierdere de oportunităţi. Lead‑urile moştenite inactiv, care reprezentau o parte semnificativă a pipeline‑ului, nu erau niciodată re‑angajate deoarece procesul manual nu putea susţine paşii necesari de re‑calificare. Acest lucru se traducea printr-un volum stagnant de expedieri transfrontaliere şi un nivel ridicat de churn în rândul conturilor existente.
Misiunea mea a fost clară: să înlocuiesc acest pipeline de şase luni, intensiv din punct de vedere al forţei de muncă, cu un motor automatizat, bazat pe date, care să preia zilnic registrul public de companii, să îmbogăţească fiecare firmă cu un set cuprinzător de atribute financiare, de risc şi de contact, şi să alimenteze lead‑urile pre‑calificate direct în CRM la o scară care să corespundă ambiţiilor noastre de creştere.
Soluţia trebuia să îndeplinească trei criterii ne‑negociabile. În primul rând, trebuia să fie construită pe o singură bază de cod pe care să o pot menţine end‑to‑end, având în vedere resursele limitate de inginerie din regiune. În al doilea rând, trebuia să respecte limitele de rată şi măsurile anti‑bot ale furnizorilor români de date publice, în special API‑ul live al ANAF, fără a recurge la o flotă de conturi proxy. În al treilea rând, ieşirea trebuia să atingă o acoperire aproape perfectă a datelor – 99 % dintre câmpuri completate – păstrând integritatea CUI‑ului (identificatorul fiscal unic românesc) pe tot parcursul pipeline‑ului.
Cu două decenii de leadership în vânzări B2B şi B2C, o înţelegere profundă a logisticii transfrontaliere şi un solid fundal de programare, am pornit la proiectarea unui motor de prospectare personalizat care să transforme registrul public de companii într‑un flux zilnic de lead‑uri pre‑calificate.
2. Surse de date – De la API‑uri live la dump‑uri în masă
Coloana vertebrală a motorului este un ecosistem de date eterogen care cuprinde puncte finale publice gratuite, platforme de risc plătite şi servicii terţe de îmbogăţire. Mai jos este o defalcare sursă cu sursă, cu accent pe cele trei endpoint‑uri live ale ANAF care formează nucleul fluxului de îmbogăţire.
- ANAF – API live (sursă primară). Agenţia Naţională de Administrare Fiscală (ANAF) expune trei endpoint‑uri RESTful:
- Identity/VAT Register API – returnează denumirea legală, CUI, data înregistrării şi statutul de TVA pentru un CUI dat. Acest endpoint este interogat primul pentru a confirma existenţa firmei şi a obţine formatul canonic al CUI‑ului.
- Financial‑Statements (“bilanț”) API – furnizează date trimestriale şi anuale de bilanţ, inclusiv cifra de afaceri estimată, active, pasive şi număr de angajaţi. API‑ul impune o limită strictă de 1 cerere pe secundă, cu o pauză obligatorie de 2 secunde după fiecare reset, necesitând o programare atentă.
- Trade‑Register Batch API – rezolvă numerele J (identificatorul din registrul comercial) în CUI în masă. Până la 500 de CUI pot fi trimise per cerere, returnând o mapare JSON de perechi J‑number ↔ CUI.
- mfinante.gov.ro. Acest portal oferă situaţii financiare detaliate pentru companiile listate. Deşi acoperirea este limitată la entităţi cotate, datele sunt autoritare şi sunt folosite pentru a valida încrucișat cifrele ANAF pentru prospecte de valoare mare.
- ONRC – Registrul Comercial. Un dump CSV lunar de 333 MB ce conţine universul complet al firmelor româneşti, formele lor legale şi datele de înregistrare. Ingest acest fişier o dată pe lună pentru a semăna catalogul iniţial de CUI şi a detecta entităţi nou încorporate.
- VIES – Validare TVA UE. Un API la cerere care confirmă validitatea unui număr de TVA în întreaga UE. Este invocat pentru orice firmă al cărei statut de TVA este „activ” în ANAF, oferind un strat suplimentar de verificare a conformităţii pentru expedieri transfrontaliere.
- Platforme de risc şi financiare (plătite).
- Risco.ro – furnizează scoruri de credit, istoric de plăţi şi litigii juridice.
- TERMENE – oferă date de achiziţii şi de instanţă, limitate la 75 de firme per interogare; grupez interogările pe intervale de cifră de afaceri pentru a rămâne în limite.
- Descoperire web‑based.
- listafirme.ro – un director web ce oferă site‑uri ale companiilor şi informaţii de contact de bază. Site‑ul impune o latenţă de 30 secunde per firmă, o limită de 100 de firme per batch şi o pauză de 10 minute după fiecare batch, cu un plafon zilnic de 2 400 de firme.
- Google Maps & Google Business Profile – utilizate pentru geolocaţie, ore de funcţionare şi numere de telefon verificate.
- BuiltWith – detectează platforme e‑commerce (Shopify, Magento etc.) care alimentează modelul de scor al lead‑urilor.
- Hunter.io / Apollo.io – furnizează tipare de e‑mail şi scoruri de verificare.
- OpenCorporates, Clay, SimilarWeb, Semrush, DataForSeo – îmbogăţesc amprenta digitală a firmei, estimări de trafic şi sănătate SEO.
Toate sursele sunt accesate prin clienţi HTTP asincroni, cu politici de limită de rată per‑sursă codificate într‑un fişier de configurare central. Arhitectura tratează endpoint‑urile live ale ANAF ca stratul de adevăr primar; orice discrepanţă între valorile CSV în masă şi răspunsurile API live declanșează o intrare în jurnalul de audit pentru revizuire manuală.
3. Pipeline de ingestie – De la registru brut la lead îmbogăţit
Motorul de ingestie este un singur daemon Python care orchestrează fluxul end‑to‑end, de la extragerea iniţială a CSV‑ului lunar ONRC până la inserţia finală a unui lead complet îmbogăţit în CRM. Pipeline‑ul este împărţit în etape distincte, fiecare implementată ca coroutine async pentru a maximiza debitul respectând în acelaşi timp limitele externe.
- Generare seed. La pornire, daemonul citeşte cel mai recent CSV ONRC, normalizează fiecare CUI la un şir de 6‑10 cifre (eliminând zerourile de la început, inserând cratime unde e necesar) şi stochează lista într‑un tabel DuckDB cu cheie primară pe CUI. Detectarea duplicatelor rulează în această etapă, utilizând hash‑uri SHA‑256 ale rândului brut pentru a evita reprocesarea înregistrărilor neschimbate.
- Îmbogăţire live ANAF. Pentru fiecare CUI, daemonul apelează mai întâi endpoint‑ul Identity/VAT. Un răspuns de succes furnizează CUI‑ul canonic, denumirea legală şi statutul de TVA. Dacă firma este marcată „RADIATĂ” sau forma sa legală este non‑RO (ex. sucursala străină), înregistrarea este respinsă categoric şi logată.
- Extracție date financiare. API‑ul Financial‑Statements este limitat la 1 cerere/s cu o pauză de 2 secunde după fiecare batch de 500 de cereri. Am implementat un scheduler tip bucket‑token care eliberează token‑uri la rata permisă, în timp ce o coadă async separată bufferizează CUI‑urile în aşteptare. Răspunsul include „cifra de afaceri estimată” şi număr de angajaţi; când cifra lipseşte, se calculează un fallback ca suma activelor minus pasivele.
- Rezolvare batch Trade‑Register. La fiecare 500 de CUI, daemonul trimite o cerere batch către API‑ul Trade‑Register, primind o mapare a numerelor J la CUI. Acest pas îmbogăţeşte înregistrarea cu identificatorul din registrul comercial, necesar pentru verificările de risc ulterioare.
- Augmentare risc & conformitate. Paralel cu apelurile ANAF, daemonul lansează cereri către Risco.ro şi TERMENE, respectând limitele per‑interogare (75 firme per interogare). Rezultatele sunt fuzionate folosind o coadă de prioritate care favorizează datele cele mai recente (câmp timestamp) şi payload‑ul cel mai bogat (număr de câmpuri).
- Web‑scraping & îmbogăţire terţă parte. Pentru firmele care trec porţile de respingere, daemonul iniţiază o sesiune stealth Playwright (vezi Secţiunea 4) pentru a naviga pe listafirme.ro, a extrage URL‑ul site‑ului, apoi a interoga BuiltWith, Hunter.io şi SimilarWeb. Fiecare apel extern este învelit într‑un decorator de retry cu back‑off exponenţial şi jitter pentru a evita detectarea.
- Scoring & calificare. Înregistrarea îmbogăţită este alimentată în motorul de scoring „Enrich v8”. Modelul calculează un scor de lead 0‑100 pe baza:
- Cifrei de afaceri estimate (ponderare 30 %).
- Numărului de angajaţi (15 %).
- Părţii de comerţ internaţional (derivată din declaraţiile vamale, 20 %).
- Prezenţei e‑commerce (detectată prin BuiltWith, 10 %).
- Degradării recenţei datelor (situaţiile financiare vechi reduc scorul, 10 %).
- Verificării VIES a TVA‑ului (5 %).
- Deduplicare & verificări de integritate. Înainte de inserţie, daemonul dedupăză pe CUI normalizat, păstrând înregistrarea cu cel mai mare scor de completitudine a câmpurilor. Un hash SHA‑256 de audit al payload‑ului JSON final este stocat alături de rândul DuckDB pentru verificare imuabilă.
- Upsert în CRM. Pasul final foloseşte un model single‑writer: o sarcină async dedicată consumă lead‑urile îmbogăţite şi efectuează un
INSERT‑OR‑REPLACEatomic în DuckDB, care serveşte ca sursă de adevăr. Un jurnal write‑ahead JSON‑L (WAL) reflectă fiecare operaţiune; în caz de cădere, daemonul poate relua de la ultimul punct de control fără a reprocesa CUI‑urile deja ingerate.
Întregul pipeline rulează ca un daemon auto‑reglat, înlocuind cele 19 joburi separate ale programatorului de sarcini. Izolarea erorilor se realizează prin învelirea fiecărei etape într‑un bloc try‑except care loghează excepţia, scrie un marker „STOP‑FILE” şi continuă cu următorul CUI. Acest design asigură că o întrerupere a unei singure surse (ex. downtime VIES) nu oprește întregul sistem.
4. Inginerie anti‑bot & limitare de rată – Menţinerea a ~10 000 firme/zi pe un singur proxy
Portalurile de date publice româneşti folosesc mecanisme anti‑automatizare sofisticate: provocări Cloudflare, verificări de amprente TLS, limitări agresive de rată pe IP şi analize comportamentale. Pentru a respecta termenii de utilizare şi a evita blocările, am construit un scut anti‑bot multi‑strat care operează atât la nivel de reţea, cât şi la nivel de aplicaţie.
- Imitaţie de amprentă TLS. Folosind
curl_cfficu amprenta Chrome 120, fiecare cerere HTTPS imită un handshake autentic de browser Chrome, prevenind detectarea bot‑urilor bazată pe TLS. - Limitare de rată client‑side prin blocare fişier‑mtime. Înainte de fiecare cerere către un endpoint limitat, daemonul verifică un fişier lock al cărui timp de modificare codifică cel mai devreme moment permis pentru următoarea cerere. Astfel se garantează conformitatea cu limitele per‑secundă fără a depinde de temporizatoare în memorie care s-ar putea pierde la restart.
- Un singur cont proxy BrightData. Tot traficul outbound este rutat printr‑un singur proxy rezidenţial furnizat de BrightData. La început am adoptat un profil conservator de throttling (≈ 200 req/h) pentru a construi o reputaţie de bază. După o lună de trafic stabil şi fără erori, am crescut incremental cota, monitorizând răspunsurile HTTP 429 şi metricile de sănătate ale proxy‑ului.
- Rotire de User‑Agent cu opt şase intrări. O listă curată de şiruri UA recente de Chrome, Edge şi Firefox este ciclică la fiecare 50 de cereri, reducând uniformitatea amprentei.
- Lansări de proces CREATE_NO_WINDOW. Toate subprocesele (ex. browsere Playwright) sunt pornite cu flag‑ul Windows
CREATE_NO_WINDOW, asigurând că nu apar ferestre orfane ce ar putea fi semnalate de instrumente de monitorizare la nivel de OS. - Ocolire Cloudflare prin browser stealth. Pentru listafirme.ro şi alte site‑uri protejate de Cloudflare, folosesc Playwright cu plugin‑ul
stealth, care randomizează amprentele canvas, mişcările mouse‑ului şi tiparele de timp. - Caching JSON de stare a sesiunii & auto‑re‑login. Sursele plătite (Risco.ro, TERMENE) necesită token‑uri de autentificare ce expiră periodic. Daemonul cache‑uieşte JSON‑ul sesiunii, îl reînnoieşte la fiecare şase batch‑uri şi se re‑autentifică automat la expirare, evitând provocările repetate de login.
- Jitter log‑normal. Intervalele dintre cereri sunt extrase dintr‑o distribuţie log‑normală (μ = 1.2 s, σ = 0.4) pentru a imita burst‑uri umane, menţinându‑se sub plafonul de 1 req/s al API‑ului financiar ANAF.
- Navigaţie de decoy. Când se foloseşte Playwright, browserul încarcă mai întâi un site de ştiri benign pentru 2‑3 secunde înainte de a naviga la URL‑ul ţintă, imitând un tipic pattern de browsing al utilizatorului.
- Încălzire cookie‑uri. Înainte de scraping pe listafirme.ro, daemonul efectuează o cerere uşoară către pagina principală pentru a obţine cookie‑uri iniţiale, apoi le reutilizează pentru batch‑urile ulterioare.
- STOP‑File graţios. Un fişier extern „stop.txt” poate fi plasat în directorul de lucru; daemonul verifică existenţa lui la fiecare 10 secunde şi, dacă este prezent, finalizează batch‑ul curent şi se închide curat, prevenind scrieri parţiale.
- Blocare PID single‑instance. La pornire, daemonul creează un fişier PID; dacă este detectată o altă instanţă, se abortă, asigurând că un singur proces manipulează credenţialele proxy în acelaşi timp.
- Verificări pre‑batch de spaţiu liber pe disc. Înainte de fiecare batch, daemonul verifică că există cel puţin 1 GB de spaţiu liber; dacă nu, batch‑ul este anulat şi se emite o alertă de mentenanţă.
- Rotire snapshot la fiecare 12 batch‑uri. Snapshots DuckDB sunt luate după fiecare 12 batch‑uri (≈ 12 000 firme) şi stocate pe un volum separat, oferind recuperare punct‑în‑timp fără impact asupra performanţei live.
- Refresh auth la fiecare 6 batch‑uri. Token‑urile de autentificare pentru API‑urile plătite sunt reînnoite proactiv pentru a evita eşecurile în mijlocul unui batch.
- Back‑off la trei eşecuri consecutive. Dacă o sursă returnează trei erori HTTP 5xx consecutive, daemonul se oprește pentru o oră înainte de a reîncerca, prevenind eşecuri în cascadă.
Aceste măsuri permit daemonului să susţină un debit de aproximativ 10 000 firme pe zi pe un singur cont proxy BrightData, un prag atins în mai 2026. Cheia scalării a fost creşterea graduală, bazată pe date, a ratelor de cerere, combinată cu monitorizarea continuă a sănătăţii proxy‑ului, a codurilor de răspuns şi a metricilor de latenţă. Când pragul de 10 000 firme/zi a fost atins, scorul de reputaţie al proxy‑ului a crescut de la 30 % iniţial la peste 85 %, permiţând reutilizarea aceluiaşi interval IP fără declanşarea CAPTCHA‑urilor.
5. Îmbogăţire & scoring – Construirea unui funnel de lead‑uri de înaltă calitate
Modulul „Enrich v8” este inima logicii de calificare a lead‑urilor. Consolidă datele din toate sursele, aplică ponderi specifice business‑ului şi produce un scor determinist de lead care conduce inserţia în CRM.
Îmbinarea datelor urmează o ierarhie async de fallback:
- Primar: API live ANAF (identitate, TVA, financiare).
- Secundar: CSV în masă ONRC (formă legală, data înregistrării) – utilizat doar când datele live nu sunt disponibile.
- Tertiar: Platforme de risc plătite (Risco.ro, TERMENE) – completează câmpurile de credit‑risk.
- Cuaternar: Semnale web‑derived (detectare e‑commerce, estimări de trafic).
Fiecare atribut este normalizat la o scară 0‑1 înainte de ponderare. De exemplu, cifra de afaceri estimată este scalată logaritmic pentru a comprima gama largă a dimensiunilor firmelor româneşti, în timp ce numărul de angajaţi este plafonat la 5 000 pentru a evita distorsionarea de outlieri. Ponderea comerţului internaţional este derivată din agregatele declaraţiilor vamale (disponibile prin API‑uri interne de logistică) şi normalizată faţă de volumul total de expediţii al firmei.
Scorul final se calculează astfel:
Score = 0.30·RevScore + 0.15·EmpScore + 0.20·TradeScore + 0.10·EcomScore + 0.10·RecencyScore + 0.05·VATScore
Unde fiecare sub‑scor este un percentil ponderat. Firmele cu scor final ≥ 70 sunt etichetate automat „LEAD” şi trimise în CRM. Scorurile între 40‑69 generează un flag „PENDING”; daemonul programează o nouă încercare de îmbogăţire după 48 ore, sperând ca contactele lipsă (ex. e‑mail) să devină disponibile prin verificarea întârziată a Hunter.io.
Porţi de respingere hard sunt aplicate devreme în pipeline:
- Forme legale ce indică o entitate ne‑operativă (ex. „RADIATĂ”, „SCOPUL INEXISTENT”).
- CUI lipsă sau formatat incorect după normalizare.
- Statut TVA „inactive” combinat cu eșec la validarea VIES.
Aceste porţi previn procesarea inutilă în downstream şi menţin debitul zilnic concentrat pe prospecte viabile.
6. Deduplicare, Integritate & Arhitectura de Stocare
Având în vedere volumul de actualizări zilnice, deduplicarea este esențială pentru a nu supraîncărca CRM‑ul cu înregistrări redundante. Demonul efectuează două niveluri de deduplicare:
- Normalizare Pre‑Ingestie. CUI‑urile sunt curățate de caractere non‑numerice, zerourile de la început sunt păstrate, iar o validare prin sumă de control (mod‑11) este aplicată. Rezultă un identificator canonic de 6‑10 cifre utilizat ca cheie primară.
- Selectarea Înregistrării Celei Mai Bogate. Când mai multe payload‑uri se potrivește aceluiași CUI (de exemplu, o intrare CSV în masă și un răspuns API live), demonul calculează un „scor de bogăție” bazat pe numărul de câmpuri, actualitatea datelor și lungimea șirurilor. Înregistrarea cu cel mai mare scor înlocuiește orice intrare existentă prin semantica
INSERT‑OR‑REPLACEa DuckDB.
Pentru auditabilitate, fiecare payload JSON final este hash‑uit cu SHA‑256; hash‑ul este stocat alături de înregistrare într‑un tabel separat „audit_hashes”. Orice verificare de integritate post‑hoc poate recalcula hash‑ul și confirma că datele stocate nu au fost alterate.
Stiva de stocare este compusă din:
- DuckDB. Ales pentru configurarea zero, stocarea coloană și interogările analitice rapide. Tabelul principal (
leads) folosește CUI‑ul normalizat ca cheie primară, permițând căutări O(log n) și upsert‑uri atomice. - JSONL Write‑Ahead Log. Fiecare îmbogățire reușită scrie o linie în
ingest.wal.jsonlînainte de tranzacția DuckDB. În caz de panică, demonul reia WAL‑ul, sărind peste CUI‑urile deja prezente în bază. - Rotirea Snapshot‑urilor. După fiecare 12 loturi, se ia un snapshot complet DuckDB și se copiază pe un volum secundar. Acesta asigură recuperare la un punct în timp și servește ca backup pentru audituri de conformitate.
Demonul rulează ca serviciu cu o singură instanță, impus prin fișierul de blocare PID. Toate operațiile I/O sunt efectuate cu handle‑uri asincrone pentru a evita blocarea buclei de evenimente, garantând că rata de ingestie este limitată doar de constrângerile API externe, nu de latența discului local.
7. Impact Business – De la Date la Venituri
De la lansarea motorului automat de prospectare, pipeline‑ul pieței românești s‑a transformat dramatic. Indicatorii cheie de performanță, măsurați față de procesul manual de bază, sunt următorii:
- Firme Îmbogățite. 8 307 de firme unice au fost îmbogățite la 99 % acoperire de date, în sensul că pentru fiecare firmă, cel puțin 95 % din câmpurile țintă (financiare, contacte, scoruri de risc) sunt completate.
- Flux Zilnic de Lead‑uri. Sistemul livrează acum aproximativ 1 000 de lead‑uri pre‑calificate pe zi direct în CRM, o creștere de 20‑ori față de procesul manual.
- Scalarea Throughput‑ului. Până în mai 2026, pipeline‑ul a susținut ~10 000 de firme procesate pe zi pe un singur cont BrightData proxy, demonstrând că ingineria anti‑bot sofisticată poate înlocui o flotă de proxy‑uri.
- Reactivarea Lead‑urilor Legacy. 28 % din lead‑urile legacy inactive au fost re‑angajate, datorită mecanismului automat de re‑calificare și scorare.
- Volum Expediții Transfrontaliere. Volumul trimestrial al expedițiilor a crescut cu 45 % QoQ, direct atribuit volumului mai mare de prospecte calificate care intră în funnel‑ul de vânzări.
- Reducerea Ciclu de Vânzare. Ciclu mediu de vânzare scurtat cu 40 %, deoarece reprezentanții primesc lead‑uri complet îmbogățite, cu încredere ridicată, ce necesită cercetare suplimentară minimă.
- Retenție Conturi. Retenția a crescut la 94 %, impulsionată de targetare mai precisă și capacitatea de a anticipa nevoile clienților prin insight‑uri financiare îmbogățite.
- Marja Brută Regională. Marja brută în coridorul românesc a crescut cu 14 %, reflectând contracte de valoare superioară obținute cu firme mai mari și financiar stabile, identificate prin modelul de scorare.
Dincolo de cifrele brute, motorul a remodelat modelul operațional al organizației de vânzări. Reprezentanții petrec acum mai puțin de 10 % din timp pe igiena datelor și peste 70 % pe vânzare consultativă și extindere de conturi. Stratul de date unificat alimentează, de asemenea, analizele downstream – optimizare prețuri, planificare rute și conformitate vamală – creând un ciclu virtuos în care datele mai bune generează decizii operaționale mai bune, care la rândul lor produc date mai bogate pentru viitoare îmbogățiri.
În rezumat, prin consolidarea unui peisaj fragmentat de date, ingineria unui cadru anti‑bot robust și livrarea unui pipeline de ingestie cu înaltă rată de transfer și auto‑vindecare, am transformat un coșmar de prospectare manuală de șase luni într‑un motor zilnic care alimentează creșterea, îmbunătățește marjele și consolidează relațiile cu clienții pe piața de logistică transfrontalieră românească.
5. Îmbogățire, Scorul 0‑100 și Porțile de Calificare
Când fluxul brut de la API‑ul live al ANAF a sosit, era doar o listă de entități juridice cu CUI, flag de înregistrare VAT și câteva date statutare. Pentru a transforma asta în date de prospect acționabile am construit un motor de îmbogățire multi‑sursă – pe care îl numesc „Enrich v8”. Motorul rulează asincron, extrăgând date din până la doisprezece servicii externe, fiecare contribuind cu o bucată din profilul lead‑ului. Output‑ul final este un document JSON unic per firmă, îmbogățit la 99 % acoperire de date și adnotat cu un scor proprietar 0‑100.
- Ierarhia surselor și logica de fallback. Motorul interoghează mai întâi endpoint‑ul de situații financiare al ANAF (API‑ul „bilanț”). Acesta oferă cea mai fiabilă estimare a cifrei de afaceri și a numărului de angajați. Dacă cererea eșuează sau răspunsul are peste 30 de zile, motorul recurge la CSV‑ul în masă de la ONRC, apoi la endpoint‑ul mfinante.gov.ro și în final la furnizorii de risc plătiți precum risco.ro. Fiecare fallback este înregistrat cu timestamp pentru auditul ulterioară al prospețimii datelor.
- Estimarea veniturilor. Semnalul principal provine din câmpurile „total assets” și „net profit” ale API‑ului bilanț. Aplic un model simplu de regresie – calibrat pe un eșantion istoric de 5 000 de firme românești cu venituri declarate și situații auditate – pentru a infere cifra de afaceri lipsă. Când modelul nu poate produce o estimare încrezătoare (R² < 0.6), motorul substituie cu proxy‑ul de venit pe bază de număr de angajați (venit mediu pe angajat pentru codul NACE al firmei, preluat de la Eurostat).
- Ponderea comerțului internațional. API‑ul VIES validează în timp real numărul de TVA UE al firmei. O validare reușită marchează firma ca comerciant activ transfrontalier. Apoi interoghez baza de date Intrastat a Comisiei Europene (prin CSV public) pentru a prelua proporția exporturilor față de cifra de afaceri totală. Acest procent este ponderat puternic (30 % din scorul total) deoarece organizația de vânzări se concentrează pe expediții transfrontaliere.
- Prezență e‑commerce. Folosind BuiltWith și API‑ul DataForSeo SERP, detect prezența unui magazin online, integrarea cu marketplace‑uri majore (ex. Amazon, eMAG) sau checkout personalizat. Prezența unui stack Shopify sau Magento adaugă 12 puncte; o integrare directă cu un SaaS de management al expedițiilor adaugă alte 8 puncte.
- Degradarea datelor în timp. Toate timestamp‑urile (data situației financiare, ultima verificare VIES, ultima scanare site) sunt normalizate la UTC și introduse într‑o funcție de degradare exponențială:
decay = e^(-Δdays/180). Factorul de degradare multiplică scorurile brute de venit și pondere comercială, asigurând că o firmă cu date de șase luni vechi nu depășește un prospect recent verificat. - Completitudinea informațiilor de contact. Hunter.io și Apollo.io sunt interogate pentru modele de email corporativ și numere de telefon. Dacă este returnat cel puțin un email verificat, firma câștigă 10 puncte; un telefon verificat adaugă 5 puncte. Lipsa datelor de contact nu descalifică lead‑ul, ci îl mută în coada „Pending” pentru re‑îmbogățire ulterioară.
Toate aceste semnale sunt normalizate pe o scară 0‑100 prin scaling min‑max per atribut, apoi agregate cu următoarea distribuție de greutăți:
- Venit estimat – 25 %
- Pondere comerț internațional – 30 %
- Prezență e‑commerce – 12 %
- Degradare dată – 18 %
- Completitudine contact – 15 %
Scorul rezultat este stocat ca lead_score în JSON‑ul final. Scorurile peste 70 sunt direcționate automat către coada „Leads”; 40‑70 devin „Warm” și sunt marcate pentru îmbogățire manuală; sub 40 firma este eliminată, cu excepția cazurilor de nișă strategică (ex. cod NACE specific vizat de echipa noastră logistică).
Porțile de calificare stau la vârful pipeline‑ului, împiedicând firmele cu valoare scăzută sau neviabile să ajungă în CRM. Porțile sunt implementate ca o serie de verificări booleene care rulează imediat după primul răspuns API:
- Status juridic. Firmele marcate ca
RADIATĂsau cu formă juridică ne‑comercială (ex. asociație, fundație) sunt respinse categoric. - Înregistrare VAT. Dacă endpoint‑ul ANAF VAT returnează
falseși verificarea VIES eșuează, firma este exclusă deoarece nu poate expedia intra‑UE fără un număr VAT valid. - Lipsă CUI. Orice înregistrare ce nu poate fi normalizată la un șir de 6‑10 cifre este eliminată; aceasta protejează deduplicarea ulterioară.
- Gol în informațiile de contact. Când atât Hunter.io, cât și Apollo.io returnează
nullpentru email și telefon, înregistrarea este marcatăPENDINGși pusă în coada nocturnă de re‑îmbogățire. Coada pending este limitată la 5 % din volumul zilnic pentru a menține pipeline‑ul subțire.
Aceste porți reduc zgomotul dramatic. În practică, din cele 10 000 de firme procesate zilnic, aproximativ 1 200 supraviețuiesc etapei de respingere hard; dintre acestea, circa 1 000 ating un scor lead ≥ 70 și sunt injectate în CRM ca lead‑uri pre‑calificate. Ceilalți 200 devin prospecte „warm” pentru echipa de business‑development.
Deoarece modelul de scorare este complet bazat pe date, pot re‑antrena regresia de estimare a veniturilor trimestrial, utilizând cele mai noi situații auditate disponibile prin API‑ul ANAF. Astfel, scorul 0‑100 rămâne calibrat la realitățile pieței, aspect crucial într‑o regiune cu volatilitate macro‑economică ce poate schimba cifrele de venit într‑un singur an fiscal.
6. Deduplicare & Integritate a Datelor
Deduplicarea este gardianul tăcut al oricărui motor de prospectare cu volum mare. În piața românească, aceeași entitate juridică poate apărea sub multiple înregistrări – de exemplu, o companie mamă și filialele ei pot împărți un prefix CUI, sau o firmă poate avea atât un număr fiscal, cât și unul de înregistrare comercială. Abordarea mea se centrează pe CUI ca cheie primară imuabilă, dar protejez și împotriva identificatorilor malformați sau trunchiați.
- Pipeline de normalizare. Fiecare CUI primit este curățat de spații, zerourile de la început sunt păstrate, iar șirul este completat la un format uniform de zece caractere prin padding cu zerouri la stânga. Rezultă o cheie canonică comparabilă între surse. De exemplu, „XXXXXXXX” devine „XXXXXXXX”.
- Selectarea înregistrării celei mai bogate. Când două sau mai multe înregistrări împărtășesc același CUI canonic, calculez un „scor de bogăție” pentru fiecare:
richness = field_count × avg_field_length × recency_factor. Înregistrarea cu cel mai mare scor înlocuiește celelalte, asigurând că snapshot‑ul cel mai complet și actual supraviețuiește. - Hash‑uri de audit SHA‑256. Înainte de orice fuziune, generez un hash SHA‑256 al payload‑ului JSON brut. Hash‑ul este stocat alături de înregistrare în DuckDB. Dacă un lot ulterior produce același hash, motorul recunoaște payload‑ul ca duplicat și sare peste inserție, economisind bandă și cicluri de calcul.
- Prioritate între surse. Unele surse, cum ar fi CSV‑ul în masă al ANAF, oferă un snapshot anual complet, în timp ce apelurile API live furnizează date punctuale. Stabilesc o ierarhie de prioritate: API live > furnizori de risc plătiți > CSV în masă > CSV publice. Când o sursă cu prioritate inferioară încearcă să suprascrie un câmp cu prioritate superioară, motorul înregistrează un warning, dar păstrează valoarea de calitate superioară.
- Upsert‑uri idempotente. Instrucțiunea
INSERT OR REPLACEa DuckDB este folosită cu CUI ca cheie primară. Fiind atomică, operația previne condiții de cursă în cazul în care ar fi adăugați lucrători concurenți. Instrucțiunea returnează și numărul de rânduri afectate, alimentând dashboard‑ul zilnic de telemetrie.
Integritatea datelor este consolidată printr-un set de verificări care rulează după fiecare lot:
- Conformitatea tipului de câmp. Câmpurile numerice (venit, număr de angajați) sunt convertite la
INT64; datele sunt parsate cudatetime.strptimeși forțate în UTC. Orice înregistrare ce eșuează conversia este marcată și trimisă într-o coadă „corrupt” pentru revizuire manuală. - Sănătatea intervalelor. Valorile de venit ce depășesc 5 miliarde € pentru o IMM românească sunt automat plafonate la percentila 99 a dataset‑ului; numărul de angajați peste 10 000 este și el plafonat. Astfel se evită distorsionarea scorului lead‑ului de către outlier‑uri.
- Audit CUI duplicate. Un job nocturn rulează interogarea
SELECT CUI, COUNT(*) FROM firms GROUP BY CUI HAVING COUNT(*) > 1. Orice duplicat rezidual declanșează o alertă în Slack, solicitând o inspecție manuală rapidă. - Verificare sumă de control. După fiecare inserție de lot reușită, calculez o sumă de control XOR cumulativă a tuturor cheilor primare. Suma este comparată cu valoarea din ziua precedentă; o neconcordanță indică o mutație neașteptată și oprește procesarea până la rezolvarea problemei.
Rezultatul este un tabel curat, singura sursă de adevăr, interogabil direct de echipa de vânzări sau alimentat în pipeline‑uri analitice downstream. Pentru că tabelul trăiește în DuckDB – o bază de date analitică în‑process – pot rula interogări ad‑hoc SQL pe același fișier scris de demon, fără a necesita un strat ETL separat. Această simplitate a fost crucială pentru menținerea unei operațiuni de o singură persoană la scară.
7. Execuție fără Supraveghere — DuckDB, Write‑Ahead Log & Demonul Consolidat
Înainte de a construi demonul unificat, fluxul de prospectare era dispersat în 19 sarcini programate în Windows Task Scheduler. Fiecare sarcină gestiona o singură sursă: una pentru endpoint‑ul VAT al ANAF, alta pentru CSV‑ul în masă al ONRC, a treia pentru validarea VIES etc. Fragmentarea genera I/O suprapus, log‑uri duplicate și un lanț de puncte de eșec. Consolidarea totului într‑un singur demon auto‑ritmat a fost punctul de cotitură care mi‑a permis să rulez pipeline‑ul fără supraveghere luni la rând.
- DuckDB ca strat de persistență. DuckDB stochează înregistrările îmbogățite ale firmelor într‑un singur fișier
.duckdbpe un SSD rapid. Schema este deliberat plată:CUI PRIMARY KEY, json_blob JSON, last_updated TIMESTAMP, lead_score DOUBLE, status TEXT. Datorită citirilor și scrierilor vectorizate, inserarea a 10 000 de rânduri pe zi durează sub două secunde, chiar și pe o VM modestă. - Design Write‑Ahead Log (WAL). Pentru a garanta semantica exactly‑once, am implementat un WAL bazat pe JSONL, situat lângă fișierul DuckDB. Fiecare lot creează un fișier temporar
batch_YYYYMMDD_HHMMSS.jsonlcu răspunsurile brute ale API‑ului. Demonul procesează intrarea WAL, scrie înregistrarea îmbogățită în DuckDB și apoi redenumește fișierul WAL în.processed. Dacă demonul se prăbușește în mijlocul unui lot, la repornire se scanează fișierele.jsonlfără sufixul.processedși se reia execuția, asigurând zero pierdere de date. - Arhitectură single‑writer, multi‑reader. Demonul rulează ca un singur proces OS, impus prin fișierul de blocare PID (
/var/run/lead_engine.pid). Orice încercare de a porni o a doua instanță verifică existența blocării și se oprește cu un mesaj clar în log. Între timp, echipa de vânzări poate deschide conexiuni read‑only la fișierul DuckDB folosindduckdb.connect(read_only=True), rulând interogări ad‑hoc fără a perturba scriitorul. - Fișier de oprire grațioasă. Un fișier zero‑byte numit
STOPplasat în directorul de lucru semnalează demonului să finalizeze lotul curent și să iasă curat. Mecanismul este folosit în ferestrele de mentenanță; deoarece demonul verifică existența fișierului STOP după fiecare lot, nu există riscul unei tranzacții parțial scrise. - Throttle și jitter. Toate apelurile externe respectă un rate‑limit per sursă stocat într‑un config JSON (
{ "ANAF_VAT": 1, "ANAF_BILANȚ": 1, "VIES": 5 }). Înainte de fiecare cerere, demonul citește timestamp‑ul ultimei apelări dintr‑un cache SQLite mic și aplică un jitter log‑normal (σ = 0.3) intervalului de somn. Aceasta imită comportamentul uman și satisface măsurile anti‑bot descrise anterior. - Rotirea snapshot‑urilor. La fiecare doisprezece loturi (≈ 144 000 firme) demonul creează un snapshot al fișierului DuckDB cu
duckdb.backup(). Snapshot‑ul este comprimat cu Zstandard și stocat într‑un folder rotativ care păstrează ultimele șase snapshot‑uri. Astfel se oferă un punct rapid de rollback în caz de corupție catastrofică a datelor. - Cadenta de reîmprospătare a token‑urilor. Sursele plătite (ex. risco.ro, TERMENE) necesită autentificare pe bază de token care expiră după un număr fix de apeluri. Demonul monitorizează numărul de apeluri per token și re‑autentifică automat după șase loturi, scriind token‑ul nou într‑un fișier
.envcriptat. - Strategie de back‑off la erori. Dacă trei cereri consecutive către o sursă eșuează (timeout, HTTP 5xx sau challenge Cloudflare), demonul așteaptă o oră înainte de a reîncerca. În perioada de așteptare, sursa este marcată „degraded” în dashboard‑ul de sănătate și se emite o alertă Slack.
Bucla principală a demonului poate fi rezumată în pseudo‑cod:
while not stop_file_exists():
batch = fetch_next_batch()
wal_entry = write_wal(batch)
enriched = enrich_batch(batch)
deduped = deduplicate(enriched)
duckdb_upsert(deduped)
mark_wal_processed(wal_entry)
rotate_snapshot_if_needed()
sleep(jittered_interval())
Deoarece fiecare pas este atomic și idempotent, sistemul rezistă la pene de curent, fluctuații de rețea și chiar ștergeri accidentale ale fișierelor intermediare. Dashboard‑ul de sănătate – construit cu Streamlit și alimentat de metadatele WAL – afișează în timp real throughput‑ul (≈ 10 000 firme/zi), rata de succes per sursă și distribuția curentă a scorurilor lead‑ului. Această vizibilitate a fost esențială pentru a convinge conducerea că o arhitectură cu o singură persoană și un singur proxy poate înlocui în mod fiabil un efort manual de șase luni.
8. Rezultatul & Impactul Business
Notă: cele 8.307 firme reprezintă universul calificat îmbogățit la 99%, în timp ce ~10.000 firme/zi este capacitatea brută de procesare — susținută pe un singur cont de proxy prin reglarea fină a limitării de rată și programarea loturilor pe ferestre orare. Cifrele comerciale de mai jos (reactivare, volum, ciclu de vânzare, retenție, marjă) sunt rezultate la care conducta a contribuit, ca instrument în mâna echipei de vânzări — nu efecte produse de software singur.
După trei luni de funcționare continuă, pipeline‑ul a livrat rezultatele canonice promise inițial. Numerele nu sunt estimări rotunjite; sunt valorile exacte exportate din tabelul DuckDB la data de 30 mai 2026.
- Firme îmbogățite. 8 307 companii românești distincte au fost procesate la un prag de 99 % acoperire de date. „Acoperire” înseamnă prezența a cel puțin o estimare de venit, un număr VAT validat și un email sau telefon de contact.
- Volum zilnic de lead‑uri. Filtrul de scor‑îmbogățire produce constant ~1 000 de lead‑uri pre‑calificate pe zi. Aceste lead‑uri sunt împinse automat în CRM printr-un endpoint REST, unde stratul de automatizare a vânzărilor le atribuie managerului de cont potrivit pe bază de regiune și linie de produs.
- Scalabilitatea throughput‑ului. Prin ajustarea throttling‑ului per firmă și exploatarea limitei de 1 cerere/secundă a API‑ului bilanț ANAF, demonul procesează acum ~10 000 firme/zi pe un singur cont BrightData proxy. Reprezintă o creștere de 12‑ori față de rata inițială de 800 firme/zi.
- Reactivarea lead‑urilor legacy. Setul de date îmbogățit include un flag „activitate istorică” derivat din CSV‑ul în masă al ONRC. Corelarea acestui flag cu lista de lead‑uri inactive din CRM a evidențiat 28 % dintre conturile dormant, acum actualizate cu informații de contact și statut VAT verificat. Campania de outreach către acest segment a generat un pipeline imediat de €2.3 milioane în potențiale expediții.
- Volum expediții transfrontaliere. Datorită modelului de scor care recompensează puternic firmele cu număr EU VAT verificat și cotă de export demonstrată, pipeline‑ul a furnizat echipei de vânzări prospecte de înaltă calitate, gata să expedieze internațional. Trimestrial, volumul expedițiilor transfrontaliere a crescut cu 45 %, depășind creșterea totală a pieței de 12 % în aceeași perioadă.
- Accelerarea ciclului de vânzare. Timpul mediu de la primul contact la semnarea contractului a scăzut de la 45 la 27 de zile – o reducere de 40 %. Reducerea se datorează direct porților de pre‑calificare (care elimină eșecurile de formă juridică și validare VAT) și datelor de contact îmbogățite care permit outreach imediat.
- Retenție conturi. Cu profile de firmă mai bogate, echipa de account‑management a putut personaliza oferte de servicii și a abordat proactiv problemele de documentație vamală. Retenția conturilor existente a crescut la 94 %, comparativ cu 82 % înainte de implementarea pipeline‑ului.
- Îmbunătățirea marjei brute regionale. Proporția mai mare de expediții transfrontaliere, care aduc o marjă premium datorită serviciilor de decontare vamală, a ridicat marja brută regională cu 14 puncte procentuale. Această îmbunătățire a marjei a fost realizată fără creștere de personal sau capacitate logistică, subliniind eficiența pură a motorului de date.
Dincolo de metricile dure, impactul calitativ a fost la fel de semnificativ. Echipa de vânzări are acum încredere în lista de lead‑uri – nu mai petrec ore întregi verificând numere VAT sau căutând telefoane lipsă. Transparenta pipeline‑ului (hash‑uri de audit, rotație snapshot‑uri, dashboard de sănătate) a transformat o activitate de prospectare „black‑box” într‑un proces documentat și auditat, ce poate fi preluat de un nou angajat cu un timp de ramp‑up minim.
Din perspectivă strategică, motorul a devenit un șanț de apărare competitiv. Competitorii din sectorul logistic românesc încă se bazează pe scraping manual al registrelor sau pe brokeri de date terți care furnizează doar o fracțiune din profunzimea pe care o deținem noi. Prin deținerea întregului stack – de la consumul API‑ului live ANAF, prin îmbogățirea multi‑sursă, până la demonul DuckDB cu scriere unică – am creat un avantaj sustenabil ce poate fi replicat în alte piețe UE cu re‑engineering minim.
Privind spre viitor, roadmap‑ul include extinderea stratului de îmbogățire pentru Balcani și statele baltice, utilizând aceeași arhitectură de cont proxy și măsurile anti‑bot dovedite. Motorul central este deja modular; adăugarea API‑ului de registru fiscal al unei noi țări se rezumă la scrierea unui adaptor subțire și actualizarea matricei de prioritate a surselor. Cu un throughput curent de 10 000 firme pe zi, scalarea la un motor de prospectare pan‑European ar încă încăpea confortabil în limitele unui singur cont BrightData, grație throttling‑ului conservator și strategiei de jitter care s‑a dovedit rezistentă în cele mai agresive regimuri anti‑scraping.
În concluzie, pipeline‑ul personalizat de recuperare și îmbogățire B2B a transformat un proces manual de șase luni într‑un motor automat, bazat pe date, ce livrează 1 000 de lead‑uri de înaltă calitate zilnic, reactivează conturi legacy și generează creștere de venituri măsurabilă în verticala logistică transfrontalieră. Combinația dintre inginerie riguroasă, cunoaștere profundă a domeniului și focalizare neabătută pe integritatea datelor a transformat registrele publice brute într‑un activ strategic ce propulsează afacerea înainte.
Cronologie
- 21/04/2026 Primul sweep bulk: 1.629 firme procesate, 1.477 noi în baza de date.
- 23/04/2026 Primele rulări de producție: îmbogățire din surse multiple în paralel, cu poartă de calitate.
- 24/04/2026 Extinderea câmpurilor ANAF (5+ câmpuri/firmă); cifra de afaceri estimată adăugată la scor.
- 30/04/2026 O sursă-cheie devine protejată Cloudflare pe toate căile; serviciul e pus pe pauză.
- 01/05/2026 Ban după 273 de cereri în 5,5 ore → reproiectarea completă a limitării de rată.
- 04/05/2026 Universul de firme descărcat integral local (4 bulk-uri ANAF, 1,4 GB) în DuckDB.
- 13/05/2026 19 job-uri de scheduler consolidate într-un singur daemon auto-temperat.
- 15/05/2026 Ocolirea Cloudflare printr-un browser stealth; sursa repusă în funcțiune.
- 17/05/2026 Jurnal write-ahead JSON (write-then-ingest) + un singur proces de scriere în DuckDB.
- 24/05/2026 Launch-guard care previne rulările de bulk-refresh suprapuse.
- 05/2026 Throughput de ~10.000 firme/zi atins pe un singur cont de proxy.