fix(parcel-sync): restore SIRUTA in dropdown, add county debug output
- Restore SIRUTA code display in parentheses next to UAT name - PATCH response now includes debug samples (sampleUat keys, county raw data) visible in browser console for diagnosing matching issues - POST endpoint now supports resync (upsert mode, safe to call again) - Client logs full PATCH result to browser console for debugging Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -165,7 +165,9 @@ export async function GET() {
|
|||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* POST /api/eterra/uats */
|
/* POST /api/eterra/uats */
|
||||||
/* */
|
/* */
|
||||||
/* Seed DB from static uat.json. */
|
/* Seed or resync DB from static uat.json. */
|
||||||
|
/* Uses upsert so it's safe to call repeatedly — new UATs are added, */
|
||||||
|
/* existing names are updated, county/workspacePk are preserved. */
|
||||||
/* eTerra nomenPk ≠ SIRUTA, so we cannot use the nomenclature API */
|
/* eTerra nomenPk ≠ SIRUTA, so we cannot use the nomenclature API */
|
||||||
/* for populating UAT data. uat.json has correct SIRUTA codes. */
|
/* for populating UAT data. uat.json has correct SIRUTA codes. */
|
||||||
/* Workspace (county) PKs are resolved lazily via ArcGIS layer query */
|
/* Workspace (county) PKs are resolved lazily via ArcGIS layer query */
|
||||||
@@ -174,15 +176,6 @@ export async function GET() {
|
|||||||
|
|
||||||
export async function POST() {
|
export async function POST() {
|
||||||
try {
|
try {
|
||||||
// Check if DB already has data
|
|
||||||
const dbCount = await prisma.gisUat.count();
|
|
||||||
if (dbCount > 0) {
|
|
||||||
return NextResponse.json({
|
|
||||||
synced: false,
|
|
||||||
reason: "already-seeded",
|
|
||||||
total: dbCount,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read uat.json from public/ directory
|
// Read uat.json from public/ directory
|
||||||
let rawUats: Array<{ siruta: string; name: string }>;
|
let rawUats: Array<{ siruta: string; name: string }>;
|
||||||
@@ -368,6 +361,11 @@ export async function PATCH() {
|
|||||||
let nameMatches = 0;
|
let nameMatches = 0;
|
||||||
const matchedSirutas = new Set<string>();
|
const matchedSirutas = new Set<string>();
|
||||||
let loggedSample = false;
|
let loggedSample = false;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
let sampleCounty: any = null;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
let sampleUat: any = null;
|
||||||
|
let totalEterraUats = 0;
|
||||||
|
|
||||||
for (const [countyPk, countyName] of countyMap) {
|
for (const [countyPk, countyName] of countyMap) {
|
||||||
if (matchedSirutas.size >= needsCounty.length) break;
|
if (matchedSirutas.size >= needsCounty.length) break;
|
||||||
@@ -376,12 +374,20 @@ export async function PATCH() {
|
|||||||
const rawUats = await client.fetchAdminUnitsByCounty(countyPk);
|
const rawUats = await client.fetchAdminUnitsByCounty(countyPk);
|
||||||
const uats = unwrapArray(rawUats);
|
const uats = unwrapArray(rawUats);
|
||||||
|
|
||||||
|
totalEterraUats += uats.length;
|
||||||
|
|
||||||
// Log first county's first UAT for debugging
|
// Log first county's first UAT for debugging
|
||||||
if (!loggedSample && uats.length > 0) {
|
if (!loggedSample && uats.length > 0) {
|
||||||
|
sampleUat = uats[0];
|
||||||
|
sampleCounty = { pk: countyPk, name: countyName, uatCount: uats.length };
|
||||||
console.log(
|
console.log(
|
||||||
`[uats-patch] Sample UAT from ${countyName}:`,
|
`[uats-patch] Sample UAT from ${countyName} (${uats.length} UATs):`,
|
||||||
JSON.stringify(uats[0]).slice(0, 500),
|
JSON.stringify(uats[0]).slice(0, 500),
|
||||||
);
|
);
|
||||||
|
console.log(
|
||||||
|
`[uats-patch] Sample UAT keys:`,
|
||||||
|
Object.keys(uats[0] ?? {}),
|
||||||
|
);
|
||||||
loggedSample = true;
|
loggedSample = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +450,23 @@ export async function PATCH() {
|
|||||||
codeMatches,
|
codeMatches,
|
||||||
nameMatches,
|
nameMatches,
|
||||||
totalCounties: countyMap.size,
|
totalCounties: countyMap.size,
|
||||||
|
totalEterraUats,
|
||||||
unmatched,
|
unmatched,
|
||||||
|
// Include debug samples so we can see what eTerra returns
|
||||||
|
debug: {
|
||||||
|
sampleCounty,
|
||||||
|
sampleUatKeys: sampleUat ? Object.keys(sampleUat) : null,
|
||||||
|
sampleUat: sampleUat
|
||||||
|
? JSON.parse(JSON.stringify(sampleUat).slice(0, 500))
|
||||||
|
: null,
|
||||||
|
sampleCountyRaw: counties[0]
|
||||||
|
? {
|
||||||
|
keys: Object.keys(counties[0]),
|
||||||
|
nomenPk: counties[0].nomenPk,
|
||||||
|
name: counties[0].name,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const message = error instanceof Error ? error.message : "Eroare server";
|
const message = error instanceof Error ? error.message : "Eroare server";
|
||||||
|
|||||||
@@ -572,18 +572,32 @@ export function ParcelSyncModule() {
|
|||||||
|
|
||||||
fetch("/api/eterra/uats", { method: "PATCH" })
|
fetch("/api/eterra/uats", { method: "PATCH" })
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.then((result: { updated?: number; error?: string }) => {
|
.then(
|
||||||
if (result.updated && result.updated > 0) {
|
(result: {
|
||||||
// Reload UAT data with fresh county info
|
updated?: number;
|
||||||
fetch("/api/eterra/uats")
|
error?: string;
|
||||||
.then((res) => res.json())
|
phase1?: number;
|
||||||
.then((data: { uats?: UatEntry[] }) => {
|
phase2?: number;
|
||||||
if (data.uats && data.uats.length > 0) setUatData(data.uats);
|
codeMatches?: number;
|
||||||
})
|
nameMatches?: number;
|
||||||
.catch(() => {});
|
unmatched?: number;
|
||||||
}
|
debug?: unknown;
|
||||||
})
|
}) => {
|
||||||
.catch(() => {});
|
console.log("[uats] County refresh result:", result);
|
||||||
|
if (result.updated && result.updated > 0) {
|
||||||
|
// Reload UAT data with fresh county info
|
||||||
|
fetch("/api/eterra/uats")
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((data: { uats?: UatEntry[] }) => {
|
||||||
|
if (data.uats && data.uats.length > 0) setUatData(data.uats);
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.catch((err) => {
|
||||||
|
console.error("[uats] County refresh failed:", err);
|
||||||
|
});
|
||||||
}, [session.connected, uatData]);
|
}, [session.connected, uatData]);
|
||||||
|
|
||||||
/* ════════════════════════════════════════════════════════════ */
|
/* ════════════════════════════════════════════════════════════ */
|
||||||
@@ -1771,8 +1785,11 @@ export function ParcelSyncModule() {
|
|||||||
setSearchResults([]);
|
setSearchResults([]);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="flex items-center gap-1.5 min-w-0">
|
<span className="flex items-center gap-1.5 min-w-0 flex-wrap">
|
||||||
<span className="font-medium">{item.name}</span>
|
<span className="font-medium">{item.name}</span>
|
||||||
|
<span className="text-muted-foreground">
|
||||||
|
({item.siruta})
|
||||||
|
</span>
|
||||||
{item.county && (
|
{item.county && (
|
||||||
<span className="text-muted-foreground">
|
<span className="text-muted-foreground">
|
||||||
–{" "}
|
–{" "}
|
||||||
@@ -1787,9 +1804,6 @@ export function ParcelSyncModule() {
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs text-muted-foreground font-mono ml-2 shrink-0">
|
|
||||||
{item.siruta}
|
|
||||||
</span>
|
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user