From a6c03a091ef09dc69e6a5d2ff361965863c1179c Mon Sep 17 00:00:00 2001 From: Claude VM Date: Wed, 13 May 2026 00:10:32 +0300 Subject: [PATCH] =?UTF-8?q?initial:=20split=20from=20gov-agreg=20=E2=80=94?= =?UTF-8?q?=20vreau.digital=20standalone=20platform?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moved from gov-agreg/src/pages/achizitii/* to root (drop prefix). - 22 pages migrated, 127 files total - All internal links: /achizitii/X → /X (176 occurrences fixed) - AchizitiiLayout subnav rewritten: /X paths, top-right link to vreaudigital.ro hub - BaseLayout new (vreau.digital branding, OG tags, site URL) - astro.config.mjs: site https://vreau.digital, server output (was static) - docker-compose: port 5096 (vreaudigital is 5095), container vreau-digital - deploy.sh: paths /opt/vreau-digital, log /var/log/vreau-digital-deploy.log Backend shared with gov-agreg: - PostgreSQL satra (same schemas: seap, firms, anaf, anre, ...) - Photon, Martin tiles - Infisical /vreaudigital path (DATABASE_URL etc. shared) build: PASS (npx astro check 0 errors, npm run build 5s vite + 10s server) --- .gitignore | 39 + CLAUDE.md | 35 + Dockerfile | 51 + MISSION.md | 3 + PLAN-DESIGN.md | 1262 +++ PLAN-OPENSOURCE.md | 521 + PLAN-PRODUCTION.md | 324 + PLAN-PRODUCTS-V2.md | 553 + PLAN-PRODUCTS.md | 523 + PLAN.md | 436 + PROMPTS.md | 1367 +++ astro.config.mjs | 21 + .../freshness-audit-2026-05-10.md | 356 + .../geocoding-strategy-2026-05-11.md | 62 + .../refresh-cadence-strategy-2026-05-11.md | 624 ++ chatGPT/deep-research-report.md | 486 + .../journalism/killer-findings-2026-05-10.md | 527 + .../sectorial-deep-dive-2026-05-10.md | 402 + chatGPT/session-summary-2026-05-11.md | 151 + chatGPT/simple-research-report.md | 375 + deploy.sh | 57 + docker-compose.yml | 14 + docker/entrypoint.sh | 45 + nginx.conf | 26 + package-lock.json | 9182 +++++++++++++++++ package.json | 49 + public/favicon.svg | 14 + public/screenshots/.gitkeep | 0 services/seap-scraper/.gitignore | 6 + services/seap-scraper/AAAS-PLAN.md | 158 + services/seap-scraper/AEP-PLAN.md | 199 + services/seap-scraper/AFIR-HISTORICAL-PLAN.md | 186 + .../seap-scraper/ANAF-DATORNICI-RECIPES.md | 175 + services/seap-scraper/ANCOM-PLAN.md | 181 + services/seap-scraper/ANI-PLAN.md | 432 + services/seap-scraper/ANRE-PLAN.md | 187 + services/seap-scraper/APIA-PLAN.md | 236 + services/seap-scraper/ASF-PLAN.md | 170 + services/seap-scraper/BUGETAR-PLAN.md | 345 + services/seap-scraper/CNAS-PLAN.md | 217 + services/seap-scraper/CNSC-PLAN.md | 273 + services/seap-scraper/CURTEACONT-PLAN.md | 205 + services/seap-scraper/Dockerfile | 16 + services/seap-scraper/GNM-PLAN.md | 209 + .../seap-scraper/HANDOFF-aaas-ordin-278.md | 36 + .../HANDOFF-anaf-datornici-2captcha.md | 300 + .../HANDOFF-asf-other-registers.md | 74 + .../seap-scraper/HANDOFF-cnas-layout-b.md | 84 + .../RESEARCH-NEXT-DATA-SOURCES.md | 203 + .../seap-scraper/SEAP-HISTORICAL-NOTES.md | 81 + services/seap-scraper/STRATEGIC-PLAN.md | 447 + .../seap-scraper/TED-DATE-BACKFILL-NOTES.md | 101 + services/seap-scraper/cron/enrich-anaf.sh | 82 + services/seap-scraper/cron/geocode-firms.sh | 343 + services/seap-scraper/cron/heartbeat.sh | 144 + .../cron/import-afir-historical.sh | 132 + .../seap-scraper/cron/import-apia-fermieri.sh | 210 + .../cron/import-financials-historical.sh | 526 + .../cron/import-financials-ong-banks.sh | 194 + .../seap-scraper/cron/import-financials.sh | 108 + .../seap-scraper/cron/import-onrc-fresh.sh | 85 + services/seap-scraper/cron/import-onrc.sh | 272 + .../seap-scraper/cron/import-postal-codes.sh | 199 + services/seap-scraper/cron/install-photon.sh | 51 + services/seap-scraper/cron/match-cui-ancom.sh | 204 + services/seap-scraper/cron/match-cui-anre.sh | 204 + .../seap-scraper/cron/match-cui-external.sh | 237 + services/seap-scraper/cron/refresh-mvs.sh | 79 + services/seap-scraper/cron/scrape-aaas.sh | 87 + .../seap-scraper/cron/scrape-aep-donatii.sh | 82 + .../cron/scrape-anaf-datornici-live.sh | 125 + .../cron/scrape-anaf-datornici.sh | 84 + .../cron/scrape-anaf-lista-alba.sh | 102 + services/seap-scraper/cron/scrape-ancom.sh | 86 + services/seap-scraper/cron/scrape-anre.sh | 89 + services/seap-scraper/cron/scrape-asf.sh | 86 + services/seap-scraper/cron/scrape-bugetar.sh | 115 + services/seap-scraper/cron/scrape-cnas.sh | 96 + services/seap-scraper/cron/scrape-cnsc.sh | 85 + .../seap-scraper/cron/scrape-curteacont.sh | 93 + services/seap-scraper/cron/scrape-da.sh | 81 + services/seap-scraper/cron/scrape-gnm.sh | 88 + services/seap-scraper/cron/scrape-regas.sh | 79 + services/seap-scraper/cron/setup-photon.sh | 70 + .../cron/vreaudigital-anaf-daily.service | 14 + .../cron/vreaudigital-anaf-daily.timer | 11 + .../cron/vreaudigital-mvs.service | 11 + .../seap-scraper/cron/vreaudigital-mvs.timer | 11 + .../cron/vreaudigital-onrc-weekly.service | 12 + .../cron/vreaudigital-onrc-weekly.timer | 11 + .../cron/vreaudigital-photon.service | 18 + services/seap-scraper/deploy/install.md | 84 + .../deploy/wsp-incremental.service | 15 + .../seap-scraper/deploy/wsp-incremental.timer | 11 + services/seap-scraper/docker-compose.yml | 11 + services/seap-scraper/import_all_2026.py | 444 + services/seap-scraper/import_anaf_cui.py | 223 + services/seap-scraper/import_datagov.py | 652 ++ services/seap-scraper/import_ted.py | 293 + services/seap-scraper/package-lock.json | 752 ++ services/seap-scraper/package.json | 24 + services/seap-scraper/requirements.txt | 4 + .../scrapers/anaf_datornici/probe.py | 212 + .../scrapers/anaf_datornici/scraper.py | 525 + .../scrapers/anaf_lista_alba/scraper.py | 425 + .../scripts/import-afir-fega-csv.py | 103 + .../scripts/import-afir-historical.py | 139 + .../scripts/import-apia-fermieri.py | 167 + .../scripts/import-seap-historical.py | 483 + .../scripts/import-seap-historical.sh | 81 + .../seap-scraper/scripts/import-seap-xlsx.sh | 73 + .../scripts/test-cnas-layout-b.ts | 56 + services/seap-scraper/scripts/xlsx-to-csv.py | 95 + services/seap-scraper/sql/001_init.sql | 189 + .../seap-scraper/sql/002_announcements.sql | 52 + services/seap-scraper/sql/003_platform.sql | 98 + services/seap-scraper/sql/004_wsp.sql | 174 + services/seap-scraper/sql/005_wsp_views.sql | 121 + .../seap-scraper/sql/006_wsp_uat_mapping.sql | 71 + services/seap-scraper/sql/007_cpv_codes.sql | 71 + services/seap-scraper/sql/008_risk_flags.sql | 233 + services/seap-scraper/sql/009_uat_kpi.sql | 94 + .../seap-scraper/sql/010_search_index.sql | 58 + services/seap-scraper/sql/011_recipe_mvs.sql | 165 + services/seap-scraper/sql/012_firms.sql | 161 + .../seap-scraper/sql/013_firms_financials.sql | 75 + .../sql/014_firms_postal_codes.sql | 46 + .../sql/015_firms_onrc_extras.sql | 32 + .../sql/016_firms_financials_categories.sql | 97 + .../seap-scraper/sql/017_fonduri_afir.sql | 58 + .../sql/018_fonduri_beneficiar_privat.sql | 102 + services/seap-scraper/sql/019_cui_matcher.sql | 66 + .../sql/020_fonduri_proiect_v2.sql | 43 + .../seap-scraper/sql/021_regas_ajutoare.sql | 74 + services/seap-scraper/sql/024_aep_donatii.sql | 203 + .../seap-scraper/sql/025_anaf_datornici.sql | 96 + services/seap-scraper/sql/026_bugetar.sql | 224 + .../seap-scraper/sql/027_afir_tip_fond.sql | 15 + services/seap-scraper/sql/028_anre.sql | 136 + services/seap-scraper/sql/029_ancom.sql | 131 + services/seap-scraper/sql/030_ani_schema.sql | 211 + services/seap-scraper/sql/031_cnas.sql | 197 + services/seap-scraper/sql/032_aaas.sql | 118 + services/seap-scraper/sql/033_cnsc.sql | 202 + services/seap-scraper/sql/034_asf.sql | 123 + services/seap-scraper/sql/035_curteacont.sql | 120 + services/seap-scraper/sql/036_apia.sql | 235 + services/seap-scraper/sql/037_gnm.sql | 115 + .../sql/038_bugetar_cui_match_stage_b.sql | 98 + .../sql/039_bugetar_uat_pattern_match.sql | 62 + .../sql/040_curteacont_uat_pattern_match.sql | 105 + .../sql/041_curteacont_cleaned_name_match.sql | 87 + .../sql/042_cnsc_authority_cui_match.sql | 101 + .../sql/043_red_flags_kpi_snapshot.sql | 87 + .../sql/044_red_flags_previews_snapshot.sql | 628 ++ .../045_index_pub_date_desc_nulls_last.sql | 22 + .../sql/046_cauta_default_facets_snapshot.sql | 140 + ...47_index_awarded_value_desc_nulls_last.sql | 18 + services/seap-scraper/src/cnas-layout-b.ts | 815 ++ services/seap-scraper/src/config.ts | 31 + services/seap-scraper/src/db.ts | 20 + services/seap-scraper/src/enrich-anaf.ts | 393 + services/seap-scraper/src/enrich.ts | 202 + services/seap-scraper/src/geocode-photon.ts | 355 + services/seap-scraper/src/index.ts | 65 + .../src/matching/locality-matcher.ts | 128 + services/seap-scraper/src/scrape-aaas.ts | 446 + .../seap-scraper/src/scrape-aep-donatii.ts | 524 + .../seap-scraper/src/scrape-anaf-datornici.ts | 348 + services/seap-scraper/src/scrape-ancom.ts | 487 + .../src/scrape-ani-declarations.ts | 363 + services/seap-scraper/src/scrape-anre.ts | 623 ++ services/seap-scraper/src/scrape-asf.ts | 515 + .../src/scrape-beneficiar-privat.ts | 418 + .../src/scrape-beneficiar-proiect.ts | 301 + services/seap-scraper/src/scrape-bugetar.ts | 444 + services/seap-scraper/src/scrape-cnas.ts | 628 ++ services/seap-scraper/src/scrape-cnsc.ts | 544 + .../seap-scraper/src/scrape-curteacont.ts | 420 + services/seap-scraper/src/scrape-gnm.ts | 602 ++ services/seap-scraper/src/scrape-regas.ts | 283 + .../src/scrapers/direct-acquisitions.ts | 129 + .../seap-scraper/src/scrapers/entities.ts | 85 + .../src/scrapers/public-notices.ts | 201 + services/seap-scraper/src/seap-client.ts | 191 + .../seap-scraper/src/utils/date-ranges.ts | 39 + services/seap-scraper/systemd/README.md | 36 + .../systemd/vreaudigital-aaas.service | 11 + .../systemd/vreaudigital-aaas.timer | 11 + .../systemd/vreaudigital-aep-donatii.service | 11 + .../systemd/vreaudigital-aep-donatii.timer | 11 + .../vreaudigital-anaf-datornici.service | 11 + .../systemd/vreaudigital-anaf-datornici.timer | 14 + .../vreaudigital-anaf-lista-alba.service | 11 + .../vreaudigital-anaf-lista-alba.timer | 13 + .../systemd/vreaudigital-ancom.service | 11 + .../systemd/vreaudigital-ancom.timer | 11 + .../systemd/vreaudigital-anre.service | 11 + .../systemd/vreaudigital-anre.timer | 11 + .../vreaudigital-apia-fermieri.service | 11 + .../systemd/vreaudigital-apia-fermieri.timer | 11 + .../systemd/vreaudigital-asf.service | 11 + .../systemd/vreaudigital-asf.timer | 11 + .../systemd/vreaudigital-cnas.service | 11 + .../systemd/vreaudigital-cnas.timer | 11 + .../systemd/vreaudigital-cnsc.service | 11 + .../systemd/vreaudigital-cnsc.timer | 11 + .../systemd/vreaudigital-curteacont.service | 11 + .../systemd/vreaudigital-curteacont.timer | 11 + .../systemd/vreaudigital-da.service | 12 + .../systemd/vreaudigital-da.timer | 11 + .../systemd/vreaudigital-gnm.service | 11 + .../systemd/vreaudigital-gnm.timer | 11 + .../systemd/vreaudigital-heartbeat.service | 11 + .../systemd/vreaudigital-heartbeat.timer | 11 + .../systemd/vreaudigital-regas.service | 11 + .../systemd/vreaudigital-regas.timer | 11 + services/seap-scraper/test_seap_demo.py | 153 + services/seap-scraper/tsconfig.json | 16 + services/seap-scraper/wsp-docker-compose.yml | 20 + services/seap-scraper/wsp/Dockerfile | 19 + services/seap-scraper/wsp/__init__.py | 0 services/seap-scraper/wsp/cert_loader.py | 102 + services/seap-scraper/wsp/client.py | 224 + services/seap-scraper/wsp/cron.sh | 47 + services/seap-scraper/wsp/db.py | 336 + services/seap-scraper/wsp/load_cpv.py | 107 + services/seap-scraper/wsp/operations.py | 202 + services/seap-scraper/wsp/pagination.py | 199 + services/seap-scraper/wsp/parsers/__init__.py | 0 services/seap-scraper/wsp/parsers/_base.py | 214 + services/seap-scraper/wsp/parsers/c_notice.py | 6 + .../seap-scraper/wsp/parsers/ca_notice.py | 287 + services/seap-scraper/wsp/parsers/catalog.py | 19 + .../seap-scraper/wsp/parsers/dc_notice.py | 6 + services/seap-scraper/wsp/parsers/e_notice.py | 6 + .../seap-scraper/wsp/parsers/ea_procedure.py | 6 + .../seap-scraper/wsp/parsers/pc_notice.py | 6 + .../seap-scraper/wsp/parsers/pi_notice.py | 6 + .../seap-scraper/wsp/parsers/rdc_notice.py | 6 + .../wsp/parsers/rfq_invitation.py | 6 + .../seap-scraper/wsp/parsers/rfq_notice.py | 6 + .../seap-scraper/wsp/parsers/su_contract.py | 83 + services/seap-scraper/wsp/parsers/su_da.py | 32 + .../seap-scraper/wsp/parsers/su_invoice.py | 49 + services/seap-scraper/wsp/runner.py | 142 + services/seap-scraper/wsp/sync.py | 193 + services/seap-scraper/wsp/xml_utils.py | 191 + services/seap-scraper/wsp_validate.py | 380 + services/seap-scraper/wsp_validate2.py | 114 + services/seed-ideas.sql | 616 ++ src/components/Footer.astro | 102 + src/components/VersionWatcher.tsx | 71 + src/components/cauta/CpvAutocomplete.tsx | 374 + src/components/cauta/SearchMap.tsx | 301 + src/components/harta/ActivityStream.tsx | 69 + src/components/harta/CommandPalette.tsx | 198 + src/components/harta/FilterChips.tsx | 46 + src/components/harta/FlowLayer.tsx | 153 + src/components/harta/HartaApp.tsx | 252 + src/components/harta/MapView.tsx | 494 + src/components/harta/MetricSwitcher.tsx | 35 + src/components/harta/PulseLayer.tsx | 118 + src/components/harta/Sparkline.tsx | 42 + src/components/harta/StatCard.tsx | 35 + src/components/harta/StatColumn.tsx | 155 + src/components/harta/TimelineScrubber.tsx | 33 + src/components/harta/county-centroids.ts | 61 + src/components/harta/harta.css | 1224 +++ src/components/harta/types.ts | 61 + src/components/harta/utils.ts | 42 + src/components/profile/CalendarHeatmap.tsx | 180 + src/components/profile/CountyBars.tsx | 58 + src/components/profile/FinancialTimeline.tsx | 136 + src/components/profile/NetworkGraph.tsx | 236 + src/components/profile/profile.css | 615 ++ src/components/viz/BarRace.tsx | 243 + src/components/viz/Sankey.tsx | 304 + src/components/viz/Treemap.tsx | 215 + src/content.config.ts | 31 + src/env.d.ts | 1 + src/layouts/AchizitiiLayout.astro | 43 + src/layouts/BaseLayout.astro | 58 + src/lib/announcement-queries.ts | 92 + src/lib/auth-queries.ts | 121 + src/lib/beneficiar-privat-queries.ts | 529 + src/lib/category-queries.ts | 212 + src/lib/county-queries.ts | 220 + src/lib/dashboard-queries.ts | 717 ++ src/lib/db.ts | 23 + src/lib/investigations.ts | 728 ++ src/lib/ocds-mapper.ts | 320 + src/lib/og-image.ts | 269 + src/lib/platform-queries.ts | 209 + src/lib/profile-queries-financial.ts | 311 + src/lib/profile-queries-utilities.ts | 396 + src/lib/profile-queries.ts | 1055 ++ src/lib/public-url.ts | 18 + src/lib/recipes.ts | 2289 ++++ src/lib/risk-queries.ts | 361 + src/lib/seap-queries.ts | 274 + src/lib/search-queries.ts | 630 ++ src/lib/supabase.ts | 15 + src/lib/viz-queries.ts | 326 + src/pages/anunt/[id].astro | 380 + src/pages/api/auth/[...route].ts | 133 + src/pages/api/cpv/search.ts | 210 + src/pages/api/harta/[...route].ts | 139 + src/pages/api/ocds/bulk/index.ts | 39 + src/pages/api/ocds/bulk/year/[year].ts | 116 + src/pages/api/ocds/index.ts | 57 + src/pages/api/ocds/parties/[id].ts | 205 + src/pages/api/ocds/release/[id].ts | 71 + src/pages/api/ocds/releases.ts | 113 + src/pages/api/og/autoritate/[cui].png.ts | 38 + src/pages/api/og/firma/[cui].png.ts | 37 + src/pages/api/og/recipe/[slug].png.ts | 43 + src/pages/api/platform/[...route].ts | 155 + src/pages/api/profil/[side]/[cui].ts | 60 + src/pages/api/traducator.ts | 116 + src/pages/api/version.ts | 17 + src/pages/autoritate/[cui].astro | 530 + src/pages/azi.astro | 231 + src/pages/beneficiar-privat/[id].astro | 288 + src/pages/categoria/[cpv].astro | 223 + src/pages/cauta.astro | 575 ++ src/pages/explorer.astro | 206 + src/pages/firma/[cui].astro | 859 ++ src/pages/fonduri-ue.astro | 417 + src/pages/fonduri-ue/anunturi.astro | 488 + src/pages/harta.astro | 25 + src/pages/index.astro | 116 + src/pages/investigation/[slug].astro | 378 + src/pages/investigation/index.astro | 82 + src/pages/judet/[county].astro | 210 + src/pages/proiect/[id].astro | 247 + src/pages/red-flags.astro | 304 + src/pages/retea/[cui].astro | 83 + src/pages/retete/[slug].astro | 148 + src/pages/retete/index.astro | 74 + src/pages/risc/concentrare.astro | 163 + src/pages/risc/economii-suspect.astro | 135 + src/pages/risc/index.astro | 244 + src/pages/risc/overprice.astro | 132 + src/pages/risc/single-bidder.astro | 155 + src/pages/risc/termen-scurt.astro | 152 + src/pages/top-contracte.astro | 198 + src/pages/top-firme.astro | 152 + src/styles/achizitii.css | 276 + src/styles/global.css | 221 + tailwind.config.mjs | 115 + tsconfig.json | 9 + 352 files changed, 75295 insertions(+) create mode 100644 .gitignore create mode 100644 CLAUDE.md create mode 100644 Dockerfile create mode 100644 MISSION.md create mode 100644 PLAN-DESIGN.md create mode 100644 PLAN-OPENSOURCE.md create mode 100644 PLAN-PRODUCTION.md create mode 100644 PLAN-PRODUCTS-V2.md create mode 100644 PLAN-PRODUCTS.md create mode 100644 PLAN.md create mode 100644 PROMPTS.md create mode 100644 astro.config.mjs create mode 100644 chatGPT/data-quality/freshness-audit-2026-05-10.md create mode 100644 chatGPT/data-quality/geocoding-strategy-2026-05-11.md create mode 100644 chatGPT/data-quality/refresh-cadence-strategy-2026-05-11.md create mode 100644 chatGPT/deep-research-report.md create mode 100644 chatGPT/journalism/killer-findings-2026-05-10.md create mode 100644 chatGPT/journalism/sectorial-deep-dive-2026-05-10.md create mode 100644 chatGPT/session-summary-2026-05-11.md create mode 100644 chatGPT/simple-research-report.md create mode 100755 deploy.sh create mode 100644 docker-compose.yml create mode 100755 docker/entrypoint.sh create mode 100644 nginx.conf create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/favicon.svg create mode 100644 public/screenshots/.gitkeep create mode 100644 services/seap-scraper/.gitignore create mode 100644 services/seap-scraper/AAAS-PLAN.md create mode 100644 services/seap-scraper/AEP-PLAN.md create mode 100644 services/seap-scraper/AFIR-HISTORICAL-PLAN.md create mode 100644 services/seap-scraper/ANAF-DATORNICI-RECIPES.md create mode 100644 services/seap-scraper/ANCOM-PLAN.md create mode 100644 services/seap-scraper/ANI-PLAN.md create mode 100644 services/seap-scraper/ANRE-PLAN.md create mode 100644 services/seap-scraper/APIA-PLAN.md create mode 100644 services/seap-scraper/ASF-PLAN.md create mode 100644 services/seap-scraper/BUGETAR-PLAN.md create mode 100644 services/seap-scraper/CNAS-PLAN.md create mode 100644 services/seap-scraper/CNSC-PLAN.md create mode 100644 services/seap-scraper/CURTEACONT-PLAN.md create mode 100644 services/seap-scraper/Dockerfile create mode 100644 services/seap-scraper/GNM-PLAN.md create mode 100644 services/seap-scraper/HANDOFF-aaas-ordin-278.md create mode 100644 services/seap-scraper/HANDOFF-anaf-datornici-2captcha.md create mode 100644 services/seap-scraper/HANDOFF-asf-other-registers.md create mode 100644 services/seap-scraper/HANDOFF-cnas-layout-b.md create mode 100644 services/seap-scraper/RESEARCH-NEXT-DATA-SOURCES.md create mode 100644 services/seap-scraper/SEAP-HISTORICAL-NOTES.md create mode 100644 services/seap-scraper/STRATEGIC-PLAN.md create mode 100644 services/seap-scraper/TED-DATE-BACKFILL-NOTES.md create mode 100755 services/seap-scraper/cron/enrich-anaf.sh create mode 100755 services/seap-scraper/cron/geocode-firms.sh create mode 100755 services/seap-scraper/cron/heartbeat.sh create mode 100755 services/seap-scraper/cron/import-afir-historical.sh create mode 100755 services/seap-scraper/cron/import-apia-fermieri.sh create mode 100644 services/seap-scraper/cron/import-financials-historical.sh create mode 100755 services/seap-scraper/cron/import-financials-ong-banks.sh create mode 100755 services/seap-scraper/cron/import-financials.sh create mode 100755 services/seap-scraper/cron/import-onrc-fresh.sh create mode 100755 services/seap-scraper/cron/import-onrc.sh create mode 100755 services/seap-scraper/cron/import-postal-codes.sh create mode 100755 services/seap-scraper/cron/install-photon.sh create mode 100755 services/seap-scraper/cron/match-cui-ancom.sh create mode 100755 services/seap-scraper/cron/match-cui-anre.sh create mode 100755 services/seap-scraper/cron/match-cui-external.sh create mode 100755 services/seap-scraper/cron/refresh-mvs.sh create mode 100755 services/seap-scraper/cron/scrape-aaas.sh create mode 100755 services/seap-scraper/cron/scrape-aep-donatii.sh create mode 100755 services/seap-scraper/cron/scrape-anaf-datornici-live.sh create mode 100755 services/seap-scraper/cron/scrape-anaf-datornici.sh create mode 100755 services/seap-scraper/cron/scrape-anaf-lista-alba.sh create mode 100755 services/seap-scraper/cron/scrape-ancom.sh create mode 100755 services/seap-scraper/cron/scrape-anre.sh create mode 100755 services/seap-scraper/cron/scrape-asf.sh create mode 100755 services/seap-scraper/cron/scrape-bugetar.sh create mode 100755 services/seap-scraper/cron/scrape-cnas.sh create mode 100755 services/seap-scraper/cron/scrape-cnsc.sh create mode 100755 services/seap-scraper/cron/scrape-curteacont.sh create mode 100755 services/seap-scraper/cron/scrape-da.sh create mode 100755 services/seap-scraper/cron/scrape-gnm.sh create mode 100755 services/seap-scraper/cron/scrape-regas.sh create mode 100755 services/seap-scraper/cron/setup-photon.sh create mode 100644 services/seap-scraper/cron/vreaudigital-anaf-daily.service create mode 100644 services/seap-scraper/cron/vreaudigital-anaf-daily.timer create mode 100644 services/seap-scraper/cron/vreaudigital-mvs.service create mode 100644 services/seap-scraper/cron/vreaudigital-mvs.timer create mode 100644 services/seap-scraper/cron/vreaudigital-onrc-weekly.service create mode 100644 services/seap-scraper/cron/vreaudigital-onrc-weekly.timer create mode 100644 services/seap-scraper/cron/vreaudigital-photon.service create mode 100644 services/seap-scraper/deploy/install.md create mode 100644 services/seap-scraper/deploy/wsp-incremental.service create mode 100644 services/seap-scraper/deploy/wsp-incremental.timer create mode 100644 services/seap-scraper/docker-compose.yml create mode 100644 services/seap-scraper/import_all_2026.py create mode 100644 services/seap-scraper/import_anaf_cui.py create mode 100644 services/seap-scraper/import_datagov.py create mode 100644 services/seap-scraper/import_ted.py create mode 100644 services/seap-scraper/package-lock.json create mode 100644 services/seap-scraper/package.json create mode 100644 services/seap-scraper/requirements.txt create mode 100644 services/seap-scraper/scrapers/anaf_datornici/probe.py create mode 100644 services/seap-scraper/scrapers/anaf_datornici/scraper.py create mode 100644 services/seap-scraper/scrapers/anaf_lista_alba/scraper.py create mode 100644 services/seap-scraper/scripts/import-afir-fega-csv.py create mode 100755 services/seap-scraper/scripts/import-afir-historical.py create mode 100755 services/seap-scraper/scripts/import-apia-fermieri.py create mode 100644 services/seap-scraper/scripts/import-seap-historical.py create mode 100755 services/seap-scraper/scripts/import-seap-historical.sh create mode 100755 services/seap-scraper/scripts/import-seap-xlsx.sh create mode 100644 services/seap-scraper/scripts/test-cnas-layout-b.ts create mode 100644 services/seap-scraper/scripts/xlsx-to-csv.py create mode 100644 services/seap-scraper/sql/001_init.sql create mode 100644 services/seap-scraper/sql/002_announcements.sql create mode 100644 services/seap-scraper/sql/003_platform.sql create mode 100644 services/seap-scraper/sql/004_wsp.sql create mode 100644 services/seap-scraper/sql/005_wsp_views.sql create mode 100644 services/seap-scraper/sql/006_wsp_uat_mapping.sql create mode 100644 services/seap-scraper/sql/007_cpv_codes.sql create mode 100644 services/seap-scraper/sql/008_risk_flags.sql create mode 100644 services/seap-scraper/sql/009_uat_kpi.sql create mode 100644 services/seap-scraper/sql/010_search_index.sql create mode 100644 services/seap-scraper/sql/011_recipe_mvs.sql create mode 100644 services/seap-scraper/sql/012_firms.sql create mode 100644 services/seap-scraper/sql/013_firms_financials.sql create mode 100644 services/seap-scraper/sql/014_firms_postal_codes.sql create mode 100644 services/seap-scraper/sql/015_firms_onrc_extras.sql create mode 100644 services/seap-scraper/sql/016_firms_financials_categories.sql create mode 100644 services/seap-scraper/sql/017_fonduri_afir.sql create mode 100644 services/seap-scraper/sql/018_fonduri_beneficiar_privat.sql create mode 100644 services/seap-scraper/sql/019_cui_matcher.sql create mode 100644 services/seap-scraper/sql/020_fonduri_proiect_v2.sql create mode 100644 services/seap-scraper/sql/021_regas_ajutoare.sql create mode 100644 services/seap-scraper/sql/024_aep_donatii.sql create mode 100644 services/seap-scraper/sql/025_anaf_datornici.sql create mode 100644 services/seap-scraper/sql/026_bugetar.sql create mode 100644 services/seap-scraper/sql/027_afir_tip_fond.sql create mode 100644 services/seap-scraper/sql/028_anre.sql create mode 100644 services/seap-scraper/sql/029_ancom.sql create mode 100644 services/seap-scraper/sql/030_ani_schema.sql create mode 100644 services/seap-scraper/sql/031_cnas.sql create mode 100644 services/seap-scraper/sql/032_aaas.sql create mode 100644 services/seap-scraper/sql/033_cnsc.sql create mode 100644 services/seap-scraper/sql/034_asf.sql create mode 100644 services/seap-scraper/sql/035_curteacont.sql create mode 100644 services/seap-scraper/sql/036_apia.sql create mode 100644 services/seap-scraper/sql/037_gnm.sql create mode 100644 services/seap-scraper/sql/038_bugetar_cui_match_stage_b.sql create mode 100644 services/seap-scraper/sql/039_bugetar_uat_pattern_match.sql create mode 100644 services/seap-scraper/sql/040_curteacont_uat_pattern_match.sql create mode 100644 services/seap-scraper/sql/041_curteacont_cleaned_name_match.sql create mode 100644 services/seap-scraper/sql/042_cnsc_authority_cui_match.sql create mode 100644 services/seap-scraper/sql/043_red_flags_kpi_snapshot.sql create mode 100644 services/seap-scraper/sql/044_red_flags_previews_snapshot.sql create mode 100644 services/seap-scraper/sql/045_index_pub_date_desc_nulls_last.sql create mode 100644 services/seap-scraper/sql/046_cauta_default_facets_snapshot.sql create mode 100644 services/seap-scraper/sql/047_index_awarded_value_desc_nulls_last.sql create mode 100644 services/seap-scraper/src/cnas-layout-b.ts create mode 100644 services/seap-scraper/src/config.ts create mode 100644 services/seap-scraper/src/db.ts create mode 100644 services/seap-scraper/src/enrich-anaf.ts create mode 100644 services/seap-scraper/src/enrich.ts create mode 100644 services/seap-scraper/src/geocode-photon.ts create mode 100644 services/seap-scraper/src/index.ts create mode 100644 services/seap-scraper/src/matching/locality-matcher.ts create mode 100644 services/seap-scraper/src/scrape-aaas.ts create mode 100644 services/seap-scraper/src/scrape-aep-donatii.ts create mode 100644 services/seap-scraper/src/scrape-anaf-datornici.ts create mode 100644 services/seap-scraper/src/scrape-ancom.ts create mode 100644 services/seap-scraper/src/scrape-ani-declarations.ts create mode 100644 services/seap-scraper/src/scrape-anre.ts create mode 100644 services/seap-scraper/src/scrape-asf.ts create mode 100644 services/seap-scraper/src/scrape-beneficiar-privat.ts create mode 100644 services/seap-scraper/src/scrape-beneficiar-proiect.ts create mode 100644 services/seap-scraper/src/scrape-bugetar.ts create mode 100644 services/seap-scraper/src/scrape-cnas.ts create mode 100644 services/seap-scraper/src/scrape-cnsc.ts create mode 100644 services/seap-scraper/src/scrape-curteacont.ts create mode 100644 services/seap-scraper/src/scrape-gnm.ts create mode 100644 services/seap-scraper/src/scrape-regas.ts create mode 100644 services/seap-scraper/src/scrapers/direct-acquisitions.ts create mode 100644 services/seap-scraper/src/scrapers/entities.ts create mode 100644 services/seap-scraper/src/scrapers/public-notices.ts create mode 100644 services/seap-scraper/src/seap-client.ts create mode 100644 services/seap-scraper/src/utils/date-ranges.ts create mode 100644 services/seap-scraper/systemd/README.md create mode 100644 services/seap-scraper/systemd/vreaudigital-aaas.service create mode 100644 services/seap-scraper/systemd/vreaudigital-aaas.timer create mode 100644 services/seap-scraper/systemd/vreaudigital-aep-donatii.service create mode 100644 services/seap-scraper/systemd/vreaudigital-aep-donatii.timer create mode 100644 services/seap-scraper/systemd/vreaudigital-anaf-datornici.service create mode 100644 services/seap-scraper/systemd/vreaudigital-anaf-datornici.timer create mode 100644 services/seap-scraper/systemd/vreaudigital-anaf-lista-alba.service create mode 100644 services/seap-scraper/systemd/vreaudigital-anaf-lista-alba.timer create mode 100644 services/seap-scraper/systemd/vreaudigital-ancom.service create mode 100644 services/seap-scraper/systemd/vreaudigital-ancom.timer create mode 100644 services/seap-scraper/systemd/vreaudigital-anre.service create mode 100644 services/seap-scraper/systemd/vreaudigital-anre.timer create mode 100644 services/seap-scraper/systemd/vreaudigital-apia-fermieri.service create mode 100644 services/seap-scraper/systemd/vreaudigital-apia-fermieri.timer create mode 100644 services/seap-scraper/systemd/vreaudigital-asf.service create mode 100644 services/seap-scraper/systemd/vreaudigital-asf.timer create mode 100644 services/seap-scraper/systemd/vreaudigital-cnas.service create mode 100644 services/seap-scraper/systemd/vreaudigital-cnas.timer create mode 100644 services/seap-scraper/systemd/vreaudigital-cnsc.service create mode 100644 services/seap-scraper/systemd/vreaudigital-cnsc.timer create mode 100644 services/seap-scraper/systemd/vreaudigital-curteacont.service create mode 100644 services/seap-scraper/systemd/vreaudigital-curteacont.timer create mode 100644 services/seap-scraper/systemd/vreaudigital-da.service create mode 100644 services/seap-scraper/systemd/vreaudigital-da.timer create mode 100644 services/seap-scraper/systemd/vreaudigital-gnm.service create mode 100644 services/seap-scraper/systemd/vreaudigital-gnm.timer create mode 100644 services/seap-scraper/systemd/vreaudigital-heartbeat.service create mode 100644 services/seap-scraper/systemd/vreaudigital-heartbeat.timer create mode 100644 services/seap-scraper/systemd/vreaudigital-regas.service create mode 100644 services/seap-scraper/systemd/vreaudigital-regas.timer create mode 100644 services/seap-scraper/test_seap_demo.py create mode 100644 services/seap-scraper/tsconfig.json create mode 100644 services/seap-scraper/wsp-docker-compose.yml create mode 100644 services/seap-scraper/wsp/Dockerfile create mode 100644 services/seap-scraper/wsp/__init__.py create mode 100644 services/seap-scraper/wsp/cert_loader.py create mode 100644 services/seap-scraper/wsp/client.py create mode 100755 services/seap-scraper/wsp/cron.sh create mode 100644 services/seap-scraper/wsp/db.py create mode 100644 services/seap-scraper/wsp/load_cpv.py create mode 100644 services/seap-scraper/wsp/operations.py create mode 100644 services/seap-scraper/wsp/pagination.py create mode 100644 services/seap-scraper/wsp/parsers/__init__.py create mode 100644 services/seap-scraper/wsp/parsers/_base.py create mode 100644 services/seap-scraper/wsp/parsers/c_notice.py create mode 100644 services/seap-scraper/wsp/parsers/ca_notice.py create mode 100644 services/seap-scraper/wsp/parsers/catalog.py create mode 100644 services/seap-scraper/wsp/parsers/dc_notice.py create mode 100644 services/seap-scraper/wsp/parsers/e_notice.py create mode 100644 services/seap-scraper/wsp/parsers/ea_procedure.py create mode 100644 services/seap-scraper/wsp/parsers/pc_notice.py create mode 100644 services/seap-scraper/wsp/parsers/pi_notice.py create mode 100644 services/seap-scraper/wsp/parsers/rdc_notice.py create mode 100644 services/seap-scraper/wsp/parsers/rfq_invitation.py create mode 100644 services/seap-scraper/wsp/parsers/rfq_notice.py create mode 100644 services/seap-scraper/wsp/parsers/su_contract.py create mode 100644 services/seap-scraper/wsp/parsers/su_da.py create mode 100644 services/seap-scraper/wsp/parsers/su_invoice.py create mode 100644 services/seap-scraper/wsp/runner.py create mode 100644 services/seap-scraper/wsp/sync.py create mode 100644 services/seap-scraper/wsp/xml_utils.py create mode 100644 services/seap-scraper/wsp_validate.py create mode 100644 services/seap-scraper/wsp_validate2.py create mode 100644 services/seed-ideas.sql create mode 100644 src/components/Footer.astro create mode 100644 src/components/VersionWatcher.tsx create mode 100644 src/components/cauta/CpvAutocomplete.tsx create mode 100644 src/components/cauta/SearchMap.tsx create mode 100644 src/components/harta/ActivityStream.tsx create mode 100644 src/components/harta/CommandPalette.tsx create mode 100644 src/components/harta/FilterChips.tsx create mode 100644 src/components/harta/FlowLayer.tsx create mode 100644 src/components/harta/HartaApp.tsx create mode 100644 src/components/harta/MapView.tsx create mode 100644 src/components/harta/MetricSwitcher.tsx create mode 100644 src/components/harta/PulseLayer.tsx create mode 100644 src/components/harta/Sparkline.tsx create mode 100644 src/components/harta/StatCard.tsx create mode 100644 src/components/harta/StatColumn.tsx create mode 100644 src/components/harta/TimelineScrubber.tsx create mode 100644 src/components/harta/county-centroids.ts create mode 100644 src/components/harta/harta.css create mode 100644 src/components/harta/types.ts create mode 100644 src/components/harta/utils.ts create mode 100644 src/components/profile/CalendarHeatmap.tsx create mode 100644 src/components/profile/CountyBars.tsx create mode 100644 src/components/profile/FinancialTimeline.tsx create mode 100644 src/components/profile/NetworkGraph.tsx create mode 100644 src/components/profile/profile.css create mode 100644 src/components/viz/BarRace.tsx create mode 100644 src/components/viz/Sankey.tsx create mode 100644 src/components/viz/Treemap.tsx create mode 100644 src/content.config.ts create mode 100644 src/env.d.ts create mode 100644 src/layouts/AchizitiiLayout.astro create mode 100644 src/layouts/BaseLayout.astro create mode 100644 src/lib/announcement-queries.ts create mode 100644 src/lib/auth-queries.ts create mode 100644 src/lib/beneficiar-privat-queries.ts create mode 100644 src/lib/category-queries.ts create mode 100644 src/lib/county-queries.ts create mode 100644 src/lib/dashboard-queries.ts create mode 100644 src/lib/db.ts create mode 100644 src/lib/investigations.ts create mode 100644 src/lib/ocds-mapper.ts create mode 100644 src/lib/og-image.ts create mode 100644 src/lib/platform-queries.ts create mode 100644 src/lib/profile-queries-financial.ts create mode 100644 src/lib/profile-queries-utilities.ts create mode 100644 src/lib/profile-queries.ts create mode 100644 src/lib/public-url.ts create mode 100644 src/lib/recipes.ts create mode 100644 src/lib/risk-queries.ts create mode 100644 src/lib/seap-queries.ts create mode 100644 src/lib/search-queries.ts create mode 100644 src/lib/supabase.ts create mode 100644 src/lib/viz-queries.ts create mode 100644 src/pages/anunt/[id].astro create mode 100644 src/pages/api/auth/[...route].ts create mode 100644 src/pages/api/cpv/search.ts create mode 100644 src/pages/api/harta/[...route].ts create mode 100644 src/pages/api/ocds/bulk/index.ts create mode 100644 src/pages/api/ocds/bulk/year/[year].ts create mode 100644 src/pages/api/ocds/index.ts create mode 100644 src/pages/api/ocds/parties/[id].ts create mode 100644 src/pages/api/ocds/release/[id].ts create mode 100644 src/pages/api/ocds/releases.ts create mode 100644 src/pages/api/og/autoritate/[cui].png.ts create mode 100644 src/pages/api/og/firma/[cui].png.ts create mode 100644 src/pages/api/og/recipe/[slug].png.ts create mode 100644 src/pages/api/platform/[...route].ts create mode 100644 src/pages/api/profil/[side]/[cui].ts create mode 100644 src/pages/api/traducator.ts create mode 100644 src/pages/api/version.ts create mode 100644 src/pages/autoritate/[cui].astro create mode 100644 src/pages/azi.astro create mode 100644 src/pages/beneficiar-privat/[id].astro create mode 100644 src/pages/categoria/[cpv].astro create mode 100644 src/pages/cauta.astro create mode 100644 src/pages/explorer.astro create mode 100644 src/pages/firma/[cui].astro create mode 100644 src/pages/fonduri-ue.astro create mode 100644 src/pages/fonduri-ue/anunturi.astro create mode 100644 src/pages/harta.astro create mode 100644 src/pages/index.astro create mode 100644 src/pages/investigation/[slug].astro create mode 100644 src/pages/investigation/index.astro create mode 100644 src/pages/judet/[county].astro create mode 100644 src/pages/proiect/[id].astro create mode 100644 src/pages/red-flags.astro create mode 100644 src/pages/retea/[cui].astro create mode 100644 src/pages/retete/[slug].astro create mode 100644 src/pages/retete/index.astro create mode 100644 src/pages/risc/concentrare.astro create mode 100644 src/pages/risc/economii-suspect.astro create mode 100644 src/pages/risc/index.astro create mode 100644 src/pages/risc/overprice.astro create mode 100644 src/pages/risc/single-bidder.astro create mode 100644 src/pages/risc/termen-scurt.astro create mode 100644 src/pages/top-contracte.astro create mode 100644 src/pages/top-firme.astro create mode 100644 src/styles/achizitii.css create mode 100644 src/styles/global.css create mode 100644 tailwind.config.mjs create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..38b174e --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +# Astro +dist/ +.astro/ + +# Node +node_modules/ +npm-debug.log* + +# Environment +.env +.env.* +!.env.example + +# Infisical Machine Identity creds (deploy-host only, NEVER commit) +.infisical-mi + +# OS +.DS_Store +Thumbs.db + +# IDE +.vscode/ +.idea/ +*.swp +*.swo + +# Cloudflare +.wrangler/ +services/seap-scraper/data/ + +# Claude Code runtime state (session-local) +.claude/ + +# Heavy raw data — recreated from sources +services/seap-scraper/data/ +services/seap-scraper/scrapers/cnsc/raw/ +services/seap-scraper/.log/ +*.zip +*.xlsx diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..8525b91 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,35 @@ +# vreau.digital — Platformă de transparență achiziții publice + +## Context + +Spin-off din `gov-agreg` (vreaudigital.ro). Acest repo conține platforma standalone de transparență achiziții publice România. + +- **Domain**: https://vreau.digital +- **Hub marketing**: https://vreaudigital.ro (rămâne gov-agreg) +- **Backend partajat**: PostgreSQL satra, Photon, Martin (același cluster ca gov-agreg) + +## Stack + +- Astro 5 + React 19 + Tailwind 3 + Node @astrojs/node standalone +- PostgreSQL @ satra:5432 (schemas: seap, firms, anaf, anre, ancom, asf, aaas, aep, cnsc, curteacont, bugetar, regas, fonduri, cnas, apia, gnm, public_kpi) +- MapLibre 5 + Martin tile server @ 10.10.10.166:3010 +- Docker container @ satra:5096 → Traefik @ proxy 10.10.10.199 → vreau.digital (Cloudflare proxied) + +## Routes (toate la rădăcină, nu /achizitii/) + +- `/` — landing page +- `/cauta` — search SEAP +- `/retete/[slug]` — investigative recipes (49+) +- `/investigation/[slug]` — narrative leads (15+) +- `/firma/[cui]`, `/autoritate/[cui]` — profile pages +- `/red-flags` — cross-source signals +- `/top-contracte`, `/top-firme`, `/fonduri-ue` — leaderboards +- `/api/*` — endpoints (og, cpv, profil, etc.) + +## Reguli operaționale + +- Backend secrets în Infisical, path `/vreaudigital` (shared cu gov-agreg deocamdată — DATABASE_URL e identic) +- TWOCAPTCHA_KEY pentru ANAF datornici/lista_alba scrapers +- `npx astro check` + `npm run build` ÎNAINTE de commit +- Push triggers webhook → satra:9867 → /opt/vreau-digital/deploy.sh +- Verify deploy via `/api/version` diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3b94ba5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,51 @@ +# ──────── Stage 1: build ──────── +FROM node:22-alpine AS build +WORKDIR /app + +COPY package.json package-lock.json ./ +RUN npm ci + +COPY . . + +ARG BUILD_SHA=dev +ARG BUILD_REF=local +ARG BUILD_TIME +ENV PUBLIC_BUILD_SHA=$BUILD_SHA +ENV PUBLIC_BUILD_REF=$BUILD_REF +ENV PUBLIC_BUILD_TIME=$BUILD_TIME + +RUN npm run build + +# ──────── Stage 2: runtime ──────── +FROM node:22-alpine +WORKDIR /app + +# Infisical CLI — pinned binary (release tarball, deterministic). +# Bump INFISICAL_CLI_VERSION when upgrading. +ARG INFISICAL_CLI_VERSION=0.43.81 +RUN apk add --no-cache bash curl ca-certificates && \ + ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') && \ + curl -fsSL "https://github.com/Infisical/cli/releases/download/v${INFISICAL_CLI_VERSION}/cli_${INFISICAL_CLI_VERSION}_linux_${ARCH}.tar.gz" \ + | tar -xz -C /usr/local/bin infisical && \ + chmod +x /usr/local/bin/infisical && \ + infisical --version && \ + rm -rf /var/cache/apk/* + +COPY --from=build /app/dist ./dist +COPY --from=build /app/node_modules ./node_modules +COPY package.json ./ +COPY docker/entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +ARG BUILD_SHA=dev +ARG BUILD_REF=local +ARG BUILD_TIME +ENV PUBLIC_BUILD_SHA=$BUILD_SHA +ENV PUBLIC_BUILD_REF=$BUILD_REF +ENV PUBLIC_BUILD_TIME=$BUILD_TIME + +ENV HOST=0.0.0.0 +ENV PORT=4321 +EXPOSE 4321 + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/MISSION.md b/MISSION.md new file mode 100644 index 0000000..0bea5b5 --- /dev/null +++ b/MISSION.md @@ -0,0 +1,3 @@ +# Mission + +imi place mvp-ul, da-mi pe moment planul pe mai departe in etape clare diff --git a/PLAN-DESIGN.md b/PLAN-DESIGN.md new file mode 100644 index 0000000..cc05b91 --- /dev/null +++ b/PLAN-DESIGN.md @@ -0,0 +1,1262 @@ +# PLAN-DESIGN.md — Brand & Design Direction: vreaudigital.ro + +**Data:** 7 aprilie 2026 +**Autor:** Marius + Claude +**Status:** Direcție de design — ghid pentru implementare + +--- + +## 0. Filosofia de design + +**Teza centrală:** vreaudigital.ro trebuie să fie el însuși dovada că digitalizarea poate fi frumoasă. Dacă portalul arată ca un site guvernamental din 2012, am pierdut înainte să începem. + +**Trei principii non-negociabile:** + +1. **Inspiră înainte de a informa** — primul lucru pe care îl simte vizitatorul e emoție, nu date +2. **Încredere prin eleganță** — nu prin sigle oficiale și PDF-uri. Încrederea vine din calitatea execuției. +3. **Simplu dar nu gol** — fiecare pixel servește un scop. Fără decorații inutile, dar nici interfețe sterile. + +**Anti-pattern-uri de evitat:** +- Albastru instituțional plictisitor (gen ghiseu.ro, anaf.ro) +- Fonturi mici pe fundal alb cu zero personalitate +- Butoane generice Bootstrap fără identitate +- Banner-e cu steagul României sau sigla guvernului +- Stock photos cu oameni care zâmbesc la laptop + +--- + +## 1. Identitate vizuală + +### 1.1 Paletă de culori + +Paleta e construită pe principiul **„viitor, nu birocratic"** — un albastru profund care inspiră încredere dar nu e plictisitor, combinat cu un portocaliu cald care dă energie și umanitate, plus accente de verde care sugerează progres și validare. + +#### Culori primare + +| Rol | Nume | Hex | Tailwind | Notă | +|-----|------|-----|----------|------| +| **Primary** — Albastru profund | `indigo-deep` | `#1E3A5F` | `primary-900` | Încredere, seriozitate, profunzime. NU e albastrul de guvern (#003399), e mai cald, mai viu. | +| **Primary light** | `indigo-bright` | `#2563EB` | `primary-600` | Pentru butoane, link-uri, elemente interactive. Echivalent Tailwind `blue-600`. | +| **Primary pale** | `indigo-wash` | `#EFF6FF` | `primary-50` | Fundal secțiuni, card backgrounds. | + +#### Culori secundare + +| Rol | Nume | Hex | Tailwind | Notă | +|-----|------|-----|----------|------| +| **Secondary** — Portocaliu cald | `amber-warm` | `#F59E0B` | `secondary-500` | Energie, umanitate, „atenție aici". Echivalent Tailwind `amber-500`. | +| **Secondary dark** | `amber-deep` | `#D97706` | `secondary-600` | Hover states, text pe fundal deschis. | +| **Secondary pale** | `amber-wash` | `#FFFBEB` | `secondary-50` | Fundal de highlight, callout-uri. | + +#### Culori de accent + +| Rol | Nume | Hex | Tailwind | Notă | +|-----|------|-----|----------|------| +| **Success / Verificat** | `emerald` | `#10B981` | `accent-green` | Badge „verificat", status pozitiv. Echivalent `emerald-500`. | +| **Neutral dark** | `slate-900` | `#0F172A` | `neutral-900` | Text principal, heading-uri. | +| **Neutral body** | `slate-600` | `#475569` | `neutral-600` | Text body, descrieri. | +| **Neutral muted** | `slate-400` | `#94A3B8` | `neutral-400` | Placeholder, metadata, text secundar. | +| **Neutral border** | `slate-200` | `#E2E8F0` | `neutral-200` | Borduri carduri, separatoare. | +| **Background** | `white-warm` | `#FAFBFC` | `bg-page` | Fundal pagină — nu alb pur (#FFF) ci un off-white cald. | + +#### Gradient-uri + +```css +/* Hero gradient — de la profund la luminos */ +--gradient-hero: linear-gradient(135deg, #1E3A5F 0%, #2563EB 50%, #3B82F6 100%); + +/* Card hover — glow subtle */ +--gradient-card-glow: radial-gradient(ellipse at top, rgba(37, 99, 235, 0.08) 0%, transparent 70%); + +/* Accent warm — pentru CTA-uri speciale */ +--gradient-warm: linear-gradient(135deg, #F59E0B 0%, #F97316 100%); + +/* Mesh gradient — pentru hero background (implementat cu CSS sau SVG) */ +--gradient-mesh: conic-gradient(from 45deg at 30% 70%, #1E3A5F, #2563EB, #3B82F6, #1E3A5F); +``` + +#### De ce exact aceste culori + +- **Albastrul #1E3A5F** — e albastrul de noapte adâncă, nu de formular de stat. Comunică seriozitate fără a fi plictisitor. E aproape de culorile folosite de Linear, Vercel, și alte branduri tech de top. +- **Portocaliul #F59E0B** — este complementar albstrului, creează tensiune vizuală plăcută. E culoarea „acțiunii" — butoane, CTA-uri, elemente care cer atenție. Amber, nu orange — mai cald, mai uman. +- **Off-white #FAFBFC** — albul pur (#FFFFFF) e agresiv pe ecran. Acest off-white e subtil mai cald, reduce oboseala vizuală. Tehnica e folosită de Notion, Linear, și alte aplicații premium. + +#### Tricolorul — subtil, nu kitsch + +NU punem tricolorul ca banner. Dar putem face referințe subtile: +- Un accent line de 3px (albastru `#2563EB` → galben `#F59E0B` → roșu `#EF4444`) folosit ca separator decorativ între secțiuni majore +- Doar pe pagina „Despre" sau footer — nicăieri altundeva +- Regula: dacă arată ca un site de partid politic, am greșit + +--- + +### 1.2 Tipografie + +#### Font-uri alese + +| Rol | Font | Backup | De ce | +|-----|------|--------|-------| +| **Heading-uri** | **Plus Jakarta Sans** (Bold, ExtraBold) | `system-ui, -apple-system, sans-serif` | Geometric dar cu personalitate. Mai distinctiv decât Inter, mai cald decât Geist. Terminalele ușor rotunjite dau un feeling prietenos fără să fie copilăros. Perfect pentru heading-uri care trebuie să inspire. | +| **Body text** | **Inter** (Regular, Medium) | `system-ui, -apple-system, sans-serif` | Standardul industriei pentru text de corp. Optimizat pentru ecran, lizibil la orice dimensiune. Nimeni n-a pierdut un proiect din cauza că a ales Inter pentru body. | +| **Monospace** (cod, badge-uri tehnice) | **JetBrains Mono** (Regular) | `ui-monospace, monospace` | Pentru fragmentele de cod, metadate tehnice, badge-uri de status. Open source, excelent pe ecran. | + +#### Scară tipografică + +Bazată pe `clamp()` pentru responsive fluid typography: + +```css +/* Display — hero, titluri de pagină */ +--text-display: clamp(2.25rem, 5vw, 3.75rem); /* 36px → 60px */ +font-weight: 800; /* Plus Jakarta Sans ExtraBold */ +letter-spacing: -0.025em; +line-height: 1.1; + +/* H1 — titluri de secțiune */ +--text-h1: clamp(1.875rem, 4vw, 3rem); /* 30px → 48px */ +font-weight: 700; +letter-spacing: -0.02em; +line-height: 1.15; + +/* H2 — subtitluri */ +--text-h2: clamp(1.5rem, 3vw, 2.25rem); /* 24px → 36px */ +font-weight: 700; +letter-spacing: -0.015em; +line-height: 1.2; + +/* H3 — card titles, section headers */ +--text-h3: clamp(1.25rem, 2.5vw, 1.5rem); /* 20px → 24px */ +font-weight: 600; +line-height: 1.3; + +/* Body large — intro text, lead paragraphs */ +--text-body-lg: clamp(1.125rem, 1.5vw, 1.25rem); /* 18px → 20px */ +font-weight: 400; +line-height: 1.7; + +/* Body — text normal */ +--text-body: 1rem; /* 16px */ +font-weight: 400; +line-height: 1.7; + +/* Small — metadate, captions */ +--text-small: 0.875rem; /* 14px */ +font-weight: 400; +line-height: 1.5; + +/* Tiny — badge text, labels */ +--text-tiny: 0.75rem; /* 12px */ +font-weight: 500; +letter-spacing: 0.025em; +text-transform: uppercase; +``` + +#### Reguli tipografice + +- **Heading-uri: max 60-70 caractere per linie** — evită heading-uri care se întind pe tot ecranul +- **Body: max 65-75 caractere per linie** (`max-w-prose` în Tailwind = 65ch) — regula de aur a lizibilității +- **Letter-spacing negativ pe heading-uri** (-0.02em) — dă un feeling premium, tehnic, modern +- **Line-height generos pe body** (1.7) — textul trebuie să respire, nu să fie înghesui +- **Nu folosim UPPERCASE pe texte lungi** — doar pe badge-uri, label-uri mici, categorii + +--- + +### 1.3 Direcție logo + +Trei concepte, de la simplu la elaborat. Toate trebuie să funcționeze la 32px (favicon) și la 200px (hero). + +#### Concept A: „Ușa digitală" (recomandat) + +``` +Descriere: +O formă geometrică minimală care combină litera „V" (de la „Vreau") cu o ușă/portal +deschisă. Ideea: intri printr-o ușă digitală spre un viitor mai bun. + +Formă: Un dreptunghi vertical (ușa) cu colțul din dreapta-sus tăiat diagonal, +formând implicit un „V". Interior: un gradient de la #1E3A5F la #2563EB. +Exteriorul dreptunghiului e solid, interiorul sugerează profunzime prin gradient. + +Variante: +- Full color: gradient albastru pe fundal deschis +- Monocrom: alb pe fundal întunecat +- Favicon: forma simplificată la un pătrat cu V-ul tăiat + +De ce funcționează: +- „Ușa" = acces, deschidere, transparență +- „V" = Vreau (din vreaudigital) +- Geometric = modern, tech, profesionist +- Simplu = scalabil, memorabil, funcționează mic +``` + +#### Concept B: „Rețeaua cetățenilor" + +``` +Descriere: +Un grid de 3×3 puncte conectate prin linii subțiri, formând o rețea/constelan. +Câteva dintre puncte sunt mai mari și colorate (#F59E0B amber), restul sunt +albastre (#2563EB). Sugerează: oameni conectați, date care circulă, o rețea +care crește. + +Variante: +- Animat (pe web): punctele pulsează subtil, liniile se desenează +- Static: snapshot al rețelei +- Favicon: 4 puncte conectate (versiune simplificată 2x2) + +De ce funcționează: +- Rețea = comunitate, conectare, date +- Punctele colorate = oameni, produse, soluții +- Organic dar geometric = tech dar uman +- Ușor de animat pe web + +Risc: poate arăta prea generic dacă nu e executat bine. +``` + +#### Concept C: „Steagul digital" + +``` +Descriere: +Trei linii orizontale paralele (subtil tricolor: albastru, galben, roșu) care +se transformă progresiv din linii ondulate (hârtie, birocratic, vechi) în +linii drepte pixelate/digitale. Tranziția de la analog la digital. + +Este mai mult un motif/signet decât un logo clasic. Poate fi folosit ca +element decorativ pe site, nu neapărat ca logo principal. + +Variante: +- Header element: liniile se animează la hover +- Print: versiune statică +- Favicon: trei linii drepte colorate + +De ce funcționează: +- Tricolor = România, fără a fi kitsch (e abstractizat) +- Tranziția = „de la vechi la digital" (exact mesajul nostru) +- Poate funcționa ca pattern/textură pe tot site-ul + +Risc: greu de scalat la favicon, poate fi confuz la dimensiuni mici. +``` + +#### Recomandare: Concept A cu elemente din B + +Logo-ul principal: „Ușa digitală" (A) — simplu, scalabil, memorabil. Pe site, folosim rețeaua de puncte (B) ca element decorativ de fundal în hero section. + +#### Wordmark + +``` +vreaudigital +``` + +- Font: Plus Jakarta Sans, ExtraBold (800) +- `vreau` — culoare `#0F172A` (slate-900) +- `digital` — culoare `#2563EB` (primary-600) +- Letter-spacing: -0.03em (tight, modern) +- Fără `.ro` în logo — apare doar în context de domeniu + +--- + +### 1.4 Stil iconuri + +**Alegere: Lucide Icons — outlined, 1.5px stroke, rounded caps** + +De ce Lucide (nu Heroicons, nu Phosphor): +- Open source, 1500+ iconuri, comunitate activă +- Stroke width consistent (1.5px default) — perfect pentru tonul nostru +- Rounded line caps = prietenos fără a fi copilăros +- Se integrează nativ cu React/Svelte (pachet `lucide-react` / `lucide-svelte`) +- Stilistic aproape de ce folosesc Linear, Vercel, Cal.com + +**Reguli de utilizare:** +- Dimensiune standard pe site: `24px` (w-6 h-6 în Tailwind) +- Dimensiune în carduri/liste: `20px` (w-5 h-5) +- Dimensiune hero/categorii: `32px` sau `40px` (w-8/w-10) +- Culoare default: `slate-600` (#475569) +- Culoare hover/activă: `primary-600` (#2563EB) +- Iconuri de categorie: pot avea fundal colorat rotund (cercuri de 48px cu icon de 24px centrat) +- **NU folosim emoji ca iconuri** — emoji-urile din wireframe-uri se înlocuiesc cu Lucide icons + +**Iconuri per categorie (mapping):** + +| Categorie | Icon Lucide | Cod | +|-----------|-------------|-----| +| Transparență și date deschise | `BarChart3` | `` | +| Comunicare cetățean-primărie | `MessageCircle` | `` | +| Cereri fără coadă | `FileCheck` | `` | +| Educație civică | `GraduationCap` | `` | +| AI pentru servicii publice | `Sparkles` | `` | + +--- + +## 2. Inspirație de design — site-uri de referință + +### 2.1 Linear.app — „The gold standard" + +**Ce împrumutăm:** +- Hero section cu text mare, bold, pe fundal întunecat cu gradient mesh subtil +- Tipografie excelentă — heading-uri tight, body spacious +- Card-uri cu borduri subtile și hover glow +- Animații de scroll — elementele apar cu fade-in/slide-up +- Calitatea generală a execuției — fiecare pixel e intenționat + +**Ce NU împrumutăm:** +- Dark mode ca default (noi suntem light-first — audiența noastră e cetățeni, nu developeri) +- Complexitatea interacțiunilor (avem buget zero pentru motion design avansat) + +### 2.2 e-Estonia.com — „GovTech care inspiră" + +**Ce împrumutăm:** +- Tonul: „Am construit o societate digitală și vă arătăm cum" — exact energia pe care o vrem +- Navigația simplă: câteva categorii clare, nu mega-menu-uri +- Hero cu mesaj emoțional puternic + CTA clar +- Storytelling prin cifre și rezultate concrete + +**Ce NU împrumutăm:** +- Designul propriu-zis e decent dar nu spectaculos — noi vrem mai bine +- Prea mult text pe unele pagini + +### 2.3 Astro.build — „Open source frumos" + +**Ce împrumutăm:** +- Demonstrează că un proiect open source poate avea un site de nivel comercial +- Gradient-urile subtile pe fundal +- Documentația integrată natural în design +- „Showcase" section — exact ce vrem pentru produsele noastre +- Performance: site-ul se încarcă instant (și al nostru trebuie) + +**Ce NU împrumutăm:** +- Tonul e pentru developeri — noi avem audiență duală +- Puțin prea mult purple (paleta noastră e diferită) + +### 2.4 Product Hunt — „Descoperire de produse" + +**Ce împrumutăm:** +- Pattern-ul de card cu: thumbnail/screenshot, titlu, descriere scurtă, badge categorie, social proof +- „Upvote" ca mecanism de engagement (la noi poate fi „Vreau asta!" sau „Susțin") +- Categorii navigabile orizontal (pills/tabs) +- Paginile de produs cu structură clară: hero, descriere, gallery, discuție +- Tonul prietenos dar profesionist + +**Ce NU împrumutăm:** +- Densitatea informațională — PH e pentru power users, noi trebuie să fim accesibili +- Leaderboard/ranking — nu vrem competiție, vrem expunere egală +- Orangiul lor (#DA552F) — prea agresiv pentru civic tech + +### 2.5 GOV.UK Design System — „Accesibilitate și claritate" + +**Ce împrumutăm:** +- Principiul „Start with user needs" — fiecare element de design servește utilizatorul +- Claritatea tipografică — text lizibil, ierarhie clară, spațiu generos +- Accesibilitate WCAG 2.1 AA ca minimum — contrast ratios, focus states, screen reader support +- Pattern-uri de formular testate intensiv cu utilizatori reali +- „Do less" — dacă un element nu ajută utilizatorul, nu există + +**Ce NU împrumutăm:** +- Estetica austeră, funcțională — GOV.UK e deliberat „boring" ca să fie accesibil. Noi vrem și accesibilitate ȘI wow factor. +- Paleta de culori (negru, alb, albastru guvernamental) + +### 2.6 Cal.com — „Open source cu atitudine" + +**Ce împrumutăm:** +- Un proiect open source care arată ca un produs SaaS de top +- Monochrome + accent color approach +- Secțiunile „feature" cu ilustrații/screenshots intercalate stânga-dreapta +- Footer generos cu link-uri utile și personalitate + +### 2.7 Vercel.com / Next.js — „Premium tech branding" + +**Ce împrumutăm:** +- Gradientele mesh pe hero — spectaculoase dar subtile +- Tipografia cu letter-spacing negativ pe heading-uri +- Secțiunile care alternează fundal deschis/întunecat +- „Ship" mentality — totul comunică viteză și progres +- Folosirea generosă a spațiului alb + +### 2.8 Tailwind CSS site — „Developer experience tradusă vizual" + +**Ce împrumutăm:** +- Color palette showcase — cum prezintă culorile inline e inspirațional +- Code examples live — „arată, nu descrie" +- Documentație care e plăcută de citit (nu doar utilă) +- Responsive design impecabil + +### 2.9 Civic Tech Field Guide (civictech.guide) — „Catalogul civic tech" + +**Ce împrumutăm:** +- Structura de catalog cu filtre și categorii +- Abordarea „field guide" — ghid, nu doar listă +- Tag-uri de clasificare pe multiple axe + +**Ce NU împrumutăm:** +- Designul e funcțional dar nu inspiră — arată ca un director, nu ca un manifest + +### 2.10 Signal.org — „Încredere prin simplitate" + +**Ce împrumutăm:** +- Demonstrează că trust se construiește prin absența manipulării, nu prin sigle oficiale +- Zero dark patterns, zero upsells, zero engagement tricks +- Design care spune „suntem aici pentru tine, nu pentru noi" +- Transparență radicală ca principiu de design + +--- + +## 3. Direcție UI/UX + +### 3.1 Pagina principală (Home) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ [Logo + vreaudigital] [Produse] [Despre]│ +│ │ +│ ╔═════════════════════════════════════════════════════════╗ │ +│ ║ HERO — fundal gradient mesh (#1E3A5F → #2563EB) ║ │ +│ ║ ║ │ +│ ║ România merită o ║ │ +│ ║ digitalizare reală. ║ │ +│ ║ ║ │ +│ ║ [text-display, Plus Jakarta Sans ExtraBold, alb] ║ │ +│ ║ ║ │ +│ ║ Nu formulare PDF. Nu site-uri din 2005. ║ │ +│ ║ Ci servicii publice care chiar funcționează. ║ │ +│ ║ [text-body-lg, Inter Regular, alb 80% opacity] ║ │ +│ ║ ║ │ +│ ║ [Vezi produsele →] [Listează-ți produsul] ║ │ +│ ║ ↑ primary btn ↑ ghost/outline btn ║ │ +│ ║ ║ │ +│ ║ ── stat counters ── ║ │ +│ ║ 12 produse · 3 demo-uri live · 100% open source ║ │ +│ ╚═════════════════════════════════════════════════════════╝ │ +│ │ +│ ── „Cum ar fi dacă..." section ── │ +│ [fundal alb/off-white] │ +│ │ +│ Three columns, fiecare cu: │ +│ ┌─────────────────┐ │ +│ │ [Icon: Clock] │ ← Lucide icon, 32px, primary-600 │ +│ │ │ │ +│ │ Cum ar fi să nu │ ← H3, Plus Jakarta Sans Bold │ +│ │ mai stai 3 ore │ │ +│ │ la coadă? │ │ +│ │ │ │ +│ │ Cereri online │ ← body, Inter, slate-600 │ +│ │ care chiar │ │ +│ │ funcționează. │ │ +│ └─────────────────┘ │ +│ │ +│ ── Featured Products (grid 2 sau 3 coloane) ── │ +│ [fundal primary-50 (#EFF6FF)] │ +│ │ +│ Titlu secțiune: „Produse care schimbă cum │ +│ interacționezi cu statul" │ +│ │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │ [Screenshot] │ │ [Screenshot] │ │ [Screenshot] │ │ +│ │ │ │ │ │ │ │ +│ │ Traducătorul │ │ Harta │ │ BugetulMeu │ │ +│ │ Birocratic │ │ Digitalizări │ │ │ │ +│ │ │ │ │ │ │ │ +│ │ #AI #NLP │ │ #Transparență│ │ #Date │ │ +│ │ │ │ │ │ │ │ +│ │ ✅ Demo live │ │ 📊 Preview │ │ 📊 Preview │ │ +│ │ De: Marius T.│ │ De: Echipa │ │ De: Andrei P.│ │ +│ └──────────────┘ └──────────────┘ └──────────────┘ │ +│ │ +│ [Vezi toate produsele →] │ +│ │ +│ ── Before / After section ── │ +│ [fundal alb] │ +│ │ +│ Vizual split-screen: │ +│ STÂNGA (gri, faded): screenshot ghiseu.ro / PDF tipizat │ +│ DREAPTA (color, viu): screenshot produs modern de pe portal│ +│ Text: „Acum vs Cum ar putea fi" │ +│ │ +│ ── CTA final ── │ +│ [fundal gradient amber-warm → amber-deep] │ +│ │ +│ „Ești programator? Ai construit ceva care ajută │ +│ cetățenii? Arată-l lumii." │ +│ [Listează-ți produsul →] │ +│ │ +│ ── Footer ── │ +│ [fundal slate-900 (#0F172A)] │ +│ Logo + „Un proiect open source pentru România" │ +│ Link-uri: GitHub · Despre · Contact · Newsletter │ +│ Tricolor accent line subtilă (3px) deasupra footer-ului │ +└─────────────────────────────────────────────────────────────┘ +``` + +**Principii de layout — Home:** + +- **Hero height:** min 80vh pe desktop, min 70vh pe mobile — impact maxim +- **Secțiunile alternează fundal:** alb → primary-50 → alb → gradient → dark footer +- **Max content width:** `max-w-7xl` (1280px) cu `px-4 sm:px-6 lg:px-8` +- **Spacing vertical între secțiuni:** `py-20 lg:py-32` — generos, lasă conținutul să respire +- **Grid produse:** `grid-cols-1 md:grid-cols-2 lg:grid-cols-3` cu `gap-6 lg:gap-8` + +--- + +### 3.2 Pagina de listing produse (Catalog) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ [Nav] │ +│ │ +│ Produse care digitalizează România │ +│ [H1, Plus Jakarta Sans Bold] │ +│ │ +│ ── Category pills (scroll horizontal pe mobile) ── │ +│ │ +│ [Toate] [Transparență] [Comunicare] [Cereri] │ +│ [Educație] [AI] │ +│ ↑ pills cu fundal, icon + text, hover state │ +│ │ +│ ── Sort / Filter bar ── │ +│ Sortează: [Cele mai noi ▾] [Cu demo ▾] │ +│ │ +│ ── Product grid ── │ +│ │ +│ Grid de carduri (identice cu cele de pe home, dar │ +│ pe full width — 3 coloane desktop, 2 tablet, 1 mobil) │ +│ │ +│ Fiecare card: │ +│ ┌────────────────────────────┐ │ +│ │ ┌────────────────────────┐ │ ← screenshot, aspect 16:9 │ +│ │ │ [Screenshot/Video] │ │ rounded-t-xl │ +│ │ └────────────────────────┘ │ obiect-cover │ +│ │ │ │ +│ │ [Badge: Demo live] ←──────── badge verde mic, absolut │ +│ │ │ pozitionat pe screenshot │ +│ │ Traducătorul Birocratic │ ← H3, font-semibold │ +│ │ │ │ +│ │ Lipești textul oficial, │ ← body, text-sm, slate-600 │ +│ │ primești explicația pe │ line-clamp-2 │ +│ │ înțelesul tău. │ │ +│ │ │ │ +│ │ ┌──────┐ ┌────┐ ┌─────┐ │ ← category pills │ +│ │ │ #AI │ │#NLP│ │ MIT │ │ text-xs, rounded-full │ +│ │ └──────┘ └────┘ └─────┘ │ bg-primary-50 │ +│ │ │ │ +│ │ ───────────────────────── │ ← separator line │ +│ │ 👤 Marius T. · Cluj │ ← author + location │ +│ │ │ text-sm, slate-400 │ +│ └────────────────────────────┘ │ +│ │ +│ [Mai multe produse ↓] sau infinite scroll │ +│ │ +│ ── CTA section pentru developeri ── │ +│ „Nu vezi ce cauți? Poate tu ești cel care o poate face." │ +│ [Listează un produs →] [Vezi provocările →] │ +└─────────────────────────────────────────────────────────────┘ +``` + +**Principii de layout — Catalog:** + +- **Card hover:** `hover:shadow-lg hover:-translate-y-1 transition-all duration-200` — card-ul se ridică subtil +- **Card border:** `border border-slate-200 rounded-xl` — borduri subtile, colțuri rotunjite +- **Screenshot:** `aspect-video object-cover` — forțăm 16:9, imaginea se crop-ează +- **Category pills:** `inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-medium bg-primary-50 text-primary-700` +- **Empty state:** Dacă o categorie nu are produse: ilustrație simplă + „Fii primul care listează un produs aici" +- **Scroll behavior:** Prefer pagination simplă (nu infinite scroll) — mai previzibil, mai bun pentru SEO + +--- + +### 3.3 Pagina de produs (Product Detail) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ [Nav] │ +│ │ +│ ← Înapoi la AI pentru servicii publice │ +│ [breadcrumb, text-sm, slate-400, hover:primary] │ +│ │ +│ ┌────────────────────────────────────────────────────┐ │ +│ │ LAYOUT: 2 coloane pe desktop (8/4 split) │ │ +│ │ │ │ +│ │ COL STÂNGA (8/12): │ │ +│ │ │ │ +│ │ Traducătorul Birocratic │ │ +│ │ [H1, text-display sau text-h1] │ │ +│ │ │ │ +│ │ Lipește orice text oficial și primește │ │ +│ │ explicația pe limba ta. │ │ +│ │ [text-body-lg, slate-600] │ │ +│ │ │ │ +│ │ [Pills: #AI #NLP #Limbaj #MIT] │ │ +│ │ │ │ +│ │ ┌──────────────────────────────────────────┐ │ │ +│ │ │ │ │ │ +│ │ │ [Screenshot principal / Video] │ │ │ +│ │ │ aspect-video, rounded-xl │ │ │ +│ │ │ shadow-lg │ │ │ +│ │ │ │ │ │ +│ │ └──────────────────────────────────────────┘ │ │ +│ │ │ │ +│ │ [Gallery thumbnails dacă există mai multe] │ │ +│ │ │ │ +│ │ ── Ce face ── │ │ +│ │ • Analizează text juridic/birocratic │ │ +│ │ • Explică pe limba cetățeanului │ │ +│ │ • Identifică ce trebuie să faci concret │ │ +│ │ [prose content, MDX rendered] │ │ +│ │ │ │ +│ │ ── De ce contează ── │ │ +│ │ [Secțiune narativă — storytelling] │ │ +│ │ │ │ +│ │ COL DREAPTA (4/12) — sticky sidebar: │ │ +│ │ │ │ +│ │ ┌──────────────────────┐ │ │ +│ │ │ [Încearcă demo →] │ ← primary btn, full-w │ │ +│ │ │ [Cod sursă ↗] │ ← outline btn │ │ +│ │ │ [Contactează autorul] │ ← ghost btn │ │ +│ │ │ │ │ │ +│ │ │ ───────────────── │ │ │ +│ │ │ │ │ │ +│ │ │ Făcut de │ │ │ +│ │ │ 👤 Marius Tarau │ │ │ +│ │ │ 📍 Cluj-Napoca │ │ │ +│ │ │ │ │ │ +│ │ │ Status │ │ │ +│ │ │ ✅ Demo live │ ← badge verde │ │ +│ │ │ │ │ │ +│ │ │ Licență │ │ │ +│ │ │ MIT │ │ │ +│ │ │ │ │ │ +│ │ │ Stack │ │ │ +│ │ │ Astro + GPT-4o │ │ │ +│ │ │ │ │ │ +│ │ │ Funcționează la │ │ │ +│ │ │ Primăria Cluj ✓ │ │ │ +│ │ │ Primăria Sibiu ✓ │ │ │ +│ │ └──────────────────────┘ │ │ +│ └────────────────────────────────────────────────────┘ │ +│ │ +│ ── Produse similare ── │ +│ [Grid 3 carduri din aceeași categorie] │ +└─────────────────────────────────────────────────────────────┘ +``` + +**Principii de layout — Product Detail:** + +- **Sidebar sticky:** `sticky top-24` — rămâne vizibilă când scrollezi conținutul +- **Screenshot principal:** `rounded-xl shadow-lg overflow-hidden` — arată premium +- **Content area:** `prose prose-slate max-w-none` — Tailwind Typography plugin pentru MDX content +- **Button hierarchy:** Primary (filled blue) → Secondary (outline) → Ghost (text only) +- **Mobile:** sidebar-ul trece SUB screenshot, butoanele devin sticky bottom bar + +--- + +### 3.4 Animații și interacțiuni + +**Principiu: subtile, funcționale, rapide. Zero animații care întârzie accesul la conținut.** + +#### Animații de intrare (scroll-triggered) + +```css +/* Fade-in + slide-up — pattern principal */ +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Folosind Intersection Observer, NU librării externe */ +/* Fiecare element: animation-duration: 0.5s, ease-out */ +/* Stagger: 100ms delay între elemente consecutive */ +/* Regula: animația se întâmplă O SINGURĂ DATĂ */ +``` + +#### Interacțiuni hover + +```css +/* Card hover — ridicare subtilă */ +.product-card { + transition: transform 200ms ease, box-shadow 200ms ease; +} +.product-card:hover { + transform: translateY(-4px); + box-shadow: 0 12px 24px -8px rgba(15, 23, 42, 0.12); +} + +/* Button hover — shift de culoare */ +.btn-primary:hover { + background-color: #1D4ED8; /* primary-700 */ + transition: background-color 150ms ease; +} + +/* Link hover — underline animation */ +.text-link:hover { + text-decoration-color: currentColor; + text-underline-offset: 4px; + transition: text-decoration-color 150ms ease; +} +``` + +#### Animații speciale (doar pe home) + +- **Hero gradient mesh:** animație lentă de mișcare (CSS `background-position` animat pe 20s loop) — dă feeling de „viu" fără JavaScript +- **Stat counters:** count-up animation la scroll (de la 0 la valoarea reală, 1.5s, ease-out) +- **Before/After slider:** drag interactiv cu linie verticală — utilizatorul trage linia pentru a compara + +#### Ce NU animăm + +- Page transitions (overhead prea mare, prea complex) +- Skeleton loading (site-ul e static, se încarcă instant) +- Parallax (distrage, probleme de performance pe mobile) +- Cursor effects (gimmick, accesibilitate) +- GSAP / Framer Motion (dependințe prea grele pentru beneficiul oferit) + +**Implementare:** CSS animations + Intersection Observer vanilla JS. Zero librării de animație. Astro's `client:visible` directive e suficientă pentru trigger-ul de scroll. + +--- + +### 3.5 Mobile-first + +**Regula: designul se face pe 375px (iPhone SE) și se extinde în sus.** + +| Breakpoint | Tailwind | Ce se schimbă | +|------------|----------|---------------| +| `< 640px` | default | 1 coloană, nav hamburger, sidebar sub content, sticky bottom CTA | +| `640px` | `sm:` | Grid 2 coloane pe catalog | +| `768px` | `md:` | Nav desktop, sidebar apare | +| `1024px` | `lg:` | Grid 3 coloane, hero full experience | +| `1280px` | `xl:` | Max content width atins, spacing generos | + +**Specifice mobile:** + +- **Nav:** Hamburger menu cu slide-in panel (nu dropdown). Logo stânga, hamburger dreapta. Max 5 items în menu. +- **Hero:** Text mai mic (clamp handles it), CTA-urile pe full width, counter-ele pe 1 rând scrollabil +- **Product cards:** Full width, screenshot aspect-video, stacked vertical +- **Product detail:** Screenshot → CTA buttons (sticky bottom) → Content → Metadata → Produse similare +- **Touch targets:** Minim 44x44px pe toate elementele interactive (standard Apple HIG) +- **Font sizes:** Nu mai mici de 16px pe body (previne zoom-ul automat pe iOS la focus pe input) + +--- + +### 3.6 Dark mode + +**Decizia: DA, dark mode — dar ca opțiune, nu ca default.** + +**De ce DA:** +- Audiența include developeri care preferă dark mode +- Credem în alegerea utilizatorului +- CSS modern + Tailwind fac implementarea trivială (`dark:` prefix) +- Site-urile premium oferă dark mode (Linear, Vercel, GitHub) +- Hero-ul nostru e deja pe fundal întunecat — dark mode extinde natural acea estetică + +**De ce NU ca default:** +- Audiența principală sunt cetățenii obișnuiți — ei se așteaptă la light mode +- Conținut editorial (text lung) se citește mai ușor pe fundal deschis +- Trust signals (badge-uri, status) au contrast mai bun pe light + +**Implementare:** +- Toggle în nav (icon sun/moon din Lucide) +- `prefers-color-scheme` detection ca default +- Salvat în `localStorage` +- **Prioritate: Faza 2** — nu blocăm lansarea pentru dark mode + +**Dark mode color mapping:** + +| Element | Light | Dark | +|---------|-------|------| +| Page background | `#FAFBFC` | `#0F172A` (slate-900) | +| Card background | `#FFFFFF` | `#1E293B` (slate-800) | +| Card border | `#E2E8F0` | `#334155` (slate-700) | +| Text primary | `#0F172A` | `#F1F5F9` (slate-100) | +| Text secondary | `#475569` | `#94A3B8` (slate-400) | +| Primary buttons | `#2563EB` | `#3B82F6` (ușor mai deschis) | + +--- + +## 4. Tailwind CSS Implementation + +### 4.1 tailwind.config.js (v4 syntax cu CSS config sau legacy JS) + +```javascript +// tailwind.config.mjs — Astro + Tailwind v4 +import defaultTheme from 'tailwindcss/defaultTheme'; + +/** @type {import('tailwindcss').Config} */ +export default { + content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'], + darkMode: 'class', + theme: { + extend: { + colors: { + // Primary — albastru profund + primary: { + 50: '#EFF6FF', + 100: '#DBEAFE', + 200: '#BFDBFE', + 300: '#93C5FD', + 400: '#60A5FA', + 500: '#3B82F6', + 600: '#2563EB', // ← main interactive color + 700: '#1D4ED8', + 800: '#1E40AF', + 900: '#1E3A5F', // ← hero, deep backgrounds + 950: '#172554', + }, + // Secondary — amber cald + secondary: { + 50: '#FFFBEB', + 100: '#FEF3C7', + 200: '#FDE68A', + 300: '#FCD34D', + 400: '#FBBF24', + 500: '#F59E0B', // ← main accent + 600: '#D97706', + 700: '#B45309', + 800: '#92400E', + 900: '#78350F', + 950: '#451A03', + }, + // Neutral — slate cu warmth + neutral: { + 50: '#F8FAFC', + 100: '#F1F5F9', + 200: '#E2E8F0', + 300: '#CBD5E1', + 400: '#94A3B8', + 500: '#64748B', + 600: '#475569', + 700: '#334155', + 800: '#1E293B', + 900: '#0F172A', + 950: '#020617', + }, + // Semantic + success: '#10B981', // emerald-500 + warning: '#F59E0B', // amber-500 + error: '#EF4444', // red-500 + info: '#3B82F6', // blue-500 + // Page background + page: '#FAFBFC', + }, + fontFamily: { + heading: ['"Plus Jakarta Sans"', ...defaultTheme.fontFamily.sans], + body: ['Inter', ...defaultTheme.fontFamily.sans], + mono: ['"JetBrains Mono"', ...defaultTheme.fontFamily.mono], + }, + fontSize: { + 'display': ['clamp(2.25rem, 5vw, 3.75rem)', { lineHeight: '1.1', letterSpacing: '-0.025em', fontWeight: '800' }], + 'h1': ['clamp(1.875rem, 4vw, 3rem)', { lineHeight: '1.15', letterSpacing: '-0.02em', fontWeight: '700' }], + 'h2': ['clamp(1.5rem, 3vw, 2.25rem)', { lineHeight: '1.2', letterSpacing: '-0.015em', fontWeight: '700' }], + 'h3': ['clamp(1.25rem, 2.5vw, 1.5rem)', { lineHeight: '1.3', fontWeight: '600' }], + 'body-lg': ['clamp(1.125rem, 1.5vw, 1.25rem)', { lineHeight: '1.7', fontWeight: '400' }], + }, + spacing: { + '18': '4.5rem', + '88': '22rem', + '128': '32rem', + }, + maxWidth: { + 'content': '72rem', // 1152px — content max + 'narrow': '42rem', // 672px — text-focused pages + }, + borderRadius: { + '4xl': '2rem', + }, + boxShadow: { + 'card': '0 1px 3px 0 rgba(15, 23, 42, 0.04), 0 1px 2px -1px rgba(15, 23, 42, 0.04)', + 'card-hover': '0 12px 24px -8px rgba(15, 23, 42, 0.12)', + 'hero': '0 24px 48px -12px rgba(30, 58, 95, 0.25)', + }, + backgroundImage: { + 'gradient-hero': 'linear-gradient(135deg, #1E3A5F 0%, #2563EB 50%, #3B82F6 100%)', + 'gradient-warm': 'linear-gradient(135deg, #F59E0B 0%, #F97316 100%)', + 'gradient-dark': 'linear-gradient(180deg, #0F172A 0%, #1E293B 100%)', + }, + animation: { + 'fade-in-up': 'fadeInUp 0.5s ease-out forwards', + 'fade-in': 'fadeIn 0.5s ease-out forwards', + }, + keyframes: { + fadeInUp: { + '0%': { opacity: '0', transform: 'translateY(20px)' }, + '100%': { opacity: '1', transform: 'translateY(0)' }, + }, + fadeIn: { + '0%': { opacity: '0' }, + '100%': { opacity: '1' }, + }, + }, + }, + }, + plugins: [ + require('@tailwindcss/typography'), // pentru prose/MDX content + ], +}; +``` + +### 4.2 CSS global (styles/global.css) + +```css +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + /* Font imports — via Google Fonts sau self-hosted */ + /* Self-hosted recomandat pentru performance */ + + html { + @apply font-body text-neutral-900 bg-page antialiased; + scroll-behavior: smooth; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + + body { + @apply text-base leading-relaxed; + } + + h1, h2, h3, h4 { + @apply font-heading; + } + + /* Focus visible — accessibility */ + *:focus-visible { + @apply outline-2 outline-offset-2 outline-primary-600 rounded-sm; + } + + /* Selection color */ + ::selection { + @apply bg-primary-100 text-primary-900; + } +} + +@layer components { + /* Butoane */ + .btn { + @apply inline-flex items-center justify-center gap-2 rounded-xl + font-heading font-semibold text-sm + px-6 py-3 + transition-all duration-200 ease-out + focus-visible:outline-2 focus-visible:outline-offset-2; + } + + .btn-primary { + @apply btn bg-primary-600 text-white + hover:bg-primary-700 + focus-visible:outline-primary-600 + shadow-sm hover:shadow-md; + } + + .btn-secondary { + @apply btn bg-secondary-500 text-white + hover:bg-secondary-600 + focus-visible:outline-secondary-500; + } + + .btn-outline { + @apply btn border-2 border-primary-600 text-primary-600 + hover:bg-primary-50 + focus-visible:outline-primary-600; + } + + .btn-ghost { + @apply btn text-primary-600 + hover:bg-primary-50 + focus-visible:outline-primary-600; + } + + /* Card produs */ + .product-card { + @apply bg-white rounded-xl border border-neutral-200 + overflow-hidden + shadow-card + transition-all duration-200 ease-out + hover:shadow-card-hover hover:-translate-y-1; + } + + /* Category pill */ + .category-pill { + @apply inline-flex items-center gap-1.5 + px-3 py-1 rounded-full + text-xs font-medium + bg-primary-50 text-primary-700 + transition-colors duration-150 + hover:bg-primary-100; + } + + .category-pill-active { + @apply bg-primary-600 text-white hover:bg-primary-700; + } + + /* Badge status */ + .badge { + @apply inline-flex items-center gap-1 + px-2 py-0.5 rounded-full + text-xs font-semibold uppercase tracking-wider; + } + + .badge-demo { + @apply badge bg-emerald-50 text-emerald-700 + border border-emerald-200; + } + + .badge-listed { + @apply badge bg-primary-50 text-primary-700 + border border-primary-200; + } + + .badge-verified { + @apply badge bg-amber-50 text-amber-700 + border border-amber-200; + } + + /* Section wrapper */ + .section { + @apply px-4 sm:px-6 lg:px-8 py-20 lg:py-32; + } + + .section-content { + @apply max-w-content mx-auto; + } + + /* Hero gradient mesh background */ + .hero-mesh { + @apply relative overflow-hidden bg-gradient-hero; + } + + .hero-mesh::before { + content: ''; + @apply absolute inset-0; + background: + radial-gradient(ellipse 80% 50% at 20% 80%, rgba(59, 130, 246, 0.3) 0%, transparent 70%), + radial-gradient(ellipse 60% 40% at 80% 20%, rgba(37, 99, 235, 0.4) 0%, transparent 60%), + radial-gradient(ellipse 50% 60% at 50% 50%, rgba(30, 58, 95, 0.2) 0%, transparent 80%); + animation: meshFloat 20s ease-in-out infinite alternate; + } + + @keyframes meshFloat { + 0% { background-position: 0% 0%, 100% 0%, 50% 50%; } + 100% { background-position: 20% 20%, 80% 30%, 40% 60%; } + } +} +``` + +### 4.3 Componente necesare (Astro/Svelte) + +Lista de componente de implementat, în ordinea priorității: + +| # | Componentă | Fișier | Descriere | +|---|-----------|--------|-----------| +| 1 | **Nav** | `Nav.astro` | Logo + link-uri + hamburger mobile. Sticky top, blur background pe scroll. | +| 2 | **Hero** | `Hero.astro` | Mesh gradient + heading display + subtitle + 2 CTA + counters | +| 3 | **ProductCard** | `ProductCard.astro` | Screenshot + title + description + pills + author. Props: `product` | +| 4 | **CategoryPill** | `CategoryPill.astro` | Icon + label. Props: `name`, `icon`, `active`, `count` | +| 5 | **Badge** | `Badge.astro` | Status badge. Props: `type: 'demo' | 'listed' | 'verified'` | +| 6 | **Section** | `Section.astro` | Wrapper cu padding + max-width + fundal alternabil | +| 7 | **Button** | `Button.astro` | Props: `variant`, `size`, `href`, `icon` | +| 8 | **Footer** | `Footer.astro` | Dark background, link-uri, accent tricolor line | +| 9 | **BeforeAfter** | `BeforeAfter.svelte` | Slider interactiv stânga/dreapta (necesită JS → Svelte island) | +| 10 | **ProductSidebar** | `ProductSidebar.astro` | Sticky sidebar cu CTA, metadata, author info | +| 11 | **StatCounter** | `StatCounter.svelte` | Număr animat count-up (JS → Svelte island) | +| 12 | **MobileMenu** | `MobileMenu.svelte` | Slide-in panel cu animație (JS → Svelte island) | +| 13 | **ScrollReveal** | `ScrollReveal.astro` | Wrapper cu Intersection Observer pentru fade-in-up | + +**Principiu: tot ce se poate face fără JavaScript → Astro component. Doar interacțiuni → Svelte island cu `client:visible`.** + +--- + +## 5. Design emoțional + +### 5.1 Prima impresie (0-5 secunde) + +Când cineva intră pe vreaudigital.ro pentru prima dată, trebuie să simtă: + +1. **„Wow, arată profesionist"** — designul în sine e dovada că digitalizarea poate fi frumoasă +2. **„Asta mă privește"** — mesajul din hero vorbește despre viața mea, nu despre tehnologie +3. **„Vreau să văd mai mult"** — CTA-ul e clar, invitant, nu agresiv + +**Mecanisme concrete:** + +- **Hero cu impact vizual maxim:** fundal gradient mesh animat subtil, text alb mare, spațiu generos. Nu stock photo. Nu banner cu steaguri. Culoare, tipografie, și spațiu. +- **Mesajul emoțional:** „România merită o digitalizare reală." — simplu, personal, ușor de simțit. Fiecare cuvânt contează. Subtext-ul detaliază ce vrem să spunem. +- **Stat counters animați:** „12 produse · 3 demo-uri live · 100% open source" — credibilitate imediată, fără a fi corporate + +### 5.2 Storytelling vizual Before/After + +**Principiul:** cea mai puternică armă de persuasiune pe care o avem e contrastul între „cum e acum" și „cum ar putea fi". + +**Implementare concretă:** + +#### Varianta A: Split-screen slider + +``` +┌─────────────────────┬─────────────────────┐ +│ │ │ +│ [Screenshot de pe │ [Screenshot │ +│ ghiseu.ro sau ←┼→ produs modern │ +│ formular PDF │ de pe portal] │ +│ scanat prost] │ │ +│ │ │ +│ ACUM │ CUM AR PUTEA FI │ +│ Desaturated, │ Full color, │ +│ ușor blur │ crisp, vibrant │ +│ │ │ +└─────────────────────┴─────────────────────┘ + ↑ slider draggable +``` + +- Partea stângă (ACUM): screenshot real de pe un site guvernamental, aplicat filtru `grayscale(0.7) brightness(0.8)` — faded, trist, vechi +- Partea dreaptă (CUM AR PUTEA FI): screenshot al unui produs de pe portal — color, modern, viu +- Slider-ul e draggable — utilizatorul poate compara direct +- Text deasupra: „Acum vs. Cum ar putea fi" (H2, center) +- Text dedesubt: „Fiecare produs de pe portal dovedește că se poate mai bine." (body-lg, center) + +#### Varianta B: Secvență scroll + +Pe mobile (unde slider-ul e mai puțin eficient), secvență verticală: + +``` +[Screenshot vechi, desaturated, mic, cu legendă „Acum"] + ↓ (arrow animat) +[Screenshot modern, full-size, color, cu legendă „Cum ar putea fi"] +``` + +#### Exemple concrete de before/after + +| Acum | Cum ar putea fi | +|------|-----------------| +| PDF scanat strâmb cu „Cerere tip" | Formular web inteligent care te ghidează pas cu pas | +| Pagina de pe anaf.ro cu tabele HTML din 2003 | Dashboard interactiv cu grafice colorate pe bugetul local | +| Copie de pe ghiseu.ro cu 14 câmpuri obligatorii | Chatbot: „Spune-mi ce ai nevoie și completez eu formularul" | +| Ușa de la ghișeul primăriei cu orar 9-13 | App de programări cu slot-uri disponibile și confirmare SMS | + +### 5.3 Trust signals fără corporate + +**Ce NU facem:** +- Logo-uri de parteneri pe care nu-i avem +- „Trusted by 10,000 users" când avem 50 +- Sigle guvernamentale pe care nu le-am primit +- Texte juridice de privacy cu font 8px + +**Ce facem:** + +1. **Open source = transparență totală** + - Link vizibil către GitHub/Gitea pe fiecare pagină + - „Codul e public. Verifică tu." — nu cerem să ne crezi pe cuvânt + - Badge „100% Open Source" pe fiecare produs care e OSS + +2. **Oamenii din spate** + - Fiecare produs are autor cu nume, foto (opțional), oraș + - „Făcut de Ionuț din Brașov" > „Powered by GovTech Solutions SRL" + - Secțiune „Despre noi" cu povești reale, nu corporate bios + +3. **Dovada funcționează** + - Badge „Demo live" = poți încerca acum, nu trebuie să te înscrii + - Badge „Funcționează la Primăria X" = cineva l-a testat în producție + - Screenshots reale, nu mockup-uri. Video-uri reale, nu render-uri. + +4. **Comunitatea** + - Counter vizibil: câte produse, câți contributori + - „Proiect open source contribuit de X programatori din Y orașe" + - Link-uri către discuții publice (GitHub Issues) + +5. **Absența manipulării** (lecția Signal) + - Zero cookie banners agresive (folosim analytics privacy-first) + - Zero popup-uri de newsletter + - Zero dark patterns de „subscribe or lose access" + - Dacă ceri email-ul, spui exact ce faci cu el și oferi un motiv clar + +### 5.4 Microinteracțiuni care creează emoție + +| Moment | Interacțiune | Emoție | +|--------|-------------|--------| +| Hover pe card produs | Card se ridică 4px, shadow crește, screenshot zoom-ează subtle (scale 1.02) | „Asta e interesant, vreau să văd" | +| Click pe „Încearcă demo" | Button pulsează scurt, apoi redirect | „Hai să vedem!" — excitare | +| Scroll peste before/after | Imaginile apar cu timing diferit (stânga fade-in prima, dreaptă după 200ms) | Contrast dramatic, „wow, ce diferență" | +| Prima vizită | Hero counter-ele se numără de la 0 | „Lucruri se întâmplă aici" — activitate | +| Hover pe badge „Demo live" | Badge-ul pulsează verde subtil | „E viu, funcționează acum" | +| Scroll la footer | Tricolor accent line se desenează de la stânga la dreapta (200ms) | „E românesc, dar modern" | + +### 5.5 Vocea brandului în design + +**Tonul vreaudigital.ro se simte în fiecare element:** + +- **Heading-uri:** directe, emoționale, scurte. „România merită mai mult." Nu: „Portal de agregare a soluțiilor digitale pentru administrația publică." +- **Descrieri:** umane, concrete. „Lipește textul oficial, primești explicația pe limba ta." Nu: „Soluție NLP pentru procesarea textelor juridice." +- **CTA-uri:** invitante, nu imperative. „Vezi ce e posibil →" nu „CLICK HERE". „Listează-ți produsul →" nu „SUBMIT YOUR SOLUTION". +- **Empty states:** prietenoase. „Încă nu avem produse în această categorie. Poate tu ești cel care schimbă asta?" nu „No results found." +- **Error states:** umane. „Ceva n-a mers bine. Încearcă din nou sau scrie-ne." nu „Error 500: Internal Server Error." + +--- + +## 6. Checklist de implementare design (Faza 1) + +### Săptămâna 1 — Fundamente + +- [ ] Setup Astro + Tailwind cu `tailwind.config.mjs` de mai sus +- [ ] Import fonturi: Plus Jakarta Sans (Google Fonts), Inter (Google Fonts), JetBrains Mono (Google Fonts) +- [ ] `global.css` cu layer-urile base/components/utilities +- [ ] Componentele: Nav, Footer, Button, Section, Badge, CategoryPill +- [ ] Logo wordmark în SVG (temporar — text stilizat până avem logo final) +- [ ] Favicon temporar (litera V pe fundal primary-900) + +### Săptămâna 2 — Paginile principale + +- [ ] Home: Hero (mesh gradient + text + CTA + counters) +- [ ] Home: „Cum ar fi dacă..." section (3 coloane cu iconuri) +- [ ] Home: Featured products grid (3 carduri) +- [ ] Home: CTA developeri (fundal gradient warm) +- [ ] Catalog: Category pills + product grid +- [ ] Product detail: Layout 2 coloane + sidebar sticky + +### Săptămâna 3 — Rafinament + +- [ ] Before/After slider (Svelte island) +- [ ] Animații scroll reveal (Intersection Observer) +- [ ] Stat counters animați +- [ ] Mobile nav (hamburger + slide-in) +- [ ] Responsive testing pe toate breakpoint-urile +- [ ] Accesibilitate: focus states, contrast check, screen reader test + +### Săptămâna 4 — Polish + +- [ ] Optimizare imagini (Astro Image component, WebP, lazy loading) +- [ ] Performance audit (target: 95+ Lighthouse pe toate categoriile) +- [ ] Open Graph images (og:image pentru social sharing) +- [ ] 404 page cu personalitate +- [ ] Final QA pe Chrome, Firefox, Safari, iOS Safari, Android Chrome + +--- + +## 7. Resurse și link-uri + +### Font-uri (toate gratuite, open source) +- Plus Jakarta Sans: https://fonts.google.com/specimen/Plus+Jakarta+Sans +- Inter: https://fonts.google.com/specimen/Inter +- JetBrains Mono: https://fonts.google.com/specimen/JetBrains+Mono + +### Iconuri +- Lucide Icons: https://lucide.dev/icons/ +- lucide-react / lucide-svelte: https://www.npmjs.com/package/lucide-svelte + +### Tailwind +- Tailwind CSS v4 docs: https://tailwindcss.com/docs +- Tailwind Typography plugin: https://tailwindcss.com/docs/typography-plugin +- shadcn/ui colors: https://ui.shadcn.com/colors + +### Design inspiration +- Linear.app: https://linear.app — hero sections, card design, dark aesthetic +- e-Estonia: https://e-estonia.com — civic tech storytelling +- Astro.build: https://astro.build — open source project branding +- Product Hunt: https://producthunt.com — product discovery UX +- GOV.UK Design System: https://design-system.service.gov.uk — accessibility patterns +- Cal.com: https://cal.com — open source premium feel +- Vercel: https://vercel.com — gradient meshes, typography +- Tailwind CSS: https://tailwindcss.com — inline demo patterns +- Civic Tech Field Guide: https://civictech.guide — catalog structure +- Signal: https://signal.org — trust through simplicity + +### Tool-uri de design +- UI Colors (Tailwind palette generator): https://uicolors.app +- Contrast checker: https://webaim.org/resources/contrastchecker/ +- Realtime Colors (test palette pe layout): https://realtimecolors.com + +--- + +*Acest document e viu — se actualizează pe măsură ce implementăm și testăm. Designul nu e optional, e diferențiatorul nostru principal.* diff --git a/PLAN-OPENSOURCE.md b/PLAN-OPENSOURCE.md new file mode 100644 index 0000000..e4a8dfb --- /dev/null +++ b/PLAN-OPENSOURCE.md @@ -0,0 +1,521 @@ +# PLAN-OPENSOURCE.md — Strategia de Lansare Open-Source +# vreaudigital.ro / gov-agreg + +**Data:** 7 aprilie 2026 +**Autor:** Marius + Claude +**Status:** Draft — planificare pre-lansare + +--- + +## Context și filozofie + +Strategia e simplă: construim în privat pe Gitea până avem ceva de care nu ne e rușine, apoi lansăm public pe GitHub cu un bang, nu un whimper. Nu lansăm "early" ca să primim feedback că site-ul e gol. Lansăm când avem cel puțin 3 demo-uri funcționale și un design care inspiră. + +**Principiu fundamental:** Prima impresie pe GitHub/HackerNews e greutatea aurului. Nu pierdem acea impresie pe un repo cu un README gol și un commit "initial setup". + +--- + +## 1. Checklist pre-lansare + +### Codul și structura + +- [ ] Site-ul e live pe vreaudigital.ro (nu doar local sau pe un subdomain de test) +- [ ] Build trece fără erori și fără warning-uri critice (`astro build` clean) +- [ ] Niciun secret, token sau credențial în git history (verifică cu `git log --all -p | grep -i "token\|secret\|key\|password"`) +- [ ] `.gitignore` corect — fără `.env`, fără `node_modules/`, fără fișiere de editor (`.DS_Store`, `.idea/`) +- [ ] Commit history curat — dacă history-ul de pe Gitea conține mesaje interne jenante sau experimente, faci un fresh repo pe GitHub (nu mirror) + +### Documentație minimă obligatorie + +**README.md** — cel mai important fișier, citit de toți: +- [ ] Ce e proiectul (2-3 propoziții, în română și engleză — da, excepție de la regula "doar română" pentru README) +- [ ] Screenshot sau GIF animat al site-ului în README (obligatoriu — repo-urile fără imagini au CTR mizerabil) +- [ ] Link spre site-ul live (primul lucru) +- [ ] Cum rulezi local (maxim 4 comenzi: clone, npm install, npm run dev) +- [ ] Cum contribui (link spre CONTRIBUTING.md) +- [ ] Licența + +**CONTRIBUTING.md:** +- [ ] Cum adaugi un produs nou (flow-ul cu fișierul MDX) +- [ ] Cum raportezi o problemă +- [ ] Convenție de commit messages (simplu: `feat:`, `fix:`, `content:`) +- [ ] Ce nu acceptăm (produse proprietare fără demo live, produse fără legătură cu administrația publică) + +**LICENSE:** +- [ ] MIT pentru codul platformei +- [ ] Notă separată: conținutul (produsele listate) aparține autorilor lor + +**CODE_OF_CONDUCT.md:** +- [ ] Folosești Contributor Covenant 2.1 (copy-paste standard, traducere în română) +- [ ] Contact pentru raportare abuzuri (un email dedicat, ex: conduct@vreaudigital.ro) + +### Issue templates (`.github/ISSUE_TEMPLATE/`) + +Trei template-uri, nu mai multe: + +**1. `product-submission.md`** — pentru cei care vor să listeze un produs: +``` +Nume produs: +URL (live sau demo): +Categorie: +Screenshot/video (link): +Descriere scurtă (2 propoziții): +Unde funcționează deja? (opțional): +``` + +**2. `bug-report.md`** — standard, minimal: +``` +Ce ai încercat să faci: +Ce s-a întâmplat: +Ce te așteptai să se întâmple: +Browser/OS: +``` + +**3. `improvement.md`** — propuneri de îmbunătățire a platformei + +### PR template (`.github/pull_request_template.md`) + +```markdown +## Ce face acest PR + +## Tip de schimbare +- [ ] Produs nou adăugat +- [ ] Fix conținut existent +- [ ] Îmbunătățire platformă +- [ ] Altele + +## Checklist +- [ ] Am rulat `npm run build` local și trece fără erori +- [ ] Screenshot-urile sunt actualizate (dacă e cazul) +- [ ] Nu am adăugat dependențe noi fără motiv +``` + +### CI/CD minimal + +**Nu avem nevoie de ceva complex.** Două GitHub Actions: + +**1. Build check** (la orice PR): +```yaml +# .github/workflows/build.yml +# Rulează: npm ci && npm run build +# Fail dacă build-ul pică +``` + +**2. Deploy automat** (la merge în main): +```yaml +# .github/workflows/deploy.yml +# Cloudflare Pages are GitHub integration nativă — probabil nici nu ai nevoie de Action manual +# Dacă folosești Cloudflare Pages GitHub integration, deploy-ul e automat out of the box +``` + +**Ce NU adăugăm la CI:** linting strict, type-check cu erori blocante, teste (nu avem), dependency scanning (overkill). Adăugăm când/dacă repo-ul are contributori activi și merită. + +--- + +## 2. Unde lansăm + +### GitHub — da, GitHub, nu Gitea + +**De ce GitHub și nu Gitea public:** +- Descoperabilitate zero pe Gitea dacă nu știi exact URL-ul +- Stars, forks, trending — GitHub are efect de rețea +- GitHub Discussions, Issues, Actions sunt așteptate de contributori +- "Contribute on Gitea" e o barieră în plus pentru oricine vrea să ajute + +**Gitea rămâne ca:** +- Mirror privat / backup (setup automat push mirror) +- Development intern dacă vrei să lucrezi "în privat" înainte de push +- Istoric — nu șterge repo-ul, dar GitHub devine primary + +### Nume organizație GitHub + +Recomandări în ordinea preferinței: + +1. **`vreaudigital`** — dacă domeniul e al nostru, organizația trebuie să fie la fel +2. **`gov-agreg`** — merge ca repo name, nu ca org name (prea tehnic) +3. **`digitalizare-ro`** — alternativă dacă vreaudigital e luat + +**Decizie recomandată:** Creezi organizația `vreaudigital` pe GitHub, cu repo-ul principal `vreaudigital.ro` (sau `platform`). Organizația lasă loc pentru repo-uri separate ulterior. + +### Structura repo-urilor — monorepo, cel puțin la start + +**Monorepo `vreaudigital/platform`** conține: +``` +/ ← codul Astro al platformei +/src/products/ ← un fișier .mdx per produs listat +/src/pages/ ← paginile site-ului +/public/ ← assets statice +/.github/ ← templates, actions +``` + +**Repo-uri separate (mai târziu, nu acum):** +- `vreaudigital/traducator-birocratic` — dacă demo-ul birocratic devine tool separat cu UI propriu +- `vreaudigital/harta-digitalizarii` — idem +- `vreaudigital/date` — eventual, date curate despre servicii publice + +**Nu face multi-repo de la start** — overhead de management fără beneficiu real la dimensiunea actuală. + +--- + +## 3. Criterii de lansare — ce declanșează "go public" + +Nu lansăm după un calendar fix. Lansăm când sunt îndeplinite toate criteriile din categoria A și cel puțin 2 din categoria B. + +### Categoria A — Obligatorii (toate trebuie bifate) + +- [ ] **Site live** pe vreaudigital.ro, accesibil public, fără erori evidente +- [ ] **Minim 5 produse listate** cu pagini complete (screenshot + descriere + link funcțional) +- [ ] **Minim 1 demo funcțional** (nu link extern, ci ceva ce rulează pe domeniul nostru sau demo interactiv embeded) +- [ ] **Design decent** — hero section cu mesaj clar, categorii vizuale, mobile-friendly +- [ ] **README cu screenshot** — cineva care vede repo-ul pe GitHub înțelege imediat ce e +- [ ] **Niciun secret în git** — verificat explicit + +### Categoria B — Cel puțin 2 din 4 + +- [ ] **Traducătorul birocratic funcțional** — cel mai viral produs, dacă îl avem la lansare crește reach-ul masiv +- [ ] **Pagina "Listează-ți produsul"** funcțională (formularul trimite cererea undeva — email sau GitHub Issue) +- [ ] **Minim 3 categorii populate** cu cel puțin 2 produse fiecare +- [ ] **Analytics setup** (Plausible sau Umami) ca să știm dacă oamenii intră + +### Ce nu contează pentru timing + +- Câte stele are repo-ul (zero la lansare, normal) +- Dacă CONTRIBUTING.md e perfect +- Dacă am răspuns la toate issue-urile (nu există încă) +- Dacă instituțiile știu de noi + +--- + +## 4. Campania de lansare + +### Cu o zi înainte — pregătire + +- [ ] Draft-urile postărilor sunt scrise și revizuite +- [ ] Screenshot-uri proaspete ale site-ului (nu din beta) +- [ ] GIF animat de 5-10 secunde care arată ce face traducătorul birocratic (tool: LICEcap sau screen2gif) +- [ ] Link-urile scurtate (nu e.g. `github.com/vreaudigital/platform/blob/main/src/...`) +- [ ] Repo-ul GitHub e public (verifică că nu e private) +- [ ] GitHub Discussions activat + +### Ziua lansării — ordinea contează + +**Dimineața (8-9 AM):** +1. Postare pe HackerNews "Show HN" — postezi tu primul, traficul vine repede dacă prinde +2. Postare pe r/Romania + +**Mijlocul zilei (12-14):** +3. Thread pe Twitter/X +4. Post pe LinkedIn (pentru developeri și oameni din tech) + +**Seara (18-20):** +5. Facebook — grupurile dev românești (cel mai activ trafic seara) +6. Răspunzi la toate comentariile de peste zi + +**Nu posta simultan pe toate canalele** — primești feedback pe unul și poți ajusta mesajul pentru următorul. + +### Unde postezi + +| Canal | Tip conținut | Ton | Așteptări | +|-------|-------------|-----|-----------| +| **HackerNews** `Show HN:` | Titlu concis, link, scurt context în comentariu | Tehnic, direct | 50-500 upvotes dacă prinde. Trafic calitativ. | +| **r/Romania** | Post cu imagine + text | Emoțional, cetățean | 100-1000 upvotes dacă e share-abil. Audiență mare. | +| **r/opensource** | Post tehnic cu README link | Tehnic, comunitate | Nișat, trafic mic dar relevant | +| **Twitter/X** | Thread 5-7 tweet-uri | Vizual, hashtags | #Romania #civic #digitalizare #opensource | +| **LinkedIn** | Post cu screenshot | Profesional, impact social | Tag developeri și oameni din gov tech | +| **Facebook — Developeri Romania** | Post cu GIF + link | Informal, direct | Grupul cel mai activ din RO pentru dev | +| **Facebook — Civic tech / ONG** | Post axat pe cetățeni | Emoțional, "de ce contează" | Audiență non-tech, share potențial | + +### Template post HackerNews + +``` +Show HN: vreaudigital.ro – open-source hub for Romanian civic tech + +[URL: https://vreaudigital.ro] + +Romania's public administration still runs on PDF forms, phone queues, +and websites from 2005. We built an open-source catalog of tools that +show what's actually possible. + +Not enterprise software — demos that work in a browser, in 30 seconds. +Built by independent developers, for citizens and municipalities. + +Current highlights: +- Birocratic Translator: paste any official text, get plain-language explanation +- Digitalization Map: interactive map of which Romanian cities have online services +- Budget Visualizer: where do your local taxes actually go? + +Stack: Astro + Tailwind + Markdown, deployed on Cloudflare Pages. +Zero database, zero backend, zero cost to run. + +Looking for Romanian civic tech projects to list. If you've built something +in this space, open an issue. +``` + +### Template post r/Romania + +``` +Am construit vreaudigital.ro — un catalog de soluții de digitalizare reală + +[screenshot/GIF] + +Toată lumea se plânge că România digitală = formulare PDF online și site-uri din 2005. +Am decis să arătăm cum ar putea fi altfel. + +vreaudigital.ro e un catalog open-source de tools și demo-uri construite de +programatori independenți, care arată ce e posibil când te gândești la cetățean, +nu la birocrație. + +**Ce găsești acum:** +- Traducătorul birocratic — lipești orice text oficial, primești explicația pe înțelesul tău +- Harta digitalizării — cât de "online" e primăria ta față de celelalte +- Vizualizare buget local — pe ce se duc banii din taxele tale, în grafice + +Toate sunt demo-uri reale, nu slide-uri. + +Suntem open-source: [link GitHub] + +Dacă ai construit ceva similar sau vrei să contribui, bine ai venit. + +Ce digitalizare vreți voi să existe și nu există? (Luăm sugestii serios.) +``` + +### Template thread Twitter/X + +``` +Tweet 1: +România digitală = formulare PDF, cozi la ghișeu, site-uri din 2005. +Noi arătăm cum ar putea fi altfel. + +Lansăm vreaudigital.ro — un hub open-source de digitalizare reală 🧵 + +[screenshot site] + +Tweet 2: +Nu e un alt portal guvernamental. +E un catalog de demo-uri construite de programatori independenți. + +Fiecare produs răspunde la: "ce s-ar schimba în viața ta dacă asta ar exista la primăria ta?" + +Tweet 3: +Primul demo: Traducătorul Birocratic 🏛️ +Lipești orice text oficial → primești explicația pe românește + +[GIF demo] + +Tweet 4: +Al doilea: Harta Digitalizării 🗺️ +Care primării au servicii online? Care sunt în 2005? +Date crowdsourced, actualizate de comunitate. + +Tweet 5: +Open-source, zero buget instituțional, construit în weekenduri. +Stack: Astro + Tailwind + Cloudflare Pages. + +Vrei să-ți listezi proiectul? Trimite un issue: +[link GitHub] + +Tweet 6: +#Romania #CivicTech #OpenSource #Digitalizare + +Dacă știi un programator care a construit ceva util pentru administrație — +tag-uiți-l. Vrem să-i dăm vizibilitate. +``` + +### Cine să contactezi direct (outreach personalizat) + +**Tech influenceri și comunități românești:** +- Comunitatea React România (Facebook group, ~30k membri) +- Developeri Romania (Facebook group) +- Cluj.rb, JSHeroes, TechHub Cluj — comunități locale cu reach +- Blogeri tech RO: cautăm oameni care au scris despre civic tech, gov tech, sau critica digitalizării + +**Jurnaliști relevanti:** +- Recorder.ro — investigații, ar fi interesați de harta digitalizării +- PressOne — tech și societate +- Libertatea — rubrica "România funcțională" sau similare +- G4Media — dacă harta sau bugetele devin știre + +**Nu spam blast — mesaj personalizat pentru fiecare:** +``` +Bună [Nume], + +Am văzut că ai scris/ai vorbit despre [subiect relevant]. +Tocmai am lansat vreaudigital.ro — un catalog open-source de soluții de digitalizare +pentru administrația publică din România. + +[Un lucru specific de pe site relevant pentru ei] + +Dacă crezi că e relevant pentru audiența ta, m-ar bucura să știu. +Nu e un comunicat de presă — e un proiect mic construit de 1-2 oameni. + +[Marius] +``` + +--- + +## 5. Community management post-lansare + +### Primele 48 de ore — totul contează + +- Răspunde la **orice** comentariu, issue, sau mesaj în primele 48h +- Nu lăsa nicio întrebare fără răspuns, oricât de banală +- Dacă cineva raportează un bug real, fix-ul în sub 24h și reply cu "fixed, merci" +- Dacă cineva propune ceva bun, deschide un issue ca să nu se piardă + +### Gestionarea primilor contributori + +**Primul contributor e cel mai important.** Tratează-l ca un client VIP: + +1. **Ghidare activă** — dacă deschid un PR care e aproape bun dar nu perfect, nu-l rejecta, ajută-i să-l corecteze +2. **Merge rapid** — dacă e ok, merge-uiești în 24-48h, nu în 2 săptămâni +3. **Credit public** — menționezi pe Twitter/LinkedIn: "Primul contributor extern: [nume] a adăugat [ce a adăugat]" +4. **Invitație în echipă** — după 2-3 contribuții serioase, îl faci collaborator pe repo + +**Ce faci cu submisiile de produse (Issues):** +- Review în maxim 72h (nu 2 săptămâni) +- Template de răspuns dacă lipsesc informații: + ``` + Mulțumim pentru submisie! + + Ca să putem lista produsul, avem nevoie de: + - [ ] Screenshot sau video demo (minim 30 de secunde) + - [ ] Link live sau demo funcțional + + Revenim imediat ce le ai. + ``` +- Dacă produsul nu se califică, explici clar de ce (nu un "nu se potrivește" vag) + +### Strategia de labels pe issues + +Minimal și funcțional — nu inventa 20 de labels: + +| Label | Culoare | Când îl folosești | +|-------|---------|------------------| +| `good-first-issue` | Verde deschis | Fix de typo, adăugat un produs cu template gata, fix CSS simplu | +| `help-wanted` | Galben | Funcționalitate pe care noi nu avem timp s-o facem dar e clară | +| `product-submission` | Albastru | Oricine trimite un produs nou | +| `bug` | Roșu | Ceva e stricat | +| `enhancement` | Mov | Idee de îmbunătățire confirmată | +| `wontfix` | Gri | Respins cu explicație | +| `stale` | Gri deschis | Issue inactiv 30+ zile (opțional, nu e urgent) | + +**Nu adăuga** labels de prioritate (P0/P1/P2) sau de component (frontend/backend) — overkill pentru un repo gestionat de 1-2 oameni. + +### Canal de comunicare cu comunitatea + +**Recomandare: GitHub Discussions, nu Discord (deocamdată)** + +De ce nu Discord acum: +- Discord necesită moderare activă și prezență constantă +- O comunitate Discord goală arată mai rău decât să nu ai deloc +- Oamenii nu intră pe un Discord cu 5 membri +- Revenim la Discord când avem 50+ contributori activi + +**GitHub Discussions — categorii:** +- **Anunțuri** — lansări, produse noi (doar maintainer poate posta) +- **Idei de produse** — ce ar trebui să existe pe portal +- **Ajutor** — întrebări tehnice despre cum să contribui +- **General** — orice altceva + +**Newsletter (opțional dar recomandat):** +- Buttondown.email (gratuit până la 1000 abonați) sau Substack +- Frecvență: o dată pe lună, nu mai des +- Conținut: produse noi, impact, câteva statistici, ce urmează +- Subiect: "vreaudigital — [luna] [an]: ce s-a întâmplat" + +--- + +## 6. Planul de migrare Gitea → GitHub + +### Opțiunea A — Fresh repo pe GitHub (recomandată) + +**Când s-o alegi:** Dacă git history-ul de pe Gitea conține experimente, mesaje de commit interne, sau commit-uri "WIP fix OMG", e mai curat să pornești fresh pe GitHub. + +**Pași:** +1. Creezi organizația `vreaudigital` pe GitHub +2. Creezi repo `platform` (public) +3. Pregătești codul local (curat, toate fișierele de mai sus prezente) +4. `git remote add github https://github.com/vreaudigital/platform.git` +5. `git push github main` +6. Setezi GitHub ca remote principal: `git remote set-url origin https://github.com/vreaudigital/platform.git` +7. Pe Gitea, setezi un **push mirror** spre GitHub (Settings → Git Hooks sau Mirrors) — orice push pe Gitea se duce automat și pe GitHub + +**Avantaj:** History curat pe GitHub, fără "urmele" de lucru intern. + +### Opțiunea B — Mirror automat Gitea → GitHub + +**Când s-o alegi:** Dacă history-ul e deja curat și vrei să continui să lucrezi pe Gitea. + +**Pași:** +1. Pe Gitea: Settings → Repository → Mirror Settings → Push Mirror +2. Adaugi GitHub URL + token GitHub cu permisii `repo` +3. Testezi că push-ul se propagă corect +4. Setezi sync interval: 10-30 minute (sau imediat la push) + +**Dezavantaj:** Issues, PRs, și Discussions de pe GitHub nu se sincronizează înapoi pe Gitea. Trebuie să decizi: GitHub e pentru comunitate, Gitea e pentru tine. + +### Ce rămâne pe Gitea + +- Backup complet al repo-ului (mirror pasiv) +- Folosit intern dacă vrei să experimentezi înainte de push la GitHub +- Nu îl faci public — rămâne privat ca "working copy" +- Dacă infrastructure-ul de la beletage.ro pică, GitHub rămâne up + +### Ce facem cu Cloudflare Pages + +Cloudflare Pages poate fi conectat direct la GitHub repo (nu Gitea). La lansare: +1. Deconectezi Cloudflare Pages de la Gitea (dacă era conectat) +2. Reconectezi la GitHub repo `vreaudigital/platform` +3. Deploy-ul automat merge acum din GitHub → Cloudflare Pages + +--- + +## 7. Timeline recomandată + +``` +Acum → Construiești MVP (Faza 1 din PLAN.md) +Săptămâna 4 → Site live pe vreaudigital.ro, 5 produse, 1 demo +Săptămâna 4 (end) → Checklist pre-lansare complet +Ziua X (lansare) → Gitea private → GitHub public + campanie +Ziua X+1 până X+7 → Răspunzi la tot, fix rapid, prima contribuție externă +Luna 2 → 15 produse, GitHub Discussions activ, newsletter #1 +Luna 3 → Evaluezi dacă Discord merită deschis +``` + +--- + +## 8. Ce nu faci la lansare (capcane comune) + +| Capcana | De ce o eviți | +|---------|---------------| +| Lansezi cu un README gol "coming soon" | Prima impresie = ultima impresie pe HN/Reddit | +| Ceri star-uri în mod agresiv | Pare spam, dăunează credibilității | +| Faci PR blast la zeci de oameni | Spam, te pui rău cu comunitatea | +| Promiti features care nu există | "Roadmap ambițios" fără delivery = credibilitate zero | +| Răspunzi defensiv la critici | Pe HN mai ales, critica negativă tratată bine devine pozitivă | +| Lansezi vineri seara | Postezi luni-marți dimineața pentru engagement maxim | +| Faci un GitHub cu 100 de issues deschise | Arată abandonat. Zero issues la lansare, deschizi tu câteva "good first issue" | + +--- + +## TL;DR — Checklist rapid înainte de butonul "Make public" + +``` +□ Site live pe vreaudigital.ro +□ 5+ produse cu pagini complete +□ 1+ demo funcțional (traducător birocratic recomandat) +□ README cu screenshot +□ CONTRIBUTING.md +□ LICENSE (MIT) +□ CODE_OF_CONDUCT.md +□ .github/ISSUE_TEMPLATE/ (3 template-uri) +□ .github/pull_request_template.md +□ GitHub Actions: build check pe PR +□ Niciun secret în git history +□ Org GitHub "vreaudigital" creată +□ Cloudflare Pages reconectat la GitHub +□ Draft-uri postări HN + r/Romania gata +□ 5 persoane de contactat direct pregătite +``` + +Când toate astea sunt bifate, lansezi un luni dimineața și stai toată ziua la ecran. diff --git a/PLAN-PRODUCTION.md b/PLAN-PRODUCTION.md new file mode 100644 index 0000000..cf1a110 --- /dev/null +++ b/PLAN-PRODUCTION.md @@ -0,0 +1,324 @@ +# vreaudigital.ro — Plan de Producție + +## Viziunea + +O platformă open-source unde oricine poate propune, construi și folosi soluții digitale care înlocuiesc birocrația din România. Nu un alt portal de "servicii online" — ci un ecosistem care demonstrează că se poate mai bine, și oferă instrumentele să se facă. + +**Principiul fundamental:** Un click... done. Fiecare produs de pe platformă trebuie să rezolve ceva concret care azi necesită ore/zile la un ghișeu. + +**Modelul:** 100% open-source, 100% gratuit, susținut de comunitate. Nu se monetizează niciodată. Se finanțează prin contribuții voluntare, granturi UE, și adoptare instituțională. + +--- + +## Ce există azi (aprilie 2026) + +| Componentă | Status | Live | +|------------|--------|------| +| Homepage cu manifest | ✅ | vreaudigital.ro | +| 5 produse listate | ✅ | /produse/* | +| Traducătorul Birocratic (AI demo) | ✅ Funcțional | /demo/traducator | +| Harta Banilor Publici | ✅ Funcțional | /harta | +| 598K+ înregistrări SEAP | ✅ | DB | +| 3135/3186 UAT-uri cu date | ✅ | DB | +| 12.787 licitații TED cu detalii | ✅ | DB | +| Deploy Docker + auto-deploy | ✅ | satra | + +--- + +## Ciclul de viață al unui produs + +``` +IDEE → SCHIȚĂ → PROTOTIP → MVP → PRODUCȚIE → ADOPȚIE + 💡 📝 🔧 🚀 ✅ 🏛️ + +Oricine Oricine Dev-uri Comunitate Testat Instituții +propune desenează construiesc validează real adoptă +``` + +### 1. IDEE (💡 Propunere) + +**Cine:** Oricine — cetățeni, programatori, funcționari publici. +**Cum:** Formular simplu pe site: "Ce te deranjează la stat? Ce ai vrea să faci dintr-un click?" +**Ce colectăm:** +- Problema concretă (ex: "am stat 4 ore la ghișeu pentru un certificat de urbanism") +- Cine e afectat (cetățeni / firme / primării) +- Câți oameni pe an (estimare) +- Există ceva similar în altă țară? + +**Criteriu de prioritizare:** +``` +SCOR = (Nr. oameni afectați × Timp pierdut/an × Frecvență) / Complexitate implementare +``` + +**Categorii de impact:** +| Nivel | Descriere | Exemplu | +|-------|-----------|---------| +| 🔴 Critice | Afectează >1M oameni/an, ore pierdute | Programare CI/pașaport, extras CF | +| 🟠 Importante | Afectează >100K, zile pierdute | Certificat urbanism, autorizație construire | +| 🟡 Utile | Afectează >10K, ore pierdute | Verificare PUZ/PUG, consultare dosar | +| 🟢 Nice-to-have | Transparență, informare | Harta banilor, traducător birocratic | + +### 2. SCHIȚĂ (📝 Design & Validare) + +**Output:** Un document de 1 pagină cu: +- Problema exactă +- Fluxul curent (câți pași, cât durează, ce documente) +- Fluxul propus (1-3 pași, sub 5 minute) +- Mockup UI (chiar și pe hârtie) +- Sursa de date (ce API/DB e necesar) +- Feziabilitate legală (se poate fără lege nouă?) + +**Template schiță:** `/produse/propuneri/template.md` + +### 3. PROTOTIP (🔧 Demo tehnic) + +**Cerințe minime:** +- Funcționează pe date reale (nu mock) +- Un singur flow complet (happy path) +- UI decent (nu trebuie perfect) +- Cod pe GitHub +- README cu instrucțiuni de rulare + +**Stack recomandat:** Astro + React/Svelte + Tailwind (consistență cu platforma) + +### 4. MVP (🚀 Produs minim viabil) + +**Cerințe:** +- Funcțional end-to-end +- Error handling basic +- Mobile responsive +- Performanță acceptabilă (<3s load) +- Documentat (README + cum contribui) +- Testat de minimum 10 utilizatori reali +- Date actualizate (nu snapshot vechi) + +### 5. PRODUCȚIE (✅ Adoptat pe platformă) + +**Cerințe:** +- Trecut prin review comunitate +- Securitate verificată (no XSS, no SQL injection, no data leaks) +- GDPR compliant (date personale tratate corect) +- Accesibilitate WCAG 2.1 AA +- Monitorizare (uptime, errors) +- Documentație utilizator +- Plan de mentenanță (cine actualizează datele?) + +### 6. ADOPȚIE (🏛️ Folosit de instituții) + +**Obiectiv final:** Primării, consilii locale, agenții adoptă produsul oficial. +**Cum:** Demonstrăm că funcționează → media scrie → cetățenii cer → instituțiile adoptă. + +--- + +## Ce vor românii la 1 click — Top 20 Produse + +Prioritizate pe impact × feziabilitate: + +### Tier 1 — Impact maxim, fezabile ACUM + +| # | Produs | Problema | Soluția "1 click" | Date necesare | Complexitate | +|---|--------|---------|-------------------|---------------|-------------| +| 1 | **Verifică starea dosarului** | Mergi la ghișeu să întrebi "ce se întâmplă cu dosarul meu" | Introdu nr. dosar → vezi status live | API instituții (unde există) | Medie | +| 2 | **Extras CF online** | 3-5 zile + deplasare la OCPI | CUI + nr. cadastral → PDF extras | ANCPI/eTerra API | Mare (API restricționat) | +| 3 | **Certificat fiscal instant** | Coadă la primărie, 1-3 zile | CNP/CUI → certificat digital | API primării | Mare (per primărie) | +| 4 | **Programare documente identitate** | Site MAI nefuncțional, cozi enorme | Alege data + locația → confirmare | MAI API sau scraping | Medie | +| 5 | **Verifică taxe și impozite** | Du-te la primărie să afli cât datorezi | CNP/CUI → sold taxe locale | API Ghișeul.ro/primării | Medie | + +### Tier 2 — Impact mare, necesită parteneriate + +| # | Produs | Problema | Soluția | Complexitate | +|---|--------|---------|---------|-------------| +| 6 | **Certificat urbanism digital** | 30-60 zile, dosare fizice, deplasări | Upload locație + parametri → CU draft | Mare | +| 7 | **Autorizație construire tracker** | Proces opac, luni de așteptare | Dashboard cu timeline + documente necesare | Mare | +| 8 | **Calculator taxe construcție** | Nimeni nu știe cât costă o autorizație | Parametri clădire → cost estimat complet | Medie | +| 9 | **Registratură digitală unificată** | Fiecare instituție are alt sistem | Depune cerere online → nr. înregistrare | Foarte mare | +| 10 | **Notificări termen expirat** | Uiți că ți-a expirat CI/permisul/ITP | Alertă pe email/SMS cu 30 zile înainte | Medie | + +### Tier 3 — Transparență & informare (putem face SINGURI) + +| # | Produs | Ce face | Status | +|---|--------|---------|--------| +| 11 | **Harta Banilor Publici** | Vezi unde se duc banii pe fiecare UAT | ✅ LIVE | +| 12 | **Traducătorul Birocratic** | AI traduce limbaj juridic → simplu | ✅ LIVE | +| 13 | **Monitor Licitații Live** | Feed real-time cu licitații + alerte CPV | 🔧 Date gata, UI de făcut | +| 14 | **Profil Autoritate Publică** | Fișă per primărie: buget, licitații, performanță | 🔧 Date gata | +| 15 | **Profil Firmă Publică** | Ce contracte a câștigat o firmă, unde, cât | 🔧 Date gata | +| 16 | **Comparator Primării** | Compară 2 UAT-uri: buget/cap locuitor, licitații, digitalizare | 🔧 Date gata | +| 17 | **Alertă Licitație Nouă** | Email când apare licitație pe CPV/județ/autoritate | Medie | +| 18 | **Generator Cereri** | AI completează cereri tip (reclamație, petiție, FOI) | Medie | +| 19 | **Harta Digitalizării** | Ce primărie are site, app, servicii online | De colectat | +| 20 | **Ghid Pas-cu-Pas** | "Vreau să..." → pași exacti, documente, taxe | Content | + +--- + +## Ce trebuie pentru producție + +### Tehnic + +| Componentă | Status | Ce mai trebuie | +|------------|--------|---------------| +| Hosting | ✅ Docker + Traefik pe satra | Nimic | +| Domain | ✅ vreaudigital.ro | SSL OK via Traefik | +| DB | ✅ PostgreSQL cu 600K+ records | Backup automat | +| Tiles | ✅ Martin + cache | Nimic | +| CI/CD | ✅ Gitea webhook auto-deploy | Nimic | +| Analytics | ❌ | Plausible self-hosted | +| Monitoring | ❌ | Uptime Kuma (deja pe satra) | +| Error tracking | ❌ | Sentry free tier sau logs | +| Backup DB | ❌ | pg_dump cron zilnic | +| Rate limiting | ⚠️ Partial | Adăugat pe API endpoints | + +### Conținut + +| Ce | Status | Prioritate | +|----|--------|-----------| +| Pagina "Despre" completă | ❌ | Alta | +| Pagina "Contribuie" | ❌ | Alta | +| Formular propunere produs | ❌ | Alta | +| GitHub public cu contributing.md | ❌ | Alta | +| 3+ produse noi funcționale | ❌ | Maximă | +| Blog/știri | ❌ | Medie | +| Testimoniale utilizatori | ❌ | După lansare | + +### Comunitate + +| Ce | Cum | Când | +|----|-----|------| +| GitHub public | Migrare de pe Gitea când e gata | Pre-lansare | +| Contributing guide | Template propunere + ghid tehnic | Pre-lansare | +| Discord/forum | Canal pentru discuții și propuneri | La lansare | +| Primul hackathon | "Digitalizează ceva real în 48h" | Lună 2 | +| Parteneriate ONG | Code for Romania, GovITHub, civic tech | Lună 1-2 | + +--- + +## Următorii 3 pași (săptămâna aceasta) + +### Pas 1: Produs #3 funcțional — Monitor Licitații Live +Avem 598K records + 12.787 TED cu detalii complete. Trebuie doar UI: +- Pagina `/licitatii` cu search, filtre (CPV, județ, valoare, tip) +- Card per licitație cu: titlu, autoritate, valoare, termen depunere, link TED/SEAP +- Alerte email pe CPV (formular simplu) +- **Datele sunt gata. E doar frontend.** + +### Pas 2: Produs #4 — Profil Autoritate Publică +Pagina `/autoritate/:cui` cu: +- Numele, adresa, județul (din ANAF dump) +- Toate achizițiile și licitățiile +- Top furnizori +- Grafic temporal cheltuieli +- Comparație cu media pe județ +- **Datele sunt gata. E doar frontend.** + +### Pas 3: Formular propunere + pagina contribuie +- `/propune` — formular: ce problemă ai, cine ești, ideia ta +- `/contribuie` — ghid: cum propui, cum construiești, cum review-uiești +- GitHub issue template automat din formular + +--- + +## Strategia de lansare + +### Pre-lansare (acum) +- Finalizare 3 produse funcționale (harta, traducător, monitor licitații) +- Pagina contribuie + formular propunere +- Analytics (Plausible) +- Backup DB + +### Soft launch (săptămâna viitoare) +- Post pe Hacker News Romania, /r/Romania, Facebook tech groups +- Email către Code for Romania, GovITHub +- Invitare 10-20 dev-uri din comunitate să testeze + +### Public launch (luna viitoare) +- Article Hotnews/Digi24/Libertatea +- Prezentare la meetup-uri tech (Cluj, București) +- GitHub public + star campaign +- Primul hackathon online + +### Creștere (lunile 2-6) +- 20+ produse listate +- 5+ produse funcționale +- Prima primărie care adoptă ceva +- Parteneriat cu o universitate (studenți contribuie) +- Aplicare grant UE pentru digitalizare + +--- + +## Cum decidem ce merită implementat + +### Matricea de decizie + +``` + IMPACT MARE + │ + ┌────────────┼────────────┐ + │ │ │ + │ PRIORITAR │ IDEAL │ + │ (date │ (date + │ + │ disponib) │ partener) │ + │ │ │ +SIMPLU ────┼────────────┼────────────┤──── COMPLEX + │ │ │ + │ QUICK WIN │ AMÂNAT │ + │ (facem │ (așteptăm │ + │ oricum) │ resurse) │ + │ │ │ + └────────────┼────────────┘ + │ + IMPACT MIC +``` + +### Reguli concrete: + +1. **Date disponibile?** Dacă datele sunt publice și accesibile → prioritar +2. **Un dev poate face MVP în 1 săptămână?** → prioritar +3. **Rezolvă ceva ce azi necesită deplasare fizică?** → prioritar +4. **Necesită parteneriat cu instituție?** → planificare pe termen mediu +5. **Necesită modificare legislativă?** → advocacy, nu implementare +6. **Există deja în altă țară UE?** → copiază și adaptează + +### Votul comunității + +Fiecare propunere primește voturi (upvote pe GitHub Issues sau pe site). Top 5 lunar intră în sprint-ul de dezvoltare. Transparență totală — oricine vede ce se lucrează și de ce. + +--- + +## Open-source by default + +### Licența: MIT +Tot codul, toate datele, toate instrumentele — MIT license. Oricine poate copia, modifica, folosi, inclusiv comercial. Scopul nu e să controlăm — e să accelerăm. + +### Structura repo-uri: +``` +github.com/vreaudigital/ +├── platform/ ← site-ul principal (Astro) +├── seap-data/ ← pipeline date achiziții publice +├── traducator/ ← AI translator engine +├── monitor/ ← sistem monitorizare licitații +├── ghid-digital/ ← conținut ghiduri pas-cu-pas +└── template/ ← template pentru produs nou +``` + +### Cum contribui: +1. **Propune** — deschide Issue cu template +2. **Discută** — comunitatea dă feedback, votează +3. **Construiește** — fork, implementează, PR +4. **Review** — 2 review-uri necesare pentru merge +5. **Deploy** — CI/CD automat după merge + +--- + +## Obiectivul: România #1 digital în UE + +Nu suntem departe. România are: +- Programatori excelenți (top 10 mondial per capita) +- Infrastructură internet rapidă (#1 UE la broadband) +- Dorință reală de schimbare +- Tineret tech-savvy + +Ce ne lipsește: **platformă unde lucrurile se fac, nu doar se discută.** + +vreaudigital.ro = locul unde digitalizarea devine realitate, o funcționalitate la un timp, un click la un timp. + +Nu așteptăm statul. Construim noi. Statul va urma. diff --git a/PLAN-PRODUCTS-V2.md b/PLAN-PRODUCTS-V2.md new file mode 100644 index 0000000..11e68d2 --- /dev/null +++ b/PLAN-PRODUCTS-V2.md @@ -0,0 +1,553 @@ +# PLAN-PRODUCTS-V2.md — Produse ancoră "One-Click" pentru vreaudigital.ro + +**Data:** 7 aprilie 2026 +**Autor:** Marius + Claude +**Status:** V2 — revizuit radical după feedback-ul "nu strigă vreau digital" +**Dependințe:** Citește PLAN.md pentru context general + +--- + +## Filozofia V2: Testul demoanaf.ro + +Fiecare produs trebuie să treacă **testul demoanaf**: + +> Un om intră pe pagină, face o singură acțiune (scrie un număr, alege o opțiune, dă click pe un buton) și primește INSTANT ceva care în mod normal îi ia ore/zile/drumuri la ghișeu. + +**Ce a schimbat demoanaf.ro:** +- Daniel Tamaș din Cluj a reconstruit portalul ANAF în 2 ore +- 44.000 vizite în 3 zile, 200.000 pageviews +- Contactat de vicepremier și ministrul finanțelor +- CJ Cluj a semnat parteneriat de digitalizare cu el +- Aceleași date publice, aceeași funcționalitate — dar modern, rapid, mobil + +**Lecția:** Nu trebuie să inventezi date noi. Trebuie să iei datele publice existente (care sunt într-o interfață din 2005) și să le prezinți cum ar trebui să arate în 2026. + +--- + +## Inventarul datelor publice din România — ce există REAL + +Înainte de produse, un inventar brutal de onest al surselor de date disponibile: + +### Date cu acces programatic (API sau structurat) + +| Sursă | Ce conține | Acces | Calitate | +|-------|-----------|-------|----------| +| **ANAF Web Services** (webservicesp.anaf.ro) | Verificare TVA, CUI, stare fiscală, e-Factura | API REST public, POST cu CUI + dată | Bun, actualizat zilnic | +| **Ministerul Finanțelor** (mfinante.gov.ro/info-pj) | Date identificare firme, bilanțuri, situații financiare | Pagină web queryable by CUI | Bun, date anuale | +| **Transparență Bugetară** (mfinante.gov.ro/apps/transparenta-bugetara) | Execuție bugetară pentru 13.700+ entități publice | Pagină web, date PDF/XLSX/XML | Bun, actualizat lunar | +| **ForexePublic** (forexepublic.mfinante.gov.ro) | Date financiare instituții publice | Portal web | Mediu, interfață greoaie | +| **data.gov.ro** | ~1500 seturi de date publice, diverse domenii | API CKAN (package_list, package_show) | Variabil, multe neactualizate | +| **SICAP/SEAP** (e-licitatie.ro) | Achiziții publice, licitații | Date publice, API nedocumentat dar scrapable | Bun, SICAP.ai a demonstrat că merge | +| **portal.just.ro** (ECRIS) | Dosare instanțe, termene, soluții | Pagină web scrapable | Bun, actualizat zilnic | +| **RAR** (rarom.ro, prog.rarom.ro) | Verificare ITP, istoric vehicul | Pagină web queryable | Bun | +| **CNAIR** (erovinieta.ro) | Verificare rovinietă | Pagină web queryable | Bun | +| **CNAS** (siui.casan.ro) | Verificare calitate asigurat sănătate | Pagină web, query by CNP | Bun | +| **ANCPI/MyETerra** (myeterra.ancpi.ro) | Extras CF, plan cadastral | Portal cu ROeID auth | Gratuit din iunie 2025, dar necesită ROeID | +| **ANCPI Geoportal** (geoportal.ancpi.ro) | Servicii INSPIRE, parcele cadastrale, limite UAT | WMS/WFS services | Bun, standard EU | +| **DGPCI** (dgpci.mai.gov.ro) | Verificare permis auto, programare ghișeu | Portal web | Mediu | +| **hub.mai.gov.ro** | Programare pașaport, carte identitate | Portal web | Bun, funcțional | + +### Date publice dar fără acces programatic (necesită scraping/descărcare manuală) + +| Sursă | Ce conține | Format | Dificultate | +|-------|-----------|--------|-------------| +| Site-uri primării (~3200 UAT-uri) | PUG-uri, bugete locale, HCL-uri, taxe locale | PDF-uri scanate, Excel-uri, pagini web | Mare — fiecare primărie e diferită | +| ANAF — liste contribuabili | Firme inactive, firme în insolvență | CSV/PDF pe site ANAF | Mediu | +| BNR | Cursuri valutare, statistici | XML feed | Mic — feed structurat | + +### Date care NU există public (deși ar trebui) + +- **Registrul urbanistic centralizat** — fiecare primărie are propriul PUG, format diferit, nu există hartă națională +- **Starea reală a serviciilor publice per primărie** — nimeni nu măsoară asta centralizat +- **Timpii reali de procesare a cererilor** — cât durează efectiv un certificat de urbanism la fiecare primărie +- **Cadastru complet** — doar ~70% din teritoriul României e cadastrat +- **API unificat pentru taxe locale** — fiecare primărie are propriul sistem, propriile grile + +--- + +## Produsele ancoră — V2 + +### Produs 0 (Featured): demoanaf.ro + +> **Deja există. Îl prezentăm pe hub ca exemplul #1 de "ce înseamnă vreau digital".** + +**Numele:** demoanaf.ro +**Făcut de:** Daniel Tamaș, Cluj +**Pain point:** Portal ANAF vechi, lent (15+ secunde per operație), nefolosibil pe mobil +**One-click promise:** Verificare CUI, curs valutar, calendar fiscal, validare e-Factura — instant, pe mobil +**Date sursă:** API-uri publice ANAF + BNR (aceleași date, interfață nouă) +**Demo wow:** Side-by-side: anaf.ro vs demoanaf.ro — aceeași operațiune, 15 secunde vs 1 secundă +**De ce îl listăm:** E gold standard-ul. Arată exact filosofia vreaudigital.ro. Plus, Daniel e din Cluj, potențial prim partener. + +**Acțiune:** Contactează Daniel Tamaș, propune-i să fie featured pe hub. E deja în discuții cu CJ Cluj — interesul e mutual. + +--- + +### Produs 1: DemoFirmă — "Radiografia oricărei firme din România" + +**Numele:** DemoFirmă (sau VerificăFirma, RadiografieFirmă) + +**Pain point-ul:** +Vrei să verifici o firmă (furnizor, angajator, partener). Acum trebuie să intri pe: +- mfinante.gov.ro → cauți după CUI → interfață din 2008, date greu de citit +- ANAF → verifici dacă e plătitor TVA, dacă e activă +- ONRC → verifici cine sunt asociații +- portal.just.ro → verifici dacă are dosare în instanță +- e-licitatie.ro → verifici dacă are contracte publice + +**Cinci site-uri diferite, cinci interfețe diferite, 20+ minute.** + +**One-click promise:** +Introdu CUI-ul → primești TOTUL pe o singură pagină, frumos formatat: +- Date identificare (denumire, adresă, CAEN, stare) +- Situație fiscală (TVA, e-Factura, inactivitate) +- Bilanț simplificat (cifra de afaceri, profit, angajați) — grafic pe ultimii 5 ani +- Dosare în instanță (număr, tip, stadiu) +- Contracte publice (din SICAP — ce a vândut statului) +- Asociați și administratori + +**Date sursă:** +- **ANAF API** (webservicesp.anaf.ro) — stare TVA, e-Factura, inactivitate → **API REST public, documentat** +- **MF info-pj** (mfinante.gov.ro) — bilanțuri, date identificare → **pagină web queryable, scraping simplu** +- **portal.just.ro** — dosare → **scrapable, structură cunoscută** +- **SICAP.ai** — achiziții publice → **API deschis, open source (github.com/ciocan/sicap.ai)** +- **ONRC** — asociați → **mai greu, portal cu CAPTCHA, dar date parțiale pe listafirme.eu** + +**Demo wow — 30 secunde:** +Scenariul: "Hai să vedem ce face firma X SRL" +- Tastezi CUI-ul +- BAM: card vizual cu toate datele, grafice, timeline dosare +- Compari cu ce vezi pe mfinante.gov.ro — diferența e brutală +- Textul viral: "Am aflat în 3 secunde tot ce trebuia să știu despre firma la care mă angajez. Normal dura o oră pe 5 site-uri." + +**Efort MVP:** + +| Task | Timp | Notă | +|------|:----:|------| +| Integrare ANAF API (TVA, stare fiscală) | 4h | API documentat, simplu | +| Scraping MF info-pj (bilanțuri) | 8h | HTML parsing, dar structură stabilă | +| Scraping portal.just.ro (dosare) | 8h | Structură cunoscută, dar rate limiting | +| Integrare SICAP.ai API (contracte publice) | 4h | API deschis | +| UI: pagină rezultat cu carduri + grafice | 12h | Recharts pentru bilanț, timeline pentru dosare | +| Backend: Cloudflare Worker agregator | 8h | Cache agresiv, proxy pentru scraping | +| **TOTAL** | **~44h** | **1 dev, 6 zile** | + +**Potențial viral:** +ENORM. Toată lumea verifică firme: angajați, freelanceri, contabili, jurnaliști, investitori. E tipul de tool pe care îl bookmark-uiești. Similar cu ce face termene.ro sau confidas.ro, dar GRATUIT și open-source. + +**Risc principal:** +Rate limiting pe site-urile scrapate (MF, portal.just.ro). Mitigare: cache agresiv (datele se schimbă rar), request queue, fallback graceful ("date indisponibile momentan, reîncearcă în 5 minute"). + +--- + +### Produs 2: DemoImpozit — "Calculează-ți TOATE impozitele în 60 de secunde" + +**Numele:** DemoImpozit (sau ImpoziteleMe, CâtPlătesc) + +**Pain point-ul:** +Românul mediu plătește: impozit pe venit/salariu, impozit auto, impozit clădire, impozit teren, rovinietă. Pentru fiecare trebuie: +- Să știe formula (care s-a schimbat în 2026 pentru auto!) +- Să caute grila de impozitare a primăriei tale (fiecare primărie are alte niveluri) +- Să facă calculul manual sau să intre pe calculatoare separate (impozitauto.ro, site-ul primăriei, etc.) + +**Nimeni nu știe exact cât plătește pe an către stat. Nimeni.** + +**One-click promise:** +Completezi un mini-formular (5 câmpuri): +1. Orașul tău (dropdown) +2. Venitul lunar brut (slider) +3. Mașina ta (motorizare + normă Euro — sau doar model din dropdown) +4. Apartamentul/casa (suprafață + tip) +5. Teren (suprafață, dacă ai) + +→ Primești **un dashboard personal**: "Tu plătești 14.280 lei/an către stat. Iată cum se împarte:" +- Grafic pie: CAS 25%, CASS 10%, impozit venit 10%, impozit auto 228 lei, impozit clădire 450 lei... +- Per lună: "Plătești 1.190 lei/lună. Din care 380 lei contribuții sociale, 810 lei impozite directe." +- Comparație cu alte orașe: "Dacă ai fi în Timișoara, ai plăti cu 120 lei/an mai puțin" + +**Date sursă:** +- **Formule impozit auto 2026** — publice, în Codul Fiscal (noi le hardcodăm) +- **Grile impozit clădire/teren** — publicate de fiecare primărie prin HCL (le colectăm manual pentru top 10-20 orașe) +- **Formule CAS, CASS, impozit venit** — publice, în Codul Fiscal +- **BNR cursuri** — XML feed public (dacă e nevoie) + +**Demo wow — 30 secunde:** +- Screenshot 1: Formularul simplu, curat, 5 câmpuri +- Screenshot 2: Dashboard-ul personal — grafic mare, cifre clare, comparație orașe +- Textul viral: "Am aflat că plătesc 14.280 lei/an. 1.190 lei/lună. Și am aflat că dacă m-aș muta în Oradea, aș plăti cu 200 lei/an mai puțin la impozitul pe clădire." + +**Efort MVP:** + +| Task | Timp | Notă | +|------|:----:|------| +| Cercetare: colectare grile impozite top 20 orașe | 8h | Muncă manuală, de pe site-uri primării | +| Formule calcul (CAS, CASS, venit, auto, clădire, teren) | 6h | Cod Fiscal 2026 | +| UI: formular input + dashboard output | 12h | Client-side, zero backend | +| Grafice (pie chart, comparație orașe) | 6h | Recharts sau Chart.js | +| Integrare Astro | 2h | | +| Testare cu cazuri reale | 4h | Verificăm cu câțiva oameni reali | +| **TOTAL** | **~38h** | **1 dev, 5 zile** | + +**Potențial viral:** +MASIV. Toată lumea vrea să știe "cât dau la stat". E personal, e share-able ("tu cât ai?"), e educational. Jurnaliștii adoră comparații între orașe. Contabilii îl vor recomanda clienților. + +**Risc principal:** +Grilele de impozite diferă între primării și se schimbă anual. Mitigare: acoperim doar top 20 orașe, afișăm data ultimei actualizări, punem link către sursa oficială. Datele se schimbă o dată pe an (ianuarie), deci mentenanța e minimă. + +--- + +### Produs 3: DemoDosar — "Urmărește orice dosar din instanță, simplu" + +**Numele:** DemoDosar (sau DosarulMeu, JustițieClară) + +**Pain point-ul:** +Ai un dosar în instanță (divorț, litigiu cu vecinul, contestație amendă, orice). Ca să vezi ce se întâmplă: +- Intri pe portal.just.ro — site din era SharePoint 2007 +- Navigarea e un coșmar: alegi instanța, tipul, faci search +- Informația e într-un tabel comprimat, fără formatare +- Nu poți pune notificări (trebuie să intri manual periodic) +- Pe mobil: INUTILIZABIL + +**One-click promise:** +Introdu numărul dosarului (ex: "123/211/2026") → +- Timeline vizuală clară: fiecare termen, fiecare acțiune, fiecare soluție +- Status mare și clar: "Următorul termen: 15 mai 2026, ora 10:00, Sala 3" +- Părți implicate, obiect dosar, instanța +- Abonare notificări (email) — "te anunțăm când apare ceva nou" +- Link direct la portal.just.ro pentru detalii oficiale + +**Date sursă:** +- **portal.just.ro** (ECRIS) — toate dosarele instanțelor din România, date publice +- Structura e cunoscută — mai multe proiecte au scrapuit-o deja (portal-just.ro, infodosare.ro, lege5.ro) +- Nu există API oficial, dar datele sunt publice și structurate în HTML + +**Demo wow — 30 secunde:** +Side-by-side: +- Stânga: portal.just.ro — tabel comprimat, font mic, neformatat +- Dreapta: DemoDosar — timeline elegantă, status colorat, mobile-first +- Textul viral: "Mama mea are un proces de 2 ani. Până acum verifica portal.just.ro o dată pe săptămână. Acum primește notificare pe email." + +**Efort MVP:** + +| Task | Timp | Notă | +|------|:----:|------| +| Scraping portal.just.ro (structură HTML) | 10h | Structură stabilă, dar complexă | +| Backend: Worker care extrage + cache-uiește | 8h | Cloudflare Worker + KV cache | +| UI: timeline vizuală + status card | 10h | React component, mobile-first | +| Notificări email (opțional MVP) | 6h | Cron check + email via Brevo/Resend | +| Integrare Astro | 2h | | +| **TOTAL** | **~36h** | **1 dev, 5 zile** | + +**Potențial viral:** +Mare. Sute de mii de români au dosare active în instanță. Avocații îl vor recomanda clienților. Jurnaliștii de investigație îl vor folosi zilnic. Notificările email sunt killer feature — nimeni altcineva nu oferă asta gratuit. + +**Risc principal:** +portal.just.ro poate schimba structura HTML sau poate pune rate limiting. Mitigare: cache agresiv (termene noi apar rar), scraping politicos, fallback la link direct oficial. + +--- + +### Produs 4: DemoCF — "Extras de Carte Funciară — vezi ce scrie în CF despre orice imobil" + +**Numele:** DemoCF (sau CărțiFunciare, ImobilulMeu) + +**Pain point-ul (perspectiva lui Marius, arhitect):** +Ca arhitect, pentru FIECARE proiect ai nevoie de extras CF. Procesul: +- Intri pe epay.ancpi.ro — plătești 20 lei per extras +- SAU intri pe MyETerra (gratuit din iunie 2025) — dar ai nevoie de cont ROeID +- Interfața MyETerra e funcțională dar greoaie +- Dacă ești cetățean simplu: probabil nici nu știi ce e CF-ul sau de ce ai nevoie de el + +Din iunie 2025, ANCPI oferă extras CF GRATUIT prin MyETerra cu autentificare ROeID. Asta schimbă jocul. + +**One-click promise:** +O interfață modernă care: +1. Explică pe înțelesul tuturor: "Ce e Cartea Funciară și de ce contează" +2. Te ghidează pas cu pas să-ți faci cont ROeID (dacă n-ai) +3. Te trimite direct la MyETerra cu instrucțiuni clare +4. **Bonus:** Vizualizare pe hartă — introdu adresa, vezi parcela pe hartă (via ANCPI Geoportal WMS services) +5. **Bonus 2:** "Traduce" extrasul CF — ia documentul oficial și explică fiecare secțiune pe limba omului + +**Date sursă:** +- **ANCPI Geoportal** (geoportal.ancpi.ro) — servicii WMS/WFS publice, parcele cadastrale, ortofotoplan +- **MyETerra** (myeterra.ancpi.ro) — extras CF gratuit (redirect, nu replicăm) +- **ANCPI ePay** — extras CF 20 lei (redirect alternativ fără ROeID) + +**IMPORTANT: Nu replicăm datele ANCPI.** Nu scrapăm, nu proxy-im. Facem un wrapper UX care: +- Explică pe limba omului +- Vizualizează pe hartă (cu serviciile WMS publice, legal) +- Redirectează către MyETerra/ePay pentru documentul oficial + +**Demo wow — 30 secunde:** +- Introduci o adresă +- Apare harta cu parcela evidențiată (WMS ANCPI) +- Buton mare: "Obține extras CF gratuit" → te duce la MyETerra +- Sub hartă: "Ce vei găsi în extras: proprietar, suprafață, sarcini, ipoteci" +- Textul viral: "Am văzut pe hartă exact parcela mea și am aflat că vecinul are ipotecă la bancă. Totul gratuit." + +**Efort MVP:** + +| Task | Timp | Notă | +|------|:----:|------| +| Integrare hartă (Leaflet + ANCPI WMS) | 8h | Servicii WMS publice, documentate | +| Geocoding adresă → coordonate | 4h | Nominatim/OpenStreetMap, gratuit | +| UI: pagină explicativă + hartă + CTA-uri | 8h | Content + design | +| "Traducător CF" — explicații secțiuni | 4h | Content, eventual AI | +| Integrare Astro | 2h | | +| **TOTAL** | **~26h** | **1 dev, 3-4 zile** | + +**Potențial viral:** +Mare în rândul profesioniștilor imobiliari (arhitecți, notari, agenți, avocați) și al oricui cumpără/vinde un imobil. Funcția de hartă e wow factor-ul — nimeni nu a făcut asta frumos. + +**Risc principal:** +Serviciile WMS ANCPI pot fi lente sau indisponibile. Mitigare: fallback pe OpenStreetMap, cache de tile-uri, mesaj "serviciu ANCPI temporar indisponibil". + +--- + +### Produs 5: DemoAchiziții — "Pe ce cheltuie statul banii TĂI" + +**Numele:** DemoAchiziții (sau BaniiMei, CheltuilPublice) + +**Pain point-ul:** +Statul cheltuie ~100 miliarde lei/an pe achiziții publice. Datele sunt pe e-licitatie.ro (SEAP/SICAP), dar: +- Interfața e enterprise-greoaie, filtrele sunt confuze +- Nu poți vedea simplu "ce a cumpărat primăria mea" +- Nu poți compara ușor: "primăria X a plătit 500 lei pe o tastatură?" +- SICAP.ai (open source!) a demonstrat deja că datele se pot extrage și prezenta frumos + +**One-click promise:** +Alegi orașul tău → vezi instant: +- Top 10 achiziții ale primăriei (sumă, furnizor, ce s-a cumpărat) +- Grafic: cheltuieli pe categorii (IT, construcții, servicii, etc.) +- Red flags automate: "Achiziție directă de 130.000 lei către firma X — singurul ofertant" +- Comparație: "Primăria Cluj a plătit 2.000 lei pentru o imprimantă. Primăria Sibiu a plătit 800 lei pentru aceeași." + +**Date sursă:** +- **SICAP.ai** — open source (github.com/ciocan/sicap.ai), API disponibil, 22M+ achiziții directe +- **e-licitatie.ro** — sursa oficială, date sub licență OGL Romania +- Datele sunt actualizate zilnic + +**Demo wow — 30 secunde:** +- Alegi "Cluj-Napoca" +- BAM: dashboard cu top achiziții, grafice, comparații +- Click pe o achiziție suspectă → detalii complete +- Textul viral: "Primăria mea a plătit 45.000 lei pe 'servicii de consultanță' către o firmă cu 1 angajat. Vreau explicații." + +**Efort MVP:** + +| Task | Timp | Notă | +|------|:----:|------| +| Integrare API SICAP.ai | 6h | API documentat, open source | +| Pipeline date: agregare per primărie | 8h | Filtrare + grouping | +| UI: dashboard achiziții + grafice + comparații | 12h | Recharts, carduri, filtre | +| Algoritm "red flags" simplu | 6h | Reguli bazice: singurul ofertant, sumă mare, frecvență | +| Integrare Astro | 2h | | +| **TOTAL** | **~34h** | **1 dev, 4-5 zile** | + +**Potențial viral:** +NUCLEAR. Jurnaliștii de investigație visează la asta. Fiecare cetățean e curios pe ce se duc banii. Fiecare postare cu un "red flag" = viral pe social media. Recorder, PressOne, Libertatea ar prelua instant. + +**Risc principal:** +Datele din SICAP sunt voluminoase și uneori incomplete. Mitigare: ne concentrăm pe achiziții directe (mai ușor de analizat, mai multe red flags), limităm la top 50 orașe, cache agresiv. + +--- + +### Produs 6: DemoITP — "Verifică ITP-ul oricărei mașini instant" + +**Numele:** DemoITP (sau VerificăMașina, ITPCheck) + +**Pain point-ul:** +Cumperi o mașină second-hand. Vrei să verifici: +- Are ITP valid? (prog.rarom.ro — interfață veche, greu de folosit pe mobil) +- Care e istoricul? (RAR Auto-Pass — 82 lei + TVA, nu e gratuit) + +**One-click promise:** +Introdu numărul de înmatriculare → vezi instant: +- ITP valid: DA/NU + data expirării +- Istoric ITP (ultimele inspecții) +- Link rapid către RAR Auto-Pass pentru istoric complet + +**Date sursă:** +- **RAR** (prog.rarom.ro) — verificare ITP gratuită, pagină web queryable +- **RAR Auto-Pass** — istoric complet, plătit (82 lei) — doar link/redirect + +**Demo wow:** +- Tastezi "CJ 99 XYZ" +- Instant: "ITP VALID până la 15.08.2026 ✅" +- Sau: "ITP EXPIRAT din 01.12.2025 ❌ — ATENȚIE: circulă fără ITP!" +- Textul viral: "Am verificat mașina pe care voiam s-o cumpăr. ITP expirat de 6 luni. Vânzătorul zicea că 'e totul ok'." + +**Efort MVP:** + +| Task | Timp | Notă | +|------|:----:|------| +| Scraping RAR verificare ITP | 6h | Pagină simplă, structură stabilă | +| Backend Worker + cache | 4h | Cloudflare Worker | +| UI: input + rezultat vizual | 6h | Card simplu, verde/roșu | +| Integrare Astro | 2h | | +| **TOTAL** | **~18h** | **1 dev, 2-3 zile** | + +**Potențial viral:** +Mare, special în comunitățile auto. Fiecare tranzacție SH e o oportunitate de share. + +--- + +### Produs 7: DemoAsigurat — "Ești asigurat la sănătate? Află în 5 secunde" + +**Numele:** DemoAsigurat (sau SuntAsigurat, SănătateMea) + +**Pain point-ul:** +Mulți români nu știu dacă sunt asigurați la sănătate. Platforma oficială (siui.casan.ro) funcționează, dar: +- Interfața e minimalistă-urâtă +- Nu explică CE ÎNSEAMNĂ rezultatul +- Dacă nu ești asigurat, nu îți spune CE SĂ FACI +- Pe mobil: funcționează dar arată din 2010 + +**IMPORTANT: Acest produs necesită CNP. Asta ridică probleme de privacy serios.** + +**One-click promise:** +Introdu CNP-ul → vezi instant: +- ASIGURAT ✅ sau NEASIGURAT ❌ +- Dacă asigurat: prin ce categorie (angajat, pensionar, etc.) +- Dacă neasigurat: explicație clară + pași concreți ce trebuie să faci +- Link-uri utile: casa de asigurări din județul tău, formular înscriere, drepturi + +**De ce îl facem wrapper, nu clone:** +CNP-ul e dată personală sensibilă. NU vrem să proxy-im CNAS-ul — nu vrem să avem acces la date personale. Facem un wrapper care: +- Explică procesul +- Redirectează la CNAS oficial pentru verificare +- După verificare, oferă ghid contextual ("ai văzut că nu ești asigurat? iată ce faci") + +**Efort MVP:** ~12h (1-2 zile) — e în mare parte content + UX, nu backend. + +**Potențial viral:** Mediu-mare. Multi romani nu știu că nu sunt asigurați. "Mama mea nu știa că nu mai e asigurată de când a ieșit la pensie timpurie." + +--- + +## Proiecte civic tech existente în România — peisajul + +Înainte de a decide lineup-ul, e important să știm cine mai face chestii similare: + +| Proiect | Ce face | Status | Relația cu noi | +|---------|---------|--------|----------------| +| **demoanaf.ro** (Daniel Tamaș) | Portal ANAF modern | Activ, viral, parteneriat CJ Cluj | **Featured pe hub, primul produs** | +| **Code for Romania** | 27+ soluții civice, Decidim, bugetare participativă | Activ, 3300+ voluntari | Inspirație, potențial parteneriat, dar sunt ONG mare — noi suntem altceva | +| **SICAP.ai** (Radu Ciocan) | Search engine achiziții publice | Activ, open source | **Sursa de date pentru DemoAchiziții** | +| **civictech.ro** | Catalog proiecte civic tech | Activ | **Competitor direct, dar inactiv/slab** | +| **impozitauto.ro** | Calculator impozit auto 2026 | Activ | Ne inspirăm, dar facem ALL-IN-ONE | +| **listafirme.eu** | Database firme cu API | Activ, freemium | Inspirație pentru DemoFirmă | +| **termene.ro** | Monitorizare firme, dosare, insolvență | Activ, plătit | Competiție indirectă — noi suntem gratuit + open source | +| **infodosare.ro** | Dosare instanțe cu notificări | Activ | Competiție — noi facem mai frumos, gratuit | +| **certificateurbanism.ro** | Obținere certificat urbanism online | Activ, plătit | Complementar, nu competiție directă | + +--- + +## Recomandare: Lineup-ul de lansare (Top 5) + +### Criteriul de selecție + +| Criteriu | Greutate | Explicație | +|----------|:--------:|-----------| +| **One-click test** | 30% | Apeși un buton, primești ceva valoros instant | +| **Date disponibile** | 25% | Datele există și sunt accesibile programatic | +| **Efort MVP** | 20% | Poate fi construit în max 1 săptămână | +| **Potențial viral** | 15% | Oamenii îl share-uiesc spontan | +| **Unicitate** | 10% | Nu există deja ceva similar și bun | + +### Scoruri + +| Produs | One-click (30%) | Date (25%) | Efort (20%) | Viral (15%) | Unic (10%) | **TOTAL** | +|--------|:-:|:-:|:-:|:-:|:-:|:-:| +| **demoanaf.ro** (featured) | 5 | 5 | 5 (0 efort, deja există) | 5 | 5 | **5.00** | +| **DemoFirmă** | 5 | 4 | 3 | 5 | 3 | **4.10** | +| **DemoImpozit** | 5 | 4 | 4 | 5 | 4 | **4.45** | +| **DemoDosar** | 5 | 4 | 4 | 4 | 3 | **4.10** | +| **DemoCF** | 3 | 3 | 4 | 3 | 4 | **3.30** | +| **DemoAchiziții** | 4 | 5 | 3 | 5 | 3 | **4.05** | +| **DemoITP** | 5 | 4 | 5 | 4 | 3 | **4.20** | +| **DemoAsigurat** | 4 | 3 | 5 | 3 | 3 | **3.50** | + +### Lineup recomandat — în ordinea construcției + +| # | Produs | Efort | Când | De ce | +|---|--------|:-----:|------|-------| +| 0 | **demoanaf.ro** (featured) | 0 | Ziua 1 | Contactăm Daniel, listăm pe hub. Zero efort de construcție. | +| 1 | **DemoImpozit** | 5 zile | Săptămâna 2-3 | Cel mai personal ("cât plătesc EU"), maxim viral, zero dependență de API-uri externe (formulele sunt publice) | +| 2 | **DemoITP** | 2-3 zile | Săptămâna 3 | Cel mai rapid de construit, one-click curat, toată lumea are mașină | +| 3 | **DemoFirmă** | 6 zile | Săptămâna 4-5 | Cel mai impresionant tehnic, agrează 5 surse, util zilnic pentru business | +| 4 | **DemoAchiziții** | 4-5 zile | Săptămâna 5-6 | Nuclear viral, datele vin gratuit din SICAP.ai open source | +| 5 | **DemoDosar** | 5 zile | Săptămâna 6-7 | Util, diferențiator, notificările email sunt killer feature | + +**Total timeline: ~7 săptămâni pentru 5 produse + 1 featured.** + +### De ce NU DemoCF la lansare + +DemoCF e important pentru Marius (arhitect), dar: +- Necesită ROeID (barieră de adopție) +- Nu putem replica datele ANCPI (legal + tehnic complicat) +- Wrapper UX e mai puțin "wow" decât un tool care îți dă date instant +- Vine la faza 2, când avem trafic și credibilitate + +### De ce NU DemoAsigurat la lansare + +- Privacy concern: CNP e dată sensibilă +- CNAS-ul funcționează OK (nu e la fel de rupt ca anaf.ro) +- Wrapper fără date proprii = mai puțin impactant +- Vine la faza 2 ca produs educational/ghid + +--- + +## Narativul integrat — cum se leagă toate + +Pagina principală vreaudigital.ro: + +``` +"România merită servicii digitale care funcționează. +Nu PDF-uri online. Nu site-uri din 2005. +Servicii REALE, RAPIDE, FRUMOASE. + +Iată cum arată digitalizarea adevărată:" + +[demoanaf.ro] — "ANAF-ul, dar cum ar trebui să fie" +[DemoImpozit] — "Toate impozitele tale, într-un singur loc" +[DemoITP] — "ITP-ul mașinii, verificat în 5 secunde" +[DemoFirmă] — "Radiografia completă a oricărei firme" +[DemoAchiziții] — "Pe ce cheltuie primăria ta banii" +[DemoDosar] — "Dosarul tău din instanță, clar și simplu" + +"Fiecare tool de mai sus folosește DATE PUBLICE care DEJA EXISTĂ. +Noi doar le-am pus într-o interfață din 2026, nu din 2005. + +Asta înseamnă vreau digital." +``` + +Fiecare produs e un "demoanaf" pentru alt ghișeu. Fiecare demonstrează același lucru: **datele există, interfețele sunt de rahat, se poate mult mai bine, cu efort minim.** + +--- + +## Decizii de luat acum + +1. ☐ **Contactează Daniel Tamaș** — propune-i featured pe vreaudigital.ro, discută viziunea +2. ☐ **Contactează Radu Ciocan (SICAP.ai)** — confirmă accesul la API, discută colaborare +3. ☐ **Validează accesul la ANAF API** — test rapid: POST cu un CUI, vezi dacă răspunde +4. ☐ **Testează ANCPI WMS** — încarcă un layer WMS în Leaflet, vezi dacă merge +5. ☐ **Alege stack-ul** — confirmă Astro + React islands + Cloudflare Workers (din PLAN.md) +6. ☐ **Cumpără domeniu** — vreaudigital.ro +7. ☐ **Decide naming** — "Demo*" ca prefix unificat? Sau fiecare cu nume propriu? + +--- + +## Nota finală: De ce V2 e radical diferit de V1 + +**V1 propunea:** Traducător birocratic (AI), Harta digitalizării, Vizualizare buget +- Abstract, informativ, "interesant dar..." +- Nu trece testul one-click: "ok, am tradus un text, și acum?" +- Harta nu avea date +- Bugetul era complex de construit + +**V2 propune:** DemoImpozit, DemoITP, DemoFirmă, DemoAchiziții, DemoDosar +- Concret, personal, "am aflat ceva valoros despre VIAȚA MEA" +- Trece testul one-click: tastezi un CUI/număr, primești ceva instant +- Datele există și sunt accesibile +- Fiecare e un "demoanaf" pentru alt domeniu + +**Diferența fundamentală:** V1 era interesant. V2 e UTIL. Și utilitatea e cea care se share-uiește. diff --git a/PLAN-PRODUCTS.md b/PLAN-PRODUCTS.md new file mode 100644 index 0000000..98cf59d --- /dev/null +++ b/PLAN-PRODUCTS.md @@ -0,0 +1,523 @@ +# PLAN-PRODUCTS.md — Specificații detaliate produse ancoră + +**Data:** 7 aprilie 2026 +**Autor:** Marius + Claude +**Status:** Rafinare strategică — specificații concrete pentru cele 3 produse ancoră +**Dependințe:** Citește PLAN.md pentru context general + +--- + +## Evaluare critică: sunt astea cele mai bune 3? + +Înainte de specificații, o analiză sinceră. + +### Scor comparativ (1-5, unde 5 = ideal) + +| Produs | Impact viral | Ușurința construcției | Date disponibile | Wow factor 30s | Utilitate reală | **TOTAL** | +|--------|:-----------:|:--------------------:|:----------------:|:--------------:|:--------------:|:---------:| +| Traducătorul birocratic (AI) | 5 | 5 | 5 (textul e inputul userului) | 5 | 3 | **23** | +| Harta digitalizării | 4 | 2 | 2 (crowdsourced, greu de validat) | 4 | 3 | **15** | +| Vizualizare buget local | 3 | 3 | 4 (date MF publice, dar dezordonate) | 4 | 5 | **19** | + +### Verdictul + +**Traducătorul birocratic = alegere excelentă.** Fără discuție, cel mai bun produs de lansare. + +**Vizualizare buget local = alegere bună.** Datele există, impactul e real, dar necesită muncă de agregare. + +**Harta digitalizării = alegere discutabilă.** Problema: datele nu există nicăieri. Trebuie crowdsourced, ceea ce necesită comunitate, pe care n-o avem încă. E un produs de faza 2, nu de lansare. + +### Alternativă propusă: înlocuiește Harta cu Generator de cereri tipizate (AI) + +| Criteriu | Harta digitalizării | Generator cereri (AI) | +|----------|:-------------------:|:--------------------:| +| Date necesare | Crowdsourced (nu există) | Template-uri cereri (le facem noi) | +| Timp de construcție | 2-3 săptămâni | 1 săptămână | +| Impactul "aha!" | "Interesant..." | "Chiar pot folosi asta!" | +| Utilitate directă | Informativă | Rezolvă o problemă concretă | +| Viralitate | Medie (share o dată) | Mare (share când ai nevoie) | + +**Recomandare finală:** Lansăm cu **Traducătorul birocratic + Generator cereri + Vizualizare buget**. Harta digitalizării vine în faza 2, când avem comunitate care contribuie cu date. + +**Dar**: planificăm toate 4 mai jos, ca să ai opțiunea. + +--- + +## Produs 1: Traducătorul birocratic (AI) + +> "Lipește textul oficial, primești explicația pe înțelesul tău" + +### Ce face exact — user flow pas cu pas + +``` +1. Userul intră pe vreaudigital.ro/traducator +2. Vede un textarea mare cu placeholder: + "Lipește aici textul oficial pe care nu-l înțelegi..." +3. Sub textarea: exemple clickable + → "Decizie de impunere" → "Încheiere proces verbal" → "Notificare ANAF" +4. Userul lipește textul (sau dă click pe un exemplu) +5. Apasă "Explică-mi →" +6. Apare traducerea în 2 secțiuni: + a) "Pe scurt" — 1-2 propoziții, limbaj simplu + b) "Pe larg" — paragraf cu toate detaliile importante + c) "Ce trebuie să faci" — acțiuni concrete (dacă e cazul) + d) "Termeni explicați" — cuvintele grele evidențiate cu tooltip +7. Sub traducere: + → "A fost util?" (thumbs up/down — feedback anonim) + → "Copiază explicația" + → "Trimite unui prieten" (share link) +``` + +### Date sursă + +**Input:** Textul vine de la user — zero dependență de API-uri externe sau date publice. + +**Prompt engineering:** Avem nevoie de: +- Un system prompt bun, în română, care știe terminologie juridică/administrativă RO +- 10-20 exemple curated (few-shot) pentru calitate consistentă +- Lista de termeni birocratici frecvenți cu explicații validate + +**Realitate România:** Nu există nicio barieră de date. Textele oficiale sunt publice prin natura lor. Userul le are deja (le-a primit de la instituție). + +### MVP tehnic + +| Componentă | Implementare | Notă | +|------------|-------------|------| +| **Frontend** | Componentă Astro + React island | Un textarea, un buton, zona de rezultat | +| **AI backend** | Cloudflare Workers AI (gratuit tier) SAU OpenAI API cu key proprie | Workers AI = 0 cost. OpenAI = ~$0.01/request cu GPT-4o-mini | +| **Prompt** | System prompt hardcodat + few-shot examples în worker | Nu trebuie bază de date, nu trebuie RAG | +| **Rate limiting** | Cloudflare Workers built-in | 100k requests/zi gratuit | +| **Analytics feedback** | Plausible events sau simplu localStorage counter | "A fost util?" → event tracking | +| **Cache** | KV store pe Cloudflare (gratuit) | Cache răspunsuri pentru texte identice | + +**Arhitectura concretă:** +``` +[Browser] + → POST /api/translate {text: "..."} + → [Cloudflare Worker] + → Verifică cache (KV) + → Dacă nu există: trimite la AI (Workers AI / OpenAI) + → Salvează în cache + → Returnează JSON {summary, detailed, actions, terms} + → [Frontend] renderează rezultatul +``` + +**Ce NU facem:** +- NU facem cont/login +- NU salvăm textele userilor (privacy by default) +- NU facem RAG pe legislație (overcomplicated, iluzoriu ca acuratețe) +- NU încercăm să fim "consilier juridic AI" — suntem doar traducător de limbaj + +### Demo wow — 30 secunde, screenshot-able + +**Scenariul perfect pentru demo/social media:** + +Input: +> "În temeiul art. 44 alin. (1) și (2) din Legea nr. 207/2015 privind Codul de procedură fiscală, cu modificările și completările ulterioare, se comunică contribuabilului prezenta decizie de impunere din oficiu, având în vedere că declarația fiscală nu a fost depusă până la termenul prevăzut de lege, urmând ca în termen de 30 de zile de la data comunicării să procedeze la contestarea acesteia conform dispozițiilor legale în vigoare." + +Output: +> **Pe scurt:** ANAF-ul ți-a calculat ei cât ai de plată, pentru că n-ai depus declarația la timp. +> +> **Ce trebuie să faci:** Ai 30 de zile să contești dacă nu ești de acord. Dacă nu contești, suma devine definitivă. +> +> **Termeni explicați:** +> - *decizie de impunere din oficiu* = ANAF a decis singur cât datorezi +> - *contribuabil* = tu, persoana care plătește taxe +> - *contestare* = poți spune "nu sunt de acord" oficial + +**Vizual:** Side-by-side, stânga text "birocratic" (cu font serif, gri, intimidant), dreapta text "uman" (font modern, clar, cu highlight-uri colorate pe termeni). Diferența vizuală vinde singură ideea. + +### Efort real + +| Task | Timp estimat | Cine | +|------|:----------:|------| +| Design UI/UX (Figma sau direct cod) | 4h | 1 dev | +| Componentă React (textarea + output) | 4h | 1 dev | +| Cloudflare Worker + prompt engineering | 6h | 1 dev | +| 10 exemple curated pentru few-shot | 3h | 1 dev | +| Testare + ajustare prompt | 3h | 1 dev | +| Integrare în site-ul Astro | 2h | 1 dev | +| **TOTAL** | **~22h** | **1 dev, 3 zile** | + +### Risc principal + +**Halucinații AI.** LLM-ul poate inventa termene, obligații, sau sume care nu există în text. + +**Mitigare:** +1. Disclaimer vizibil: "Aceasta e o explicație orientativă, nu consiliere juridică" +2. Prompt strict care instruiește AI-ul să rămână la ce scrie în text, nu să inventeze +3. Secțiunea "Termeni explicați" forțează AI-ul să ancoreze explicațiile în text real +4. Feedback loop: "A fost util?" cu opțiune de report "Explicația e greșită" + +--- + +## Produs 2: Generator de cereri tipizate (AI) + +> "Spune-mi ce vrei, îți generez cererea gata de depus" + +### Ce face exact — user flow pas cu pas + +``` +1. Userul intră pe vreaudigital.ro/cereri +2. Vede o grilă vizuală cu tipuri de cereri frecvente: + → Certificat fiscal + → Certificat de urbanism + → Cerere de eliberare acte + → Adeverință de venit + → Reclamație la primărie + → Cerere de audiență + → [+ altele] +3. Userul alege tipul (ex: "Certificat de urbanism") +4. Apare un formular conversațional (nu clasic): + → "Pentru ce adresă ai nevoie de certificat?" + → "Ce vrei să faci la adresa respectivă?" + → "Numele tău complet?" + → "CNP-ul?" (cu disclaimer de privacy) + → "Adresa de domiciliu?" +5. Pe măsură ce completează, pe dreapta apare LIVE preview-ul cererii +6. La final: + → "Descarcă PDF" + → "Descarcă Word" + → "Copiază text" +7. Cererea e formatată oficial, cu antet, dată, formulare standard +``` + +### Date sursă + +**Template-uri cereri:** Trebuie create manual, din surse publice: +- Site-urile primăriilor publică modele de cereri (PDF-uri scanate, de obicei) +- Legislație care definește conținutul minim al fiecărui tip de cerere +- Portalul e-guvernare.ro are câteva formulare standard + +**Realitate România:** +- Nu există un repository centralizat de template-uri de cereri +- Fiecare primărie are variațiuni minore (antet diferit, câmpuri extra) +- Multe cereri sunt "text liber" cu elemente obligatorii + +**Soluția pragmatică:** Creăm noi 10 template-uri pentru cele mai comune cereri. Le validăm cu 2-3 primării mici (telefon + email). Nu trebuie să fie perfect — trebuie să fie mai bun decât "scriu de mână pe o foaie". + +### MVP tehnic + +| Componentă | Implementare | Notă | +|------------|-------------|------| +| **Frontend** | Componentă Astro + React island | Formular wizard + preview live | +| **Template engine** | JSON schema per cerere + Handlebars/Mustache | Fiecare cerere = JSON cu câmpuri + template text | +| **AI** | Opțional — LLM pentru "cerere text liber" | Nu e necesar pentru cereri structurate | +| **PDF generation** | jsPDF sau pdfmake (client-side) | Zero backend, totul în browser | +| **Stocare** | Zero. Nimic nu se salvează pe server | Privacy by default — datele rămân în browser | +| **Template-uri** | Fișiere MDX/JSON în repo | Ușor de contribuit, versionat | + +**Arhitectura concretă:** +``` +[Browser] + → Userul alege tipul de cerere + → Se încarcă schema JSON (câmpuri necesare) + → Completează formularul (totul client-side) + → Template engine generează textul cererii (live preview) + → Userul descarcă PDF generat în browser + → NIMIC nu ajunge la server +``` + +**Ce NU facem:** +- NU salvăm date personale (CNP, adresă, etc.) — totul rămâne în browser +- NU facem submit automat la primărie (prea complex, prea multe variabile) +- NU acoperim toate tipurile de cereri — doar top 10 cele mai comune +- NU pretindem că înlocuim un avocat + +### Demo wow — 30 secunde, screenshot-able + +**Scenariul:** + +1. Screenshot 1: Grila cu 10 tipuri de cereri, design curat, iconuri +2. Screenshot 2: Formularul conversațional pentru "Reclamație la primărie" + - "Ce vrei să reclami?" → "Groapa din strada X nu e reparată de 3 luni" + - "Adresa ta?" → autocomplete +3. Screenshot 3: Preview-ul cererii generate — arată profesionist, cu antet, dată, formulare corecte +4. Screenshot 4: Buton "Descarcă PDF" → PDF deschis, gata de printat și depus + +**Textul viral:** "Am generat o cerere oficială în 30 de secunde. Normal durează 45 de minute și 2 drumuri la primărie ca să iei modelul." + +### Efort real + +| Task | Timp estimat | Cine | +|------|:----------:|------| +| Cercetare: colectare 10 modele cereri reale | 6h | 1 pers | +| Creare JSON schemas pentru 10 cereri | 8h | 1 dev | +| Creare template-uri text pentru 10 cereri | 6h | 1 dev | +| UI: wizard formular + live preview | 12h | 1 dev | +| PDF generation (client-side) | 6h | 1 dev | +| Integrare în site-ul Astro | 2h | 1 dev | +| Testare + feedback de la 2-3 oameni | 4h | 1 dev | +| **TOTAL** | **~44h** | **1 dev, 6 zile** | + +### Risc principal + +**Cererea generată nu e acceptată de primărie.** Funcționarul zice "nu e pe formularul nostru." + +**Mitigare:** +1. Disclaimer: "Verifică la primăria ta dacă acceptă acest format" +2. Design conservator — cererea arată oficial, nu "fancy" +3. Includem opțiunea de a descărca doar textul (fără formatare), ca userul să-l pună pe orice template +4. Pe termen lung: parteneriate cu primării mici care validează template-urile +5. Formulăm cererea în limbaj juridic standard — funcționarii recunosc structura + +--- + +## Produs 3: Vizualizare buget local + +> "Pe ce se duc banii tăi?" + +### Ce face exact — user flow pas cu pas + +``` +1. Userul intră pe vreaudigital.ro/buget +2. Vede o hartă simplificată a României SAU un dropdown cu localități +3. Selectează orașul/comuna (ex: "Cluj-Napoca") +4. Apare dashboard-ul: + a) TOTAL buget: "423 milioane lei (2025)" + b) Treemap/sunburst vizualizare pe categorii: + - Educație: 28% (118M lei) + - Infrastructură drumuri: 22% (93M lei) + - Sănătate: 12% (51M lei) + - Administrație: 15% (63M lei) + - Cultură: 5% (21M lei) + - ... + c) Click pe categorie → detalii sub-categorii + d) Comparație cu anul anterior (+ / - %) + e) "Cât plătești TU?" — slider cu venitul lunar + → "Din taxele tale de 400 lei/lună, 112 lei merg pe educație" +5. Sub grafice: + → "Sursa datelor: Ministerul Finanțelor, execuția bugetară 2025" + → "Descarcă datele" (CSV) + → "Compară cu alt oraș" (opțional, faza 2) +``` + +### Date sursă + +**Sursa principală: Ministerul Finanțelor — Forexebug/Execuție bugetară** + +Realitatea (nu e roz): +- **Datele EXISTĂ** — Ministerul Finanțelor publică execuția bugetară pe site-ul forexebug.mfinante.ro +- **Formatul e problematic** — fișiere Excel/CSV, structură inconsistentă între ani, coduri bugetare fără descrieri umane +- **Granularitatea variază** — unele primării raportează detaliat, altele minimal +- **Actualizarea e trimestrială** — nu e real-time + +**Surse concrete:** +1. `forexebug.mfinante.ro` — execuție bugetară pe UAT-uri (Unități Administrativ-Teritoriale) +2. `data.gov.ro` — câteva seturi de date bugetare (incomplete, neactualizate) +3. Site-urile primăriilor — publică bugetul local anual (PDF, de obicei scanat) + +**Efort de obținere date:** +- Download-ul datelor de la MF: 2-4h (trebuie navigat prin interfața greoaie) +- Parsarea și normalizarea: 8-12h (cel mai mare efort — formatul e inconsistent) +- Maparea codurilor bugetare pe categorii umane: 4-6h (există clasificație standard, dar trebuie simplificată) +- **Total inițial:** ~20h pentru a avea date clean pentru 5-10 orașe + +### MVP tehnic + +| Componentă | Implementare | Notă | +|------------|-------------|------| +| **Frontend** | Componentă Astro + React island | Dashboard interactiv | +| **Grafice** | D3.js treemap SAU Recharts/Nivo | Treemap = cel mai wow vizual pentru buget | +| **Date** | JSON static per oraș, generat offline | Zero backend, zero DB | +| **Pipeline date** | Script Python/Node care parsează Excel-urile MF | Rulează offline, output = JSON files | +| **Search/selector** | Dropdown simplu cu autocomplete | Pagefind (built-in Astro) sau simplu select | +| **Calculator personal** | Slider JS cu formulă simplă | (venit * rata_impozit) * procent_categorie | + +**Arhitectura concretă:** +``` +[Offline pipeline — rulează manual trimestrial] + → Download Excel-uri de la forexebug.mfinante.ro + → Script Python: parsează, normalizează, mapează categorii + → Output: /data/buget/cluj-napoca-2025.json + → Commit în repo → deploy automat + +[Browser] + → Userul selectează orașul + → Se încarcă JSON-ul static (CDN, instant) + → D3.js/Recharts renderează graficele + → Slider "cât plătești tu" = calcul client-side + → Zero requests la server (totul e static) +``` + +**Ce NU facem:** +- NU facem real-time data pipeline (overkill, datele se schimbă trimestrial) +- NU scrapăm automat site-ul MF (fragil, se poate strica oricând) +- NU acoperim toate cele ~3200 UAT-uri de la început — doar top 10 orașe +- NU comparăm cu media europeană (date incomparabile, contexte diferite) + +### Demo wow — 30 secunde, screenshot-able + +**Scenariul:** + +1. Screenshot: Treemap colorat pe categorii bugetare pentru Cluj-Napoca + - Blocuri mari și mici, culori distincte, sume vizibile + - Titlu mare: "Bugetul Cluj-Napoca 2025: 423M lei" +2. Screenshot: Zoom pe "Educație" — sub-categorii (salarii profesori, renovări școli, burse) +3. Screenshot: Slider "Cât plătești tu?" setat pe 5000 lei/lună + - "Din taxele tale: 47 lei/lună pe educație, 37 lei pe drumuri, 9 lei pe cultură" +4. Screenshot: Comparație 2024 vs 2025 — săgeți verzi/roșii pe categorii + +**Textul viral:** "Am aflat că din taxele mele de 400 lei/lună, 60 lei se duc pe 'administrație internă'. Ce face primăria cu 60 lei/lună de la mine doar pe propria funcționare?" + +### Efort real + +| Task | Timp estimat | Cine | +|------|:----------:|------| +| Download + analiză date MF (structură, format) | 6h | 1 dev | +| Script parsare Excel → JSON normalizat | 12h | 1 dev | +| Mapare coduri bugetare → categorii umane | 6h | 1 dev | +| Generare JSON-uri pentru 5-10 orașe | 4h | 1 dev | +| UI: selector oraș + treemap + detalii categorie | 16h | 1 dev | +| UI: slider "cât plătești tu" | 4h | 1 dev | +| UI: comparație ani | 6h | 1 dev | +| Integrare în site-ul Astro | 2h | 1 dev | +| Testare + ajustare vizualizări | 4h | 1 dev | +| **TOTAL** | **~60h** | **1 dev, 8-10 zile** | + +### Risc principal + +**Datele de la MF sunt inconsistente sau lipsesc.** Format diferit între ani, categorii care se schimbă, primării care nu raportează corect. + +**Mitigare:** +1. Începem cu 5 orașe mari (Cluj, București, Timișoara, Iași, Brașov) — datele lor sunt mai complete +2. Script de parsare cu fallback-uri (categorii "Alte cheltuieli" pentru ce nu se mapează) +3. Afișăm întotdeauna sursa și data actualizării: "Date din execuția bugetară Q3 2025" +4. Transparent cu limitările: "Datele vin de la MF și pot conține erori de raportare" +5. Păstrăm pipeline-ul simplu (manual, trimestrial) — nu automatizăm ce nu putem controla + +--- + +## Produs 4 (Faza 2): Harta digitalizării + +> "Cât de digitalizată e primăria ta?" + +**De ce faza 2, nu faza 1:** Necesită date crowdsourced. La lansare n-avem comunitate care să contribuie. Dar e un produs excelent de "faza tracțiune" când avem deja 100-500 de vizitatori. + +### Ce face exact — user flow pas cu pas + +``` +1. Userul intră pe vreaudigital.ro/harta +2. Vede harta României, colorată pe județe (gradient: roșu → verde) +3. Hover pe județ → tooltip: "Județul Cluj: 4.2/10 digitalizare" +4. Click pe județ → lista primăriilor cu scor individual +5. Click pe primărie → fișa detaliată: + a) Scor general: 3.7/10 + b) Checklist vizual: + ✅ Site funcțional + ✅ Plăți online (Ghișeul.ro) + ❌ Cereri online + ❌ Transparență buget + ❌ Programări online + ✅ Email de contact funcțional + ❌ Răspuns în 30 zile la cereri + c) "Ultima verificare: 15 martie 2026 de Andrei M." + d) "Verifică tu" → formular de contribuție +6. Clasament: top 10 primării / bottom 10 primării +7. Evoluție în timp (când avem date pe mai multe luni) +``` + +### Date sursă + +**Aici e problema principală:** Datele nu există nicăieri centralizat. + +**Surse posibile:** +1. **Crowdsourcing** — cetățeni verifică manual criteriile pentru primăria lor +2. **Scraping automat** — verificăm dacă primăria are site, dacă site-ul funcționează, dacă are HTTPS +3. **Date oficiale parțiale** — ADR publică lista primăriilor conectate la Ghișeul.ro +4. **SEAP** — putem verifica dacă primăria face achiziții online + +**Realitate:** +- Există ~3200 UAT-uri (primării + consilii) în România +- Doar ~10% au site-uri funcționale cu servicii online reale +- Verificarea manuală a unei primării durează 5-10 minute +- Un scraper poate verifica automat: site activ, HTTPS, pagini funcționale, email de contact + +**Strategie realistă:** +1. Scraper automat pentru criteriile tehnice (site activ, HTTPS, pagini cheie) +2. Formulare crowdsourcing pentru criterii subiective (responsivitate, calitate servicii) +3. Începem cu cele 41 de reședințe de județ (verificare manuală completă) +4. Creștem prin contribuții comunitare + +### MVP tehnic + +| Componentă | Implementare | Notă | +|------------|-------------|------| +| **Hartă** | Leaflet.js sau MapLibre cu GeoJSON al României | GeoJSON județe/UAT disponibil gratuit | +| **Date** | JSON static, generat din scraper + contribuții manuale | Zero backend la început | +| **Scraper** | Script Python: verifică site activ, HTTPS, pagini standard | Rulează periodic offline | +| **Contribuții** | Formspree sau Google Forms → review manual → merge în JSON | Crowdsourcing low-tech | +| **Scor** | Formulă simplă: nr criterii îndeplinite / total criterii | Transparent, ușor de înțeles | + +### Demo wow + +Harta României colorată gradient, cu tooltip-uri pe hover. Clasamentul "Top 10 / Bottom 10" e extrem de share-able — jurnaliștii vor face articole instant. + +### Efort real + +| Task | Timp estimat | +|------|:----------:| +| Scraper: verificare automată criterii tehnice | 8h | +| Verificare manuală: 41 reședințe de județ | 16h (munca manuală) | +| Frontend: hartă + tooltip + clasament | 16h | +| Sistem contribuții (forms + review) | 4h | +| **TOTAL** | **~44h** | + +### Risc principal + +**Date incomplete = hartă care arată goală și neinteresantă.** Dacă avem date doar pentru 41 de orașe, harta arată 3200 de puncte gri și 41 colorate. + +**Mitigare:** Afișăm harta la nivel de județ (41 entități, nu 3200). Scorul județului = media orașelor verificate din județ. + +--- + +## Rezumat comparativ și timeline integrată + +### Ordinea de construcție recomandată + +| # | Produs | Efort | Când | De ce acum | +|---|--------|:-----:|------|------------| +| 1 | Traducătorul birocratic | 3 zile | Săptămâna 2-3 | Cel mai viral, cel mai rapid, cel mai wow | +| 2 | Generator cereri | 6 zile | Săptămâna 3-4 | Utilitate directă, completează traducătorul | +| 3 | Vizualizare buget | 8-10 zile | Săptămâna 5-7 | Cel mai complex dar cel mai util pe termen lung | +| 4 | Harta digitalizării | 6 zile + muncă manuală | Săptămâna 8-10 | Necesită comunitate, vine după ce avem trafic | + +### Costul real + +| Resursă | Cost | +|---------|:----:| +| Domeniu vreaudigital.ro | ~12 EUR/an | +| Cloudflare Pages hosting | 0 EUR | +| Cloudflare Workers (traducător AI) | 0 EUR (free tier: 100k req/zi) | +| OpenAI API (backup dacă Workers AI nu e destul de bun) | ~5-10 EUR/lună la 1000 traduceri/zi | +| **TOTAL lunar** | **0-10 EUR** | + +### Decizii de luat acum + +1. **Traducătorul: Workers AI vs OpenAI?** + - Workers AI: gratuit, dar calitatea modelelor în română e de testat + - OpenAI GPT-4o-mini: ~$0.15/1M input tokens, calitate excelentă în română + - **Recomandare:** Testăm Workers AI întâi. Dacă calitatea nu e ok, trecem pe OpenAI. + +2. **Generator cereri: câte cereri la lansare?** + - 5 e suficient. Cele mai comune: certificat fiscal, cerere audiență, reclamație, certificat urbanism, adeverință. + +3. **Buget: câte orașe la lansare?** + - 5-10 e suficient. Cele mai mari = cele mai căutate = cele mai bune date. + +4. **Harta: o includem în lansare sau nu?** + - Recomandare: NU la lansare. O anunțăm ca "vine curând" și invităm oamenii să contribuie cu date. + +--- + +## Notă finală: Cele 3 produse ca narativ integrat + +Site-ul nu e doar 3 tool-uri separate. E o poveste: + +> **"Statul vorbește într-o limbă pe care n-o înțelegi."** → Traducătorul +> **"Cererea e un labirint birocratic."** → Generatorul +> **"Nu știi pe ce se duc banii tăi."** → Vizualizarea buget + +Fiecare produs rezolvă un "pain point" real. Împreună, arată o viziune: **cum ar putea arăta România dacă digitalizarea ar fi făcută pentru cetățeni, nu pentru funcționari.** + +Asta e mesajul care se vinde singur. diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..edc8eda --- /dev/null +++ b/PLAN.md @@ -0,0 +1,436 @@ +# PLAN.md — Ultra Plan: gov-agreg / vreaudigital.ro + +**Data:** 7 aprilie 2026 +**Autor:** Marius + Claude +**Status:** Draft strategic — faza de planificare, zero cod + +--- + +## 1. Analiză critică a propunerilor ChatGPT + +### Ce e over-engineered (cam 80% din raport) + +ChatGPT a produs un raport de enterprise consulting, nu un plan pentru o echipă mică cu buget zero. Concret: + +**Sandbox architecture — complet nerealist pentru MVP:** +- Propune WASM + gVisor + Kata Containers + Firecracker microVM — patru runtime-uri de sandbox. Noi nu suntem AWS. Nu avem nevoie de multi-tenant untrusted code execution în prima fază. Nici măcar în a doua. +- Fiecare demo poate fi pur și simplu un link extern, un video, un iframe, sau o aplicație statică. Nu trebuie să rulăm codul altora pe infrastructura noastră de la început. + +**Supply-chain controls — overkill total:** +- SBOM (SPDX/CycloneDX), SLSA provenance, Sigstore Cosign, Rekor transparency log, admission policies... Toate astea sunt pentru platforme cu milioane de utilizatori și sute de artefacte. Noi vrem să listăm 10 produse. +- La dimensiunea noastră, un review manual al fiecărei listări e mai eficient decât orice pipeline automatizat. + +**Echipă propusă — delirantă:** +- 4-5 FTE: Product Lead, Tech Lead, Security Lead, SRE, UX, Community, Legal. Noi suntem 1-2 oameni. +- Buget de 0-5k per checklist item, cu ~40 de items. Noi avem buget zero. + +**Compliance overkill pentru MVP:** +- DSA notice-and-action workflow + transparency reporting — pentru un site cu 50 de vizitatori pe zi? +- DPIA templates, coordinated vulnerability disclosure SLA — prematur cu cel puțin 12 luni. +- Pilot packs cu security/privacy/deployment/procurement notes — nimeni nu ne va cere asta până n-avem trafic real. + +**publiccode.yml superset cu 30+ câmpuri:** +- Demo runtime descriptors, AI disclosure fields, interoperability schemas... Noi avem nevoie de: nume, descriere, screenshot, link. Atât. + +### Ce e realist și merită păstrat + +1. **Ideea de trust ladder simplificată** — oamenii chiar vor să știe „pot să am încredere?" Dar 2 nivele, nu 5. +2. **Dual audience** (cetățeni + developeri) — corect, dar trebuie prioritizat: cetățenii primii. +3. **Categorii ancorate pe servicii existente** — plăți, identitate, date deschise — da, oamenii înțeleg asta. +4. **„No PII in demos" ca principiu** — bun, simplu, ușor de aplicat. +5. **Referința la modele europene** (Italia, Germania, Franța) — util ca inspirație, nu ca spec de implementat. + +### Ce lipsește complet + +**1. WOW Factor / Design:** +- Zero mențiuni despre cum arată efectiv site-ul. Niciun mockup, nicio direcție vizuală. +- Raportul presupune că oamenii vor citi metadata YAML. Nu vor. +- Un portal de digitalizare care nu e el însuși frumos și modern e o contradicție fatală. + +**2. Storytelling și emoție:** +- De ce ar intra cineva pe site? Ce problemă simte cetățeanul? +- „Am stat 3 ore la coadă la ghișeu" → „Uite cum ar putea fi" — acest arc narativ lipsește complet. +- Raportul e scris pentru un comitet EU, nu pentru oameni. + +**3. Comunitate și virality:** +- Cum atragi primii 10 developeri? Primii 100 de vizitatori? +- Zero strategie de lansare, zero marketing. +- Nicio mențiune de social media, content marketing, hackathoane. + +**4. Demo-uri care impresionează:** +- Raportul vorbește despre sandbox-uri enterprise. Noi avem nevoie de video-uri de 30 de secunde, GIF-uri animate, și link-uri spre demo-uri live hostate de autori. +- Un before/after vizual valorează cât 100 de pagini de SBOM. + +**5. Vocea umană:** +- Cine sunt oamenii din spatele produselor? Povești, fotografii, motivație. +- „Ionuț din Cluj a făcut un bot care te ajută să-ți depui declarația de impozit" — asta vinde. + +### Ce e naiv sau greșit despre contextul românesc + +1. **Presupune că ADR și instituțiile vor colabora activ** — în realitate, instituțiile sunt lente, birocratice, și sceptice față de orice nu vine pe filiera oficială. Nu pornim de la parteneriate instituționale — pornim de la comunitate. + +2. **ROeID, ROePAS, Ghișeul.ro ca „ancore"** — aceste sisteme nu sunt open source, nu au API-uri publice documentate, și nu sunt exemple de digitalizare bună. Sunt exact opusul: sisteme închise, greoaie, cu UX slab. Le putem folosi ca exemple negative („cum e acum") nu ca „ancore de succes". + +3. **Presupune că primăriile au capacitate IT** — cele mai multe primării din România nu au nici măcar un administrator IT dedicat. Soluțiile trebuie să fie „fără IT local" — cloud, SaaS, zero config. + +4. **Modelul de monetizare cu „managed hosting for agencies"** — prematur cu cel puțin 2 ani. Primăriile cumpără prin licitații, nu prin marketplace-uri. Mai întâi construim credibilitate. + +5. **Presupune buget** — „0-5k per item" nu e buget zero. Buget zero înseamnă: hosting gratuit (Vercel/Cloudflare Pages), domeniu de 10€, și timp voluntar. + +--- + +## 2. MVP-ul real — vreaudigital.ro + +### Principiul #1: Inspiră, nu doar informează + +Portalul nu e un catalog tehnic. E un **manifest vizual** care arată: „Uite cum poate fi România digitală." + +Fiecare produs listat trebuie să răspundă la întrebarea: **„Ce s-ar schimba în viața mea dacă asta ar exista la primăria din orașul meu?"** + +### Ce vede un cetățean care intră prima dată + +``` +┌─────────────────────────────────────────────────────┐ +│ vreaudigital.ro │ +│ │ +│ ╔══════════════════════════════════════════════════╗ │ +│ ║ România merită o digitalizare reală. ║ │ +│ ║ ║ │ +│ ║ Nu formulare PDF online. ║ │ +│ ║ Nu site-uri din 2005 cu fonturi mici. ║ │ +│ ║ Ci servicii care chiar funcționează. ║ │ +│ ║ ║ │ +│ ║ [Vezi ce e posibil →] ║ │ +│ ╚══════════════════════════════════════════════════╝ │ +│ │ +│ ── Produse care schimbă cum interacționezi cu statul │ +│ │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ 📋 │ │ 💬 │ │ 📊 │ │ +│ │ Cereri │ │ Comunicare│ │ Trans- │ │ +│ │ fără │ │ directă │ │ parență │ │ +│ │ coadă │ │ cu │ │ bugetară │ │ +│ │ │ │ primăria │ │ │ │ +│ │ [3 prod] │ │ [2 prod] │ │ [4 prod] │ │ +│ └──────────┘ └──────────┘ └──────────┘ │ +│ │ +│ ── Despre noi │ +│ Un proiect open-source. Facem digitalizarea │ +│ vizibilă, accesibilă, și reală. │ +│ │ +│ [Ești programator? Listează-ți produsul →] │ +└─────────────────────────────────────────────────────┘ +``` + +**Elemente cheie:** +- Hero section cu mesaj emoțional, nu tehnic +- Categorii vizuale cu iconuri mari și descriptive +- Fiecare produs are: screenshot/video, descriere de 2 propoziții, „cine l-a făcut", „unde funcționează deja" +- Zero jargon tehnic pe prima pagină +- CTA clar pentru developeri (dar secundar, nu primar) + +### Ce vede un programator care vrea să-și listeze produsul + +``` +┌─────────────────────────────────────────────────────┐ +│ Listează-ți produsul │ +│ │ +│ Ai construit ceva care ajută cetățenii sau │ +│ administrația? Arată-l lumii. │ +│ │ +│ Ce primești: │ +│ ✓ Vizibilitate în fața a mii de oameni │ +│ ✓ Credibilitate — verificat de comunitate │ +│ ✓ Contact direct cu primării interesate │ +│ ✓ Badge de „produs listat pe vreaudigital.ro" │ +│ │ +│ Ce ai nevoie: │ +│ 1. Nume + descriere scurtă │ +│ 2. Minim un screenshot sau video demo (30s) │ +│ 3. Link spre produs (live, GitHub, sau demo) │ +│ 4. Categoria (alege din listă) │ +│ 5. Unde funcționează deja? (opțional) │ +│ │ +│ [Trimite produsul tău →] │ +│ │ +│ Nu ai un produs încă? │ +│ → Vezi lista de idei și provocări │ +│ → Participă la următorul hackathon │ +└─────────────────────────────────────────────────────┘ +``` + +**Principii:** +- Onboarding în 5 minute, nu în 5 ore +- Nu cerem publiccode.yml, SBOM, sau alte artefacte la început +- Review manual de calitate (curated, nu automated) +- Fiecare produs acceptat primește o pagină frumoasă generată de noi + +### Pagina de produs — cum arată + +``` +┌─────────────────────────────────────────────────────┐ +│ ← Înapoi la Transparență bugetară │ +│ │ +│ BugetulMeu.ro │ +│ ───────────────────────── │ +│ Vizualizare interactivă a bugetului local. │ +│ Află exact pe ce se cheltuie banii din taxele tale. │ +│ │ +│ ┌───────────────────────────────────────┐ │ +│ │ │ │ +│ │ [Screenshot / Video Demo] │ │ +│ │ │ │ +│ └───────────────────────────────────────┘ │ +│ │ +│ [Încearcă demo →] [Cod sursă] [Contactează] │ +│ │ +│ Făcut de: Andrei P. (Cluj) │ +│ Stack: React + date de la MF │ +│ Funcționează la: Primăria Cluj, Primăria Sibiu │ +│ Licență: MIT │ +│ Status: ✅ Verificat de comunitate │ +│ │ +│ ── Ce face │ +│ • Importă automat datele bugetare de la MF │ +│ • Vizualizări interactive pe categorii │ +│ • Comparații între ani și între localități │ +│ • Export PDF pentru consilieri locali │ +│ │ +│ ── De ce contează │ +│ Bugetul local e public dar ilizibil. Acest tool │ +│ transformă PDF-uri de 200 de pagini în grafice │ +│ pe care le înțelege oricine. │ +└─────────────────────────────────────────────────────┘ +``` + +### Categorii de produse (primele 5) + +| # | Categorie | Ce include | De ce prima | +|---|-----------|------------|-------------| +| 1 | **Transparență și date deschise** | Vizualizare bugete, monitorizare cheltuieli, dashboards primărie, date.gov.ro tools | Impact vizual mare, date publice disponibile, zero dependențe de instituții | +| 2 | **Comunicare cetățean-primărie** | Chatboți, sisteme de ticketing, notificări, programări online | Problemă simțită zilnic de cetățeni, ușor de demonstrat | +| 3 | **Cereri și documente fără coadă** | Generatoare de cereri, formulare inteligente, tracking status | Pain point #1 al românilor cu statul | +| 4 | **Educație civică și informare** | Ghiduri interactive, explainer-e despre drepturi, calculator taxe | Content viral, ușor de făcut, atrage trafic | +| 5 | **AI pentru servicii publice** | Asistenți virtuali, OCR documente, traducere limbaj birocratic → limbaj uman | Wow factor maxim, subiect fierbinte | + +### Stack tehnic — simplu, rapid, fără enterprise bloat + +| Componentă | Alegere | De ce | +|------------|---------|-------| +| **Framework** | Astro + React/Svelte islands | Static-first, rapid, SEO perfect, deploy gratuit | +| **Styling** | Tailwind CSS | Rapid, consistent, ușor de personalizat | +| **Content** | Markdown/MDX files în Git | Zero bază de date, versionat, ușor de contribuit | +| **CMS (opțional)** | Decap CMS (fost Netlify CMS) sau direct GitHub | Editare fără cod pentru non-tehnici | +| **Hosting** | Cloudflare Pages | Gratuit, rapid, CDN global, custom domain | +| **Formulare** | Formspree sau Cloudflare Workers | Recepție submisiuni fără backend | +| **Analytics** | Plausible (self-hosted) sau Umami | Privacy-first, GDPR ok, lightweight | +| **Domeniu** | vreaudigital.ro | Emoțional, memorabil, clar | + +**Ce NU avem nevoie la MVP:** +- ❌ Bază de date (Postgres, etc.) +- ❌ Backend API (FastAPI, NestJS) +- ❌ Kubernetes +- ❌ OCI Registry +- ❌ Sandbox runtime +- ❌ SBOM pipeline +- ❌ Search engine (Meilisearch, etc.) — search-ul built-in din Astro e suficient +- ❌ Auth system + +**Principiul: dacă poți face fără, nu adăuga.** + +--- + +## 3. Produse ancoră — ce listăm la lansare + +### Produse existente (sau rapid de făcut) care ar putea fi primele + +| Produs | Categorie | Există? | Impact vizual | Efort listare | +|--------|-----------|---------|---------------|---------------| +| **Vizualizare buget local** | Transparență | De construit (date publice de la MF) | ⭐⭐⭐⭐⭐ | Mediu — trebuie agregat datele | +| **Generator cereri tipizate** (AI) | Cereri fără coadă | Rapid de construit cu LLM | ⭐⭐⭐⭐ | Mic — API ChatGPT + template | +| **Traductor limbaj birocratic** (AI) | AI servicii publice | Rapid de construit | ⭐⭐⭐⭐⭐ | Mic — viral pe social media | +| **Dashboard achiziții publice** | Transparență | date din SEAP sunt publice | ⭐⭐⭐⭐ | Mediu — scraping/API SEAP | +| **Chatbot „Cum depun cererea X?"** | Comunicare | Rapid de construit | ⭐⭐⭐ | Mic — RAG pe legislație | +| **Monitorizare ședințe consiliu local** | Transparență | Parțial există (diverse inițiative) | ⭐⭐⭐⭐ | Mediu | +| **Calculator taxe și impozite locale** | Educație civică | Simplu | ⭐⭐⭐ | Mic | +| **Comparator servicii publice între orașe** | Date deschise | De construit | ⭐⭐⭐⭐⭐ | Mare — date greu de agrerat | +| **Harta digitalizării** — care primării au servicii online | Transparență | De construit (crowdsourced) | ⭐⭐⭐⭐⭐ | Mic ca MVP | +| **open-source.gov.ro viewer** — ce cod au publicat instituțiile | Transparență | De construit | ⭐⭐⭐ | Mic — scan GitHub/GitLab | + +### Primele 3 produse ancoră recomandate + +**1. Traducătorul birocratic (AI)** — „Lipește textul oficial, primești explicația pe înțelesul tău" +- Impact viral enorm — toată lumea urăște limbajul birocratic +- Demo ușor de construit (un weekend) +- Arată puterea AI aplicată pe o problemă reală +- Perfect pentru social media + +**2. Harta digitalizării** — „Cât de digitalizată e primăria ta?" +- Vizual spectaculos (hartă interactivă a României) +- Crowdsourced — comunitatea contribuie cu date +- Creează conversație și presiune civică +- Jurnaliștii adoră hărți interactive + +**3. Vizualizare buget local** — „Pe ce se duc banii tăi?" +- Întrebare pe care o pune toată lumea +- Datele sunt publice (Ministerul Finanțelor) +- Grafice interactive = wow factor +- Util real pentru consilieri locali și jurnaliști + +--- + +## 4. Strategie de comunitate și lansare + +### Cum atragem primii contributori + +1. **Postare de lansare pe social media** — manifest vizual + link spre site +2. **Thread pe r/Romania și Facebook dev groups** — „Construim Product Hunt-ul digitalizării" +3. **Outreach direct** — contactăm 10-20 de developeri din RO care au proiecte civic tech +4. **Hackathon virtual** — „Weekend de Digitalizare" — 48h, premii simbolice +5. **Newsletter** — actualizări lunare despre ce s-a listat și ce impact a avut + +### Cum atragem cetățeni + +1. **Content viral** — traducătorul birocratic + harta digitalizării = share-abil +2. **Comparații vizuale** — „Cum arată plata taxelor în Estonia vs România" +3. **Povești umane** — „Ionuț din Brașov a făcut un bot care economisește 3 ore/lună cetățenilor" +4. **Parteneriate cu jurnaliști** — datele de pe portal = surse de știri + +### Cum atragem instituții (mai târziu, nu de la început) + +1. **Social proof** — „5000 de cetățeni au folosit demo-ul X" +2. **Abordare bottom-up** — un funcționar IT din primărie descoperă tool-ul → recomandă intern +3. **Pachete de implementare gratuite** — „Implementăm noi, tu doar aprobi" +4. **Case studies** — „Primăria X a redus cozile cu 40% cu tool-ul Y" + +--- + +## 5. Plan de acțiune pe faze + +### Faza 1 — Fundamentul (Săptămânile 1-4) + +**Obiectiv:** Site live cu 5 produse listate și un produs demo funcțional. + +| Săpt. | Task | Responsabil | Output | +|-------|------|-------------|--------| +| 1 | Setup proiect Astro + Tailwind + Cloudflare Pages | Dev | Repo + deploy pipeline | +| 1 | Design: logo, paletă culori, tipografie | Dev/Design | Brand kit minimal | +| 1-2 | Pagina principală: hero + categorii + footer | Dev | Landing page live | +| 2 | Template pagină de produs (MDX) | Dev | Un produs listat complet | +| 2-3 | **Traducătorul birocratic** — demo funcțional | Dev | Prima demonstrație live | +| 3 | Adaugă încă 4 produse (chiar și doar cu screenshots) | Dev + Content | 5 produse pe site | +| 3-4 | Pagina „Listează-ți produsul" + formular de submisiune | Dev | Flow de onboarding | +| 4 | Pagina „Despre" + manifest | Content | Storytelling | +| 4 | **Lansare soft** — postare pe social media | All | Primii vizitatori | + +**Buget Faza 1:** ~15€ (domeniu vreaudigital.ro) — restul e gratuit. + +### Faza 2 — Tracțiune (Săptămânile 5-8) + +**Obiectiv:** 15+ produse, 2-3 demo-uri funcționale, comunitate activă. + +| Săpt. | Task | Output | +|-------|------|--------| +| 5-6 | **Harta digitalizării** — MVP interactiv | Al doilea produs wow | +| 5-6 | Onboarding primii 5 contributori externi | Produse noi listate | +| 6-7 | **Vizualizare buget local** — MVP pentru 2-3 orașe | Al treilea produs wow | +| 7 | Sistem de badge-uri simplu (2 nivele: Listat / Demo live) | Trust signals | +| 7-8 | Blog: prima postare despre progres + ce urmează | Content marketing | +| 8 | Newsletter #1 + push social media | Awareness | +| 8 | **Hackathon virtual „Weekend de Digitalizare"** | Comunitate + produse noi | + +**Buget Faza 2:** ~0-50€ (premii simbolice hackathon, eventual stickers). + +### Faza 3 — Maturizare (Lunile 3-6) + +**Obiectiv:** Portal de referință pentru civic tech în România. + +| Task | Timeline | Impact | +|------|----------|--------| +| 30+ produse listate, 5+ cu demo live | Luna 3-4 | Catalog credibil | +| Contact direct cu 3-5 primării mici (open-minded) | Luna 3 | Primele piloturi | +| Trust ladder extins: Listat → Demo live → Testat cu primărie | Luna 4 | Credibilitate | +| Outreach presă: Recorder, Libertatea, PressOne | Luna 4-5 | Vizibilitate națională | +| GitHub organization + contributing guide | Luna 3 | Comunitate dev | +| Prima primărie care adoptă un tool de pe portal | Luna 5-6 | Social proof masiv | +| Eveniment fizic: „Digitalizare Reală" meetup (Cluj?) | Luna 6 | Comunitate fizică | + +**Buget Faza 3:** ~100-500€ (meetup, materiale, deplasări). + +--- + +## 6. Ce NU facem (și de ce) + +| Nu facem | De ce | +|----------|-------| +| Sandbox de execuție cod | Prea complex, prea costisitor, prea devreme. Link-uri externe și video-uri sunt suficiente. | +| SBOM / SLSA / Sigstore | Enterprise tooling fără audiență. Adăugăm când/dacă avem 100+ produse listate. | +| publiccode.yml obligatoriu | Barieră inutilă. Colectăm noi metadatele printr-un formular simplu. | +| Backend API + DB | Static site cu Markdown e mai rapid, mai sigur, mai ieftin. | +| Parteneriate instituționale devreme | Pierdem luni în ședințe. Mai bine construim ceva impresionant și ei vin la noi. | +| Kubernetes / Docker în producție | Cloudflare Pages e gratis și mai fiabil decât orice am putea opera noi. | +| Moderation workflow formal (DSA) | Avem review manual. La 50 de produse listate nu avem nevoie de ticketing system. | +| Multi-language (EN) | Portalul e pentru România, în română. Engleza vine când/dacă avem sens. | + +--- + +## 7. Metrici de succes + +### Faza 1 (luna 1) +- Site live ✅ +- 5 produse listate ✅ +- 1 demo funcțional ✅ +- 100+ vizitatori unici în prima săptămână + +### Faza 2 (luna 2) +- 15+ produse listate +- 3+ demo-uri funcționale +- 5+ contributori externi +- 500+ vizitatori unici/lună +- Minim 1 share de la o personalitate/publicație + +### Faza 3 (lunile 3-6) +- 30+ produse listate +- 1000+ vizitatori unici/lună +- 1+ primărie care adoptă un produs +- Articol de presă în cel puțin o publicație națională +- 10+ contributori activi + +--- + +## 8. Riscuri reale (nu enterprise fantasy risks) + +| Risc | Probabilitate | Mitigare | +|------|--------------|----------| +| Nu găsim suficiente produse de listat | Mare | Construim noi primele 3-5 + active outreach la developeri | +| Nimeni nu intră pe site | Mare | Content viral (traducător birocratic), social media, SEO | +| Produsele listate sunt de calitate slabă | Medie | Curated, nu open submission. Review manual. | +| Instituțiile ne ignoră | Mare | Nu depindem de ei. Focus pe comunitate și cetățeni. | +| Burnout — suntem puțini | Mare | Scope mic. Faze scurte. Celebrăm fiecare victorie. | +| Domeniul vreaudigital.ro e luat | Mică | Alternativă: digitalreal.ro, romaniadigitala.ro | +| Ne copie cineva ideea | Mică | Bine. Cu cât mai mulți, cu atât mai bine pentru digitalizare. | + +--- + +## 9. Decizii de luat acum + +1. ☐ **Domeniu** — verifică dacă vreaudigital.ro e disponibil, cumpără-l +2. ☐ **Primele 3 produse** — confirmă traducătorul birocratic, harta, bugetul ca priorități +3. ☐ **Brand** — nume final, un logo minimal, culori (propunere: albastru-portocaliu, tricolor subtil) +4. ☐ **Repo** — setup pe GitHub (public din ziua 1) sau Gitea? +5. ☐ **Timeline** — începem acum sau așteptăm ceva? + +--- + +## TL;DR + +**ChatGPT a proiectat un Enterprise GovTech Platform.** +**Noi construim un Product Hunt pentru digitalizarea României.** + +Diferența: ei au propus 12 luni de infrastructură. Noi livrăm în 4 săptămâni un site frumos cu 5 produse care inspiră oamenii să ceară mai mult de la administrația lor. + +Stack: Astro + Tailwind + Markdown + Cloudflare Pages. +Buget: 15€. +Echipă: 1-2 oameni motivați. +Primele produse: Traducător birocratic (AI), Harta digitalizării, Vizualizare buget local. +Mantra: **Inspiră, nu documenta.** diff --git a/PROMPTS.md b/PROMPTS.md new file mode 100644 index 0000000..0e6a833 --- /dev/null +++ b/PROMPTS.md @@ -0,0 +1,1367 @@ +# 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: +1. **[Continuare /achizitii sub-app](#1-continuare--achizitii-sub-app)** — pickup + pentru lucrul pe achiziții publice +2. **[Bugs/features /achizitii](#2-bugsfeatures-achizitii)** — pentru + modificări incrementale pe sub-app-ul de achiziții +3. **[Bugs/features marketing](#3-bugsfeatures-marketing-vreaudigitalro)** — + pentru `/`, `/idei`, `/produse`, `/despre`, `/contribuie`, `/cont/*` + +Plus [Context comun](#0-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 în `chatGPT/data-quality/` +> și `chatGPT/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 " 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 <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_previews` snapshot table (14 slugs × top-5 = 66 rows precomputed) +- `public_kpi.refresh_red_flags_previews()` plpgsql fn, called din `refresh-mvs.sh` daily 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 peste `seap.cpv_codes` (9454 rows, levels 1-4) +- `src/components/cauta/CpvAutocomplete.tsx` — react component +- `src/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.tsx` subscribe-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) +- `/cauta` no-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ă vezi `chatGPT/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_inmatriculare` stripped 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 STALE +- `services/seap-scraper/cron/scrape-da.sh` — wrapper SEAP DA (era missing!) +- `public_kpi.red_flags_counts` table (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): + +11. Deploy.sh fails pe untracked files pe satra — pre-push verifică `ssh satra "cd /opt/vreaudigital && git status --short | grep '^??'"` +12. Sub-agent file split pattern (separate helper files = no merge conflicts on parallel codegen) +13. Memory sync cron clobbers ~/.claude/.../memory/*.md every 60s — write DIRECT la ~/Code/claude-memory/projects//memory/ + commit acolo +14. Geocoding silent bug (label set, lat/lng not written) — validate cross-check +15. ASF CUI suffix corruption la sursă — fix at ingest +16. cnas.furnizori.name zgomotos — pre-cleanup ÎNAINTE de fuzzy +17. cnas/apia name_norm columns NULL — fix at insert +18. Kendo OFFSET >20K bug — per-judet drilldown workaround +19. WSP cron silent failure (tz-aware crash) — heartbeat catches now +20. Backups run from root's crontab (not bulibasa's) — check both +21. systemd OnCalendar needs SPACE after day-of-week (`Sun *-*-*` not `Sun*-*-*`) +22. ONRC parenthetical suffix pattern — strip ` (Primaria X)` before normalize → exact match +23. Romanian orthography `â↔î↔i` — `normalize_company_name` doesn't unify (Cârlogani vs Cirlogani) +24. "Code complete ≠ data flowing" — pipeline ready but no timer = 3x in this session +25. `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.* diff --git a/astro.config.mjs b/astro.config.mjs new file mode 100644 index 0000000..9f2283f --- /dev/null +++ b/astro.config.mjs @@ -0,0 +1,21 @@ +import { defineConfig } from 'astro/config'; +import tailwind from '@astrojs/tailwind'; +import react from '@astrojs/react'; +import node from '@astrojs/node'; + +export default defineConfig({ + site: 'https://vreau.digital', + output: 'server', + adapter: node({ + mode: 'standalone', + }), + integrations: [ + tailwind(), + react(), + ], + vite: { + build: { + cssMinify: true, + }, + }, +}); diff --git a/chatGPT/data-quality/freshness-audit-2026-05-10.md b/chatGPT/data-quality/freshness-audit-2026-05-10.md new file mode 100644 index 0000000..9517ab6 --- /dev/null +++ b/chatGPT/data-quality/freshness-audit-2026-05-10.md @@ -0,0 +1,356 @@ +# Audit prospețime + completitudine — gov-agreg DB +**Data:** 2026-05-10 +**Sub-agent:** G3 (data quality) +**Bază date:** `architools_db` @ 10.10.10.166 — **dimensiune totală 29 GB** +**Acoperire audit:** 17 schemas / 33 tabele de date (excludem staging și scrape_log) +**Total rânduri reconciliat:** **17,907,148** (~17.9M, vs ~6.94M citate anterior — schimbarea majoră vine din `fonduri.afir_plati` cu 5.33M rânduri și `firms.entities` la 3.99M). + +--- + +## 1. Executive summary — Tabel sinteză 17 schemas + +| Schema | Rânduri | Ultima înregistrare | Ultim scrape | Sursă (frecvență) | Gap | Acțiune | Prioritate | +|---|---:|---|---|---|---|---|---| +| **seap** | 4,011,832 | 2026-05-30 | 2026-05-10 | live API + WSP | live OK; gap 2020-21 + 2024 + DA pre-2025 | Backfill DA 2017-24 (~8M) + WSP retake 2020-21 | 🔴 | +| **firms** | 8,640,978 | 2026-05-09 | 2026-05-09 | ONRC weekly | OK | menține cron weekly | 🟢 | +| **fonduri** | 5,430,381 | 2026-05-10 | 2026-05-10 | data.gov.ro | OK | (afir 2025 nepublicat încă) | 🟢 | +| **regas** | 78,546 | 2026-05-07 | 2026-05-09 | C.Concurenței lunar | OK | menține cron lunar | 🟢 | +| **anaf** | 140,777 | 2016-03-31 (datornici!) | 2026-05-09 (no-op) | data.gov.ro Q | **3,693 zile** | scrape Q4 2025 (date nouă necesită captcha) | 🔴 | +| **aep** | 379,977 | 2024-12-27 | 2026-05-09 | banipartide.ro | ~140 zile | re-scrape 2025 (anual e OK) | 🟡 | +| **ani** | 25 PDFs / 0 parsate | 2023 | n/a | live ANI | parser ne-implementat | dezvoltare parser ANI 1.3M PDFs | 🔴 | +| **bugetar** | 18,822 entități / 0 execuție | n/a | 2026-05-09 | mfinante.gov.ro | execuție 0 rows!!! | repară pipeline `bugetar.executie` | 🔴 | +| **anre** | 29,536 | 2027-11-20 (data_emitere) | 2026-05-10 | live ANRE | OK; 2025 fresh | adaugă electricieni pipeline | 🟢 | +| **ancom** | 3,054 | live | 2026-05-10 | live ANCOM | OK | menține cron | 🟢 | +| **cnsc** | 29,488 | 2026 listing | 2026-05-10 | live CNSC | listing OK; 0% PDF parse | extracție decision_type din PDF (medium) | 🟡 | +| **cnas** | 36,244 (61 doc + 36k furnizori) | 2025-03-31 | 2026-05-10 | WP media CNAS | OK; 0% CUI match | activează matcher CUI | 🟡 | +| **asf** | 849 | 2022-12-19 | 2026-05-10 | live ASF | OK (nightly) | menține | 🟢 | +| **aaas** | 11 | n/a (last_action_date NULL) | 2026-05-10 | aaas.ro portfolio | only 11 firme — incomplete | backfill ORDIN 278/2005 PDF (~150 firme) | 🟡 | +| **curteacont** | 1,133 | 2026-05-15 | 2026-05-10 | live curteadeconturi.ro | listing OK; 0% PDF + 0 CUI | Stage 2 detail-page resolve | 🟡 | +| **apia** | 191 | 2024 (campaign) | 2026-05-10 | data.gov.ro CKAN | doar 1 CUI matched (191 PF) | re-rulează matcher cu fuzzy + adaugă camp.2025 | 🔴 | +| **gnm** | 349 (348 com + 1 amendă) | 2026-03-18 | 2026-05-10 | live gnm.ro RSS | listing OK; 0.6% amenzi parsate | finalizează Stage B (fuzzy matcher live) | 🟡 | + +Legendă: 🟢 sănătos · 🟡 are gap-uri rezolvabile <2 zile · 🔴 problemă structurală sau backlog mare + +--- + +## 2. Per-schema deep dive + +### 2.1 SEAP (`seap.*`) + +| Tabel | Rânduri | Min - Max date | Distinct CUI authority/supplier | +|---|---:|---|---| +| `announcements` | **781,029** | 2015-04-29 → 2026-05-30 | 14,616 / 65,643 | +| `direct_acquisitions` | **2,229,285** | 2025-01-01 → 2025-12-31 | 14,642 / 74,239 | +| `cui_location` | 96,523 | upd 2026-04-13 → 2026-05-09 | 96,523 | +| `entities` | 432 | 2026-04-13 (one shot) | 430 | +| `cpv_codes` | ~9,500 | static | — | +| `public_notices`, `notice_contracts` | **0 / 0** | gol | (legacy goale) | + +**Distribuție anuală announcements:** +``` +2015: 4,368 2016: 39 2017: 26,871 2018: 17,871 +2019: 16,570 2020: 0 2021: 0 2022: 24,676 +2023: 46,996 2024: 750 2025: 607,256 2026: 26,178 +``` +**Probleme observate:** +- ❌ **2020 + 2021 lipsă completă** (gap de 2 ani — confirmat în CLAUDE.md). Sursa: WSP scraper a sărit fereastra când a fost lansat în 2022. +- ❌ **2024 cvasi-absent** (doar 750 rows în martie). Backfill nu a recoperit 2024. +- ❌ **direct_acquisitions doar pentru 2025** (2,2M rows!) — istoric 2017-2024 = ~8M rânduri pierdute. CLAUDE.md confirmă "direct procurement 2017-2024 not ingested (~8M rows pending)". +- ❌ `seap.sync_state` arată feed `da` în `running` din **2025-10-16**, ultim update 2026-04-13 — backfill istoric blocat, nu mai progresează. +- ❌ `wsp_sync_state` nu a mai rulat din **2026-05-07** (3 zile stale; scraper rulează cron 2-4 ori/zi de obicei). +- ❌ `seap.public_notices` și `seap.notice_contracts` complet goale (legacy schema sau pipeline dezactivat). +- ⚠️ TED import: `import_ted.py` linia 22-38 — array `FIELDS` **NU conține `'publication-date'`**, deși codul îl folosește la linia 152. Toate `publication_date` din TED sunt **NULL** (1-line fix). + +**Completitudine recentă:** announcements ultimele 30 zile = 3,474 rânduri ✅. DA ultimele 30 zile = **0** ❌. + +### 2.2 firms (`firms.*`) + +| Tabel | Rânduri | Coverage | +|---|---:|---| +| `entities` | **3,985,967** | 3.99M total · 3.32M active ANAF · 3.74M cu CAEN · 3.64M geocodate · 2.62M cu reprezentanți | +| `financials` | 4,245,749 | 2020-2024 · 1.18M CUI distincți | +| `financials_banks` | 66 | 2024 | +| `financials_ong` | 286,240 | 2020-2024 · 74,862 ONG | +| `reprezentanti_if` | 122,956 | sucursale UE | + +**Completitudine:** +- 91.3% au CAEN (`caen_principal NOT NULL`) +- 91.3% sunt geocodate (`lat NOT NULL`) +- 65.7% au reprezentanți legali în JSON +- 83.4% activi ANAF (restul radiate / suspendate) + +**Probleme:** niciuna critică. Last update 2026-05-09. Cron weekly OK. Există `staging_onrc_*` (~3GB) — probabil de șters după backfill. + +### 2.3 fonduri (`fonduri.*`) + +| Tabel | Rânduri | Date range | CUI matched | +|---|---:|---|---| +| `afir_plati` | **5,329,006** | source_year 2023-2024 | 37,647 distincți | +| `beneficiar_anunt` | 41,494 | 2013-10 → 2026-05-08 | 8,772 | +| `beneficiar_anunt_lot` | 48,392 | — | — | +| `beneficiar_proiect` | 11,489 | 2010-05 → 2026-05-08 | **0 matched** ⚠️ | + +**Probleme:** +- `beneficiar_proiect` are 11,489 rânduri dar **0 CUI matched** (column `cui` populat?, dar `count(distinct cui)` = 0 — necesită investigație: probabil toate NULL). +- AFIR plăți istoric 2007-2022 nepublicat (sursa data.gov.ro publică doar 2023-2024 unificat). +- AFIR 2025 — sursa de obicei publică în Q1 anul următor; nu e gap real, e timing. + +### 2.4 regas (`regas.ajutoare`) + +- **78,546 rânduri**, 2016-01-13 → 2026-05-07 (live, lunar) +- 23,805 CUI distincți cu ajutoare de stat +- Distribuție: 2020-2023 sunt anii vârf (12k-21k/an), 2024 = 10,245, 2025 abia început +- ✅ **Sănătos** — last fetch 2026-05-09 + +### 2.5 anaf (`anaf.*`) + +| Tabel | Rânduri | Min/Max date | Status | +|---|---:|---|---| +| `datornici` | 140,777 | **2016-03-31** *(static!)* | 🔴 stale ~10 ani | +| `lista_alba` | **0** | — | gol | +| `datornici_latest` | view | — | reflect static | + +**Probleme catastrofale:** +- `anaf.datornici` are **doar Q1 2016** (publication_date = 2016-03-31). Sursa data.gov.ro publică trimestrial; ultimul Q4 2025 ar trebui ingerat. +- `anaf.lista_alba` complet gol — 0 rânduri. +- CLAUDE.md confirmă blocaj: "ANAF datornici via 2captcha" — site-ul actual ANAF cere captcha, ingestul automat a fost blocat după 2016. + +### 2.6 aep (`aep.*`) + +| Tabel | Rânduri | Min/Max | Note | +|---|---:|---|---| +| `donatii_pf` | 30,173 | 1997-03-29 → 2024-12-27 | persoane fizice | +| `donatii_pj` | 3,567 | 2000-05-16 → 2024-12-13 | persoane juridice (2,148 CUI distincți) | +| `donatii_rvc` | **346,237** | 2000-01-11 → **2034-01-31** ⚠️ | venituri (date eronate viitor) | +| `partide` | 64 | — | partide active | + +**Probleme:** +- ✅ Coverage 2024 prezent — bun. +- ⚠️ `donatii_rvc` are date până la **2034-01-31** — câteva rânduri cu data eronată în viitor (probabil OCR error pe banipartide.ro). +- ⚠️ Surse 2025 lipsă pentru toate sursele AEP (raportările partidelor pe 2025 se publică abia Q2 2026). + +### 2.7 ani (`ani.*`) + +| Tabel | Rânduri | +|---|---:| +| `declaratii` | **25** (toate `parse_status='pending'`) | +| `officials`, `bunuri`, `donatii`, `functii`, `shareholdings` | **0** | + +**Status:** Schema definită, **pipeline ne-implementat**. CLAUDE.md confirmă: "ANI 1.3M PDFs" — multi-week effort. + +### 2.8 bugetar (`bugetar.*`) + +| Tabel | Rânduri | +|---|---:| +| `entitate` | 18,822 (6,564 cu CUI matched, 12,258 fără) | +| `executie` | **0** ❌ | +| `crawl_job` | **0** ❌ | + +**Probleme catastrofale:** +- `bugetar.entitate` populat cu 18,822 entități publice, dar `executie` și `crawl_job` complet goale. +- Pipeline-ul mfinante.gov.ro pentru execuție bugetară nu rulează (sau rulează dar respinge toate datele). + +### 2.9 anre (`anre.*`) + +| Tabel | Rânduri | Stare | +|---|---:|---| +| `licente` | **29,536** | 1999-09-20 → 2027-11-20 (autorizări viitoare incluse) | +| `electricieni` | **0** | nu rulează | +| Source breakdown | atestat: 23,996 · electricitate: 4,541 · gaze: 999 | | + +**Distribuție stare:** 11,957 expirate · 8,077 atestate · 3,436 retrase · 1,332 acordate · ~5k alte stări. +**Problemă:** `anre.electricieni` complet gol — pipeline pentru registrul electricienilor neimplementat sau eșuat. + +### 2.10 ancom (`ancom.*`) + +| Tabel | Rânduri | +|---|---:| +| `operatori` | 518 (toți cu CUI matched ✅) | +| `drepturi` | 2,536 (1,311 servicii + 1,225 rețea) | + +✅ **Sănătos** — registru live, 100% CUI match. Last fetch 2026-05-10. + +### 2.11 cnsc (`cnsc.decizii`) + +- **29,488 rânduri**, distribute pe 2015-2026 (medie ~2,800/an) +- **0% au `decision_type`, `decision_summary`, `pdf_text_sha1`** — listing OK, dar PDF-uri **complet neparsate** +- CLAUDE.md target: "50/page × 617 pages = ~30,850" — captura curentă (29,488) ≈ 96% din target. ✅ aproape complet. +- Last fetch 2026-05-10. + +### 2.12 cnas (`cnas.*`) + +| Tabel | Rânduri | Status | +|---|---:|---| +| `documents` | 61 (46 ok · 14 no_table · 1 unsupported) | 2022-03 → 2025-03 | +| `furnizori` | **36,183** | **0 CUI matched** ⚠️ | + +**Probleme:** +- 100% furnizori extrași, **0% matched la CUI** — câmpul `cui_match_method` este gol pentru toate rândurile. +- 25% PDF-uri (15/61) eșuat la parsing (no_table sau format necunoscut). + +### 2.13 asf (`asf.entitati`) + +- **849 rânduri** (788 brokeri + 61 asigurători) +- Live nightly, `data_autorizare` 1900-2022 (1900 = data lipsă în sursă) +- ✅ Sănătos. + +### 2.14 aaas (`aaas.firme`) + +- **11 firme** (toate `aaas_status='active_holding'`) +- **`last_action_date` = NULL pentru toate** — câmp ne-populat +- CLAUDE.md target: "12-15 firme active portfolio" — captura curentă (11) ≈ 73-92% din target. +- ❌ Backfill **ORDIN 278/2005** PDF (~150 firme istorice) **deferred**. + +### 2.15 curteacont (`curteacont.rapoarte`) + +- **1,133 rânduri**: 500 conformitate + 499 financiar + 114 follow-up + 20 performanță +- Last finished_at: 2026-05-10 (Stage 1 = listing OK) +- ❌ **0% au `pdf_path`** (zero PDF-uri descărcate) +- ❌ **0% au `audited_entity_cui`** (entitatea auditată nu e extrasă) +- ❌ **0% `parsed_at`** — Stage 2 (detail-page resolve) ne-implementat +- audit_year: 2021(1), 2022(5), 2023(74), 2024(415), 2025(4) + +### 2.16 apia (`apia.fermieri`) + +- **191 rânduri** — campania 2024 +- ⚠️ **Doar 1 CUI matched** — 190/191 sunt PF (persoane fizice fără CUI), legitim, dar și **PJ-urile nu sunt matchuite** +- CLAUDE.md target: "monthly via CKAN" — sursa publică doar lista anuală +- Lipsește campania 2025 (în mod normal disponibilă din martie 2026) +- Sub-utilizat — datasetul real APIA are ~800k fermieri/an, captura noastră are 191 (probabil un eșantion) + +### 2.17 gnm (`gnm.*`) + +| Tabel | Rânduri | +|---|---:| +| `comunicate` | 348 | +| `amenzi_extrase` | **1** | + +- Distribuție: 2016(23), 2020-2023(8-51/an), 2024(51), 2025(92), **2026(5)** +- Last `publicat_la` = 2026-03-18 (~7 săptămâni stale față de scrape 2026-05-10) +- 36/348 (10%) flagged `is_enforcement=true`, 20/348 (5.7%) cu `total_amenzi_lei` +- Stage B fuzzy matcher recent comise (cf. commit `82b64b3`) dar a produs doar 1 amendă — pipeline necesită testare. + +--- + +## 3. Quick wins (≤2h fixes — ranking by impact) + +| # | Fix | Schema | Effort | Impact | Comandă/path | +|---|---|---|--:|---|---| +| 1 | **Adaugă `'publication-date'` în `FIELDS` array (TED import)** | seap (TED) | 5 min | 100% TED publication_date populat | `services/seap-scraper/import_ted.py` linia 22-38 | +| 2 | **Re-rulează scraper SEAP WSP** (3 zile stale, sync_state blocat la 2025-10-16) | seap | 30 min | recoperare daily live + deblochează backfill istoric | `services/seap-scraper/wsp/` + `seap.sync_state` reset manual | +| 3 | **Re-rulează matcher CUI pentru `cnas.furnizori`** (36k rows, 0% matched) | cnas | 20 min | 36k furnizori legabili la entități firme | `services/seap-scraper/cron/match-cui-external.sh` (extindere) | +| 4 | **Re-rulează matcher CUI pentru `apia.fermieri`** | apia | 10 min | match PJ (cu CUI explicit) la firms.entities | `cron/match-cui-external.sh` | +| 5 | **Curățare date eronate `aep.donatii_rvc`** (date 2034-01-31) | aep | 10 min | UPDATE … SET data_donatie = NULL WHERE data_donatie > now() | direct SQL | +| 6 | **Re-rulează scrape AEP donatii** pentru 2025 | aep | 1 h | adaugă raportările financiare 2024 finale | `cron/scrape-aep-donatii.sh` | +| 7 | **Drop staging tables firms.staging_onrc_*** (~3GB liberi) | firms | 5 min | recuperare spațiu DB după backfill | DROP TABLE manual | +| 8 | **Drop seap.public_notices, seap.notice_contracts** (legacy goale) | seap | 1 min | curățare schema | DROP TABLE | +| 9 | **Repornire scraper GNM** (last comunicat 2026-03-18, gap 53 zile) | gnm | 15 min | aducerea la zi a comunicatelor martie-mai 2026 | `cron/scrape-gnm.sh` | + +**Total quick wins recomandate: ~3h** pentru a rezolva 9 issues cu impact direct vizibil. + +--- + +## 4. Medium effort (1-2 zile fiecare) + +| # | Fix | Schema | Effort | Impact | +|---|---|---|--:|---| +| 1 | **CNSC PDF parse pentru `decision_type` + `decision_summary`** | cnsc | 1-2 zile | 29,488 decizii devin filtrabile pe tip (admisă/respinsă) | +| 2 | **Curtea Conturi Stage 2** — detail-page resolve + extract `audited_entity_cui` + descarcă PDF | curteacont | 2 zile | 1,133 rapoarte legate la CUI + PDF disponibile | +| 3 | **AAAS ORDIN 278/2005 backfill** — parse PDF cu lista istorică ~150 firme | aaas | 1 zi | 11 → ~150 firme acoperire (12-13× growth) | +| 4 | **bugetar.executie pipeline repair** — entitate populat dar executie 0 rows | bugetar | 1-2 zile | adaugă date execuție pe ~6,564 instituții cu CUI matched | +| 5 | **APIA campania 2025** + **fixează volumul** (191 rânduri pare mic vs ~800k fermieri reali) | apia | 1 zi | datasetul devine real reprezentativ | +| 6 | **CNAS PDF parse upgrade** pentru 14 doc cu `parse_status='no_table'` | cnas | 1 zi | +25% acoperire furnizori CNAS | +| 7 | **GNM Stage B finalizare** — fuzzy matcher activ pe toate cele 348 comunicate (acum capturat 1/348) | gnm | 1 zi | extragerea efectivă a violatorilor de mediu | +| 8 | **ANRE electricieni** — pipeline neimplementat | anre | 1 zi | adaugă registrul electricienilor (~10k entries) | +| 9 | **Reset `seap.sync_state` pentru `da`** (blocat în `running` din 2025-10-16) | seap | 30 min + replay | deblochează backfill direct_acquisitions | +| 10 | **anaf.lista_alba** populare din data.gov.ro | anaf | 1 zi | listă albă completă (paralel datornici) | +| 11 | **`fonduri.beneficiar_proiect` matcher CUI** (11,489 rows, 0 matched) | fonduri | 1 zi | proiectele POIM/POR devin filtrabile pe CUI | + +--- + +## 5. Heavy lifts (multi-week) + +| # | Investiție | Schema | Effort | Impact | +|---|---|---|--:|---| +| 1 | **ANI 1.3M PDFs** — declaratii avere + interese, parser + match officials | ani | **4-6 săptămâni** | unlock declaratii politicieni — feature flagship | +| 2 | **SEAP direct_acquisitions backfill 2017-2024** — ~8M rânduri | seap | **2-3 săptămâni** | acoperire achiziții directe completă (acum doar 2025) | +| 3 | **SEAP announcements backfill 2020-2021** + **2024 lipsă** | seap | **1-2 săptămâni** | închidere gap istoric anunțuri | +| 4 | **ANAF datornici via 2captcha** — re-acoperire 2017-2025 (33 trimestre stale) | anaf | **2-3 săptămâni** | reactivare datornici (acum static la Q1 2016) | +| 5 | **Curtea Conturi PDF text extraction + entity resolution** | curteacont | **3-4 săptămâni** | rapoarte audit devin căutabile pe text + linked la firme | +| 6 | **ONRC raw → entities pipeline complet** (există staging 791MB + 938MB + 443MB nefolosit) | firms | **2 săptămâni** | refresh weekly al `firms.entities` din ONRC fresh dump | + +--- + +## 6. Refresh cadence recommendation (cron schedule sustenabil) + +Propunere `/etc/cron.d/govagreg-refresh` pentru steady-state: + +```cron +# === LIVE / NEAR-REAL-TIME (multiple ori pe zi) === +0 */4 * * * satra scrape-seap-wsp.sh # SEAP live feed (4h cycle, ~3-4k rows/zi) +30 2 * * * satra scrape-cnsc.sh # CNSC daily (~30 decizii noi/zi) + +# === DAILY (o dată pe zi, off-peak 02:00-06:00) === +0 3 * * * satra scrape-anre.sh # ANRE licențe (live registry) +0 4 * * * satra scrape-ancom.sh # ANCOM operatori (live) +0 5 * * * satra scrape-asf.sh # ASF entitati (rebuilt nightly) +30 5 * * * satra scrape-curteacont.sh # Curtea Conturi listing (Stage 1) +0 6 * * * satra refresh-mvs.sh # MV refresh (post-toate-scrape-urile) + +# === WEEKLY (luni dimineață) === +0 2 * * 1 satra scrape-gnm.sh # GNM weekly RSS (~5-15 noi) +0 3 * * 1 satra scrape-aaas.sh # AAAS portfolio (rar schimbă) +0 4 * * 1 satra scrape-cnas.sh # CNAS WP media (lunar dar ieftin weekly) +0 5 * * 1 satra import-onrc-fresh.sh # ONRC update săptămânal + +# === MONTHLY (1 ale lunii) === +0 2 1 * * satra scrape-regas.sh # RegAS — monthly publish +0 3 1 * * satra scrape-bugetar.sh # Bugetar mfinante (lunar) +0 5 1 * * satra import-apia-fermieri.sh # APIA CKAN + +# === QUARTERLY (1 ale trim) === +0 2 1 1,4,7,10 * satra scrape-anaf-datornici.sh # ANAF datornici Q (după activare 2captcha) +0 3 15 1,4,7,10 * satra scrape-aep-donatii.sh # AEP — raportări trimestriale partide + +# === ANUAL (15 ianuarie) === +0 2 15 1 * satra import-afir-historical.sh # AFIR plăți an precedent (CSV) +0 4 15 1 * satra import-financials.sh # Bilanțuri ANAF anul precedent +``` + +### Estimări runtime per scraper (best-effort, observed) + +| Scraper | Frecv | Runtime | Notes | +|---|---|---|---| +| scrape-seap-wsp | 4h | 5-15 min | depinde de volum daily | +| scrape-cnsc | daily | 2-5 min | (full re-scan ~617 pages = 30 min) | +| scrape-anre | daily | 3-5 min | 3 surse (atestat/electricitate/gaze) | +| scrape-ancom | daily | 1-2 min | 518 operatori | +| scrape-asf | daily | 2-3 min | 849 entități | +| scrape-curteacont | daily | 1-3 min | listing only | +| scrape-gnm | weekly | 1-2 min | RSS feed | +| scrape-aaas | weekly | 30 sec | 11 firme | +| scrape-cnas | weekly | 5-10 min | 61 PDF + parse | +| import-onrc-fresh | weekly | 30-60 min | 4M rows ETL | +| scrape-regas | monthly | 10-15 min | 78k rows update | +| scrape-bugetar | monthly | 30-60 min | 6,5k rapoarte | +| import-apia-fermieri | monthly | 5-10 min | CKAN API | +| scrape-anaf-datornici | quarterly | 30-60 min | dependent de captcha | +| import-afir-historical | yearly | 2-4 ore | 5M rows CSV | + +**Total cron load:** ~30 min CPU/zi în steady-state, ~2h/lună în rafale lunare. Sustenabil pe `satra` Docker host. + +--- + +## Concluzie executivă (200 cuvinte) + +Baza de date `architools_db` (29 GB) conține 17.9M rânduri pe 17 schemas. **6 schemas sunt sănătoase** (firms, fonduri, regas, anre, ancom, asf), **6 au gap-uri rezolvabile sub 2 zile** (aep, cnsc, cnas, aaas, curteacont, gnm), iar **5 au probleme structurale** (seap istoric, anaf datornici stale 10 ani, ani neimplementat, bugetar executie 0 rows, apia subvolum). + +**Quick wins (3h total):** (1) adaugă `'publication-date'` în `FIELDS` la `import_ted.py`, (2) reset `seap.sync_state` pentru deblocare backfill DA, (3) rerulează matcher CUI pentru `cnas.furnizori` (36k rows, 0% match) și `apia.fermieri`. + +**Priorități critice:** (a) backfill SEAP DA 2017-2024 = ~8M rânduri lipsă (CLAUDE.md confirmat), (b) reactivare ANAF datornici via 2captcha (date înghețate la Q1 2016), (c) repară pipeline `bugetar.executie` (entități populate dar execuție 0). + +Cron-ul propus rulează în 30 min CPU/zi steady-state. ANI 1.3M PDFs rămâne flagship-ul de 4-6 săptămâni — singura sursă cu adevărat blocată din cauze tehnice (parser PDF complex), restul sunt operaționale. + +--- + +**Raport complet:** `/home/orchestrator/Code/gov-agreg/chatGPT/data-quality/freshness-audit-2026-05-10.md` diff --git a/chatGPT/data-quality/geocoding-strategy-2026-05-11.md b/chatGPT/data-quality/geocoding-strategy-2026-05-11.md new file mode 100644 index 0000000..aac5388 --- /dev/null +++ b/chatGPT/data-quality/geocoding-strategy-2026-05-11.md @@ -0,0 +1,62 @@ +# Geocoding strategy — firms.entities + +Data: 2026-05-11. Sub-agent A2. + +## Final coverage + +| Source | Rows | Accuracy | Notes | +|---|---:|---|---| +| `geonames_postal` | 2,128,990 | ~100m–2km | Exact 5/6-digit RO postal match against geonames RO.zip (firms.postal_codes). | +| `photon` | 839,643 | ~50–500m | Komoot Photon OSM geocoder, free-text `adr_full`. Earlier batch (services/seap-scraper/src/geocode-photon.ts). | +| `uat_centroid` | 670,657 | 5–30km | UAT polygon centroid match by locality+county. | +| `judet_centroid` | 346,675 | 30–150km | Median of all postal codes within the judet. Filled the 2026-05-11 gap where `judet_fallback` was tagged but lat/lng never written. | +| `seap_siruta_centroid` | 4,681 | 5–30km | NEW stub rows for SEAP-only CUIs (not present in ONRC firme dataset) using SIRUTA → gis_uats centroid. | +| `seap_judet_centroid` | 2,497 | 30–150km | NEW stub rows for SEAP-only CUIs with city/county data in seap.cui_location. | +| _unmapped_ | 2 | — | Two firms with literally zero address fields. Out of reach. | + +**Total: 3,993,143 / 3,993,145 = 100.00 %.** + +## Fallback chain (priority order) + +For any new row entering firms.entities, apply in this order, stop at first hit: + +1. **Postal-code exact match** → `firms.postal_codes.postal_code = adr_cod_postal` (5/6 digit). Source = `geonames_postal`. +2. **Postal-code normalized** (strip non-digit), same lookup. (Adds ~9K to the bucket — already covered in current dataset.) +3. **Photon free-text** on `adr_full` (OSM geocoder, requires network — see geocode-photon.ts). +4. **UAT centroid** by `(adr_localitate, adr_judet)` → `firms.postal_codes` median of matching place_name + county_code, OR `public.gis_uats` polygon centroid. +5. **Judet centroid** — median of all `firms.postal_codes` rows for the normalized judet name (`upper(unaccent(replace(adr_judet,'MUNICIPIUL ','')))`). 42 distinct judet keys cover all of RO + București. +6. **SIRUTA centroid** — for SEAP-mentioned CUIs only, where firms.entities row didn't exist: `seap.announcements.{authority,supplier}_siruta` → `gis_uats.siruta` centroid (transformed 3844→4326). +7. **City+county from seap.cui_location** → judet centroid fallback (`seap_judet_centroid`). + +## Authority / supplier coverage (downstream) + +After backfill, JOIN-based coverage from SEAP: + +| Bucket | Total distinct CUIs | Geocoded | Pct | +|---|---:|---:|---:| +| authority_cui | 14,617 | 14,119 | 96.6 % | +| supplier_cui | 65,675 | 64,793 | 98.7 % | + +Residual: 498 authorities + 882 suppliers (~1,373 unique) — these CUIs appear nowhere with address data (no siruta, no city/county in seap.cui_location, no usable address in any announcement). Most are malformed CUI strings (commas, semicolons, trailing punctuation) — should be cleaned up at SEAP ingestion. Out of scope for geocoding. + +## Cross-schema enrichment + +- `aaas.firme` — 11 rows total, all 11 have geocoded parent in firms.entities via CUI. No action needed; UI agents JOIN. +- `anre.licente` — 27,275 rows with titular_cui populated, 11,043 distinct. All 11,043 CUIs match a geocoded firm. UI agents JOIN on `firms.entities.cui = anre.licente.titular_cui`. +- `seap.announcements` — `supplier_address`, `authority_address`, `supplier_siruta`, `authority_siruta` are populated. After this batch, almost every announcement can render on a map via firms.entities lookup. + +## Geom integrity + +- `firms.entities.geom` (geography 4326) is now 1:1 with lat/lng (12,735 prior mismatches fixed where judet_fallback had stale geom from an older run). +- 2 unmapped firms have NULL on both. PostGIS spatial indexes still valid. + +## Forward maintenance + +1. Anyone ingesting new firms (ANAF/ONRC weekly refresh) must apply the fallback chain in code before INSERT. +2. The seap_siruta_centroid and seap_judet_centroid stubs should be **upgraded** the moment an ANAF/ONRC record arrives for the same CUI — re-run the chain with the real `adr_full`. +3. If the SEAP CUI hygiene gets fixed (A1's domain), the 1,373 residual can be re-attempted. +4. `judet_centroid` (and the two seap variants) have only `geocode_score = 0.1` and `0.3`. UI clustering should down-weight or hide these at high zoom. + +## Queries used + +All idempotent UPDATEs filtered on `lat IS NULL`. Centroid sources read from `firms.postal_codes` and `public.gis_uats` (SRID 3844 → 4326). Saved in-line in the agent transcript; the strategy itself is the artifact. diff --git a/chatGPT/data-quality/refresh-cadence-strategy-2026-05-11.md b/chatGPT/data-quality/refresh-cadence-strategy-2026-05-11.md new file mode 100644 index 0000000..0cb6304 --- /dev/null +++ b/chatGPT/data-quality/refresh-cadence-strategy-2026-05-11.md @@ -0,0 +1,624 @@ +# Refresh cadence master strategy — gov-agreg / vreaudigital.ro +**Data:** 2026-05-11 +**Sub-agent:** S1 (refresh cadence master strategy) +**Bază date:** `architools_db` @ 10.10.10.166 — 29 GB +**Cuprinde:** 17 schemas, 2 sub-pipeline-uri (ANAF v9 + ANAF datornici), strategie captcha, monitorizare, idempotență, DR +**Audit-ul de prospețime anterior:** `chatGPT/data-quality/freshness-audit-2026-05-10.md` + +--- + +## 0. Context & constrângeri + +| Constrângere | Stare actuală | +|---|---| +| Host orchestrare | `satra` (10.10.10.166), Docker, Ubuntu, **disc la 85% (299/371 GB)** ⚠️ | +| Sistem de scheduling | systemd timers (3 active) + ad-hoc shell wrappers; **nu există crontab agregat pentru toți 13 scraperi** | +| Secrete | Infisical Machine Identity (`/opt/vreaudigital/.infisical-mi`) — refresh per wrapper | +| Anti-pattern interzis | `docker run -e $DATABASE_URL` (leakă via `ps`); folosim `--env-file` 600 + delete | +| Run-as | `bulibasa` (systemd), `root` (cron actual eterra/backup) | +| Captcha sources | ANAF datornici live, Bugetar Faza 2, ANI e-DAI 2022+ (Cloudflare Turnstile) | +| Buget | Mic — 2captcha (~$1/1000), playwright headless OK, headed pe Orchi doar la nevoie | + +**Stat actual systemd (verificat azi):** +- `vreaudigital-anaf-daily.timer` → 02:00 zilnic, enrich-anaf.sh tier=daily, concurrency=2 +- `vreaudigital-onrc-weekly.timer` → marți 03:00, import-onrc-fresh.sh +- `vreaudigital-mvs.timer` → 04:00 zilnic, refresh-mvs.sh (9 MV-uri seap) + +**13 wrappers existente NE-programate prin systemd** (rulează doar manual sau via cron neagregat încă): +`scrape-aaas`, `scrape-aep-donatii`, `scrape-anaf-datornici`, `scrape-ancom`, `scrape-anre`, `scrape-asf`, `scrape-bugetar`, `scrape-cnas`, `scrape-cnsc`, `scrape-curteacont`, `scrape-gnm`, `scrape-regas`, `import-afir-historical`, `import-apia-fermieri`, `import-financials*`. + +Audit-ul `scrape_log` confirmă totuși că **toți cei 9 scraperi cu schema dedicată au rulat în ultimele 24h** — deci există un cron ascuns (probabil în `bulibasa` user crontab, nu în `sudo crontab`). Strategia de mai jos **înlocuiește cron-ul ascuns cu un /etc/cron.d/ vizibil + systemd timers per scraper**. + +--- + +## 1. Per-schema cadence table + +Coloane: Schema · Sursă (ritm publicare) · Cadență recomandată · Wrapper · Runtime · Risc · Monitor signal (max age tolerat) + +| # | Schema | Sursă upstream — ritm | Cadență recomandată | Wrapper | Runtime | Risc | Monitor signal (max age) | +|---|---|---|---|---|---|---|---| +| 1 | **seap.announcements** (WSP) | live | la 4h | `scrape-seap-wsp` (lipsește wrapper!) | 5-15 min | F5 WAF, ASP session | `wsp_sync_state.last_run_at` ≤ 6h | +| 2 | **seap.direct_acquisitions** | live | la 6h | `scrape-seap-da` (lipsește wrapper!) | 10-30 min | session expiry, retry storms | `sync_state[source=da].updated_at` ≤ 8h | +| 3 | **seap.entities + cui_location** | după WSP/DA refresh | seara, după daily | inclus în WSP wrapper | (incl.) | n/a | `entities.fetched_at` ≤ 24h | +| 4 | **anaf** (v9 enrichment — daily delta) | live API | zilnic 02:00 | `enrich-anaf.sh` TIER=daily | 1-2h | rate limit ANAF 503 | `firms.entities WHERE anaf_fetched_at > now-2d` count ≥ 1000 | +| 5 | **anaf.datornici** (data.gov.ro Q) | quarterly | trim 15-ian/15-apr/15-iul/15-oct | `scrape-anaf-datornici` SOURCE=datagov | 30-60 min | NEW — necesită captcha doar pt live | `anaf.datornici WHERE publication_date > now-180d` ≥ 1 | +| 6 | **anaf.datornici** (anaf.ro live) | live, captcha | trim — **opțional dacă plătim 2captcha** | `scrape-anaf-datornici` SOURCE=live | 2-4h | reCAPTCHA v2 | (decis în §3) | +| 7 | **firms.entities** (ONRC weekly) | săptămânal | marți 03:00 | `import-onrc-fresh.sh` | 30-60 min | bulk diff fail | `firms.entities.updated_at` ≤ 8 zile | +| 8 | **firms.financials** (ANAF bilanțuri) | anual (15-iul publicare an N-1) | 15 iul + 15 aug rerun | `import-financials.sh` | 2-4h | mărime CSV ~3GB | `firms.financials WHERE source_year = year(now)-1` ≥ 800k | +| 9 | **firms.financials_ong / banks** | anual | 20-iul | `import-financials-ong-banks.sh` | 1h | n/a | acelaşi | +| 10 | **fonduri.afir_plati** | anual data.gov.ro | 15-feb (date an N-1) | `import-afir-historical.sh` | 2-4h | CSV mare | `fonduri.afir_plati WHERE source_year = year(now)-1` ≥ 1M | +| 11 | **fonduri.beneficiar_anunt / proiect** (FEADR + FEGA) | live data.gov.ro | săptămânal lun 02:00 | `import-fonduri-beneficiari` (lipsește!) | 15-30 min | n/a | `fonduri.beneficiar_anunt.fetched_at` ≤ 8d | +| 12 | **regas.ajutoare** (Consiliul Concurenței) | lunar | luna 1 ale lunii 02:00 | `scrape-regas` | 10-15 min | n/a | `regas.ajutoare.fetched_at` ≤ 35d | +| 13 | **bugetar.entitate** (mfinante public registry) | lunar | luna 1 ale lunii 03:00 | `scrape-bugetar` | 30-60 min | n/a | `bugetar.entitate.fetched_at` ≤ 35d | +| 14 | **bugetar.executie** (Faza 2 — captcha) | lunar (raportare 30 zile decalaj) | **deferred** — vezi §3 | `scrape-bugetar-executie` (lipsește) | 4-8h pt 1000 entități | captcha + 1000 detail pages | (deferred) | +| 15 | **anre.licente** (3 surse: atestat/electricitate/gaze) | live | zilnic 03:00 | `scrape-anre` SOURCE=all | 3-5 min | TLS cert intermediary | `anre.licente.fetched_at` ≤ 36h | +| 16 | **anre.electricieni** | live (~100k entries) | săptămânal duminică 04:00 | `scrape-anre` SOURCE=electricieni | 30-60 min | pagination volume | `anre.electricieni.fetched_at` ≤ 8d *(when implemented)* | +| 17 | **ancom.operatori + drepturi** | live registry | zilnic 04:00 | `scrape-ancom` | 1-2 min | n/a | `ancom.operatori.fetched_at` ≤ 36h | +| 18 | **asf.entitati** | live (rebuild nightly) | zilnic 05:00 | `scrape-asf` | 2-3 min | "omit g-recaptcha" trick must hold | `asf.entitati.fetched_at` ≤ 36h | +| 19 | **cnsc.decizii** (listing) | live | zilnic 02:30 | `scrape-cnsc` MAX_PAGES=10 (incremental) | 2-5 min | session-based | `cnsc.decizii.fetched_at` ≤ 36h | +| 20 | **cnsc Stage 2** (PDF parse → decision_type) | după listing | săptămânal sâmbătă 02:00 | `cnsc-parse-pdfs` (lipsește) | 4-8h pt 30k | I/O storage PDFs | % decizii `WHERE decision_type IS NOT NULL` ≥ 90% | +| 21 | **cnas.documents** | lunar pe WP media | săptămânal lun 04:00 | `scrape-cnas` | 5-10 min | format CNAS schimbabil | `cnas.documents.fetched_at` ≤ 8d | +| 22 | **cnas.furnizori** (parse din PDF) | inclus în .documents | săptămânal | (incl.) | (incl.) | parser failure 25% | % docs `parse_status='ok'` ≥ 75% | +| 23 | **aaas.firme** | live portal | săptămânal lun 04:30 | `scrape-aaas` | 30s | listă mică (11 firme) | `aaas.firme.fetched_at` ≤ 8d | +| 24 | **curteacont.rapoarte** (Stage 1 listing) | live săptămânal | zilnic 05:30 | `scrape-curteacont` | 1-3 min | n/a | `curteacont.rapoarte.fetched_at` ≤ 36h | +| 25 | **curteacont Stage 2** (detail + PDF + audited CUI) | după Stage 1 | săptămânal duminică 03:00 | `curteacont-detail` (lipsește) | 4-6h pt 1133 | n/a | % rapoarte `WHERE audited_entity_cui IS NOT NULL` ≥ 50% | +| 26 | **aep.donatii_pf/pj/rvc + partide** | trimestrial (raportări) | trim 15-ian/15-apr/15-iul/15-oct + lunar smoke check | `scrape-aep-donatii` | 1h | banipartide.ro mortality | `aep.donatii_pj.fetched_at` ≤ 95d | +| 27 | **ani.declaratii** (PDFs) | live ANI dar **parser ne-implementat** | **deferred** | n/a | n/a | Cloudflare Turnstile | (deferred — multi-week) | +| 28 | **apia.fermieri** (CKAN data.gov.ro) | anual (campania an N publicată 1-mar an N+1) | 15-mar + lunar smoke | `import-apia-fermieri` | 5-10 min | volum mic actual (191 rows — needs investigation) | `apia.fermieri.fetched_at` ≤ 35d | +| 29 | **gnm.comunicate** (RSS) | săptămânal | zilnic 06:00 | `scrape-gnm` | 1-2 min | RSS format change | `gnm.comunicate.fetched_at` ≤ 36h ŞI `publicat_la_max > now-30d` | +| 30 | **gnm.amenzi_extrase** (Stage B fuzzy) | după Stage A | săptămânal duminică 05:00 | `gnm-extract-amenzi` (post-A2) | 30 min | NLP false positives | % comunicate flagged enforcement cu amendă extrasă ≥ 50% | +| 31 | **seap MV refresh** (9 materialized views) | după toate SEAP scrape | zilnic 06:00 (după WSP+DA) | `refresh-mvs.sh` | 5-15 min | dependență de WSP/DA | `mv_authority_concentration` ultim refresh ≤ 26h | + +**Note critice:** +- **Wrappere lipsă:** `scrape-seap-wsp`, `scrape-seap-da`, `import-fonduri-beneficiari`, `scrape-bugetar-executie`, `cnsc-parse-pdfs`, `curteacont-detail`, `gnm-extract-amenzi`. Scraperele TypeScript există în `src/`, dar nu au wrapper `cron/scrape-*.sh` cu pattern Infisical MI → env-file → docker run. **Aceasta este lacuna #1 înainte de oricărei programări noi.** +- ANRE rulează deja zilnic via cron ascuns dar nu via systemd vizibil — strategia mută totul în systemd timers per scraper, ca **mvs.timer** azi. + +--- + +## 2. Cron schedule recommendation + +Două opțiuni implementabile: +- **(A) /etc/cron.d/govagreg-refresh** — un singur fișier vizibil, ușor de auditat. +- **(B) systemd timers per scraper** — match-uiește patternul existent (`vreaudigital-*.timer`), permite `journalctl -u`, status uniform. + +**Recomandare: B (systemd timers)**, pentru că: +1. Patternul există deja (3 timere), iar `journalctl` e mai util decât `/var/log/cron`. +2. Per-unit `OnFailure=` permite alerting nativ. +3. `Persistent=true` reia rulările pierdute după reboot (cron-ul de pe satra nu are anacron). +4. `RandomizedDelaySec=` evită contenția în vârful 02:00-06:00. + +### 2.1 Timer skeleton (canonical pattern) + +Un template pentru fiecare scraper: + +```ini +# /etc/systemd/system/vreaudigital-.service +[Unit] +Description=vreaudigital — refresh +Wants=network.target docker.service +After=network.target docker.service vreaudigital-prerequisites.service + +[Service] +Type=oneshot +User=bulibasa +ExecStart=/opt/vreaudigital/services/seap-scraper/cron/scrape-.sh +StandardOutput=journal +StandardError=journal +TimeoutStartSec=4h +OnFailure=vreaudigital-alert@%n.service + +# /etc/systemd/system/vreaudigital-.timer +[Unit] +Description=vreaudigital — at