Commit Graph

76 Commits

Author SHA1 Message Date
Claude VM f44d57629f feat: county sync on monitor page + in-app notification system
- GET /api/eterra/counties — distinct county list from GisUat
- POST /api/eterra/sync-county — background sync all UATs in a county
  (TERENURI + CLADIRI + INTRAVILAN), magic mode for enriched UATs,
  concurrency guard, creates notification on completion
- In-app notification service (KeyValueStore, CRUD, unread count)
- GET/PATCH /api/notifications/app — list and mark-read endpoints
- NotificationBell component in header with popover + polling
- Monitor page: county select dropdown + SyncTestButton with customBody

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 22:56:59 +03:00
AI Assistant fc7a1f9787 feat(monitor): add Refresh ALL UATs button with delta sync
New endpoint POST /api/eterra/refresh-all processes all 43 UATs
sequentially. UATs with >30% enrichment get magic mode, others
get base sync only. Each UAT uses the new delta engine (quick-count
+ VALID_FROM + rolling doc check). Progress tracked via progress store.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 01:02:47 +03:00
AI Assistant 7a93a28055 fix(parcel-sync): always run syncLayer for delta detection + no-geom freshness
- Always call syncLayer for TERENURI/CLADIRI (not gated by isFresh)
  so that quick-count + VALID_FROM delta actually run on daily syncs
- syncLayer handles efficiency internally via quick-count match
- Add 48h freshness check for no-geom import (skip if recent)
- Admin layers: skip if synced within 24h
- Log sync summary (new features, updated features)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 23:25:23 +03:00
AI Assistant b8061ae31f feat(wds): limit force sync to terenuri + cladiri only
Manual trigger now only processes sync_terenuri and sync_cladiri steps.
import_nogeom and enrich are left for the regular weekend window.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 07:36:35 +03:00
AI Assistant 730eee6c8a feat(wds): add manual sync trigger button with force-run mode
- triggerForceSync() resets error steps, clears lastSessionDate, starts sync immediately
- Force mode uses extended night window (22:00-05:00) instead of weekend-only
- API action 'trigger' starts sync in background, returns immediately
- 'Porneste sync' button in header (hidden when already running)
- Respects __parcelSyncRunning guard to prevent concurrent runs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 01:59:07 +03:00
AI Assistant 4410e968db feat(wds): live status banner, auto-poll, and instant error emails
- Auto-poll every 15s when sync is running, 60s when idle
- Live status banner: running (with city/step), error list, weekend window waiting, connection error
- Highlight active city card and currently-running step with pulse animation
- Send immediate error email per failed step (not just at session end)
- Expose syncStatus/currentActivity/inWeekendWindow in API response
- Stop silently swallowing fetch/action errors — show them in the UI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 01:41:55 +03:00
AI Assistant 9d45799900 revert: disable building labels + remove debug endpoints
Building labels (C1/C2/C3) disabled — Martin MVT tiles don't include
cadastral_ref as a property despite the PostgreSQL view exposing it.
Root cause needs investigation (Martin config or alternative tile server).

Removed temporary debug endpoints:
- /api/eterra/debug-tile-props
- /api/eterra/debug-tile-sample

Kept /api/eterra/debug-fields (useful long-term diagnostic).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 08:43:20 +02:00
AI Assistant 311f63e812 debug: add /api/eterra/debug-tile-sample for Martin tile diagnostics
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 08:22:26 +02:00
AI Assistant 6c5aa61f09 debug: add /api/eterra/debug-tile-props to check Martin tile columns
Temporary diagnostic to verify what columns gis_cladiri view exposes
for Martin vector tiles. Needed to debug missing C1/C2 labels.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 07:39:21 +02:00
AI Assistant 4e67c29267 feat(parcel-sync): add /api/eterra/debug-fields diagnostic endpoint
Shows all available eTerra fields for a parcel + buildings:
- GIS layer attributes (raw from ArcGIS)
- Immovable parcel details (intravilan, categories)
- Immovable list entry (address, areas)
- Documentation data (owners, registrations)
- Local DB state (enrichment, sync dates)

