/** * POST /api/eterra/no-geom-debug * * Diagnostic endpoint: fetches a small sample of no-geometry immovables * and returns ALL their raw fields, so we can understand what data is * available for quality filtering. * * Body: { siruta: string, sampleSize?: number } * Returns: { sample: [...raw items], allFields: [...field names], fieldStats: {...} } */ import { NextResponse } from "next/server"; import { EterraClient } from "@/modules/parcel-sync/services/eterra-client"; import { getSessionCredentials } from "@/modules/parcel-sync/services/session-store"; export const runtime = "nodejs"; export const dynamic = "force-dynamic"; export async function POST(req: Request) { try { const body = (await req.json()) as { siruta?: string; sampleSize?: number; }; const siruta = String(body.siruta ?? "").trim(); if (!/^\d+$/.test(siruta)) { return NextResponse.json( { error: "SIRUTA must be numeric" }, { status: 400 }, ); } const session = getSessionCredentials(); const username = String( session?.username || process.env.ETERRA_USERNAME || "", ).trim(); const password = String( session?.password || process.env.ETERRA_PASSWORD || "", ).trim(); if (!username || !password) { return NextResponse.json( { error: "Nu ești conectat la eTerra" }, { status: 401 }, ); } const client = await EterraClient.create(username, password); // Fetch first page of immovables const response = await client.fetchImmovableListByAdminUnit( // We need workspace PK — try to resolve 0, // placeholder, we'll get from the sample siruta, 0, 20, true, // inscrisCF = -1 ); // If workspace 0 doesn't work, try to resolve it let items = response?.content ?? []; if (items.length === 0) { // Try without inscrisCF filter const response2 = await client.fetchImmovableListByAdminUnit( 0, siruta, 0, 20, false, ); items = response2?.content ?? []; } // If still empty, try to get workspace from GIS layer if (items.length === 0) { const features = await client.fetchAllLayer( { id: "TERENURI_ACTIVE", name: "TERENURI_ACTIVE", endpoint: "aut" as const, whereTemplate: "{{adminField}}={{siruta}} AND IS_ACTIVE=1", }, siruta, { returnGeometry: false, outFields: "WORKSPACE_ID", pageSize: 1 }, ); const wsId = features?.[0]?.attributes?.WORKSPACE_ID; if (wsId) { const response3 = await client.fetchImmovableListByAdminUnit( Number(wsId), siruta, 0, 20, true, ); items = response3?.content ?? []; } } if (items.length === 0) { return NextResponse.json({ error: "Nu s-au găsit imobile", raw: response, }); } // Analyze ALL fields across all items const allFields = new Set(); const fieldStats: Record< string, { present: number; nonNull: number; nonEmpty: number; sample: unknown } > = {}; for (const item of items) { if (typeof item !== "object" || item == null) continue; for (const [key, value] of Object.entries(item)) { allFields.add(key); if (!fieldStats[key]) { fieldStats[key] = { present: 0, nonNull: 0, nonEmpty: 0, sample: undefined, }; } const stat = fieldStats[key]!; stat.present++; if (value != null) { stat.nonNull++; if (stat.sample === undefined) stat.sample = value; } if (value != null && value !== "" && value !== 0) stat.nonEmpty++; } } // Also try to get GIS features for comparison const gisFeatures = await client.fetchAllLayer( { id: "TERENURI_ACTIVE", name: "TERENURI_ACTIVE", endpoint: "aut" as const, whereTemplate: "{{adminField}}={{siruta}} AND IS_ACTIVE=1", }, siruta, { returnGeometry: false, outFields: "OBJECTID,NATIONAL_CADASTRAL_REFERENCE,IMMOVABLE_ID,AREA_VALUE", pageSize: 5, }, ); const gisFieldStats: Record = {}; if (gisFeatures.length > 0) { const sample = gisFeatures[0]!.attributes; for (const [key, value] of Object.entries(sample ?? {})) { gisFieldStats[key] = value; } } const sampleSize = Math.min(body.sampleSize ?? 5, items.length); return NextResponse.json({ totalItems: response?.totalElements ?? items.length, totalPages: response?.totalPages ?? 1, sampleCount: sampleSize, sample: items.slice(0, sampleSize), allFields: Array.from(allFields).sort(), fieldStats, gisSampleFields: gisFieldStats, }); } catch (error) { const message = error instanceof Error ? error.message : "Eroare server"; return NextResponse.json({ error: message }, { status: 500 }); } }