feat: enrichment fallback via direct parcel details endpoint

PROBLEM:
For no-geometry parcels (and many geometry parcels without application
IDs), CATEGORIE_FOLOSINTA was always '-' because:
1. fetchImmAppsByImmovable returned no apps (no applicationId)
2. Without appId, fetchParcelFolosinte was skipped entirely
3. No fallback existed

DISCOVERY (from eTerra UI investigation):
The endpoint /api/immovable/details/parcels/list/{wp}/{pk}/{page}/{size}
returns parcel use categories DIRECTLY — no applicationId needed.
Example: [{useCategory:'arabil', intravilan:'Necunoscut', parcelPk:17753903}]

FIX:
- After the app-based CATEGORIE_FOLOSINTA attempt, if result is still '-',
  fall back to fetchImmovableParcelDetails (the direct endpoint)
- formatCategories now handles both API formats:
  - App-based: categorieFolosinta + suprafata fields
  - Direct: useCategory field (no area — shows category name only)
- When direct endpoint provides area=0, format shows just the category
  name without ':0' (e.g. 'arabil; faneata' instead of 'arabil:0; faneata:0')
- Also picks up intravilan from direct endpoint if app-based was empty
- Fixed fetchImmovableParcelDetails default size: 1 → 20 (one immovable
  can have multiple parcels, e.g. IE 25332 has 2: arabil + faneata)
- Results are cached in folCache to avoid duplicate requests
This commit is contained in:
AI Assistant
2026-03-08 00:46:02 +02:00
parent a7c9e8a6cc
commit f09eaaad7c
2 changed files with 43 additions and 6 deletions
@@ -362,9 +362,7 @@ export class EterraClient {
await sleep(500); // small delay before retry with smaller page
continue;
}
throw new Error(
`Failed to fetch layer ${layer.name}: ${cause}`,
);
throw new Error(`Failed to fetch layer ${layer.name}: ${cause}`);
}
const features = data.features ?? [];
@@ -504,7 +502,7 @@ export class EterraClient {
workspaceId: string | number,
immovableId: string | number,
page = 1,
size = 1,
size = 20,
): Promise<any[]> {
const url = `${BASE_URL}/api/immovable/details/parcels/list/${workspaceId}/${immovableId}/${page}/${size}`;
return this.getRawJson(url);