Usage: /api/eterra/debug-fields?siruta=161829&cadRef=77102

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 06:59:35 +02:00
AI Assistant a6d7e1d87f fix(wds): auto-initialize queue with default cities on first access
The /wds page was showing 0 cities because the KeyValueStore was empty
until the scheduler ran for the first time. Now the GET endpoint
initializes the queue with the 9 default cities on first access.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:46:50 +02:00
AI Assistant 24b565f5ea feat(parcel-sync): DXF export in ZIP + detailed tooltips on hero buttons
DXF Export:
- Add gpkgToDxf() helper using ogr2ogr -f DXF (non-fatal fallback)
- export-local: terenuri.dxf, cladiri.dxf, terenuri_magic.dxf in ZIP
- export-bundle: same DXF files alongside GPKGs
- Zero overhead — conversion runs locally from DB data, no eTerra calls

Hero Button Tooltips:
- Hover shows ZIP contents: layer names, entity counts, sync dates
- Base tooltip: "GPKG + DXF per layer"
- Magic tooltip: "GPKG + DXF + CSV complet + Raport calitate"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:24:35 +02:00
AI Assistant bde25d8d84 feat(parcel-sync): add LIMITE_UAT to sync package everywhere
All sync paths now include both admin layers (LIMITE_INTRAV_DYNAMIC +
LIMITE_UAT) as best-effort alongside terenuri + cladiri:
- export-bundle (hero buttons)
- sync-background (fire-and-forget)
- auto-refresh scheduler (weekday nights)
- weekend deep sync (weekend nights)
- freshness check (export tab badge)

LIMITE_UAT rarely changes so incremental sync will skip it almost
every time, but it stays fresh in the DB freshness check.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:13:29 +02:00
AI Assistant 3b456eb481 feat(parcel-sync): incremental sync, smart export, auto-refresh + weekend deep sync
Sync Incremental:
- Add fetchObjectIds (returnIdsOnly) to eterra-client — fetches only OBJECTIDs in 1 request
- Add fetchFeaturesByObjectIds — downloads only delta features by OBJECTID IN (...)
- Rewrite syncLayer: compare remote IDs vs local, download only new features
- Fallback to full sync for first sync, forceFullSync, or delta > 50%
- Reduces sync time from ~10 min to ~5-10s for typical updates

Smart Export Tab:
- Hero buttons detect DB freshness — use export-local (instant) when data is fresh
- Dynamic subtitles: "Din DB (sync acum Xh)" / "Sync incremental" / "Sync complet"
- Re-sync link when data is fresh but user wants forced refresh
- Removed duplicate "Descarca din DB" buttons from background section

Auto-Refresh Scheduler:
- Self-contained timer via instrumentation.ts (Next.js startup hook)
- Weekday 1-5 AM: incremental refresh for existing UATs in DB
- Staggered processing with random delays between UATs
- Health check before processing, respects eTerra maintenance

Weekend Deep Sync:
- Full Magic processing for 9 large municipalities (Cluj, Bistrita, TgMures, etc.)
- Runs Fri/Sat/Sun 23:00-04:00, round-robin intercalated between cities
- 4 steps per city: sync terenuri, sync cladiri, import no-geom, enrichment
- State persisted in KeyValueStore — survives restarts, continues across nights
- Email status report at end of each session via Brevo SMTP
- Admin page at /wds: add/remove cities, view progress, reset
- Hint link on export tab pointing to /wds

API endpoints:
- POST /api/eterra/auto-refresh — N8N-compatible cron endpoint (Bearer token auth)
- GET/POST /api/eterra/weekend-sync — queue management for /wds page

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:50:34 +02:00
AI Assistant 2f114d47de feat(rgi): sortable/filterable table, county selector, smart filenames, soft blocked msg
Page improvements:
- County dropdown with all 41 Romanian counties (default Cluj)
- orgUnitId auto-computed (countyId * 1000 + 2)
- Sortable columns: click header to sort asc/desc with arrow indicators
- Search input: filters across all visible columns (diacritics-insensitive)
- Soft blocked message: amber toast "Documentul nu este inca disponibil"
  auto-hides after 5s (no more redirect errors)

