import { NextResponse } from "next/server"; import { prisma } from "@/core/storage/prisma"; export const runtime = "nodejs"; export const dynamic = "force-dynamic"; /** * GET /api/eterra/db-summary * * Returns a summary of ALL data in the GIS database, grouped by UAT. * No siruta required — shows everything across all UATs. * * Response shape: * { * uats: [{ * siruta, uatName, * layers: [{ layerId, count, enrichedCount, lastSynced }], * totalFeatures, totalEnriched * }], * totalFeatures, totalUats * } */ export async function GET() { try { // Feature counts per siruta + layerId const featureCounts = await prisma.gisFeature.groupBy({ by: ["siruta", "layerId"], _count: { id: true }, }); // Enriched counts per siruta + layerId const enrichedCounts = await prisma.gisFeature.groupBy({ by: ["siruta", "layerId"], where: { enrichedAt: { not: null } }, _count: { id: true }, }); const enrichedMap = new Map(); for (const e of enrichedCounts) { enrichedMap.set(`${e.siruta}:${e.layerId}`, e._count.id); } // Latest sync run per siruta + layerId const latestRuns = await prisma.gisSyncRun.findMany({ where: { status: "done" }, orderBy: { completedAt: "desc" }, select: { siruta: true, uatName: true, layerId: true, completedAt: true, }, }); const latestRunMap = new Map< string, { completedAt: Date | null; uatName: string | null } >(); for (const r of latestRuns) { const key = `${r.siruta}:${r.layerId}`; if (!latestRunMap.has(key)) { latestRunMap.set(key, { completedAt: r.completedAt, uatName: r.uatName, }); } } // UAT names from GisUat table const uatNames = await prisma.gisUat.findMany({ select: { siruta: true, name: true, county: true }, }); const uatNameMap = new Map< string, { name: string; county: string | null } >(); for (const u of uatNames) { uatNameMap.set(u.siruta, { name: u.name, county: u.county }); } // Group by siruta const uatMap = new Map< string, { siruta: string; uatName: string; county: string | null; layers: { layerId: string; count: number; enrichedCount: number; lastSynced: string | null; }[]; totalFeatures: number; totalEnriched: number; } >(); for (const fc of featureCounts) { if (!uatMap.has(fc.siruta)) { const uatInfo = uatNameMap.get(fc.siruta); const runInfo = latestRunMap.get(`${fc.siruta}:${fc.layerId}`); uatMap.set(fc.siruta, { siruta: fc.siruta, uatName: uatInfo?.name ?? runInfo?.uatName ?? `UAT ${fc.siruta}`, county: uatInfo?.county ?? null, layers: [], totalFeatures: 0, totalEnriched: 0, }); } const uat = uatMap.get(fc.siruta)!; const enriched = enrichedMap.get(`${fc.siruta}:${fc.layerId}`) ?? 0; const runInfo = latestRunMap.get(`${fc.siruta}:${fc.layerId}`); uat.layers.push({ layerId: fc.layerId, count: fc._count.id, enrichedCount: enriched, lastSynced: runInfo?.completedAt?.toISOString() ?? null, }); uat.totalFeatures += fc._count.id; uat.totalEnriched += enriched; // Update UAT name if we got one from sync runs if (uat.uatName.startsWith("UAT ") && runInfo?.uatName) { uat.uatName = runInfo.uatName; } } const uats = Array.from(uatMap.values()).sort( (a, b) => b.totalFeatures - a.totalFeatures, ); const totalFeatures = uats.reduce((s, u) => s + u.totalFeatures, 0); return NextResponse.json({ uats, totalFeatures, totalUats: uats.length, }); } catch (error) { const message = error instanceof Error ? error.message : "Eroare server"; return NextResponse.json({ error: message }, { status: 500 }); } }