import { define, z } from "@jelou/functions";
export default define({
name: "cleanup-job",
description: "Limpia sesiones expiradas y sincroniza registros",
input: z.object({}),
config: {
cron: [
{ expression: "0 3 * * *", timezone: "UTC" },
{ expression: "0 15 * * 1-5", timezone: "America/Guayaquil" },
],
mcp: false,
},
handler: async (_input, ctx) => {
if (!ctx.isCron) {
return { skipped: true, reason: "solo se ejecuta por cron" };
}
ctx.log("Ejecutando limpieza", { cron: ctx.trigger.cron });
// Evitar duplicados con ctx.memory
if (ctx.memory.available) {
const yaEjecutado = await ctx.memory.get("limpieza_hoy", false);
if (yaEjecutado) {
ctx.log("Ya se ejecutó hoy, omitiendo");
return { skipped: true, reason: "ya ejecutado" };
}
}
const dbUrl = ctx.env.get("DATABASE_URL");
const apiKey = ctx.env.get("EXTERNAL_API_KEY");
const staleRecords = await fetch(`${dbUrl}/api/sessions?expired=true`)
.then((r) => r.json());
let cleaned = 0;
for (const record of staleRecords) {
await fetch(`${dbUrl}/api/sessions/${record.id}`, {
method: "DELETE",
headers: { Authorization: `Bearer ${apiKey}` },
});
cleaned++;
}
// Notificar al admin por WhatsApp
if (ctx.jelou.available && cleaned > 0) {
await ctx.jelou.send({
type: "text",
to: ctx.env.get("ADMIN_PHONE") || "",
text: `Limpieza completada: ${cleaned} registros eliminados.`,
});
}
// Marcar como ejecutado (expira en 20h)
if (ctx.memory.available) {
await ctx.memory.set("limpieza_hoy", true, 72000);
}
ctx.log("Limpieza completada", { cleaned, total: staleRecords.length });
return { cleaned, checked: staleRecords.length };
},
});