Download improvements:
- Meaningful filenames: {docType}_{appNo}.pdf (e.g. Harti_planuri_66903.pdf)
- Romanian diacritics stripped from filenames
- Returns { blocked: true } JSON instead of redirect when unavailable

Bug fix: replaced incorrect useState() side-effect with proper useEffect()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:37:00 +02:00
AI Assistant 3614c2fc4a fix(rgi): set application context before download attempt
Before downloading, now calls:
1. verifyCurrentActorAuthenticated — sets actor context in session
2. appdetail/details — loads application context

Then tries download regardless of fileVisibility result.
The session context might be what enables downloads that previously
returned 404.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 22:50:27 +02:00
AI Assistant 4beac959c8 fix(rgi): redirect to eTerra when server-side download unavailable
When fileVisibility returns OK → download server-side (fast).
When not available → HTTP 302 redirect to eTerra direct URL.
User's browser session handles authentication automatically.

This means: if logged into eTerra in browser, ALL documents download.
If not logged in, eTerra shows its own login page.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 22:48:01 +02:00
AI Assistant b0a5918bd7 fix(rgi): fast download with fileVisibility gate + clear error message
Download route simplified:
1. fileVisibility check — if 404, returns "indisponibil" + eTerra URL
2. Single download pattern (the one that works)

When document not available server-side, response includes direct
eTerra URL as fallback. No more 7 pattern attempts = much faster.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 22:39:53 +02:00
AI Assistant 0e5c01839d fix(rgi): exhaustive download debug — tries 7 URL patterns + GET/POST confirmOnView
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 22:25:14 +02:00
AI Assistant d780c3c973 fix(rgi): diagnostic download route — tries multiple URL patterns
Download route now:
- Calls fileVisibility with documentTypeId (if provided)
- Calls confirmOnView with documentPk
- Tries 3 different download URL patterns until one works
- Add &debug=1 to see diagnostic results instead of downloading
- Page now passes documentTypeId in download link

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 22:13:34 +02:00
AI Assistant e5e2fabb1d fix(rgi): correct download flow — confirmOnView + downloadFile by documentPk
The download uses documentPk (not documentTypeId) as the file identifier:
1. confirmOnView/{wid}/{appId}/{documentPk} — confirm view
2. loadDocument/downloadFile/{wid}/{documentPk} — actual download

Removed fileVisibility step (not needed, was causing 404).
Updated page download links to pass documentPk.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:46:37 +02:00
AI Assistant 64f10a63ff fix(rgi): user-friendly page + 3-step download flow
Rewrote RGI test page:
- Clean card-based UI with status icons (green=solved, amber=pending)
- Click row to expand and see issued documents
- Each document has a direct "Descarca" download button
- Filter toggle "Doar solutionate cu termen viitor"
- No more raw JSON tables

Download route now follows eTerra's 3-step flow:
1. fileVisibility — check access, get fileId
2. confirmOnView — confirm document view
3. loadDocument/downloadFile — actual file download

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:18:32 +02:00
AI Assistant aa11ca389e feat(eterra): RGI API routes + test page for issued documents
New eTerra RGI (Registrul General de Intrare) integration:

API routes (/api/eterra/rgi/):
- POST /applications — list applications with workspace/year filters
- GET /details?applicationId=X — application details
- GET /issued-docs?applicationId=X&workspaceId=Y — issued documents list
- GET /download-doc?wid=X&aid=Y&did=Z — download issued document

EterraClient: added rgiPost, rgiGet, rgiDownload methods for RGI API.

Test page (/rgi-test):
- Filters: workspace, orgUnit, year
- Toggle: "Doar solutionate cu termen viitor"
- Table with application list, expandable issued docs, download links
- Raw JSON debug sections (collapsible)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 20:59:49 +02:00
AI Assistant 3da45a4cab feat(parcel-sync): sync button on empty Harta tab + intravilan in base sync
Map tab: when UAT has no local data, shows a "Sincronizează terenuri,
clădiri și intravilan" button that triggers background base sync.

