email service and template using resend
This commit is contained in:
@@ -55,7 +55,7 @@ async function getJobSummary(jobName: string): Promise<JobSummary> {
|
||||
}
|
||||
|
||||
// Daftar cron yang dipantau. Tambah entry baru saat menambah cron route handler.
|
||||
const TRACKED_JOBS = ["auto-complete-trips"] as const;
|
||||
const TRACKED_JOBS = ["auto-complete-trips", "process-email-jobs"] as const;
|
||||
|
||||
function healthOf(summary: JobSummary): "ok" | "stale" | "failed" {
|
||||
if (summary.lastRun?.status === "FAILED") return "failed";
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { emailService } from "@/lib/email/send";
|
||||
import { runCron } from "@/lib/cron-runner";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
/**
|
||||
* Cron — proses retry queue email (jobs status PENDING/FAILED dengan
|
||||
* attempts<5 dan scheduledAt sudah lewat).
|
||||
*
|
||||
* Trigger setiap 5 menit via system crontab — lihat docs/CRON_SETUP.md.
|
||||
* Header wajib: `Authorization: Bearer ${CRON_SECRET}`.
|
||||
*/
|
||||
export async function GET(req: NextRequest) {
|
||||
const secret = process.env.CRON_SECRET;
|
||||
if (!secret) {
|
||||
return NextResponse.json(
|
||||
{ error: "Server misconfigured (CRON_SECRET)" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
const authHeader = req.headers.get("authorization");
|
||||
if (authHeader !== `Bearer ${secret}`) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
const outcome = await runCron("process-email-jobs", async () => {
|
||||
return emailService.processQueue(50);
|
||||
});
|
||||
|
||||
if (!outcome.ok) {
|
||||
return NextResponse.json({ error: outcome.error }, { status: 500 });
|
||||
}
|
||||
return NextResponse.json({ ok: true, ...outcome.payload });
|
||||
}
|
||||
Reference in New Issue
Block a user