From 8b6d6ba1d019c8f246aba31a99437b06bc55f542 Mon Sep 17 00:00:00 2001 From: AI Assistant Date: Thu, 26 Mar 2026 22:10:26 +0200 Subject: [PATCH] fix(parcel-sync): add intravilan to primary layers + tooltip on stale badge - LIMITE_INTRAV_DYNAMIC added to primary layers checked for freshness - Auto-refresh scheduler and weekend sync now also sync intravilan - "X vechi" badge shows tooltip with exact layer names and dates - "Proaspete" badge also shows tooltip with layer details Co-Authored-By: Claude Opus 4.6 (1M context) --- .../components/tabs/export-tab.tsx | 34 +++++++++++-------- .../services/auto-refresh-scheduler.ts | 12 +++++++ .../parcel-sync/services/weekend-deep-sync.ts | 14 +++++++- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/modules/parcel-sync/components/tabs/export-tab.tsx b/src/modules/parcel-sync/components/tabs/export-tab.tsx index 33b0f33..816b443 100644 --- a/src/modules/parcel-sync/components/tabs/export-tab.tsx +++ b/src/modules/parcel-sync/components/tabs/export-tab.tsx @@ -143,9 +143,8 @@ export function ExportTab({ const dbTotalFeatures = dbLayersSummary.reduce((sum, l) => sum + l.count, 0); - // Only check primary layers (terenuri + cladiri) for freshness — - // secondary layers (intravilan, limite UAT) don't affect export readiness - const PRIMARY_LAYERS = ["TERENURI_ACTIVE", "CLADIRI_ACTIVE"]; + // Primary layers synced by background jobs — these determine freshness + const PRIMARY_LAYERS = ["TERENURI_ACTIVE", "CLADIRI_ACTIVE", "LIMITE_INTRAV_DYNAMIC"]; const primaryLayers = dbLayersSummary.filter((l) => PRIMARY_LAYERS.includes(l.id), ); @@ -626,11 +625,8 @@ export function ExportTab({ layere {(() => { - // Check freshness only for primary layers (terenuri + cladiri) - const freshCount = primaryLayers.filter( - (l) => l.isFresh, - ).length; - const staleCount = primaryLayers.length - freshCount; + const staleLayers = primaryLayers.filter((l) => !l.isFresh); + const freshLayers = primaryLayers.filter((l) => l.isFresh); const newestSync = primaryLayers.reduce( (newest, l) => { if (!l.lastSynced) return newest; @@ -639,25 +635,35 @@ export function ExportTab({ }, null as Date | null, ); + // Tooltip: list which layers are stale/fresh with dates + const staleTooltip = staleLayers.length > 0 + ? `Vechi: ${staleLayers.map((l) => `${l.label} (${l.lastSynced ? relativeTime(l.lastSynced) : "nesincronizat"})`).join(", ")}` + : ""; + const freshTooltip = freshLayers.length > 0 + ? `Proaspete: ${freshLayers.map((l) => `${l.label} (${l.lastSynced ? relativeTime(l.lastSynced) : ""})`).join(", ")}` + : ""; + const fullTooltip = [staleTooltip, freshTooltip].filter(Boolean).join("\n"); return ( <> - {staleCount === 0 && primaryLayers.length > 0 ? ( + {staleLayers.length === 0 && primaryLayers.length > 0 ? ( Proaspete - ) : ( + ) : staleLayers.length > 0 ? ( - {staleCount} vechi + {staleLayers.length} vechi - )} + ) : null} {newestSync && ( Ultima sincronizare: {relativeTime(newestSync)} diff --git a/src/modules/parcel-sync/services/auto-refresh-scheduler.ts b/src/modules/parcel-sync/services/auto-refresh-scheduler.ts index ed0be7e..05b3c80 100644 --- a/src/modules/parcel-sync/services/auto-refresh-scheduler.ts +++ b/src/modules/parcel-sync/services/auto-refresh-scheduler.ts @@ -172,6 +172,18 @@ async function runAutoRefresh() { "CLADIRI_ACTIVE", { uatName: uat.name }, ); + // Intravilan — lightweight, non-fatal + try { + await syncLayer( + username, + password, + uat.siruta, + "LIMITE_INTRAV_DYNAMIC", + { uatName: uat.name }, + ); + } catch { + // intravilan is best-effort + } const dur = ((Date.now() - start) / 1000).toFixed(1); console.log( `[auto-refresh] ${uat.name} (${uat.siruta}): terenuri +${tRes.newFeatures}/-${tRes.removedFeatures}, cladiri +${cRes.newFeatures}/-${cRes.removedFeatures} (${dur}s)`, diff --git a/src/modules/parcel-sync/services/weekend-deep-sync.ts b/src/modules/parcel-sync/services/weekend-deep-sync.ts index ef948eb..189c7e5 100644 --- a/src/modules/parcel-sync/services/weekend-deep-sync.ts +++ b/src/modules/parcel-sync/services/weekend-deep-sync.ts @@ -186,10 +186,22 @@ async function executeStep( "TERENURI_ACTIVE", { uatName: city.name, forceFullSync: true }, ); + // Also sync intravilan limits (lightweight, non-fatal) + try { + await syncLayer( + process.env.ETERRA_USERNAME!, + process.env.ETERRA_PASSWORD!, + city.siruta, + "LIMITE_INTRAV_DYNAMIC", + { uatName: city.name }, + ); + } catch { + // intravilan is best-effort + } const dur = ((Date.now() - start) / 1000).toFixed(1); return { success: res.status === "done", - message: `Terenuri: ${res.totalLocal} local (+${res.newFeatures}/-${res.removedFeatures}) [${dur}s]`, + message: `Terenuri: ${res.totalLocal} local (+${res.newFeatures}/-${res.removedFeatures}) + intravilan [${dur}s]`, }; }