Sync background (base mode): now also syncs LIMITE_INTRAV_DYNAMIC layer
(intravilan boundaries) alongside TERENURI_ACTIVE + CLADIRI_ACTIVE.
Non-critical — if intravilan fails, the rest continues.

Also fixed remaining \u2192 unicode escapes in export/layers/epay tabs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 18:04:09 +02:00
AI Assistant 3fcf7e2a67 fix(geoportal): Google satellite, ESC/right-click exit, no UAT fill, ANCPI bbox fix
Basemaps: added Google Satellite option
ANCPI ortofoto: fixed bbox conversion (all 4 corners, not just SW/NE)
Selection: ESC key and right-click exit selection mode, tooltips updated
UAT layers: removed fill (only lines + labels), less visual clutter
Proprietari vechi: greyed out (opacity-50) so current owners stand out

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 14:19:02 +02:00
AI Assistant 6c55264fa3 feat(geoportal): OpenFreeMap vector basemaps + eTerra ORTO 2024 ortophoto
Basemap options:
- Liberty (OpenFreeMap vector) — default, sharp vector tiles
- Dark (OpenFreeMap) — dark theme, auto-styled
- Satellite (ESRI World Imagery) — raster
- ANCPI Ortofoto 2024 — proxied via /api/eterra/tiles/orto, converts
  Web Mercator z/x/y to EPSG:3844 bbox, authenticates with eTerra
  session, caches 24h. Requires ETERRA_USERNAME/PASSWORD env vars.

Replaces old raster OSM/OpenTopoMap with vector styles.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 18:43:21 +02:00
AI Assistant 14a77dd6f7 perf: cache GisFeature counts in memory (5min TTL, stale-while-revalidate)
Feature count groupBy query is expensive but data changes rarely.
First request waits for query, subsequent ones return cached instantly.
After 5min, stale cache is returned immediately while background
refresh runs. Badge "N local" is back on UAT dropdown.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:45:33 +02:00
AI Assistant d0c1b5d48e perf: select only needed columns from GisUat, skip geometry (~100MB) 2026-03-23 13:23:23 +02:00
AI Assistant ad4c72f527 perf(parcel-sync): make GisFeature groupBy opt-in on /api/eterra/uats
The groupBy query scanning the entire GisFeature table (~30k+ rows)
was blocking the UAT list API for 25+ seconds on every page load.
Feature counts are now opt-in via ?features=true query param.
Default response is instant (just GisUat table, no joins).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 12:44:09 +02:00
AI Assistant f6781ab851 feat(parcel-sync): store UAT geometries from LIMITE_UAT in local DB
- Add geometry (Json), areaValue (Float), lastUpdatedDtm (String) to
  GisUat model for local caching of UAT boundaries
- County refresh now fetches LIMITE_UAT with returnGeometry=true and
  stores EsriGeometry rings per UAT in EPSG:3844
