fix: remove all hardcoded workspaceId=65 + add robustness for large UATs

- enrich-service: resolve workspacePk from feature attrs / GisUat DB / ArcGIS
  (was hardcoded 65, broke enrichment for non-BN counties)
- enrich-service: skip already-enriched features (resume after crash)
- no-geom-sync: use resolved wsPk in synthetic attributes
- no-geom-sync: batched DB inserts (50/batch) with retry + exponential backoff
- Fixes: Magic export for Cluj/other counties getting empty enrichment
This commit is contained in:
AI Assistant
2026-03-07 17:17:55 +02:00
parent db6ac5d3a3
commit 40b9522e12
2 changed files with 158 additions and 61 deletions
@@ -170,6 +170,7 @@ export async function enrichFeatures(
objectId: true,
attributes: true,
cadastralRef: true,
enrichedAt: true,
},
});
@@ -187,6 +188,56 @@ export async function enrichFeatures(
};
}
// Resolve workspace PK from feature attributes or GisUat DB
let resolvedWsPk: number | null = null;
for (const f of terenuri) {
const ws = (f.attributes as Record<string, unknown>).WORKSPACE_ID;
if (ws != null) {
const n = Number(ws);
if (Number.isFinite(n) && n > 0) {
resolvedWsPk = n;
break;
}
}
}
if (!resolvedWsPk) {
try {
const row = await prisma.gisUat.findUnique({
where: { siruta },
select: { workspacePk: true },
});
if (row?.workspacePk && row.workspacePk > 0)
resolvedWsPk = row.workspacePk;
} catch {
/* ignore */
}
}
if (!resolvedWsPk) {
// Last resort: try ArcGIS layer query for 1 feature
try {
const features = await client.listLayer(
{
id: "TERENURI_ACTIVE",
name: "TERENURI_ACTIVE",
endpoint: "aut",
whereTemplate: "{{adminField}}={{siruta}} AND IS_ACTIVE=1",
},
siruta,
{ limit: 1, outFields: "WORKSPACE_ID" },
);
const wsId = features?.[0]?.attributes?.WORKSPACE_ID;
if (wsId != null) {
const n = Number(wsId);
if (Number.isFinite(n) && n > 0) resolvedWsPk = n;
}
} catch {
/* ignore */
}
}
// If still null, enrichment will fail gracefully with empty lists
const workspacePkForApi = resolvedWsPk ?? 65;
console.log(`[enrich] siruta=${siruta} workspacePk=${workspacePkForApi}`);
push({
phase: "Pregătire îmbogățire",
downloaded: 0,
@@ -261,7 +312,7 @@ export async function enrichFeatures(
while (listPage < listTotalPages) {
const listResponse = await throttled(() =>
client.fetchImmovableListByAdminUnit(
65,
workspacePkForApi,
siruta,
listPage,
200,
@@ -299,7 +350,7 @@ export async function enrichFeatures(
for (let i = 0; i < immovableIds.length; i += docBatchSize) {
const batch = immovableIds.slice(i, i + docBatchSize);
const docResponse = await throttled(() =>
client.fetchDocumentationData(65, batch),
client.fetchDocumentationData(workspacePkForApi, batch),
);
(docResponse?.immovables ?? []).forEach((item: any) => {
const idKey = normalizeId(item?.immovablePk);
@@ -348,6 +399,20 @@ export async function enrichFeatures(
for (let index = 0; index < terenuri.length; index += 1) {
const feature = terenuri[index]!;
const attrs = feature.attributes as Record<string, unknown>;
// Skip features already enriched (resume after crash/interruption)
if (feature.enrichedAt != null) {
enrichedCount += 1;
if (index % 50 === 0) {
options?.onProgress?.(
index + 1,
terenuri.length,
"Îmbogățire parcele (skip enriched)",
);
}
continue;
}
const immovableId = attrs.IMMOVABLE_ID ?? "";
const workspaceId = attrs.WORKSPACE_ID ?? "";
const applicationId = (attrs.APPLICATION_ID as number) ?? null;