perf(parcel-sync): make GisFeature groupBy opt-in on /api/eterra/uats
The groupBy query scanning the entire GisFeature table (~30k+ rows) was blocking the UAT list API for 25+ seconds on every page load. Feature counts are now opt-in via ?features=true query param. Default response is instant (just GisUat table, no joins). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -119,31 +119,33 @@ function unwrapArray(data: any): any[] {
|
|||||||
/* No eTerra credentials needed — instant response. */
|
/* No eTerra credentials needed — instant response. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET(req: Request) {
|
||||||
try {
|
try {
|
||||||
// Fetch UATs and local feature counts in parallel
|
const url = new URL(req.url);
|
||||||
const [rows, featureCounts] = await Promise.all([
|
const withFeatures = url.searchParams.get("features") === "true";
|
||||||
prisma.gisUat.findMany({ orderBy: { name: "asc" } }),
|
|
||||||
prisma.gisFeature
|
const rows = await prisma.gisUat.findMany({ orderBy: { name: "asc" } });
|
||||||
.groupBy({
|
|
||||||
by: ["siruta"],
|
// Feature counts are expensive (scans entire GisFeature table)
|
||||||
_count: { id: true },
|
// Only include when explicitly requested
|
||||||
})
|
let featureCounts: Map<string, number> | null = null;
|
||||||
.then((groups) => {
|
if (withFeatures) {
|
||||||
const map = new Map<string, number>();
|
const groups = await prisma.gisFeature.groupBy({
|
||||||
for (const g of groups) {
|
by: ["siruta"],
|
||||||
map.set(g.siruta, g._count.id);
|
_count: { id: true },
|
||||||
}
|
});
|
||||||
return map;
|
featureCounts = new Map<string, number>();
|
||||||
}),
|
for (const g of groups) {
|
||||||
]);
|
featureCounts.set(g.siruta, g._count.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const uats: UatResponse[] = rows.map((r) => ({
|
const uats: UatResponse[] = rows.map((r) => ({
|
||||||
siruta: r.siruta,
|
siruta: r.siruta,
|
||||||
name: r.name,
|
name: r.name,
|
||||||
county: r.county ?? "",
|
county: r.county ?? "",
|
||||||
workspacePk: r.workspacePk ?? 0,
|
workspacePk: r.workspacePk ?? 0,
|
||||||
localFeatures: featureCounts.get(r.siruta) ?? 0,
|
localFeatures: featureCounts?.get(r.siruta) ?? 0,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Populate in-memory workspace cache for search route
|
// Populate in-memory workspace cache for search route
|
||||||
|
|||||||
Reference in New Issue
Block a user