- Uses LAST_UPDATED_DTM from eTerra for future incremental sync
- Skips geometry fetch if >50% already have geometry stored

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 23:14:52 +02:00
AI Assistant 7b10f1e533 fix(parcel-sync): use verified WORKSPACE_ID → county mapping from eTerra
LIMITE_UAT provides SIRUTA + WORKSPACE_ID for all 3186 UATs across 42
workspaces. eTerra nomenclature APIs all return 404, and immovable list
returns empty for small communes. Use verified workspace→county mapping
derived from eTerra data (cross-referenced sample UATs + DB confirmations).
Logs unknown workspaces if eTerra ever adds new ones.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 22:52:46 +02:00
AI Assistant 61a44525bf fix(parcel-sync): resolve county names 100% from eTerra, zero hardcoding
LIMITE_UAT gives SIRUTA + WORKSPACE_ID for all 3186 UATs. For each of
the 42 unique workspaces, fetch 1 immovable via fetchImmovableListBy
AdminUnit — the response includes workspace.name = county name.
No static mappings, no nomenclature endpoints (they 404).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 22:39:02 +02:00
AI Assistant ce49b9e536 fix(parcel-sync): resolve counties via LIMITE_UAT WORKSPACE_ID + known UAT seats
eTerra nomenclature endpoints (fetchCounties, fetchNomenByPk) return
404. New approach: LIMITE_UAT gives ADMIN_UNIT_ID + WORKSPACE_ID for
all 3186 UATs across 42 workspaces. Use a static mapping of county
seat SIRUTAs to identify which workspace belongs to which county.
Logs unresolved workspaces for debugging.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 22:36:29 +02:00
AI Assistant f9a2f6f82a fix(parcel-sync): use LIMITE_UAT + fetchNomenByPk for county data
fetchCounties() returns 404 — endpoint doesn't exist on eTerra.
New approach: query LIMITE_UAT layer for all features (no geometry)
to discover SIRUTA + WORKSPACE_ID per UAT, then resolve each unique
WORKSPACE_ID to county name via fetchNomenByPk(). Fallback: resolve
county for UATs that already have workspacePk in DB.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 22:29:56 +02:00
AI Assistant 899b5c4cf7 fix(parcel-sync): populate county data during login, not via PATCH
Root cause: PATCH endpoint created a new EterraClient which tried
to re-login with expired session → 401. Now county refresh runs
immediately after successful login in the session route, using the
same authenticated client (fire-and-forget). Component reloads UAT
data 5s after connection to pick up fresh county info.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 22:23:46 +02:00
AI Assistant 379e7e4d3f feat(parcel-sync): add diagnostic endpoint for county debugging
GET /api/eterra/uats/test-counties returns raw eTerra nomenclature
response structure — shows exact field names and data format for
fetchCounties() and fetchAdminUnitsByCounty(). Temporary diagnostic
to fix county population issue.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 22:04:37 +02:00
AI Assistant 8fa89a7675 fix(parcel-sync): restore SIRUTA in dropdown, add county debug output
- Restore SIRUTA code display in parentheses next to UAT name
- PATCH response now includes debug samples (sampleUat keys, county
  raw data) visible in browser console for diagnosing matching issues
- POST endpoint now supports resync (upsert mode, safe to call again)
- Client logs full PATCH result to browser console for debugging

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 21:34:29 +02:00
AI Assistant 431291c410 fix(parcel-sync): robust county population + local feature count in dropdown
- PATCH /api/eterra/uats: handle nested responses (unwrapArray), try
  multiple field names (extractName/extractCode), log sample UAT for
  debugging, match by code first then by name
- GET /api/eterra/uats: include localFeatures count per SIRUTA via
  GisFeature groupBy query
- Dropdown: show green badge with local feature count, county with dash
- Add SKILLS.md for ParcelSync/eTerra/GIS module context

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 21:18:22 +02:00
AI Assistant 79750b2a4a fix(parcel-sync): use eTerra nomenclature API for county population
LIMITE_UAT layer lacks WORKSPACE_ID field, so the previous approach
failed silently. Now uses fetchCounties() + fetchAdminUnitsByCounty()
nomenclature API: Phase 1 fills county for UATs with existing
workspacePk, Phase 2 enumerates counties and matches by name.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 20:56:43 +02:00
AI Assistant 86c39473a5 feat(parcel-sync): show county in UAT search dropdown via eTerra data
PATCH /api/eterra/uats fetches counties from eTerra nomenclature and
LIMITE_UAT layer, then batch-updates GisUat records with county name
and workspacePk. Auto-triggers on first eTerra connection when county
data is missing. Helps distinguish same-name UATs in different counties.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 20:46:13 +02:00
AI Assistant b7a236c45a feat(parcel-sync): eTerra health check + maintenance detection
- New eterra-health.ts service: pings eTerra periodically (3min),
  detects maintenance (503, keywords), tracks consecutive failures
