fix: scan math consistency + stale enrichment detection + re-enrichment
- withGeometry = matched immovable count (not GIS feature count) — numbers always add up - Added remoteGisCount to show raw GIS layer count separately - Enrichment completeness check: ENRICHMENT_REQUIRED_KEYS 7-field schema - localDbEnrichedComplete vs localDbEnriched detects stale enrichment - UI: orange warning when enrichment incomplete (missing PROPRIETARI_VECHI) - UI: workflow preview uses enrichedComplete for accurate time estimate - UI: note when GIS feature count differs from matched immovable count - enrich-service: re-enriches features with incomplete schema instead of skipping
This commit is contained in:
@@ -93,8 +93,10 @@ const normalizeCadRef = (value: unknown) =>
|
||||
|
||||
export type NoGeomScanResult = {
|
||||
totalImmovables: number;
|
||||
/** Features present in the remote ArcGIS TERENURI_ACTIVE layer (have geometry) */
|
||||
/** Immovables that matched a remote GIS feature (have geometry) */
|
||||
withGeometry: number;
|
||||
/** Total features in the remote ArcGIS TERENURI_ACTIVE layer */
|
||||
remoteGisCount: number;
|
||||
noGeomCount: number;
|
||||
/** Sample of immovable identifiers without geometry */
|
||||
samples: Array<{
|
||||
@@ -111,6 +113,8 @@ export type NoGeomScanResult = {
|
||||
localDbNoGeom: number;
|
||||
/** How many are already enriched (magic) in local DB */
|
||||
localDbEnriched: number;
|
||||
/** How many enriched features have complete/current enrichment schema */
|
||||
localDbEnrichedComplete: number;
|
||||
/** Whether local sync is fresh (< 7 days) */
|
||||
localSyncFresh: boolean;
|
||||
/** Error message if workspace couldn't be resolved */
|
||||
@@ -149,12 +153,14 @@ export async function scanNoGeometryParcels(
|
||||
return {
|
||||
totalImmovables: 0,
|
||||
withGeometry: 0,
|
||||
remoteGisCount: 0,
|
||||
noGeomCount: 0,
|
||||
samples: [],
|
||||
localDbTotal: 0,
|
||||
localDbWithGeom: 0,
|
||||
localDbNoGeom: 0,
|
||||
localDbEnriched: 0,
|
||||
localDbEnrichedComplete: 0,
|
||||
localSyncFresh: false,
|
||||
error: `Nu s-a putut determina workspace-ul (județul) pentru SIRUTA ${siruta}`,
|
||||
};
|
||||
@@ -222,7 +228,19 @@ export async function scanNoGeometryParcels(
|
||||
}
|
||||
|
||||
// 4. Query local DB for context (what's already synced/imported)
|
||||
const [localTotal, localNoGeom, localEnriched, lastSyncRun] =
|
||||
// Also check enrichment completeness — do enriched features have
|
||||
// the current schema? (e.g., PROPRIETARI_VECHI added later)
|
||||
const ENRICHMENT_REQUIRED_KEYS = [
|
||||
"NR_CAD",
|
||||
"NR_CF",
|
||||
"PROPRIETARI",
|
||||
"PROPRIETARI_VECHI",
|
||||
"ADRESA",
|
||||
"CATEGORIE_FOLOSINTA",
|
||||
"HAS_BUILDING",
|
||||
];
|
||||
|
||||
const [localTotal, localNoGeom, enrichedFeatures, lastSyncRun] =
|
||||
await Promise.all([
|
||||
prisma.gisFeature.count({
|
||||
where: { layerId: "TERENURI_ACTIVE", siruta },
|
||||
@@ -234,12 +252,13 @@ export async function scanNoGeometryParcels(
|
||||
geometrySource: "NO_GEOMETRY",
|
||||
},
|
||||
}),
|
||||
prisma.gisFeature.count({
|
||||
prisma.gisFeature.findMany({
|
||||
where: {
|
||||
layerId: "TERENURI_ACTIVE",
|
||||
siruta,
|
||||
enrichedAt: { not: null },
|
||||
},
|
||||
select: { enrichment: true },
|
||||
}),
|
||||
prisma.gisSyncRun.findFirst({
|
||||
where: { siruta, layerId: "TERENURI_ACTIVE", status: "done" },
|
||||
@@ -248,20 +267,37 @@ export async function scanNoGeometryParcels(
|
||||
}),
|
||||
]);
|
||||
|
||||
const localEnriched = enrichedFeatures.length;
|
||||
let localEnrichedComplete = 0;
|
||||
for (const f of enrichedFeatures) {
|
||||
const e = f.enrichment as Record<string, unknown> | null;
|
||||
if (
|
||||
e &&
|
||||
ENRICHMENT_REQUIRED_KEYS.every((k) => k in e && e[k] !== undefined)
|
||||
) {
|
||||
localEnrichedComplete++;
|
||||
}
|
||||
}
|
||||
|
||||
const localWithGeom = localTotal - localNoGeom;
|
||||
const syncFresh = lastSyncRun?.completedAt
|
||||
? Date.now() - lastSyncRun.completedAt.getTime() < 168 * 60 * 60 * 1000
|
||||
: false;
|
||||
|
||||
// withGeometry = immovables that MATCHED a GIS feature (always adds up)
|
||||
const matchedCount = allImmovables.length - noGeomItems.length;
|
||||
|
||||
return {
|
||||
totalImmovables: allImmovables.length,
|
||||
withGeometry: remoteFeatures.length,
|
||||
withGeometry: matchedCount,
|
||||
remoteGisCount: remoteFeatures.length,
|
||||
noGeomCount: noGeomItems.length,
|
||||
samples: noGeomItems.slice(0, 20),
|
||||
localDbTotal: localTotal,
|
||||
localDbWithGeom: localWithGeom,
|
||||
localDbNoGeom: localNoGeom,
|
||||
localDbEnriched: localEnriched,
|
||||
localDbEnrichedComplete: localEnrichedComplete,
|
||||
localSyncFresh: syncFresh,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user