59 lines
1.6 KiB
TypeScript
59 lines
1.6 KiB
TypeScript
import type { APIRoute } from "astro";
|
|
import { prisma } from "../../lib/prisma";
|
|
import { Prisma } from "@prisma/client";
|
|
|
|
export const prerender = false;
|
|
|
|
const DISTINCT_FIELDS = new Set([
|
|
"ciudad",
|
|
"estado",
|
|
"profesion",
|
|
"nivel_academico",
|
|
"nacionalidad",
|
|
"pais",
|
|
]);
|
|
|
|
const SIMILARITY_THRESHOLD = 0.35;
|
|
|
|
export const GET: APIRoute = async ({ url }) => {
|
|
try {
|
|
const sp = url.searchParams;
|
|
const field = (sp.get("field") || "").trim();
|
|
const q = (sp.get("q") || "").trim();
|
|
const limit = Math.min(100, Math.max(1, parseInt(sp.get("limit") || "25", 10)));
|
|
|
|
if (!DISTINCT_FIELDS.has(field)) {
|
|
return Response.json(
|
|
{ success: false, message: "Campo no permitido" },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
const col = Prisma.raw(field);
|
|
|
|
const rows = await prisma.$queryRaw<{ value: string; count: number }[]>`
|
|
SELECT ${col} AS value, COUNT(*)::int AS count
|
|
FROM formularios
|
|
WHERE ${col} IS NOT NULL AND ${col} <> ''
|
|
${q.length >= 2 ? Prisma.sql`AND (similarity(lower(${col}), lower(${q})) > ${SIMILARITY_THRESHOLD} OR ${col} ILIKE ${`%${q}%`})` : Prisma.empty}
|
|
GROUP BY ${col}
|
|
ORDER BY count DESC
|
|
LIMIT ${limit}
|
|
`;
|
|
|
|
return Response.json({
|
|
success: true,
|
|
field,
|
|
data: rows.map((r) => ({ value: r.value, count: r.count })),
|
|
}, {
|
|
headers: { "Cache-Control": "private, max-age=300, stale-while-revalidate=600" },
|
|
});
|
|
} catch (error) {
|
|
console.error("Error en /api/admin/voluntarios/distinct:", error);
|
|
return Response.json(
|
|
{ success: false, message: "Error al obtener valores" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
};
|