- New /api/eterra/health endpoint for explicit health queries
- Session route blocks login when eTerra is in maintenance (503 response)
- GET /api/eterra/session now includes eterraAvailable/eterraMaintenance
- ConnectionPill shows amber 'Mentenanță' state with AlertTriangle icon
  instead of confusing red error when eTerra is down
- Auto-connect skips when maintenance detected, retries when back online
- 30s session poll auto-detects recovery and re-enables auto-connect
2026-03-08 10:28:30 +02:00
AI Assistant 6557cd5374 feat(parcel-sync): per-UAT analytics dashboard in Database tab
- New API route /api/eterra/uat-dashboard with SQL aggregates
  (area stats, intravilan/extravilan split, land use, top owners, fun facts)
- CSS-only dashboard component: KPI cards, donut ring, bar charts
- Dashboard button on each UAT card in DB tab, expands panel below
2026-03-08 10:18:34 +02:00
AI Assistant 6558c690f5 feat(parcel-sync): owner name search (proprietar) in Search tab
- New search mode toggle: Nr. Cadastral / Proprietar
- Owner search queries:
  1. Local DB first (enrichment PROPRIETARI/PROPRIETARI_VECHI ILIKE)
  2. eTerra API fallback (tries personName/titularName/ownerName filter keys)
- DB search works offline (no eTerra connection needed) — uses enriched data
- New API route: POST /api/eterra/search-owner
- New eterra-client method: searchImmovableByOwnerName()
- Owner results show source badge (DB local / eTerra online)
- Results can be added to saved list and exported as CSV
- Relaxed search tab guard: only requires UAT selection (not eTerra connection)
- Cadastral search still requires eTerra connection (shows hint when offline)
2026-03-08 03:48:23 +02:00
AI Assistant d12f01fc02 fix(parcel-sync): add 2min timeout to no-geom scan, non-blocking UI
- Server: Promise.race with 120s timeout on no-geom-scan API route
- Client: AbortController with 120s timeout on scan fetch
- UI: show 'max 2 min' during scanning + hint that buttons work without scan
- UI: timeout state shows retry button + explains no-geom won't be available
- Prevents indefinitely stuck 'Se scanează...' on slow eTerra responses
2026-03-08 02:28:51 +02:00
AI Assistant e57ca88e7e fix: increase background job progress retention to 6h, localStorage recovery to 8h 2026-03-08 01:59:09 +02:00
AI Assistant c43082baee feat(parcel-sync): background sync + download from DB
- New POST /api/eterra/sync-background: fire-and-forget server-side processing
  Starts sync + optional enrichment in background, returns 202 immediately.
  Progress tracked via existing /api/eterra/progress polling.
  Work continues in Node.js event loop even if browser is closed.
  Progress persists 1 hour for background jobs (vs 60s for normal).

- Enhanced POST /api/eterra/export-local: base/magic mode support
  mode=base: ZIP with terenuri.gpkg + cladiri.gpkg from local DB
  mode=magic: adds terenuri_magic.gpkg (enrichment merged, includes no-geom),
  terenuri_complet.csv, raport_calitate.txt, export_report.json
  All from PostgreSQL — zero eTerra API calls, instant download.

- UI: background sync section in Export tab
  'Sync fundal Baza/Magic' buttons: start background processing
  'Descarc─â din DB Baza/Magic' buttons: instant download from local DB
  Background job progress card with indigo theme (distinct from export)
  localStorage job recovery: resume polling after page refresh
  'Descarc─â din DB' button shown on completion
2026-03-08 01:53:24 +02:00
AI Assistant b287b4c34b fix: stable scan display, accurate workflow preview, cladiri count
ROOT CAUSE: The cross-reference between immovable list and GIS layer
produces wildly different matchedCount on each scan (320, 430, 629, 433)
because the eTerra immovable/list API with inscrisCF=-1 returns
inconsistent results across calls. The GIS layer count (505) is stable.

