- eterra-client: detect server maxRecordCount cap in fetchAllLayerByWhere
When server returns exactly 1000 (or other round cap) but we asked for 2000,
recognize this as a server limit, adjust pageSize, and CONTINUE paginating.
Previously: 1000 < 2000 -> break (lost all data beyond page 1).
- no-geom-sync: count layers first, pass total to fetchAllLayer
Belt-and-suspenders: even if cap detection misses, known total prevents
early termination. Also use pageSize 1000 to match typical server cap.
Clădiri count uses countLayer instead of fetching all OBJECTIDs.
- UI: add include-no-geom checkbox in background sync section
Users can toggle it independently of scan status.
Shows '(scanare in curs)' hint when scan is still running.
- fetchImmovableParcelDetails called FIRST (1 call, no applicationId needed)
- app-based fetchParcelFolosinte only as fallback when direct returns nothing
- SOLICITANT skipped entirely (was always '-' for old CF records)
- Remove unused pickApplication helper
- Net savings: ~500+ API calls per UAT enrichment (50-65% reduction)
- copycf/get returns same data as list (no enrichment value, kept as utility)
QUALITY GATE TIGHTENED:
No-geometry import now requires hasLandbook=1 (imobil electronic).
This filters out immovables without carte funciara — they have no
CF data, no owners, no parcel details to extract. For Cosbuc this
reduces useful no-geom from ~1916 to ~468 (only IEs with real data).
Three-tier quality gate:
1. Active (status=1)
2. Has landbook (hasLandbook=1) — is electronic immovable [NEW]
3. Has identification (cadRef/paperLbNo/paperCadNo) OR area
CLEANUP also updated: DB cleanup now removes stale no-geom records
that don't pass the tightened gate (existing non-IE records will be
cleaned on next import run).
NEW API METHODS (eterra-client):
- checkIfIsIE(adminUnitId, paperCadNo, topNo, paperCfNo) → boolean
Calls /api/immovable/checkIfIsIE — verifies IE status per-parcel
Available for future per-item verification if needed
- getCfExtractUrl(immovablePk, workspaceId) → string
Returns URL for /api/cf/landbook/copycf/get/{pk}/{ws}/0/true
Downloads the CF extract as PDF blob (future enrichment)
UI updated: 'Filtrate' label now says 'fara CF/inactive/fara date'
to reflect the new hasLandbook filter.
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
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
- 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
BUGS FIXED:
- paperCfNo does NOT exist in eTerra API — field is paperLbNo
Renamed withPaperCf → withPaperLb everywhere (type, scan, UI)
- Area fields: only measuredArea and legalArea exist on immovable/list
Removed phantom area/areaValue/suprafata checks from import filter
FILTERING TIGHTENED:
- Quality gate now requires status=1 (active) in eTerra
- Items with status≠1 are filtered out before import
- Quality breakdown adds: withActiveStatus, withLandbook counters
- Import attributes now store MEASURED_AREA, LEGAL_AREA, HAS_LANDBOOK
- workspace.nomenPk used instead of workspacePk for accuracy
ENRICHMENT ROBUSTNESS:
- Area fallback: when AREA_VALUE is missing (no-geom), enrichment
now falls back to listItem.measuredArea/legalArea from immovable list
- Post-enrichment verification: logs 100% coverage or warns about gaps
- EnrichResult type extended with totalFeatures + unenrichedCount
UI UPDATES:
- Quality grid shows 6 stats: cadRef, CF/LB, paperCad, area, active, landbook
- Filter explanation updated: 'inactive sau fără date' instead of old text
- NoGeomScanResult now includes: localDbTotal, localDbWithGeom, localDbNoGeom,
localDbEnriched, localSyncFresh (parallel DB queries, fast)
- Scan card shows 'Baza de date locala: X cu geometrie + Y fara + Z imbogatite'
- Workflow preview shows numbered steps with smart estimates:
step 1 shows 'skip (date proaspete)' when sync is fresh
step 2 shows '~N noi de importat' or 'deja importate' for no-geom
step 3 shows '~N de procesat (~M min)' or 'deja imbogatite' for enrichment
- All-geometry card also shows local DB summary
- User can see exactly what will happen before pressing Magic
- scanNoGeometryParcels now fetches TERENURI_ACTIVE features from remote
ArcGIS (lightweight, no geometry) to cross-reference with eTerra immovable list
- Cross-references by both NATIONAL_CADASTRAL_REFERENCE and IMMOVABLE_ID
- Works correctly regardless of whether user has synced to local DB
- Renamed totalInDb -> withGeometry in NoGeomScanResult, UI, and API
- Extended fetchAllLayer() to forward outFields/returnGeometry options
- resolveWorkspacePk chain: explicit param -> GisUat DB -> ArcGIS layer query
- UI passes workspacePk from UAT selection to scan API
- Fixes: FELEACU (Cluj, workspace!=65) returning 0 immovables
- Better messaging: shows X total, Y with geometry, Z without
- Shows warning when 0 immovables found (workspace resolution failed)
- Add geometrySource field to GisFeature (NO_GEOMETRY marker)
- New no-geom-sync service: scan + import parcels missing from GIS layer
- Uses negative immovablePk as objectId to avoid @@unique collision
- New /api/eterra/no-geom-scan endpoint for counting
- Export-bundle: includeNoGeometry flag, imports before enrich
- CSV export: new HAS_GEOMETRY column (0/1)
- GPKG: still geometry-only (unchanged)
- UI: checkbox + scan button on Export tab
- Baza de Date tab: shows no-geometry counts per UAT
- db-summary API: includes noGeomCount per layer