import { NextResponse } from "next/server"; import { EterraClient } from "@/modules/parcel-sync/services/eterra-client"; import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient(); /** * GET /api/eterra/debug-fields?siruta=161829&cadRef=77102 * * Diagnostic endpoint — shows all available fields from eTerra + local DB * for a specific parcel and its buildings. */ export async function GET(request: Request) { const url = new URL(request.url); const siruta = url.searchParams.get("siruta") ?? "161829"; const cadRef = url.searchParams.get("cadRef") ?? "77102"; const username = process.env.ETERRA_USERNAME; const password = process.env.ETERRA_PASSWORD; if (!username || !password) { return NextResponse.json({ error: "ETERRA creds missing" }, { status: 500 }); } const result: Record = { query: { siruta, cadRef }, timestamp: new Date().toISOString(), }; try { const client = await EterraClient.create(username, password); // 1. GIS layer: TERENURI_ACTIVE — raw attributes const terenuri = await client.listLayerByWhere( { id: "TERENURI_ACTIVE", name: "TERENURI_ACTIVE", endpoint: "aut" }, `ADMIN_UNIT_ID=${siruta} AND IS_ACTIVE=1 AND NATIONAL_CADASTRAL_REFERENCE='${cadRef}'`, { limit: 1, outFields: "*" }, ); const parcelAttrs = terenuri[0]?.attributes ?? null; result.gis_parcela = { found: !!parcelAttrs, fields: parcelAttrs ? Object.entries(parcelAttrs) .sort(([a], [b]) => a.localeCompare(b)) .map(([k, v]) => ({ field: k, value: v, type: typeof v })) : [], }; // 2. GIS layer: CLADIRI_ACTIVE — buildings on this parcel const cladiri = await client.listLayerByWhere( { id: "CLADIRI_ACTIVE", name: "CLADIRI_ACTIVE", endpoint: "aut" }, `ADMIN_UNIT_ID=${siruta} AND IS_ACTIVE=1 AND NATIONAL_CADASTRAL_REFERENCE LIKE '${cadRef}-%'`, { limit: 20, outFields: "*" }, ); result.gis_cladiri = { count: cladiri.length, buildings: cladiri.map((c) => { const a = c.attributes; return { cadastralRef: a.NATIONAL_CADASTRAL_REFERENCE, fields: Object.entries(a) .sort(([x], [y]) => x.localeCompare(y)) .filter(([, v]) => v != null && v !== "" && v !== 0) .map(([k, v]) => ({ field: k, value: v, type: typeof v })), }; }), }; // 3. Immovable details (enrichment source) const immId = parcelAttrs?.IMMOVABLE_ID; const wsId = parcelAttrs?.WORKSPACE_ID; if (immId && wsId) { try { const details = await client.fetchImmovableParcelDetails( wsId as string | number, immId as string | number, ); result.immovable_parcel_details = { count: details.length, items: details, }; } catch (e) { result.immovable_parcel_details = { error: e instanceof Error ? e.message : String(e), }; } // 4. Immovable list entry (address source) try { const listResponse = await client.fetchImmovableListByAdminUnit( wsId as number, siruta, 0, 5, true, ); const items = (listResponse?.content ?? []) as Record[]; // Find our specific immovable const match = items.find( (item) => String(item.immovablePk) === String(immId) || String(item.identifierDetails ?? "").includes(cadRef), ); result.immovable_list_entry = { totalInUat: listResponse?.totalElements ?? "?", matchFound: !!match, entry: match ?? null, note: "Acest obiect contine campul immovableAddresses cu adresa completa", }; } catch (e) { result.immovable_list_entry = { error: e instanceof Error ? e.message : String(e), }; } // 5. Documentation data (owner source) try { const docResponse = await client.fetchDocumentationData( wsId as number, [String(immId)], ); const immovables = docResponse?.immovables ?? []; const regs = docResponse?.partTwoRegs ?? []; result.documentation_data = { immovablesCount: immovables.length, immovables: immovables.slice(0, 3), registrationsCount: regs.length, registrations: regs.slice(0, 10), note: "partTwoRegs contine proprietarii (nodeType=P, nodeStatus=-1=radiat)", }; } catch (e) { result.documentation_data = { error: e instanceof Error ? e.message : String(e), }; } } // 6. Local DB data (what we have stored) const dbParcel = await prisma.gisFeature.findFirst({ where: { layerId: "TERENURI_ACTIVE", siruta, cadastralRef: cadRef }, select: { objectId: true, cadastralRef: true, areaValue: true, isActive: true, enrichment: true, enrichedAt: true, geometrySource: true, }, }); const dbBuildings = await prisma.gisFeature.findMany({ where: { layerId: "CLADIRI_ACTIVE", siruta, cadastralRef: { startsWith: `${cadRef}-` }, }, select: { objectId: true, cadastralRef: true, areaValue: true, attributes: true, }, }); result.local_db = { parcel: dbParcel ? { objectId: dbParcel.objectId, cadastralRef: dbParcel.cadastralRef, areaValue: dbParcel.areaValue, enrichedAt: dbParcel.enrichedAt, geometrySource: dbParcel.geometrySource, enrichment: dbParcel.enrichment, } : null, buildings: dbBuildings.map((b) => ({ objectId: b.objectId, cadastralRef: b.cadastralRef, areaValue: b.areaValue, is_legal: (b.attributes as Record)?.IS_LEGAL, })), }; } catch (e) { result.error = e instanceof Error ? e.message : String(e); } return NextResponse.json(result, { headers: { "Content-Type": "application/json; charset=utf-8" }, }); }