Se corrigió hardcode de id de template y se permite recibir body para el downloadReport

This commit is contained in:
2026-03-20 13:08:20 -06:00
parent 93c4e46e62
commit d378c43821
+88 -20
View File
@@ -18,6 +18,7 @@ const ActionSchema = z.object({
const DownloadReportSchema = z.object({
action: z.literal("downloadReport"),
plan_estudio_id: z.string().min(1),
body: z.record(z.unknown()),
});
type DownloadReportInput = z.infer<typeof DownloadReportSchema>;
@@ -29,10 +30,10 @@ function getAuthHeader(req: Request): string | null {
async function loadPlanDatos(
supabase: ReturnType<typeof createClient<Database>>,
planEstudioId: string,
): Promise<Json> {
): Promise<{ datos: Json; estructura_id: string }> {
const { data, error } = await supabase
.from("planes_estudio")
.select("datos")
.select("datos, estructura_id")
.eq("id", planEstudioId)
.maybeSingle();
@@ -52,7 +53,48 @@ async function loadPlanDatos(
{ plan_estudio_id: planEstudioId },
);
}
return data.datos;
return {
datos: data.datos,
estructura_id: data.estructura_id,
};
}
async function loadTemplateIdForEstructura(
supabase: ReturnType<typeof createClient<Database>>,
estructuraId: string,
): Promise<string> {
const { data, error } = await supabase
.from("estructuras_plan")
.select("template_id")
.eq("id", estructuraId)
.maybeSingle();
if (error) {
throw new HttpError(
500,
"Error consultando la estructura del plan.",
"DB_ERROR",
{ message: error.message, details: error.details, hint: error.hint },
);
}
if (!data) {
throw new HttpError(
404,
"Estructura del plan no encontrada.",
"NOT_FOUND",
{ estructura_id: estructuraId },
);
}
if (!data.template_id) {
throw new HttpError(
409,
"La estructura del plan no tiene template_id configurado.",
"MISSING_TEMPLATE_ID",
{ estructura_id: estructuraId },
);
}
return data.template_id;
}
Deno.serve(async (req: Request): Promise<Response> => {
@@ -110,10 +152,9 @@ Deno.serve(async (req: Request): Promise<Response> => {
}
const CARBONE_API_TOKEN = Deno.env.get("CARBONE_API_TOKEN");
const CARBONE_TEMPLATE_ID = Deno.env.get("CARBONE_TEMPLATE_ID");
const CARBONE_BASE_URL = Deno.env.get("CARBONE_BASE_URL") ||
"https://carbone.lci.ulsa.mx";
if (!CARBONE_API_TOKEN || !CARBONE_TEMPLATE_ID) {
if (!CARBONE_API_TOKEN) {
throw new HttpError(
500,
"Configuración del servidor incompleta.",
@@ -121,7 +162,6 @@ Deno.serve(async (req: Request): Promise<Response> => {
{
missing: [
!CARBONE_API_TOKEN ? "CARBONE_API_TOKEN" : null,
!CARBONE_TEMPLATE_ID ? "CARBONE_TEMPLATE_ID" : null,
].filter(Boolean),
},
);
@@ -140,12 +180,22 @@ Deno.serve(async (req: Request): Promise<Response> => {
bodyUnknown,
);
const datos = await loadPlanDatos(supabase, input.plan_estudio_id);
const { datos, estructura_id } = await loadPlanDatos(
supabase,
input.plan_estudio_id,
);
const templateId = await loadTemplateIdForEstructura(
supabase,
estructura_id,
);
const carbone = new CarboneClient(CARBONE_BASE_URL, CARBONE_API_TOKEN);
const { data: _ignoredData, ...extraBody } = input.body;
console.log("body:", extraBody);
const result = await carbone.render(
CARBONE_TEMPLATE_ID,
{ data: datos, convertTo: "pdf" },
templateId,
{ data: datos, ...extraBody },
{ download: true },
);
@@ -196,18 +246,36 @@ Deno.serve(async (req: Request): Promise<Response> => {
{ action },
);
}
} catch (err) {
const error = err instanceof HttpError ? err : new HttpError(
500,
"Error interno del servidor.",
"INTERNAL_SERVER_ERROR",
{
original: err instanceof Error
? { message: err.message, stack: err.stack }
: err,
},
} catch (error) {
if (error instanceof HttpError) {
console.error(
`[${new Date().toISOString()}][${functionName}] ⚠️ Handled Error:`,
{
message: error.message,
code: error.code,
internalDetails: error.internalDetails || "N/A",
},
);
return sendError(error.status, error.message, error.code);
}
const unexpectedError = error instanceof Error
? error
: new Error(String(error));
console.error(
`[${
new Date().toISOString()
}][${functionName}] 💥 CRITICAL UNHANDLED ERROR:`,
unexpectedError.stack || unexpectedError.message,
);
return sendError(
500,
"Ocurrió un error inesperado en el servidor.",
"INTERNAL_SERVER_ERROR",
);
return sendError(error.status, error.message, error.code);
}
});