Deleted (live in gov-agreg repo): - src/lib/auth-queries.ts, supabase.ts, platform-queries.ts (marketing only) - src/pages/api/auth/, platform/, traducator.ts Added: - PROMPTS.md: §0 vreau.digital context + full historic (sections §0a-§0e from gov-agreg pre-split — 1367 lines preserved as "Istoric sesiuni") - CLAUDE.md: vreau.digital scope, 17 data sources table, deploy, sister project link Memory dir bootstrapped at ~/Code/claude-memory/projects/vreau-digital/memory/ with 23 .md files (all relevant context from gov-agreg). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
75 KiB
Prompts pentru sesiuni Claude — vreau.digital
0. Context comun (citește PRIMUL)
Lucrăm la vreau.digital — platforma de transparență achiziții publice
România. Repo: git.beletage.ro/gitadmin/vreau-digital.
SPLIT MAJOR 2026-05-13: spin-off din `gov-agreg` (vreaudigital.ro). Acest
repo conține platforma standalone — toate scrapers, recipes, investigation
pages, SQL migrations, Postgres queries cross-source.
vreaudigital.ro = hub marketing/discoverability (gov-agreg repo)
vreau.digital = platforma achiziții (acest repo)
Stack:
- Astro 5 + React 19 + Tailwind 3.4 (NU v4) + Node @astrojs/node standalone
- PostgreSQL 17 @ satra:5432 (schema `seap`, `firms`, `anaf`, ... 17 schemas)
- MapLibre 5 + Martin tile server @ 10.10.10.166:3010 (gis_uats_z0/z5/z8/z12)
- Photon geocoder daemon @ satra:2322
- Container Docker @ satra:5096, Traefik @ proxy 10.10.10.199, Cloudflare proxied → vreau.digital
Date prod (post 2026-05-13):
- 4.005M firme ONRC (100% geocoded)
- 7.77M financials (10 ani, 2015-2024)
- 781K+ anunțuri SEAP/TED
- 47K datornici ANAF T1 2026 + 648K lista albă (live via 2captcha)
- 17 systemd timers scrapere (daily/weekly/monthly/quarterly)
- 49 retete + 15 investigation pages
Infra:
- CI/CD: Gitea webhook → satra:9867/hooks/vreau-digital-deploy → /opt/vreau-digital/deploy.sh
- Secrete: Infisical Machine Identity `/vreaudigital` (DATABASE_URL, TWOCAPTCHA_KEY, etc.)
- DB queries dev: `/tmp/govq.sh` reads SQL stdin → architools_db pe satra
- Verifică `/api/version` post-push
Routes (toate la rădăcină, NU /achizitii/):
- /, /cauta, /retete/[slug], /investigation/[slug], /firma/[cui], /autoritate/[cui]
- /red-flags, /top-contracte, /top-firme, /fonduri-ue, /azi, /risc/*, /explorer
- /harta (Civic OS), /api/* (og, cpv, profil, ocds, harta, version)
Reguli operaționale:
- `npx astro check` + `npm run build` PASS înainte de commit
- DACĂ scp pe satra → reset ÎNAINTE de push (deploy.sh git pull --ff-only fails)
- Pre-create /var/log/vreau-digital-*.log cu chown bulibasa pentru scrapere noi
- NU echo niciun secret. $VAR unexpanded, --env-file (NU -e)
- Memory persistat: scrie DIRECT în ~/Code/claude-memory/projects/vreau-digital/memory/ + git commit + push (sync cron clobbers ~/.claude/.../memory/ every 60s)
- systemd OnCalendar: `Sun *-*-*` (cu space după ziua), NU `Sun*-*-*`
Istoric sesiuni (din gov-agreg, păstrat aici după split 2026-05-13)
Prompts pentru sesiuni Claude — vreaudigital.ro
Fișier de copy-paste pentru sesiunile viitoare Claude Code, ca să nu reexpli o oră de fiecare dată context. Update-ează când schimbi arhitectura major.
Trei prompt-uri gata-de-folosit:
- Continuare /achizitii sub-app — pickup pentru lucrul pe achiziții publice
- Bugs/features /achizitii — pentru modificări incrementale pe sub-app-ul de achiziții
- Bugs/features marketing —
pentru
/,/idei,/produse,/despre,/contribuie,/cont/*
Plus Context comun — citește PRIMUL.
0. Context comun
Lipește asta la începutul oricărei sesiuni dacă nu folosești prompt-urile dedicate de mai jos (sau dacă vrei rezumat scurt).
Lucrăm la vreaudigital.ro — platformă de transparență achiziții publice
România. Repo: git.beletage.ro/gitadmin/gov-agreg.
PIVOT MAI 2026: proiectul e DOAR despre achiziții publice. /idei, /produse,
/contribuie sunt shell secundar — NU investim acolo. Toate feature-urile noi
merg pe /harta + /achizitii + /api/ocds.
Stack:
- Astro 5.18 + React 19 + Tailwind 3.4 (NU v4) + Node @astrojs/node standalone
- PostgreSQL + PostGIS @ satra:5432 (schema `seap` în arhitools_db)
- MapLibre 5 + Martin tile server @ 10.10.10.166:3010 (gis_uats_z0/z5/z8/z12)
- Public domain: https://vreaudigital.ro
Date prod:
- 642K+ anunțuri SEAP/TED/datagov în seap.announcements
- 13.8K autorități (~99% georef siruta), 57K furnizori (~99.3% georef)
- 9 materialized views pentru perf (uat_kpi, uat_procurement_stats,
mv_authority_concentration, mv_cpv_median_value, mv_top_* etc.)
- Refresh nightly via systemd timer vreaudigital-mvs.timer @ 04:00
Infra:
- Container Docker @ satra:5095 (host 10.10.10.166), Traefik @ proxy
10.10.10.199, Sophos DNAT 80/443. Test pe pages: curl https://vreaudigital.ro/...
- CI/CD: Gitea webhook → satra:9867 → /opt/vreaudigital/deploy.sh
- git pull → docker compose build cu BUILD_SHA build-arg → up -d
- Verifică /api/version după push să confirmi sha-ul corect
- Secrete: Infisical Machine Identity Universal Auth la runtime
(project beletage-infra, env prod, path /vreaudigital). NU sunt în .env;
container's entrypoint.sh face login + `infisical run -- node ...`
- Cron MV refresh: `vreaudigital-mvs.timer` rulează nightly
Design constraints (HARD):
- Paletă: blue (primary) + amber (secondary) + slate (neutral)
- Fonts: Plus Jakarta Sans (heading), Inter (body), JetBrains Mono (DOAR cod)
- rounded-xl + shadow-card (vezi global.css)
- ANTI-PATTERNS respinse explicit: brutalism, bento grids, big-number hero,
monospace numbers ca podoabă, warm earth palette, "modern AI dashboard"
generic. NU facem ca 90% din AI-uri.
Sub-app /achizitii are propriul layout scoped (`AchizitiiLayout`) cu vocabular
dens (`achizitii.css`) — paper/ink/stamp/state/signal redefinite peste paleta
de bază. NU modifica global.css sau tailwind.config.mjs din /achizitii.
Layouts:
- BaseLayout — pagini marketing (`/`, `/idei`, `/produse/*`, `/despre`)
- AchizitiiLayout — toate paginile sub `/achizitii/*` (wrapper peste BaseLayout
+ achizitii.css + sub-nav strip)
- /harta este aplicație separată cu propriul harta.css (Civic OS direction)
Reguli operaționale:
- Comit-uri mici, focusate. NU amend, doar commits noi.
- Verifică `npx astro check` și `npm run build` ÎNAINTE de commit.
- Push-ul trigger-ează webhook → deploy automat. Verifică /api/version după.
- Pentru DB queries: rulează `psql` pe satra prin `infisical run` (vezi
refresh-mvs.sh ca exemplu pentru pattern-ul corect cu Machine Identity).
- NU echo niciun secret în output. Niciodată.
- Repo branch principal: main. Stash branch: stash/hub-achizitii-prototype
(codul brutalist vechi, nu se mai folosește).
0b. Continuare FIRMS + EU funds + scrapers (sesiune NOUĂ după 2026-05-09)
Lipește în sesiune nouă pentru a continua de unde am rămas în 2026-05-09. Acesta înlocuiește §0a — citește 0b ca prompt principal pentru next session.
Continuă proiectul vreaudigital.ro — extindem firms registry + ingest noi
surse publice (fonduri EU, ANI, ANPC, license registries) cu join-uri
unice anti-corupție.
[CONTEXT — vezi PROMPTS.md §0 pentru stack, infra, conventions, design]
STATE LA 2026-05-09 (sha live: după commit-ul nou cu recipe euFundsAndSeap):
DATE LIVE ÎN PROD (DB):
firms.* — registry firme:
entities 3,985,967 = 3.97M ONRC + 12,737 stub authorities
inserted 2026-05-09 from seap.announcements (auth
cuis with no ONRC entry — pending ANAF v9 enrichment).
99.99% ANAF v9 enriched on private side
(phone 60.5%, vat_registered 12.4%, e-Factura 7.1%)
GIS: 100% geocoded (was 91.6%) post-2026-05-09 fix
- geonames_postal 2,128,990 (53.4%, 100m-2km)
- photon 839,643 (21.0%, ~50% housenumber)
- uat_centroid 670,657 (16.8%, 5-30km)
- judet_fallback 333,940 (8.4%, large radius)
- photon-nomatch 96
name_normalized GENERATED column (lowercase + unaccent
+ strip SC/SRL/SA prefixes/suffixes) cu btree+trgm gin
mv_eu_funds_per_cui 8,772 cuis with EU-funds beneficiary status (anunturi/
proiecte/buget/programs) for fast firma profile lookup.
financials 3.86M WEB_UU + 250K WEB_BL_BS_SL (5 ani, source-tagged)
financials_ong 286K NGO records (5 ani)
financials_banks 66 banks 2024 (URL pattern per-year fix needed)
reprezentanti_if 122,956 IF reps (56K firms)
sucursale_ue 235 EU branches (20 țări)
postal_codes 37,915 RO postal codes (GeoNames CC-BY 4.0)
fonduri.* — fonduri EU:
afir_plati 563,310 plăți FEADR 2024 (1.37 mld EUR)
70,088 matched cu CUI (12.4% / 22% of distinct names)
beneficiar_anunt 41,494 anunțuri achiziții privați-cu-fonduri-EU
32,778 matched cu CUI (79.0%) — Stage A 28,475
exact_norm + Stage B 161 trgm_unique +
Stage C 4,142 trgm_judet (judet disambig).
Restul 8,716 unmatched ≈ ONG-uri/ministere (nu sunt
în firms.entities = registry ONRC privat).
Source: beneficiar.fonduri-ue.ro:8080 (TLS self-signed)
beneficiar_anunt_lot 48,366 loturi cu buget total 44.5 mld RON (~9 mld EUR)
beneficiar_proiect 11,489 proiecte FULL scraped 2026-05-09.
30 programe distincte (PRC/PRSM/PRNE/PCIDIF/POIM/
PNRR/PRSVO/etc.), 100% program/axă, 98% data_contract,
time range 2010-2026.
Pagina expune 7 fields per proiect.
seap.* — preexisting (642K announcements + 9 MVs).
regas.* — Registrul Ajutoarelor de Stat (Consiliul Concurenței) — ingest 2026-05-09:
ajutoare 78,546 rows (de-duped; source raporta 132,363 dar
conține ~40% duplicate intra-page). 2016-01 → 2026-05,
23,805 firme distincte, 199 măsuri, 37 finanțatori,
122.8 mld RON cumulat (~24.5 mld EUR pe 10 ani).
6,502 firme apar în RegAS ȘI ca furnizor SEAP
(cross-source overlap, recipe regasAndSeap).
Câmpuri-cheie: cui, denumire_beneficiar, denumire_masura
(titlu act normativ), referinta_masura (SA.xxx/yyyy),
finantator (ministerul/agenția), instrument_acordare
(fonduri nerambursabile / garanții / scutiri / alocații
bugetare), ajutor_acordat_subcategorie (RON), data_acordare,
intensitate %.
MV: regas.mv_ajutoare_per_cui (per-firm rollup pentru
fast lookup în profile pages).
Source: https://regas.consiliulconcurentei.ro/transparenta/
API: POST /apitransparenta/cautareTransparenta cu
XSRF-TOKEN cookie+header (TLS chain not in node CA bundle
→ NODE_TLS_REJECT_UNAUTHORIZED=0 set la wrapper-level
numai pentru acest scraper).
Idempotent (sha1-key UPSERT). Wrapper:
cron/scrape-regas.sh (mirror enrich-anaf.sh pattern).
CRON LIVE (systemd timers pe satra):
vreaudigital-anaf-daily.timer 02:00 daily (tier=daily, conc=2)
vreaudigital-onrc-weekly.timer Tue 03:00 (auto-detect new monthly snapshot)
vreaudigital-mvs.timer 04:00 daily
scrape-regas.sh manual sau adăugat ca timer săptămânal
(~14 min/run, refresh MV la final)
CE E DEJA FĂCUT (pages/recipes/services live):
- /achizitii/firma/[cui] cu firms.entities + financials timeline + rep_legali
- /achizitii/autoritate/[cui] cu firms.entities (regii autonome, S.A. de stat)
- /achizitii/beneficiar-privat/[id] cu lots + project SMIS link + matched firma
- /achizitii/fonduri-ue cu DOUĂ secțiuni — A (Partea SEAP, EU contracts) +
B (Partea privată, beneficiar_anunt) — KPIs / top firme / top proiecte /
județe / programe + cross-source CTA la euFundsAndSeap
- 11+1+1 retete firme: top CA, 1-salariat, pierderi+contracte, firme-noi (SEAP),
EU+SEAP cross, firme-noi-cu-fonduri-eu-mari (instant EU winners),
beneficiari-eu-fara-seap (EU-only, no SEAP), AFIR+SEAP (352 firms),
TRIPLE pipe BEN+SEAP+AFIR (13 firms ULTRA-RARE 🔱), BEN+AFIR (134),
AFIR-only top absorbers (rural EU absorption), top județe absorbție
publică (toate cele 3 surse cumulate per județ),
+ RegAS+SEAP (2026-05-09, "firme cu ajutor de stat ȘI contracte SEAP")
- /achizitii/firma + /autoritate cu 🇪🇺 EU section + badge când CUI există
în beneficiar_anunt
- /achizitii/firma cu 🏛️ RegAS section + badge când CUI primește ajutoare
de stat (vezi ALRO SA — 469.8 mil RON din 2 ajutoare la EximBank +
Min. Energiei). getRegasStatus() din profile-queries.ts.
- /achizitii/cauta cu 🇪🇺 inline badge pe supplier names
- Photon JAR 0.5.0 ca daemon nativ pe satra (ES backend, port 2322)
- vreaudigital-photon.service systemd unit (vezi cron/install-photon.sh)
- CUI fuzzy matcher Stage A+B+C live (cron/match-cui-external.sh) pentru BEN;
AFIR doar Stage A (rest e individual farmers, RUN_TRGM=false)
KILLER JOIN deja live (recipe euFundsAndSeap):
2,020 firme apar simultan în fonduri.beneficiar_anunt (privat cu EU funds)
ȘI seap.announcements (furnizor la stat) — chain "EU money + SEAP"
(1,676 din exact_norm + 344 noi din trgm_judet Stage C, 2026-05-09).
Test: /achizitii/retete/firme-cu-fonduri-eu-si-seap
CE LIPSEȘTE — ordonat după impact (vezi STRATEGIC-PLAN.md pentru full):
0. ANAF datornici trimestrial — BLOCKED prin design.
Source https://www.anaf.ro/restante/ și /listaalba.xhtml folosesc PrimeFaces
JSF cu CAPTCHA (kaptcha.jpg) la submit. Nu există XLSX/CSV public echivalent
pe data.gov.ro / static.anaf.ro. Pentru ingest e nevoie de OCR pe
kaptcha.jpg sau serviciu CAPTCHA-solving (2captcha/anti-captcha) — out
of scope pentru ingest fără cost recurent. ALTERNATIVE evaluate:
(a) Încărca un volunteer-mode UI care să cere user să rezolve CAPTCHA
o dată per trimestru → un singur snapshot acoperă 5K-15K firme.
(b) Publicăm doar derived view (la firms.entities adăugăm coloana
anaf_inactive — există deja în datele scrape ANAF v9 — care e
proxy pentru "datornic notabil"). Unele firme sunt declarate inactive
fiscal pentru neplata datoriilor.
(c) Deferi până apare alt sursă (data.gov.ro periodic, sau acord
direct cu ANAF — n-am).
Pentru moment, NU includem datornici ANAF în scope.
0b. RegAS extras follow-ups (după ingest 2026-05-09):
- Recipe variations: "firme cu doar ajutor de stat fără SEAP"
(deductible legitime), "ajutor stat × afir × seap × beneficiar EU
QUADRA-pipe" (cele 4 mari surse), "ajutoare de stat acordate la
firme nou-înmatriculate <12L".
- /achizitii/ajutoare-de-stat landing page (top finanțatori, top
firme, top măsuri, breakdown per instrument).
- PDF download pentru fiecare măsură: regas.consiliulconcurentei.ro/
apitransparenta/downloadPdfMasura/{idMasura} → mirror local cu PDF
extraction pentru text full-search.
- cron timer săptămânal pentru ingest (sumele se actualizează lunar
în portal pe măsură ce raportările intră).
A. Match-uire ONG-uri — BLOCKED. firms.financials_ong are doar CUI + indicatori
financiari, FĂRĂ name column. Pentru match BEN.beneficiar_name → ONG cui
trebuie altă sursă cu nume: (a) ANAF v9 fetch by CUI pe cele 74,862 ONG-uri
cu financiare → ~2.5h, (b) Min. Justiției Registrul Național ONG (scraping
sau CKAN data.gov.ro), (c) ANR Registrul Asociații/Fundații. Defer until
we pick a source.
B. Photon retry-nomatch (270K firme cu photon-nomatch) — adresele extrem de
ambigue. Fallback: just county centroid. Or: try EEA E-PRTR-style
anchor-by-known-postal-code disambiguation.
C. Scraper /proiecte/details/{type}/{id} pe beneficiar.fonduri-ue.ro
(~30K proiecte) — completează fonduri.beneficiar_proiect cu sume,
programs (POIM/POR/PNRR), data start/end, contributie UE.
D. AFIR backfill: 2020-2023 + FEGA (separate XLSX URLs prin CKAN-discover).
E. Recipe-uri noi peste euFundsAndSeap (variations):
- "Firme nouă cu fonduri EU mari" (înmatriculate <24L + ben_anunturi)
- "Furnizori SEAP care au cumpărat tot prin proceduri restrictive"
(intersect cu single_bidder)
- "Cluster geografic EU funds vs SEAP — județe care primesc disproporționat"
F. /achizitii/fonduri-ue page — landing pentru noua sursă (top beneficiari,
top proiecte, breakdown per program/an/județ).
G. Tier 1 din STRATEGIC-PLAN (1-2 zile fiecare):
- INS Tempo via gov2-ro/tempo-ins-dump (per-UAT macro stats — POP107D,
SOM101F, FOM104D, LOC103B; concrete schemas + queries în plan)
- Recensământ 2021 XLSX per UAT
- ANI declarații T1 (640 oficiali parlament+government, 15 zile MVP) —
vezi STRATEGIC-PLAN §3 pentru schema completă ani.* + killer query
- ANPC sancțiuni WP REST API
- EEA E-PRTR + SEVESO + Natura2000 mirrors (CUI-linkable, "Polluter ↔
Public Money" killer story)
H. /harta cluster pin layer over choropleth — folosind firms.entities.geom
populat 91.6%. Layer cu MapLibre `cluster: true`. (Frontend work.)
I. Recipe firme-radiate-cu-contracte-recente — nu se poate fără mapping
pentru cele 4-digit ONRC stare codes (1084=activ?, 2069=?, etc.).
Necesită nomenclator ONRC stare separat. Defer.
REGULI OPERAȚIONALE (recap, NU le încălca):
- npx astro check + npm run build PASS înainte de commit
- Push declanșează deploy webhook automat → /api/version după 30s
- DACĂ ai scp-uit fișiere pe satra în această sesiune → reset git înainte
de push (deploy.sh face git pull --ff-only care eșuează la conflict)
Soluție: ssh satra "cd /opt/vreaudigital && git checkout -- <files> &&
rm -f <new untracked files>"
Apoi bash /opt/vreaudigital/deploy.sh manual (ca bulibasa NU sudo).
- NU echo niciun secret în output
- Pentru DB queries: PGPASSWORD env (NU psql "$URL" cu URL pe cmdline)
- Comit-uri mici, focusate
- Pentru tsx scripts pe satra: docker run node:22-alpine cu --env-file
(NU -e), pentru a nu leak DATABASE_URL via ps aux
- TLS gov.ro self-signed: NODE_TLS_REJECT_UNAUTHORIZED=0 în env-file
GOTCHAS / DECIZII LUATE (cumulative):
- siruta_source 'county_capital_fallback' marcă rândurile aproximate
- numar_salariati = BIGINT (nu INT) — staging avea 7.7e14 valori absurde
- ONRC date_inmatriculare format DD.MM.YYYY uneori cu timestamp suffix
- DISTINCT ON (cui) + ORDER BY data DESC pentru duplicate CUIs
- COPY CSV ONRC necesită QUOTE E'\b' (firmele au quote-uri embedded)
- ANAF script: NU folosi cursor pagination cu ORDER BY COUNT(...)
- public."GisUat".geom e SRID 3844 (RO STEREO70) — necesită ST_Transform
la 4326 înainte de cast la geography
- ANAF v9: HTTP 404 cu body parseabil = batch toate invalid; CUI length>10
e CNP (PFA), filtrate la query level
- Postal codes UPDATE pe 2M rows trebuie chunked (50K) cu deadlock-retry
în bash, NU PL/pgSQL DO block (single-tx, abort = pierdere totală)
- Photon address normalization: strip "Str./Sat/Com./Mun./Orş./PARTER",
build query din adr_strada+adr_numar+adr_localitate+adr_judet (NU adr_full)
- Photon 0.5.0 e ultima versiune ES; 0.6+ folosește OpenSearch (incompatibil
cu country extracts graphhopper)
- ANAP Inactivi/Lista Albă/Datornici sunt TOATE behind JSF captcha (nu
bulk-scrapeable fără OCR)
- ROLII mort, REJUST anonimizat, BPI paywalled, ONRC UBO paid+e-signature
- AFIR XLSX: openpyxl read_only iter_rows + pipe-delimited CSV (comma în nume)
- CUI matcher SQL: GROUP BY trebuie să includă MIN(e.cui) sau eroare PG silent
- beneficiar.fonduri-ue.ro:8080: server slow ~11s/req, max ~1 req/s
indiferent de concurrency — adăugare workers = marginal benefit
- Stage B trgm match (rezolvat 2026-05-09): pipeline = (1) materializează
unmatched în temp table cu DISTINCT pe norm (BEN 13K→2K, AFIR 493K→274K),
(2) SET pg_trgm.similarity_threshold = 0.7 (același psql session, păstrează
semantica gap≥0.10 din WHERE), (3) JOIN gin %, (4) UPDATE prin temp table
rowid. Rulare BEN: ~10 min Stage B + ~20 min Stage C judet (acceptabil
pentru cron 04:00). Stage C judet aduce mult mai mult decât Stage B
(4,142 vs 161) pentru că disambig pe județ permite acceptare la 0.7,
nu 0.85+gap. AFIR e SKIPPED via RUN_TRGM=false: unmatched-ul e majoritar
persoane fizice (popa gheorghe, fermieri PFA fără CUI 10-cifre) —
zero overlap cu firms.entities, 30+ ore de scan inutil.
FĂRĂ SECURITY DEBT REZIDUAL nou — toate fix-urile preventive sunt în place.
Rotirea parolei DB architools_user încă AMÂNATĂ de la 2026-05-07.
DELTAS post 2026-05-10 (overnight session: audit + 6 sub-agenți paraleli + Phase 1-4):
NEW SCHEMAS LIVE:
regas.ajutoare 78,546 records (Consiliul Concurenței, 2016-2026,
122.8 mld RON state aid, 23,805 firme distincte)
anaf.datornici 140,777 records (data.gov.ro Q1 2016 snapshot,
83 mld RON datorii). LIMITARE: live scrape
captcha-blocked (anaf.ro/restante JSF).
bugetar.entitate 18,822 entities discovered Faza 1 (42% CUI matched).
bugetar.executie schema ready, Faza 2 = CAPTCHA-blocked.
ani.{officials, declaratii, bunuri, shareholdings, functii, donatii}
Schema ready. 25 declarații Iohannis test ingerate.
Full ingest = 15 zile MVP (PDF parser + entity res).
aep.donatii_pj 3,567 donații legal entities
aep.donatii_pf 30,173 donații PF (CNPs SHA-256 hashed)
aep.donatii_rvc 346,237 granular donații + cotizații
aep.partide 64 partide
fonduri.afir_plati 2023 +474,720 (FEADR 2023 ingest, total 1.04M rows)
fonduri.beneficiar_proiect 11,489 proiecte EU (full scraped)
CROSS-SOURCE KILLER OVERLAPS LIVE:
RegAS ∩ SEAP 6,502 firme (recipe firme-cu-ajutor-de-stat-si-seap)
BEN_PRIVAT ∩ SEAP 2,057 firme (recipe firme-cu-fonduri-eu-si-seap)
ANAF datornici → SEAP post-debt 1,561 firme (recipe firme-datornice-cu-contracte-seap)
AEP donator → SEAP supplier (live, recipe donatori-care-au-castigat-seap)
AFIR ∩ SEAP 352 firme (recipe firme-cu-afir-si-seap)
BEN ∩ AFIR 134 firme (recipe firme-cu-fonduri-eu-si-afir)
TRIPLE pipe (BEN ∩ SEAP ∩ AFIR) 13 firme (recipe firme-triplu-pipe-public)
QUADRA pipe (+ RegAS) 10 firme (recipe firme-quadra-pipe-public)
39 RETETE TOTALE in 9 categorii (firme/red-flags/concentrare/directa/modificate/
temporal/reach/cpv/politicieni). Red flags = 4 retete cross-source post-2026-05-10.
PROFILE INTEGRATIONS (firma + autoritate):
- 🇪🇺 EU funds badge + section
- 🏛️ ajutor de stat badge + section (RegAS)
- 🗳️ donator partide badge + section (AEP)
- 🚨 datornic ANAF badge + red section (Legea 98/2016 art. 165)
IMEDIATE RECOMMENDED NEXT STEPS (post 2026-05-10):
1. SEAP historical backfill 2017+2018+2019+2022+2023+2024 (1-2 zile) —
CKAN datasets confirmate. Pipeline scaffolded (services/seap-scraper/scripts/
import-seap-historical.{py,sh}, 750 contracte 2024-Q1 deja imported as PoC).
Adds ~5M historical rows. BIGGEST data multiplier remaining.
2. AFIR FEGA 2023+2024 (60 min) — schema augment cu tip_fond. ~5M rânduri.
3. Bugetar Faza 1.1 (2h) — fuzzy match bugetar.entitate × firms.entities
(now includes 12,737 stub auth cuis from yesterday) → expected 42% → ~80%.
4. ANI parser implementation (15 zile MVP) — pdftotext + section regex +
tesseract-ron fallback. Unlocks politicieni × firme cross-join.
5. num_offers WSP backfill — needs WSP CANotice scraper run + sync_state
fix. Unlocks single-bidder corruption analysis.
6. Bugetar Faza 2 — 2captcha integration ($300 top-1000 entities × 60 months).
7. ANAF live captcha scrape — needs paid captcha solver.
8. Curtea de Conturi audit reports (15-25h) — PDF parsing per institution.
9. Update /achizitii/cauta cu 🚨 datornic + 🏛️ ajutor + 🗳️ donator badges
inline (paritate cu 🇪🇺 EU badge existing).
10. New landing page /achizitii/red-flags collecting all 4 red-flag recipes
+ real-time KPI strip ("X firms currently flagged across N criteria").
Pentru research roadmap exhaustiv: services/seap-scraper/STRATEGIC-PLAN.md
Pentru gotchas detaliate: memory project_scraper_gotchas.md
0c. State CURENT după megasprint 2026-05-09/10 (40 commits) + Phase 5 UI merge 2026-05-11
Acesta înlocuiește §0b. Lipește în sesiune nouă pentru context complet. Toate datele din §0b sunt încă valide PLUS adăugările Phase 5.
POST-MERGE 2026-05-11 (sha live
57af3a6): Phase 5 UI integration COMPLET. 7 badges noi + 5 sections noi pe firma profile, 6 retete noi (total 45 pe /achizitii/retete). Reports cross-source paralelle închatGPT/data-quality/șichatGPT/journalism/— vezi §0c "POST-MERGE FINDINGS" mai jos.
Continuă proiectul vreaudigital.ro după megasprintul de 40 commits din
2026-05-09/10. Sesiunea anterioară a adăugat 14 scheme noi cross-source
via CUI key. Phase 5 UI integration shipped 2026-05-11 (sha 57af3a6).
[CONTEXT — vezi PROMPTS.md §0 pentru stack, infra, conventions, design]
DATE LIVE ÎN PROD (DB) — toate joinable via firms.entities.cui:
firms.entities 3,985,967 (3.97M ONRC + 12,737 stub auth cuis).
100% geocoded (judet_fallback ultim tier).
99.99% ANAF v9 enriched on private side.
firms.financials 4.25M records 2020-2024
firms.mv_eu_funds_per_cui 8,772 cuis cu EU-funds status
seap.* 781,029 announcements:
- 643K original (datagov Q1 2025 + WSP 12mo)
- +137,398 historical 2017-2023 (30 sources)
- 378 bln RON awarded across 8 ani
- 100% pub_date (TED backfill done — hybrid B+C estimate, see
TED-DATE-BACKFILL-NOTES.md for root cause + Stage 2 fix)
- 30 source tags (datagov_YYYY_TX_{type})
fonduri.afir_plati 5,329,006 plăți (vs 563K initial):
- FEADR 2023: 474,720 (1.41 mld RON UE)
- FEADR 2024: 563,310 (1.37 mld RON UE)
- FEGA 2023: 2,476,897 (1.99 mld RON UE)
- FEGA 2024: 1,814,079 (1.92 mld RON UE)
- TOTAL: 6.70 mld RON UE (vs 2.79 mld before)
- tip_fond discriminator: 'FEADR' | 'FEGA'
- 2020-2022 BLOCKED (Law 544/2001 FOIA needed — comunicare@afir.info)
fonduri.beneficiar_anunt 41,494 anunțuri EU privați
fonduri.beneficiar_anunt_lot 48,392 loturi
fonduri.beneficiar_proiect 11,489 proiecte full (30 programe EU)
regas.ajutoare 78,546 ajutoare de stat 2016-2026
122.8 mld RON · 23,805 firme · 199 măsuri
Cross: 6,502 firme RegAS ∩ SEAP
Wrapper: cron/scrape-regas.sh (~14 min)
anaf.datornici 140,777 firme Q1 2016 (83 mld RON debt)
Live ANAF scrape captcha-blocked.
1,561 firme datornice → SEAP post-debt (5.83 mld RON)
aep.donatii_pj 3,567 PJ legal-entity donations
aep.donatii_pf 30,173 PF (CNP SHA-256 hashed — GDPR safe)
aep.donatii_rvc 346,237 granular all-donations
aep.partide 64 partide
TOTAL AEP: 379,977. Source: banipartide.ro (Expert Forum, AEP PDF
reCAPTCHA-protected — pivot la EFOR). Wrapper: cron/scrape-aep-donatii.sh.
bugetar.entitate 18,822 instituții publice MFP
58.3% matched (Stage A+B trgm pe firms.entities)
Faza 2 = CAPTCHA-blocked (~$300 2captcha integration)
bugetar.executie schema gata, awaiting Faza 2
ani.* schema ready, 25 declarații test (Iohannis sample).
6 tabele: officials, declaratii, bunuri, shareholdings, functii, donatii.
Full ingest = 15-day MVP cu PDF parser + entity resolution.
Pagini: old-declaratii.integritate.eu = PRIMARY (no auth, no captcha,
JSF POST + date-range slicing). New e-DAI 2022+ = Cloudflare Turnstile,
needs Playwright.
anre.licente 29,536 licențe energie (electricitate+gaze+atestate)
92.3% CUI matched (Stage A+B+C)
electricieni Kendo OFFSET>9000 server bug — defer
ancom.operatori 518 telco operators, 100% CUI direct
ancom.drepturi 2,536 R/S rights per operator
cnsc.decizii 29,488 contestații SEAP 2016-prezent
95% contestator_cui + 42% authority_cui
6,845 contestatori unici · 3,249 autorități unice
Stage 2 = PDF parse (15-25h next session)
cnas.furnizori 36,183 furnizori medicali / 12,392 unici
46/61 PDFs parsed. Phase 4 = CUI matching.
Source: cnas.ro WP REST (CNAS migration mid-flight).
asf.entitati 849 entități financiare (asigurători + brokeri)
100% CUI direct · 437 (51%) în firms.entities
69 firme × 3,530 contracte SEAP = €614M.
KEY TRICK: omit g-recaptcha-response field for
captcha-bypass on data.asfromania.ro.
aaas.firme 11 active state holdings (100% CUI matched)
AAAS publishes deliberately narrow (post-priv
+ creanțe = "section under construction").
Backfill from PDF (ORDIN 278/2005) = next session.
curteacont.rapoarte 1,133 audit reports Stage 1 sample (universe ~4,605)
Full backfill: ~6 min. Stage 2 PDF parse: ~10h.
apia.fermieri 191 (data.gov.ro publishes only 1 comuna Găgești)
National 500K dataset DOES NOT EXIST on CKAN.
Pipeline future-proof, auto-discovers new datasets.
gnm.comunicate 348 GNM press releases
gnm.amenzi_extrase 1 named firm (Retim, regex extracted)
Per-firm CUI publication = secret de serviciu OUG
195/2005. Legea 544 FOIA needed for full registry.
CROSS-SOURCE KILLER JOINS LIVE (via CUI):
RegAS ∩ SEAP 6,502 firme · €122.8 mld state aid
AEP donator → SEAP supplier live · 11+ donatori în 99-sample
ASF licensed × SEAP 69 firme × 3,530 contracts · €614M
BEN_PRIVAT ∩ SEAP (EU funds × stat) 2,057 firme
ANRE energy × SEAP 3,055 CUIs cross-source
ANAF datornici → SEAP post-debt 1,561 firme · 5.83 mld RON
AFIR ∩ SEAP 352 firme
BEN ∩ AFIR (EU + agri) 134 firme
TRIPLE pipe (BEN ∩ SEAP ∩ AFIR) 13 firme · ULTRA-rare
QUADRA pipe (+ RegAS) 10 firme · ULTRA-RARE
AAAS state-owned × SEAP 11 firme · 100% (full state portfolio)
45 RETETE TOTALE pe /achizitii/retete în 9 categorii (39 + 6 noi Phase 5):
- 7 RED FLAGS (4 originale + energie-fara-licenta · telco-fara-licenta ·
stat-actionar-seap · autoritati-audited-repetitiv)
- 8 firme (top CA, 1-salariat, pierderi, firme-noi, EU+SEAP variants, etc.)
- + asiguratori-furnizori-stat (financial sector, 'firme' category)
- + autoritati-contestate-cnsc (CNSC concentration, 'firme' category)
- rest pe categorii originale
UI INTEGRATIONS LIVE (post 2026-05-11):
/achizitii/firma/[cui] 11 badges:
🇪🇺 EU · 🏛️ ajutor RegAS · 🗳️ donator AEP ·
🚨 datornic ANAF · 🔌 ANRE · 📡 ANCOM ·
⚖️ CNSC×2 · 💰 ASF · 🏛️ stat acționar AAAS ·
📋 audited Curtea Conturi
9 sections detail (existing 4 + 🔌 ANRE energy ·
⚖️ CNSC contestații (dual: as authority/contestator) ·
🏛️ AAAS state shareholder · 📋 Curtea de Conturi ·
💰 ASF financial register)
Helpers split în 2 fișiere noi:
src/lib/profile-queries-utilities.ts (ANRE/ANCOM/CNSC)
src/lib/profile-queries-financial.ts (ASF/AAAS/Curtea)
/achizitii/autoritate/[cui] paritate cu firma (EU section)
/achizitii/beneficiar-privat/[id] enrichment cu program/axa/domeniu/operatiune
/achizitii/proiect/[id] NEW dedicated page (KPI strip + program/axa/etc)
/achizitii/fonduri-ue dual-section: A SEAP-EU + B beneficiar privat
/achizitii/red-flags NEW landing (KPI strip + 6 recipe cards live preview)
/achizitii/cauta supplier rows cu 4 inline badges
TEST URL post-merge: /achizitii/firma/13267213 (HIDROELECTRICA)
arată 4 ANRE active + 59 contestații CNSC + 214M datornic ANAF live.
CRON LIVE (systemd timers pe satra):
vreaudigital-anaf-daily.timer 02:00 daily (tier=daily, conc=2)
vreaudigital-onrc-weekly.timer Tue 03:00
vreaudigital-mvs.timer 04:00 daily
Plus manual wrappers shipped: scrape-{regas,aep-donatii,anaf-datornici,
bugetar,ani-declarations,anre,scrape-anre,ancom,cnsc,cnas,asf,aaas,
curteacont,apia,gnm}.sh — all Infisical MI + docker run --env-file pattern.
IMEDIATE RECOMMENDED NEXT STEPS (updated 2026-05-11):
1. ✅ DONE 2026-05-11 (sha 57af3a6): Recipe + UI integration la Phase 5.
- getAnreStatus / getAncomStatus / getCnscStatus în
src/lib/profile-queries-utilities.ts
- getAsfStatus / getAaasStatus / getCurteaContStatus în
src/lib/profile-queries-financial.ts
- 7 badges noi + 5 sections noi pe /achizitii/firma/[cui]
- 6 retete noi: energie-fara-licenta · telco-fara-licenta ·
autoritati-contestate-cnsc · asiguratori-furnizori-stat ·
stat-actionar-seap · autoritati-audited-repetitiv
2. Stage 2 PDF parses (multi-day fiecare):
- CNSC Stage 2: PDF parse pentru decision_type (admis/respins) +
seap_procedure_ref → killer recipe "autorități cu rată mare contestații
pierdute" (~15-25h)
- Curtea de Conturi Stage 2: 4.6K PDFs → audited_entity_cui + findings_count
(~10h)
- CNAS Phase 2: 14 PDFs cu layout dificil + CUI matching (~2-3h)
- ANI parser: 1.3M PDFs (15-day MVP)
3. Sub-agent rate-limit recovery — re-launch AFIR FEGA agent (was rate-limited)
pentru a documenta unrar + RAR pattern în plan dedicat.
4. ANAF datornici live scrape via 2captcha (~$1-3 per 1K captchas):
- 5-15K rânduri × 20 trimestre = 5K-300K rânduri total
- Implementare în scrape-anaf-datornici.ts::scrapeAnafLive() — stub în place
- Cost mic, deblochează refresh quarterly (current snapshot e Q1 2016)
5. Bugetar Faza 2 (CAPTCHA, ~$300 2captcha pentru top-1000 entities × 60 luni):
- 800K rapoarte FXB-EXB-900 XML
- Cross-source killer: "Primării cu cea mai mare concentrare buget pe
1 furnizor SEAP"
6. /achizitii/red-flags v2:
- Adaugă ANRE energy violators, ANCOM telco-fără-licență, ASF brokeri
radiați-cu-contracte cards
- Top-N rolling counters: "X firme flagged azi vs ieri"
- RSS feed pentru jurnaliști
7. Backfilluri agricole + de cohort (data ghost):
- APIA Lista Fermierilor: re-run lunar (auto-discover via CKAN)
- AAAS PDF parser: ORDIN 278/2005 ANEXA (~500-700 historical CUIs)
8. Re-imports & data quality:
- import_ted.py: add 'publication-date' to FIELDS list (1-line fix)
→ re-import 12,787 TED rows cu authoritative dates (replaces estimates)
- SEAP Achiziții Directe (cumpărări directe, ~8M rânduri 2017-2024)
— pipeline ready, doar launch ingestor cu type='da'
- SEAP 2020+2021 gap → supplement din TED bulk XML (EU-threshold only)
POST-MERGE FINDINGS (2026-05-11 sub-agent investigations):
G3 (chatGPT/data-quality/freshness-audit-2026-05-10.md, 21KB):
Total rows reconciled: 17,907,148 (vs ~6.94M previously cited).
Top quick wins (≤2h):
• TED publication-date: 1-line fix import_ted.py:22-38 FIELDS list
• SEAP DA sync_state stuck "running" since 2025-10-16 — reset
• CUI matcher rerun for cnas.furnizori (36,183 rows, 0% matched)
• CUI matcher rerun for apia.fermieri
Priority gaps (multi-day): SEAP DA 2017-2024 backfill (~8M rows),
ANAF datornici frozen Q1 2016 (10y stale, needs 2captcha),
bugetar.executie 0 rows despite 18,822 entities (broken pipeline).
Health: 6 healthy / 6 sub-2-day stale / 5 structural issues.
G4 (chatGPT/journalism/killer-findings-2026-05-10.md, 23KB):
Top 5 lead findings (real CUIs, real money, real storylines):
1. HIDROELECTRICA (CUI 13267213) — 214M ANAF debt + 562M SEAP
from 39 buyers. State-on-state circular at industrial scale.
2. AVIOANE CRAIOVA (CUI 2326144) — 98.6M debt + 105M SEAP. ~1:1.
3. SSAB-AG (CUI 2816022) — Only firm hitting all 4 state pipes
(PDL donor + EU + SEAP + RegAS) + ANAF debt.
4. METAMINDS (CUI 34770594) — 1.22B SEAP, 835M single contract
from STS in Feb 2026, single-bidder, on debt list.
5. CONCELEX (CUI 6544184) — Largest SEAP supplier 4.22 mld RON
+ 111.6M RegAS state aid.
+ 7 additional storylines (UTILNAVOREP, ASIROM concentration, CNAIR
368 contestations on 73.6B procurement, etc.)
G5 (chatGPT/journalism/sectorial-deep-dive-2026-05-10.md, 28KB):
ENERGIE (17.4 mld RON, HHI=814): 1.35 mld RON contracte la 67 furnizori
activi pe CPV 09310/09123/6531 fără licență ANRE — many are retail
brands operating under parent-company license (PPC Energie Muntenia
24387371 vs parent 22000460). SEAP nu validează cross CUI titularul.
TELECOM (7.4 mld RON, HHI=661): 94% concentrare București. METAMINDS
contract STS de 835M = 4.6× cifra anuală (46 angajați, 180M cifră
2024). Operatorii clasici (Orange, Vodafone) NU sunt în top 5 —
domeniul dominat de integratori IT/TIC nereglementați ANCOM.
FINANCIAR (2.2 mld RON, HHI=1029): cea mai concentrată (top 3 = 51%,
top 10 = 78%). Caz: FAST BROKERS (CUI 14785760) — autorizație ASF
retrasă 30.04.2024 prin sancțiune (MO 403/2024), 81.8M acumulați
în 125 contracte SEAP înainte de radiere, schimbat CAEN broker →
imobiliare pentru a continua operarea.
Cross-sector red-flags: (1) concentrare București disproportionată
(53/94/93%), (2) ASF stochează CUI cu sufix `/data_inmatriculare`
care strică JOIN-uri (90% din "decalaj raw" = artefact de date),
(3) reglementarea sectorială absentă din proces SEAP (nu cere CUI
titularului licenței la atribuire).
REGULI OPERAȚIONALE (recap):
- npx astro check + npm run build PASS înainte de commit
- Push declanșează deploy webhook automat → /api/version după ~30s
- DACĂ scp pe satra → reset git înainte de push (deploy.sh git pull --ff-only)
Solution documented: ssh satra "rm -f <untracked files>" pre-push
- NU echo niciun secret. Always $VAR unexpanded, --env-file (NU -e)
- PGPASSWORD env (NU URL cmdline). DB queries via ssh satra /tmp/baseline.sh
- TLS gov.ro self-signed: NODE_TLS_REJECT_UNAUTHORIZED=0 IN env-file
(per-scraper, never globally)
- Comit-uri mici. NU amend.
- Pre-create /var/log/vreaudigital-*.log files cu chown bulibasa BEFORE
prima rulare a noului scraper (tee -a fails on Permission denied otherwise)
- Schemas: 14 schemas in DB now: firms, seap, fonduri (+ regas, anaf, aep, ani,
bugetar, anre, ancom, cnsc, cnas, asf, aaas, curteacont, apia, gnm)
- SQL slot allocation register: see PROMPTS.md §0c (017-037 used)
GOTCHAS cumulative (top 10 hot):
- Stage B trgm pe 2K-5K norms × 4M entities = 10-30 min. Pattern: dedupe pe
norm + temp table + SET pg_trgm.similarity_threshold = 0.7 IN aceeași
psql session (heredoc <<SQL).
- ASF reCAPTCHA bypass: omit g-recaptcha-response in POST body (only server-
side check fires when field present).
- Regas pagination: explicit sort `[{field,direction,priority}]` array else
rows shuffle and only ~38% coverage.
- CNSC pagination is session-stateful: GET /decizii.html?page=N before each
POST on same session.
- AFIR FEGA = RAR archive (need unrar on satra). FEADR XLSX vs FEGA CSV format
but identical 15-column schema.
- ANAF v9: 100 cui/req, 1.1s sleep, length filter 1-10 (CNP=13 errors).
- AEP date parser tolerant: month>12 swap (banipartide.ro has bad dates).
- CKAN datasets: search via /api/3/action/package_search?q=X — confirm
exact slug before download (e.g. 2019 typo "achiziti-publice-2019").
- judet normalization: translate('ţșțŢȘȚşŞ', 'TSTTSTSS') + upper for cross-
match between firms.adr_judet (UPPER+old cedilla) and gis_uats.county
(TitleCase+modern).
- Build size warning HartaApp 1MB gzip 294KB — pre-existing, NOT a regression.
NEXT-SESSION QUICK PROMPT (copy-paste — vezi §0d post-2026-05-11):
vezi §0d "Continuare după 17-tick autonomous run 2026-05-11"
0e. State CURENT după sesiunea investigation + perf 2026-05-12 (sha a7567d1)
Supersede §0d. 9 commits adăugate post-§0d. Pentru cronologie session vezi
~/.claude/projects/.../memory/project_session_2026_05_12.md.
DELTA majore vs §0d
Investigation lead pages — NEW: /achizitii/investigation/[slug] cu 10 leads:
- metaminds (CUI 34770594) — 1,21 mld RON STS dependency
- hidroelectrica (13267213) — 214M ANAF + 19 ANRE licențe (state-to-state)
- bb-business (21820372) — 10K donat vs 281,8M datorie (1:28.184)
- avioane-craiova (2326144) — 98,6M debt + aging warhorse
- ssab-ag (2816022) — quadrupla state-money pipes (AEP+RegAS+EU+ANAF)
- municipiul-constanta (4785631) — 90 CNSC + 3 CdC = 93 dual signals
- sheriff-guard (14793194) — 62 contestații vs 27K donatie (vexatious extreme)
- romgaz (14056826) — 35 ANRE + 18,9M debt + 52 CNSC ca autoritate
- autoprima-serv (11394440) — 1,21 mld RON + 37 contestații + 100K PNL
- victor-construct (4013062) — 670K donat (top recipe) + 23 contestații + CNI/ANL
Plus: /achizitii/investigation index page · Investigații în subnav AchizitiiLayout · tier-0 cards pe /red-flags.
Perf — /red-flags 17s → 207ms (~80×):
public_kpi.red_flags_previewssnapshot table (14 slugs × top-5 = 66 rows precomputed)public_kpi.refresh_red_flags_previews()plpgsql fn, called dinrefresh-mvs.shdaily 04:00- SLOW_PREVIEW_SKIP eliminat — TRIPLE/QUADRA pipe acum au preview real
- SQL:
services/seap-scraper/sql/044_red_flags_previews_snapshot.sql
CPV autocomplete pe /cauta:
/api/cpv/search?q=...— typeahead pesteseap.cpv_codes(9454 rows, levels 1-4)src/components/cauta/CpvAutocomplete.tsx— react componentsrc/lib/search-queries.ts— prefix-match pentru codes deeper than level-1- Unaccent-aware (după fix
219036e) — "constructii" găsește "construcţii"
Hover-to-highlight pe /cauta map:
.search-row[data-result-id]mouseenter →CustomEvent('cauta:hover')SearchMap.tsxsubscribe-uie la window event, update hover state intern- Hover paint: radius 5→11, stroke 1.5→2.5, dark stroke color
Cauta perf — fully unblocked, all paths:
?q=spital(free text): 4.6s → ~700ms (q-shape branching in sql/046's commit)/cautano-filter home: 1.9s → ~230ms (sql/046 default facets snapshot)?sort=value_desc: 3.5s → ~500ms (sql/047 + isDefaultBrowse allows any sort)- Index migrations: sql/045 (pub_date DESC NULLS LAST), sql/047 (awarded_value DESC NULLS LAST)
- Snapshot tables:
public_kpi.cauta_default_facets,public_kpi.cauta_default_totals(refreshed nightly via refresh-mvs.sh)
Commits (13 post-§0d)
a0c11ec cauta: awarded_value DESC index + isDefaultBrowse allows any sort
937350f cauta: snapshot default-browse facets+totals (1.9s → ~230ms)
5a41172 seap: composite index (pub_date DESC NULLS LAST, id DESC) for /cauta home
5213865 PROMPTS.md §0e: update with 10 leads + cauta perf fix
a7567d1 cauta: branch q matcher by shape (4.6s → ~700ms)
4810d9a investigation: add ROMGAZ + AUTOPRIMA SERV + VICTOR CONSTRUCT leads
7fac7d9 PROMPTS.md §0e: state after 7 investigation pages + perf snapshot + CPV
219036e cpv: unaccent-aware label search (Romanian diacritics tolerant)
322913f cauta: hover-to-highlight markers from result rows
6d14d73 investigation: add 2 authority/contestator leads
f2f9c02 cauta: CPV autocomplete (typeahead) over seap.cpv_codes nomenclature
939bfb1 investigation: 5 narrative lead pages on cross-source data
688ac07 red-flags: read previews from snapshot table instead of live recipe fetches
fabca9f red-flags: materialize TOP-5 previews per recipe to snapshot table
Next-session candidates (prioritized)
[A++] More investigation leads — există signal pentru 3-5 more easy wins:
- ROMGAZ (CUI 14056826) — 18,8M datorie + 31 ANRE licențe
- ELECTRICA (CUI ?) — 41M datorie + 1 ANRE
- VICTOR CONSTRUCT (în donator-contestator recipe top, 670K + 23 contestații)
- AUTOPRIMA SERV (100K + 37 contestații)
- IRIDEX GROUP (496K + 10)
[B] Stage 2 PDF parses (multi-day):
- CNSC decision_type (15-25h): unlocks "vexatious vs legitimate" pe SHERIFF GUARD
- Curtea Conturi findings_count (10h): cifre concrete pentru audituri
- CNAS Layout-B (3-5h)
- ANI parser MVP (15 zile)
[C] Data acquisition cu 2captcha:
- ANAF datornici live ($15-25/an, $60-100 backfill — 10 ani stale!)
- Bugetar Faza 2 (~$300) — unlocks executii per CUI
[D] Data quality finishers:
- TED full re-import (fix shipped, doar trigger re-import)
- normalize_company_name v2 (â↔î↔i) — +400-1500 matches
- ANRE 92.3% residue commercial firms
[E] UI/perf still open:
- /api/og generation cached (currently re-render per request)
- CPV autocomplete fuzzy/typo tolerance (currently exact ILIKE on unaccent)
- /cauta 4.6s — FIXED in a7567d1 (q-shape branching)
0d. State după autonomous run 2026-05-11 (17 ticks + Phase 5 merge)
Supersede §0c. 20 commits adăugate post-Phase-5 (sha live
0b5b5ba). Pentru cronologie completă vezichatGPT/session-summary-2026-05-11.md. Pentru memory persistat vezi~/.claude/projects/.../memory/project_session_2026_05_11.md.
DELTA-uri majore față de §0c
Data quality:
- Geocoding firms.entities: 91.3% → 100% (toate 3.99M firme au lat/lng acum)
- ASF CUI clean: 51% → 100% (
/data_inmatricularestripped at scraper + DB) - CNSC authority_cuis: 42% → 77.5% (+10,328 via strip-parens UAT-pattern, SQL 042)
- Curteacont audited_entity_cui: 0% → 64.4% (+730, SQL 040+041)
- Bugetar.entitate: 58.3% → 63.4% (+961, SQL 039)
- CNAS.furnizori: 0% → 9% (Stage A exact_norm; data dirty, restul deferred)
- ANRE.electricieni: 0 → 73,164 rows (per-judet drilldown bypass Kendo OFFSET bug)
Recipes (49 total, +10 noi):
donatori-politici-care-datoreaza-statului(360 firme, B&B BUSINESS 10K vs 281M)donatori-politici-care-contesta-la-cnsc(185, SHERIFF GUARD 62 contestații)energie-licentiati-anre-datornici-anaf(875, 3.14 mld RON, HIDROELECTRICA 214M)autoritati-dubla-alerta-cdc-cnsc(50, MUNICIPIUL CONSTANTA 93 semnale)autoritati-contestate-cnsc·autoritati-audited-repetitiv(refactored direct-CUI)asiguratori-furnizori-stat·stat-actionar-seap·energie-fara-licenta·telco-fara-licenta
Infra (17 systemd timers acum, era 4):
- Daily 02:00 anaf-daily · 02:30 da (NEW) · 04:00 mvs · 07:00 heartbeat (NEW)
- Weekly Sun-Sat 01:00 (staggered): anre, ancom, asf, aaas, curteacont, gnm, cnsc
- Monthly 1st 03:00/03:30/05:00: regas, aep-donatii, cnas
- Monthly 15th 03:00: apia-fermieri
- Tue 03:00 onrc-weekly (existing)
services/seap-scraper/cron/heartbeat.sh— probe 20 surse, webhook n8n când STALEservices/seap-scraper/cron/scrape-da.sh— wrapper SEAP DA (era missing!)public_kpi.red_flags_countstable (12s INTERSECT → 1ms read)- 156 GB disc liber pe satra (89% → 45% via
docker builder/image prune)
UI:
- /achizitii/cauta: rewrite cu MapLibre map (red supplier · blue authority markers)
- /achizitii/fonduri-ue/anunturi: NEW browse hub (41,494 anunțuri EU funds)
- /achizitii/red-flags: 6 → 13 cards + 3 KPI tiles + perf 60s→17s
- /achizitii/firma + /achizitii/autoritate: parity completă cross-source (badges + sections)
CRITICAL gotchas adăugate (vezi project_session_2026_05_11.md complete):
- Deploy.sh fails pe untracked files pe satra — pre-push verifică
ssh satra "cd /opt/vreaudigital && git status --short | grep '^??'" - Sub-agent file split pattern (separate helper files = no merge conflicts on parallel codegen)
- Memory sync cron clobbers ~/.claude/.../memory/*.md every 60s — write DIRECT la ~/Code/claude-memory/projects//memory/ + commit acolo
- Geocoding silent bug (label set, lat/lng not written) — validate cross-check
- ASF CUI suffix corruption la sursă — fix at ingest
- cnas.furnizori.name zgomotos — pre-cleanup ÎNAINTE de fuzzy
- cnas/apia name_norm columns NULL — fix at insert
- Kendo OFFSET >20K bug — per-judet drilldown workaround
- WSP cron silent failure (tz-aware crash) — heartbeat catches now
- Backups run from root's crontab (not bulibasa's) — check both
- systemd OnCalendar needs SPACE after day-of-week (
Sun *-*-*notSun*-*-*) - ONRC parenthetical suffix pattern — strip
(Primaria X)before normalize → exact match - Romanian orthography
â↔î↔i—normalize_company_namedoesn't unify (Cârlogani vs Cirlogani) - "Code complete ≠ data flowing" — pipeline ready but no timer = 3x in this session
Promise.race(setTimeout)doesn't cancel pg queries — pool stays busy
NEXT-SESSION QUICK PROMPT (copy-paste pentru sesiune nouă post /clear):
Continuă vreaudigital.ro după autonomous run 2026-05-11 (17 ticks, sha live `0b5b5ba`).
CITEȘTE ÎNTÂI:
1. `chatGPT/session-summary-2026-05-11.md` — retrospectivă completă 17 ticks
2. PROMPTS.md §0d (acest fișier) — state delta cumulativ
3. memory: `project_session_2026_05_11.md` — gotchas + per-tick decisions
STATE CURENT:
- 49 retete pe /achizitii/retete (cele mai noi 10 sunt cross-source surprise findings)
- /achizitii/red-flags = surface principal cu 13 cards organizate în 4 tier-uri
- Geocoding 100% · CNSC CUI 77.5% · Curteacont CUI 64.4% · Bugetar 63.4%
- 17 systemd timers active pe satra (heartbeat zilnic 07:00 prinde anomalii)
- SEAP DA timer fire-uri zilnic 02:30 (catch-up 7 luni stale începe automat tomorrow)
- Sha live `0b5b5ba` · 20 commits post-Phase 5 merge
PRIORITĂȚI NEXT (ordonate după impact/effort):
[A] Lead-driven journalism pages — pagini dedicate per top-5 G4 findings:
- HIDROELECTRICA (CUI 13267213) · AVIOANE CRAIOVA (2326144) · SSAB-AG (2816022)
- METAMINDS (34770594) · CONCELEX (6544184) · B&B BUSINESS (din donatori-datornici)
- /investigation/[slug] cu narrative + tabel cross-source agregat per CUI
- ~3-5h per pagină. Highest user value, low risk.
[B] Stage 2 PDF parses (multi-day fiecare):
- **CNSC decision_type** (15-25h): pdftotext + regex pentru admis/respins/...
→ unlocks killer recipe "autorități cu rată mare contestații pierdute"
→ 730 CUIs deja matched în decizii, doar tipul lipsește
- **Curtea Conturi findings_count** (10h): pdftotext + extract "constatări" + amounts
→ recipe "audituri cu cele mai mari valori prejudiciu"
- **CNAS Layout-B** (3-5h): 9 PDFs rămași în format judet-grouped fără nr_crt
- **ANI parser MVP** (15 zile): 1.3M PDFs declarații avere
[C] Data acquisition cu CAPTCHA (cost mic):
- ANAF datornici live 2captcha (~$15-25/an incremental, $60-100 backfill complet)
→ snapshot curent Q1 2016 = **10 ani stale**!
- Bugetar Faza 2 (~$300 pentru top-1000 entități × 60 luni)
→ unlocks executii bugetare per CUI, recipe "primării cu 1 furnizor dominant"
[D] Re-imports & data quality finishers:
- TED full re-import (fix shipped tick #1, fixul 1-line e committed)
→ backfill 12,787 rânduri cu authoritative publication_date
- normalize_company_name v2 (orthography â↔î↔i unification)
→ +400-1500 matches în residue bugetar/curteacont
- ANRE 92.3% residue commercial firms (need fuzzy + locality + suffix strip)
[E] UI polish & perf:
- /achizitii/red-flags încă 17s — materializează top-5 preview per recipe în nightly cron
- Hover-to-highlight pe SEAP cauta map (A4 a notat dar n-a wired client-side JS)
- CPV autocomplete pe cauta (vs current top-15 facets)
- Map clustering threshold pe fonduri-ue/anunturi când >50 markers
REGULI OPERAȚIONALE (recap §0c + adăugări):
- npx astro check + npm run build PASS înainte de commit
- Push deploys ~30s; primul redeploy s-a întâmplat sub `bash deploy.sh` manual
- DACĂ scp pe satra → reset/clean ÎNAINTE de push (deploy.sh git pull --ff-only fails)
- Pre-create /var/log/vreaudigital-*.log cu chown bulibasa pentru noi scrapere
- NU echo niciun secret. $VAR unexpanded, --env-file (NU -e)
- Pentru DB queries: `/tmp/govq.sh` reads SQL stdin → architools_db pe satra
- Pentru memory persistat în repo: write DIRECT la `~/Code/claude-memory/projects/gov-agreg/memory/` + git commit + push
- 17 systemd timers active — verifică cu `ssh satra "sudo systemctl list-timers --all | grep vreau"`
- Pentru sub-agenți paraleli: split fișiere dedicate per group (ex profile-queries-utilities.ts vs financial.ts) ca să eviți merge conflicts
Începe cu [A] sau [E] pentru wins vizibile rapide. [B] dacă vrei impact mare cu effort mare.
0a. Continuare proiect FIRMS (3.97M companii RO + financials)
Lipește în sesiune nouă pentru a continua dezvoltarea pe registry firme RO.
Continuă proiectul firms.* — registry complet companii RO + date financiare.
[CONTEXT — vezi PROMPTS.md §0 pentru stack, infra, conventions, design]
STATE LA 2026-05-08 (sha live: c5cb223, sesiune third-pass overnight):
DATE LIVE ÎN PROD (DB schema `firms`):
- firms.entities: 3,973,230 firme RO (ONRC bulk firme-03-04-2026, CC-BY 4.0)
- 1.74M cu siruta UAT (44%), 2.6M cu administratori (rep_legali JSONB),
2.7M cu CAEN autorizate
- 2.6M SRL, 30K SA, 708K PFA
- ✅ ANAF v9 enrichment FINISHED 2026-05-08 ~05:30: 3,208,535 firme
enriched în 5.1h overnight la 173 cui/s sustained (concurrency=2,
bulk UPDATE via UNNEST). 99.99% coverage anaf_fetched_at.
- phone: 2,403,249 firme (60.5%)
- is_vat_registered: 494,125 (12.4%)
- is_efactura: 283,008 (7.1%)
- is_active_anaf: ~99% populated
- caen_principal: din ANAF (poate diferi de cel ONRC)
- ✅ Geocoding done 2026-05-08 ~01:25:
- geonames_postal: 2,128,990 firme (53.6%) — postal centroid ~100m-2km
- uat_centroid: 670,657 firme (16.9%) — UAT centroid 5-30km
- NULL: 1,173,583 (29.5%) — fără postal valid AND fără siruta
- Total cu lat/lng: 2,799,647 (70.5%)
- firms.financials: 3,861,043 records, 5 ani × 21 indicatori per firmă-an
(cifră afaceri, profit brut/net, active, datorii, capitaluri, salariați
etc.). Source: Min. Finanțelor Situații financiare 2020-2024 pe data.gov.ro.
- firms.mv_financials_latest: pentru fast profile lookup (cui-ul cu cea mai
recentă date)
- firms.postal_codes: 37,915 postal codes RO din GeoNames (CC-BY 4.0)
cu lat/lng. firms.postal_codes_best — view DISTINCT ON (postal_code).
CRON LIVE (systemd timers pe satra, enabled 2026-05-08):
- vreaudigital-anaf-daily.timer — 02:00 zilnic, tier=daily (SEAP-active >14d
+ new), conc=2. Wrapper: cron/enrich-anaf.sh.
- vreaudigital-onrc-weekly.timer — Tue 03:00, auto-detect dataset nou via
CKAN API data.gov.ro (firme-DD-MM-YYYY pattern, ~monthly publication).
Wrapper: cron/import-onrc-fresh.sh.
- vreaudigital-mvs.timer — 04:00 zilnic, refresh seap.* MVs (existing).
PROFILE PAGES WIRED:
- /achizitii/firma/[cui] (cba6b49+): badge forma juridică + cod ONRC, sediu
social, data înmatriculare, count CAEN, web, financial timeline 5 ani,
administratori top 10, SEAP heatmap când există
- /achizitii/autoritate/[cui] (1abfbf3+): wire identic — funcționează pentru
autorități care SUNT firme (regii autonome, S.A. de stat, universități).
Ministerele/primăriile pure n-au entries → fallback la profile.address.
Test: vreaudigital.ro/achizitii/autoritate/1590120 (ROMSILVA REGIE AUTONOMĂ).
- Test live firma: /achizitii/firma/45407951 (M.D.A Energy — full),
/firma/34304829 (RICHRBT — fără SEAP, cu CA 3.6 mld), /firma/8955860
(Alliance — SEAP, fără financials în WEB_UU — în alt categorie MFP)
RECIPE-URI FIRME LIVE (categoria 'firme', 1abfbf3+):
- /achizitii/retete/top-firme-cifra-afaceri — top 50 național după CA
- /achizitii/retete/firme-1-salariat-contracte-mari — 0-1 sal + >1M RON
(proxy front company)
- /achizitii/retete/firme-cu-pierderi-mari-castigatoare — pierdere >1M +
contracte >5M (zombie company)
- /achizitii/retete/firme-noi-cu-contracte-mari — <24 luni + >500K
(instant winners)
CE LIPSEȘTE ÎNCĂ:
A. /harta integration — adaugă cluster pin layer peste choropleth-ul existent
folosind firms.entities.geom (deja populated 70.5%). Filter pe geocode_source
pentru a marca precision (postal vs UAT centroid).
B. Photon JAR nativ pe satra (housenumber-precision pin pentru ~3M firme cu
adr_strada+adr_numar) — task #9 research în progres. Avem deja /opt/photon
/photon_data 641MB ES extract gata. Variant a/b/c din lista veche urmate
de research agent acum.
C. Date financiare suplimentare — task #10 research în progres:
- WEB_BL_BS_SL_AN20XX.txt (bilanț scurt — Alliance Healthcare e aici)
- WEB_ONG_AN20XX.txt (ONG-uri), WEB_Inst_de_credit, WEB_IFN, WEB_IP_IEME
- 2025 data când publica MFP (~mai-iunie 2026)
D. Date contact + branches + license registries — task #11 research în progres:
- PUNCTE DE LUCRU (ONRC are doar pe web, nu în bulk)
- EMAIL (orice sursă publică)
- ANRE/ANCOM/ANSPDCP/CSA license registries per CUI
- Insolvent.ro / BPI bulk insolvency data
- listafirme/termene API/scraping legality
E. Date procurement-adjacent — task #12 research în progres:
- Curtea de Conturi audit reports per institution
- CNSC contestation decisions
- Plăți efective per furnizor (vs contracte semnate)
- PNRR + fonduri europene execuție per supplier
- DNA / Consiliul Concurenței decisions
F. Recipe firme-radiate-cu-contracte-recente — NEIMPLEMENTAT pentru că
firms.entities.is_radiated_onrc e mereu false (codurile 4-digit din
status_text nu se mapează la firms.stare_codelist 1-9). Necesită
mapping explicit ONRC sau parser pe text.
G. Top firme NATIONALE pe explorer/azi pages (treemap CA × CAEN × județ,
map flow contracte cross-județ). Date sunt disponibile, doar UI lipsește.
⚠️ SECURITY DEBT REZIDUAL:
1. **Rotirea parolei DB architools_user** AMÂNATĂ de user pe 2026-05-07
("las-o asa, ne ocupam alta data"). Parola a leak-uit prin ps aux la
14:24 pe 2026-05-07. Pentru rotație viitoare: scriptul satra cu MI
universal-auth nu poate UPDATE secrete (perm 403); user trebuie să
schimbe manual via UI Infisical, după care script-ul aplică
ALTER USER pe PG cu parola veche.
2. ✅ refresh-mvs.sh — fixed în a2fbb82 (PGPASSWORD env vars în loc de URL)
3. ✅ enrich-anaf.ts pagination bug — fixed în f943bba (drop lastId cursor)
4. ✅ setup-photon.sh URL discovery — fixed în f943bba (auto-detect dated)
5. ✅ ANAF 404+body parsing — fixed în 754935d (treat as no-results, not throw)
6. ✅ enrich-anaf bulk UPDATE + concurrency — în 228af23 (~3.3× speedup)
7. ✅ Geocoding: GeoNames postal + UAT centroid (ff6594d/4642dc5/c5cb223)
8. ✅ Tiered cron daily ANAF + weekly ONRC (c6fa7cd)
GOTCHAS / DECIZII LUATE (cumulative):
- siruta_source 'county_capital_fallback' marcă rândurile aproximate (12.5K
rânduri Bucharest cu Sector 1 fallback) — folosește pentru a filtra în
vizualizări care cer precizie reală.
- numar_salariati = BIGINT (nu INT) — au fost valori absurde 7.7e14 în
staging. Sanitize la i20 BETWEEN 0 AND 100M.
- ONRC date_inmatriculare format: DD.MM.YYYY uneori cu timestamp suffix
"DD.MM.YYYY HH:MM:SS" — substring(s, 1, 10) inainte de to_date.
- DISTINCT ON (cui) + ORDER BY data DESC necesar pentru duplicate CUIs.
- COPY CSV ONRC necesită QUOTE E'\b' (firmele au quote-uri embedded).
- ANAF script: NU folosi cursor pagination cu ORDER BY COUNT(...)
decât-citit-tot-up-front. WHERE filter pe anaf_fetched_at e suficient.
- Photon RO data e ES format, dar default rtuszik image vrea OS — incompatibil.
- satra n-are node host. Pentru tsx scripts: docker run node:22-alpine cu
--env-file (NU -e), pentru a evita leak DATABASE_URL via ps aux.
- Deploy: rulează `bash /opt/vreaudigital/deploy.sh` ca user bulibasa
(NU sudo) — root n-are ssh known_hosts pentru git.beletage.ro.
- Concurrency=2 worker pool acceptat de ANAF fără 429 sustained — practic
rate limit-ul declarat (1 req/sec) e softer. Concurrency=3+ untested.
- public."GisUat".geom e SRID 3844 (RO STEREO70) — necesită ST_Transform la
4326 înainte de cast la geography. firms.entities.geom e SRID 4326.
- Postal codes UPDATE pe 2M rows trebuie chunked (50K) cu deadlock-retry
in bash, NU PL/pgSQL DO block (single-tx, abort = pierdere totală).
- ANAF v9: când ALL CUIs din batch sunt invalid, returnează HTTP 404 cu
body parseabil {found:[], notFound:[...]}. Trateaza ca no-results.
- ANAF v9: CUIs cu length>10 (CNP-uri 13-digit din ONRC PFA) generează 404
pe tot batch-ul. Filter `length BETWEEN 1 AND 10`.
IMEDIATE RECOMMENDED NEXT STEPS:
1. Frontend /harta: cluster pin layer over choropleth folosind lat/lng nou
2. Citește rezultatele celor 4 research agents (tasks #9-12) pentru next moves
3. Photon JAR install (când agent #9 returnează planul)
4. ONRC stare codelist mapping pentru radiate-cu-contracte recipe
4. Investighează ONRC stare codelist pentru radiate-cu-contracte recipe
5. Treemap top firme + map flow cross-județ pe /achizitii/explorer
1. Continuare /achizitii sub-app
Lipește asta când vrei să continui dezvoltarea sub-app-ului de achiziții, mai ales features noi din lista de "Phase 4" mai jos.
Continuă lucrul la vreaudigital.ro/achizitii — sub-app pură transparență
achiziții publice România.
[CONTEXT — vezi sectia 0 din PROMPTS.md în repo]
CE E DEJA LIVE:
- /achizitii — landing hub (cu KPI strip live)
- /achizitii/firma/[cui] — profil furnizor cu auto-dossier (3 fraze
generate), KPI strip (top buyer dependency, geo footprint, CPV diversity
Shannon entropy, YoY growth, modifications), calendar heatmap 5y SVG,
county distribution bars, top buyers, CPV breakdown, recent contracts,
external links (listafirme, termene, ONRC, ANAF, Curtea de Conturi)
- /achizitii/autoritate/[cui] — profil autoritate cu KPI tone-coded după
praguri DOJ/OCP/EU SMSC: direct% (<20/20-40/>40), HHI suppliers
(<1500/1500-2500/>2500), top supplier share (<30/30-50/>50), Q4 spike
(<1.3/1.3-1.7/>1.7), modification count
- /achizitii/retea/[cui] — graph radial 2-ring (top 10 inner + 10 outer
furnizori orbital, click neighbor expandează cu 4 alte counterparts în
linii dashed amber). Auto-detect supplier vs authority.
- /achizitii/retete — 20 retete investigative cu OG images dinamice
(satori + resvg @vercel/og style)
- /achizitii/cauta — search FTS via tsvector (ranked relevance, ~10ms)
- /achizitii/azi, /top-contracte, /top-firme, /fonduri-ue, /risc/* (5
sub-pages: single-bidder, economii-suspect, overprice, concentrare,
termen-scurt), /explorer, /anunt/[id], /judet/[county], /categoria/[cpv]
- /api/ocds — discovery + releases (paginated) + release/[id] + parties/[id]
+ bulk/[year] (streaming JSONL via pg-cursor)
- /api/og — recipe/[slug].png, firma/[cui].png, autoritate/[cui].png
URMĂTOARELE PRIORITĂȚI (Phase 4):
A. AUTH + WATCHLIST + ALERTS
- Cont gratuit cu email magic link (folosește Supabase deja integrat în
/cont/login — vezi src/pages/api/auth/[...route].ts)
- Tabel users.watchlist (entity_type, cui, alert_freq)
- Alerte email weekly digest pentru: "în watchlist-ul tău s-a întâmplat X"
- Frontend /cont/profil cu UI watch/unwatch din pagina de profil
entitate (button "Urmărește" pe /achizitii/firma/* și /autoritate/*)
- Email infra: Brevo SMTP deja configurat (vezi $BREVO_SMTP_*)
B. CITIZEN REPORTING DOZORRO-STYLE
- Buton "Raportează această licitație" pe /achizitii/anunt/[id]
- Tabel reports cu thread, status, vot
- Dashboard /achizitii/raportari pentru ONG/jurnaliști
- Validare/curare via cont moderator (rol)
C. POVESTI — DATA ESSAYS SCROLLYTELLING
- Sub-rută /achizitii/povesti/[slug]
- Format MDX cu Mapbox Storytelling pattern + scroll-tell
- Primele 3 cazuri: Drumul banilor PNRR Suceava, Spitale fără competiție,
CFR contracte modificate
D. SQL EDITOR POWER USER (stil Stripe Sigma)
- /achizitii/explorer/sql cu editor Monaco
- Whitelist queries (SELECT only, schema seap, max rows 1000)
- Templates predefinite (ex: "find me X")
- Pentru abonați Pro/Business
E. ONRC INTEGRATION
- Import data.gov.ro CSV-uri ONRC cu administratori
- Tabel seap.entity_administrators(cui, full_name, role, effective_from)
- Highlight shared admins în NetworkGraph
- Recipe nouă: "firme cu același administrator care câștigă de la aceleași autorități"
F. eForms 2024 SCHEMA READINESS
- Când ANAP migrează SEAP la eForms (2026-2027 estimat) vor fi 50+ câmpuri
noi: bids[], amendments[], milestones[], documents[]. Schema-pregătire în
ocds-mapper.ts să accepte gracefully.
CONVENTIONS PENTRU CODE:
- React components în .tsx pentru island, Astro frontmatter pentru SSR queries
- queries SQL în src/lib/*-queries.ts (ex: profile-queries.ts, recipes.ts,
ocds-mapper.ts, seap-queries.ts, search-queries.ts, risk-queries.ts etc.)
- materialized views în services/seap-scraper/sql/NNN_xxx.sql, applied via
refresh-mvs.sh sau manual one-shot
- API routes în src/pages/api/* — APIRoute cu prerender=false
- Rute statice (`prerender = true` implicit) pentru tot ce nu schimbă pe
request — toate paginile actuale au prerender=false pentru că depind de DB
- Layout: import AchizitiiLayout pentru orice /achizitii/* page; ogImage prop
pentru meta tags
URMĂTOR PAS PROPUS: alege A (auth+watchlist) ca prioritate maximă — e baza
pentru retention și pentru tier-ul Pro plătit.
2. Bugs/features /achizitii
Lipește asta când raportezi un bug sau ceri o feature mică pe sub-app.
Lucrez la vreaudigital.ro/achizitii — sub-app de transparență achiziții publice.
[CONTEXT — vezi PROMPTS.md sectia 0 în repo pentru stack/infra/conventions]
[DESCRIE BUG-UL / FEATURE-UL AICI — fii specific:]
- Pagina afectată (URL exact): ...
- Comportament curent: ...
- Comportament așteptat: ...
- Reproducere: ...
- Browser/device dacă e UI bug: ...
CONSTRAINTS PENTRU MODIFICĂRI:
- NU modifica src/styles/global.css sau tailwind.config.mjs din /achizitii.
- NU adăuga dependențe noi fără verificare alpine compat (rulăm Docker alpine).
- TOATE schimbările care ating DB:
- Scrie migration nouă în services/seap-scraper/sql/NNN_xxx.sql
- Aplică via psql cu Infisical MI (vezi refresh-mvs.sh pattern)
- Migration MUST fi idempotent (CREATE OR REPLACE, IF NOT EXISTS)
- Verifică `npx astro check` cu 0 errors ÎNAINTE de commit
- Verifică `npm run build` PASS
- Commit message stil convențional: "Fix X" sau "Add Y" + corpul cu why+how
- Push declanșează deploy automat — verifică /api/version după 30s pentru
noul sha; dacă deploy.sh log la satra arată failure, debug imediat
WORKFLOW DEBUGGING:
1. Reproduceți problema cu curl pe API endpoints, sau cu HTTP code check
pe pagina întreagă: `curl -fso /dev/null -w "%{http_code}\n" URL`
2. Pentru DB issues: rulează psql direct pe satra cu Infisical MI
3. Pentru container errors: `ssh satra "docker logs vreaudigital --tail 50"`
4. Pentru deploy errors: `sudo tail -50 /var/log/vreaudigital-deploy.log`
CE NU SCHIMBI fără să întrebi:
- Auth flow (Supabase magic link existent în /api/auth/)
- Schema seap.announcements (MV-urile depind de coloanele actuale)
- Schema OCDS mapping (ocds-mapper.ts) — clienții externi pot fi deja folosind-o
- Layout-urile de bază (BaseLayout, AchizitiiLayout structure)
- Routing principal (/achizitii/* paths)
CE POȚI SCHIMBA LIBER:
- UI mici tweak-uri (style fixes, layout adjustments scoped la pagina vizată)
- Adăugarea de retete noi în src/lib/recipes.ts
- Coloane noi pe view-uri / queries
- Performance optimizations cu materialized views noi
- Conținut text (titluri, descrieri)
3. Bugs/features marketing (vreaudigital.ro)
Pentru pagini din afara
/achizitii/*și/api/*— adică homepage, /idei, /produse, /despre, /contribuie, /cont/, /demo/, /propune*.
Lucrez la vreaudigital.ro — secțiunea marketing (NON-/achizitii).
PAGINILE DIN SCOPUL MEU:
- / (homepage) — Hero + CategoryCards + ProductCards
- /idei — listă idei propuse de comunitate
- /propune — formular propunere idee
- /produse/[slug] — pagini produse demo (hartabanilor, demo-firma, demoanaf,
generator-cereri, programare-buletin, sesizare-plus, sicap-ai,
traducator-birocratic, demo-impozit)
- /propune-produs — formular propunere produs
- /despre — pagină despre
- /contribuie — call-to-action contribuție
- /cont/login, /cont/register, /cont/profil — auth (Supabase magic link)
- /demo/traducator — demo AI traducător birocratic
PAGINILE DIN AFARA SCOPULUI MEU (NU le ating fără permisiune explicită):
- /harta — aplicație separată Civic OS, NU o tratezi ca pagină marketing
- /achizitii/* — sub-app de transparență, regim diferit (vezi PROMPTS.md #2)
- /api/* — endpoints SSR
[DESCRIE BUG-UL / FEATURE-UL AICI:]
- Pagina afectată: ...
- Comportament curent: ...
- Comportament așteptat: ...
DESIGN CONSTRAINTS HARD (NU le încălca):
- Paleta: blue (primary-600 #2563EB) + amber (secondary-500 #F59E0B) + slate
- Fonts: Plus Jakarta Sans + Inter (definite în BaseLayout via @fontsource)
- rounded-xl + shadow-card pe carduri
- ANTI-PATTERNS respinse: brutalism, bento, big-number hero, monospace
numbers ca podoabă, warm earth palette
- Folosește utility classes din global.css: .btn-primary, .btn-secondary,
.product-card, .category-pill, .badge-*, .stat-card, .input-field,
.progress-bar, .section. NU recrea ce există.
- Layout = BaseLayout (NU AchizitiiLayout)
- ogImage prop pe BaseLayout dacă vrei share image custom (default e
https://vreaudigital.ro/og-default.png)
WORKFLOW IDENTIC:
- npx astro check 0 errors → npm run build PASS → commit + push → verifică
/api/version pentru sha nou după 30s
- Push declanșează deploy automat satra. Dacă pică, vezi
/var/log/vreaudigital-deploy.log
- Dacă schimbi vreun layout structural sau adaugi routes noi, update și
PROMPTS.md în repo (secția listă de pagini)
CONTENT CONSTRAINTS:
- NU scrie în engleză sau in stil corporate engleză tradusă. Tonul site-ului
e direct, fără buzz-words ("inovativ", "soluție de ultimă generație",
"platformă holistică" — tot rebut). Vezi commit `670434d` pentru exemple
de "AI slop" eliminate anterior.
- Românescul corect, fără diacritice forțate sau majuscule de marketing.
- Voice: arhitect care vrea să rezolve probleme reale, nu pitch deck.
Anexă: inventar pagini la mai 2026
Marketing (BaseLayout)
| URL | File | Render |
|---|---|---|
/ |
src/pages/index.astro |
static |
/despre |
src/pages/despre.astro |
static |
/idei |
src/pages/idei.astro |
SSR |
/contribuie |
src/pages/contribuie.astro |
static |
/propune |
src/pages/propune.astro |
SSR |
/propune-produs |
src/pages/propune-produs.astro |
SSR |
/produse/[slug] |
src/pages/produse/[...slug].astro |
static (9 produse) |
/demo/traducator |
src/pages/demo/traducator.astro |
static |
/cont/login |
src/pages/cont/login.astro |
SSR |
/cont/register |
src/pages/cont/register.astro |
SSR |
/cont/profil |
src/pages/cont/profil.astro |
SSR |
App separată (custom layout)
| URL | File | Render |
|---|---|---|
/harta |
src/pages/harta.astro |
SSR fullscreen |
Legacy redirects → /achizitii/*
| URL | Redirect către |
|---|---|
/firma/[cui] |
/achizitii/firma/[cui] |
/autoritate/[cui] |
/achizitii/autoritate/[cui] |
Sub-app /achizitii (AchizitiiLayout)
| URL | File |
|---|---|
/achizitii |
src/pages/achizitii/index.astro |
/achizitii/azi |
src/pages/achizitii/azi.astro |
/achizitii/cauta |
src/pages/achizitii/cauta.astro |
/achizitii/explorer |
src/pages/achizitii/explorer.astro |
/achizitii/fonduri-ue |
src/pages/achizitii/fonduri-ue.astro |
/achizitii/top-contracte |
src/pages/achizitii/top-contracte.astro |
/achizitii/top-firme |
src/pages/achizitii/top-firme.astro |
/achizitii/firma/[cui] |
src/pages/achizitii/firma/[cui].astro |
/achizitii/autoritate/[cui] |
src/pages/achizitii/autoritate/[cui].astro |
/achizitii/retea/[cui] |
src/pages/achizitii/retea/[cui].astro |
/achizitii/anunt/[id] |
src/pages/achizitii/anunt/[id].astro |
/achizitii/judet/[county] |
src/pages/achizitii/judet/[county].astro |
/achizitii/categoria/[cpv] |
src/pages/achizitii/categoria/[cpv].astro |
/achizitii/retete |
src/pages/achizitii/retete/index.astro |
/achizitii/retete/[slug] |
src/pages/achizitii/retete/[slug].astro (20 rețete) |
/achizitii/risc |
src/pages/achizitii/risc/index.astro |
/achizitii/risc/single-bidder |
+ 4 sub-pages risc/* |
API (SSR endpoints)
| URL | File |
|---|---|
/api/version |
src/pages/api/version.ts |
/api/auth/[...route] |
src/pages/api/auth/[...route].ts |
/api/platform/[...route] |
src/pages/api/platform/[...route].ts |
/api/profil/[side]/[cui] |
src/pages/api/profil/[side]/[cui].ts |
/api/traducator |
src/pages/api/traducator.ts |
/api/harta/[...route] |
src/pages/api/harta/[...route].ts (stats, choropleth/[year], metric/[m], uat/[siruta], flows/[siruta], feed/[limit], anunt/[id], mvt/[table]/[z]/[xy]) |
/api/ocds |
src/pages/api/ocds/index.ts (discovery) |
/api/ocds/releases |
src/pages/api/ocds/releases.ts |
/api/ocds/release/[id] |
src/pages/api/ocds/release/[id].ts |
/api/ocds/parties/[id] |
src/pages/api/ocds/parties/[id].ts |
/api/ocds/bulk |
src/pages/api/ocds/bulk/index.ts (manifest) |
/api/ocds/bulk/year/[year] |
src/pages/api/ocds/bulk/year/[year].ts (streaming JSONL) |
/api/og/recipe/[slug].png |
src/pages/api/og/recipe/[slug].png.ts |
/api/og/firma/[cui].png |
src/pages/api/og/firma/[cui].png.ts |
/api/og/autoritate/[cui].png |
src/pages/api/og/autoritate/[cui].png.ts |
SQL migrations (services/seap-scraper/sql/)
| File | Purpose |
|---|---|
| 003_unified_announcements.sql | core schema |
| 004_wsp.sql | WSP scraper tables |
| 005_wsp_views.sql | WSP-derived views |
| 006_wsp_uat_mapping.sql | UAT geo-matching |
| 007_cpv_codes.sql | CPV taxonomy |
| 008_risk_flags.sql | risk_flags JSONB + 73 OCP indicators |
| 009_uat_kpi.sql | per-UAT KPI MV (multi-metric choropleth) |
| 010_search_index.sql | tsvector FTS + GIN index + immutable_unaccent |
| 011_recipe_mvs.sql | 5 MVs pentru retete (top_cpv, top_suppliers, top_authorities, recurrent_pairs, supplier_cpv_share) |
Update PROMPTS.md când adaugi pagini noi sau schimbi major arhitectura.