diff --git a/src/modules/parcel-sync/services/enrich-service.ts b/src/modules/parcel-sync/services/enrich-service.ts index d2e1ec5..db675c7 100644 --- a/src/modules/parcel-sync/services/enrich-service.ts +++ b/src/modules/parcel-sync/services/enrich-service.ts @@ -135,6 +135,23 @@ export type FeatureEnrichment = { CATEGORIE_FOLOSINTA: string; HAS_BUILDING: number; BUILD_LEGAL: number; + // Extended fields (extracted from existing API calls, zero overhead) + /** "Intabulare, drept de PROPRIETATE, dobandit prin..." */ + TIP_INSCRIERE?: string; + /** "hotarare judecatoreasca nr..." / "contract vanzare cumparare nr..." */ + ACT_PROPRIETATE?: string; + /** "1/1" or fractional */ + COTA_PROPRIETATE?: string; + /** Date of registration application (ISO) */ + DATA_CERERE?: string; + /** Number of building bodies on this parcel */ + NR_CORPURI?: number; + /** Comma-separated list: "C1:352mp, C2:248mp, C3:104mp" */ + CORPURI_DETALII?: string; + /** 1 if condominium, 0 otherwise */ + IS_CONDOMINIUM?: number; + /** Date parcel was created in eTerra (ISO) */ + DATA_CREARE?: string; }; /** @@ -369,6 +386,8 @@ export async function enrichFeatures( // ── Fetch documentation/owner data ── push({ phase: "Descărcare documentații CF" }); const docByImmovable = new Map(); + // Store raw registrations per landbookIE for extended enrichment fields + const regsByLandbook = new Map(); const immovableIds = Array.from(immovableListById.keys()); const docBatchSize = 50; for (let i = 0; i < immovableIds.length; i += docBatchSize) { @@ -385,6 +404,13 @@ export async function enrichFeatures( const nodeMap = new Map(); for (const reg of regs) { if (reg?.nodeId != null) nodeMap.set(Number(reg.nodeId), reg); + // Store all registrations by landbookIE for extended enrichment + if (reg?.landbookIE) { + const lbKey = String(reg.landbookIE); + const existing = regsByLandbook.get(lbKey) ?? []; + existing.push(reg); + regsByLandbook.set(lbKey, existing); + } } // Check if an entry or any ancestor "I" inscription is radiated const isRadiated = (entry: any, depth = 0): boolean => { @@ -641,6 +667,59 @@ export async function enrichFeatures( : null); } + // Extended fields — extracted from existing data, zero extra API calls + let tipInscriere = ""; + let actProprietate = ""; + let cotaProprietate = ""; + let dataCerere = ""; + // Extract registration details from already-fetched documentation + const lbKey = landbookIE || cadRefRaw; + const regsForParcel = regsByLandbook.get(String(lbKey)) ?? []; + for (const reg of regsForParcel) { + const nt = String(reg?.nodeType ?? "").toUpperCase(); + const nn = String(reg?.nodeName ?? "").trim(); + if (nt === "I" && nn && !tipInscriere) { + tipInscriere = nn; + const quota = reg?.registration?.actualQuota; + if (quota) cotaProprietate = String(quota); + } + if (nt === "A" && nn && !actProprietate) { + actProprietate = nn; + } + if (nt === "C" && !dataCerere) { + const appDate = reg?.application?.appDate; + if (typeof appDate === "number" && appDate > 0) { + dataCerere = new Date(appDate).toISOString().slice(0, 10); + } + } + } + + // Building body details from local DB cladiri + const cadRefBase = baseCadRef(cadRefRaw); + let nrCorpuri = 0; + const corpuriParts: string[] = []; + for (const cFeature of cladiri) { + const cAttrs = cFeature.attributes as Record; + const cRef = String(cAttrs.NATIONAL_CADASTRAL_REFERENCE ?? ""); + if (baseCadRef(cRef) === cadRefBase && cRef.includes("-")) { + nrCorpuri++; + const suffix = cRef.slice(cRef.lastIndexOf("-") + 1); + const cArea = typeof cAttrs.AREA_VALUE === "number" ? cAttrs.AREA_VALUE : 0; + corpuriParts.push(`${suffix}:${Math.round(cArea)}mp`); + } + } + + // Condominium status and creation date from documentation + const docImmovable = docKey ? docByImmovable.get(docKey) : undefined; + const isCondominium = Number( + (docImmovable as Record)?.isCondominium ?? 0, + ); + const createdDtm = attrs.CREATED_DTM; + const dataCreare = + typeof createdDtm === "number" && createdDtm > 0 + ? new Date(createdDtm).toISOString().slice(0, 10) + : ""; + const enrichment: FeatureEnrichment = { NR_CAD: cadRefRaw, NR_CF: nrCF, @@ -654,8 +733,16 @@ export async function enrichFeatures( SOLICITANT: solicitant, INTRAVILAN: intravilan, CATEGORIE_FOLOSINTA: categorie, - HAS_BUILDING: hasBuilding, + HAS_BUILDING: hasBuilding || (nrCorpuri > 0 ? 1 : 0), BUILD_LEGAL: buildLegal, + TIP_INSCRIERE: tipInscriere || undefined, + ACT_PROPRIETATE: actProprietate || undefined, + COTA_PROPRIETATE: cotaProprietate || undefined, + DATA_CERERE: dataCerere || undefined, + NR_CORPURI: nrCorpuri, + CORPURI_DETALII: corpuriParts.length > 0 ? corpuriParts.join(", ") : undefined, + IS_CONDOMINIUM: isCondominium, + DATA_CREARE: dataCreare || undefined, }; // Store enrichment in DB