SCAN DISPLAY — now uses only stable numbers:
- Header shows 'Layer GIS: 505 terenuri + X cladiri' (stable ArcGIS count)
- Shows 'Lista imobile: 2.717 (estimat ~2.212 fara geometrie)' using
  simple subtraction totalImmovables - remoteGisCount
- Cross-ref matchedCount kept internally for import logic, but NOT shown
  as the primary number — eliminates visual instability
- hasNoGeomParcels now uses estimated count (stable)

WORKFLOW PREVIEW — now accurate:
- Step 1: 'Sync GIS — descarca 505 terenuri + X cladiri' (separate counts)
  or 'skip (date proaspete in DB)' when fresh
- Step 2 (enrichment): Fixed 'deja imbogatite' bug when DB is empty.
  Now correctly computes what WILL be in DB after sync completes:
  geoAfterSync + noGeomAfterImport - localDbEnrichedComplete
- Steps 3-4 unchanged

CLADIRI COUNT:
- Scan now also fetches CLADIRI_ACTIVE layer count (lightweight, OBJECTID only)
- New field remoteCladiriCount in NoGeomScanResult
- Displayed in header and workflow step 1
- Non-fatal: if CLADIRI fetch fails, just shows 0
2026-03-07 21:40:38 +02:00
AI Assistant 531c3b0858 fix: scan numbers always add up, match quality tracking, pipeline audit
SCAN DISPLAY:
- Use matchedCount (withGeometry) for 'cu geometrie' — ALWAYS adds up
  with noGeomCount to equal totalImmovables (ground truth arithmetic)
- Show remoteGisCount separately as 'Layer GIS: N features (se descarca toate)'
- When remoteGisCount != matchedCount, show matching detail with breakdown
  (X potrivite + cadRef/ID split) so mismatches are transparent
- Workflow preview step 1 still uses remoteGisCount (correct: all GIS
  features get downloaded regardless of matching)

MATCH QUALITY TRACKING:
- New fields: matchedByRef, matchedById in NoGeomScanResult
- Track how many immovables matched by cadastral ref vs by IMMOVABLE_ID
- Console log match quality for server-side debugging
- scannedAt timestamp for audit trail

PIPELINE AUDIT (export report):
- New 'pipeline' section in export_report.json with full trace:
  syncedGis, noGeometry (imported/cleaned/skipped), enriched, finalDb
- raport_calitate.txt now has PIPELINE section before quality analysis
  showing exactly what happened at each step
- Capture noGeomCleaned + noGeomSkipped in addition to noGeomImported
2026-03-07 21:22:29 +02:00
AI Assistant 1e6888a32a fix: show remoteGisCount (505) as cu geometrie, add no-geom cleanup step
- UI: scan card now shows remoteGisCount instead of matchedCount (withGeometry)
  as the primary 'cu geometrie' number — this is the true GIS layer feature count
- UI: workflow preview step 1 shows remoteGisCount for download count
- UI: mismatch note reworded as secondary detail about cross-reference matching
- Import: automatic cleanup step at start of syncNoGeometryParcels
  - Builds valid immovablePk set from fresh list (active + identification/area)
  - Deletes stale NO_GEOMETRY records not in the valid set
  - Reports cleaned count in result + progress note
- NoGeomSyncResult type: added 'cleaned' field
- Gitignore: temp-db-check.cjs
2026-03-07 21:00:43 +02:00
AI Assistant af2631920f feat(parcel-sync): quality gate filter for no-geom import + diagnostic endpoint
- Filter no-geom items before import: must have identification (cadRef/CF/paperCad/paperLb) OR area
- Multi-field area extraction: area, measuredArea, areaValue, suprafata
- Scan quality breakdown: withCadRef, withPaperCf, withPaperCad, withArea, useful, empty
- Added paperLbNo to quality analysis and samples
- UI: quality breakdown grid in scan card
- UI: filtered count in workflow preview (shows useful, not total)
- UI: enrichment estimate uses useful count
- New diagnostic endpoint /api/eterra/no-geom-debug for field inspection
2026-03-07 19:58:43 +02:00