fix email sender all flow
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { Prisma } from "@/app/generated/prisma/client";
|
||||
import type { EmailJobStatus } from "@/app/generated/prisma/enums";
|
||||
|
||||
/** Filter untuk halaman admin email log. Keduanya opsional, match `contains`. */
|
||||
export interface EmailLogFilters {
|
||||
to?: string;
|
||||
template?: string;
|
||||
}
|
||||
|
||||
const LIST_LIMIT = 100;
|
||||
|
||||
function buildWhere<T extends { to?: unknown; template?: unknown }>(
|
||||
filters: EmailLogFilters
|
||||
): T {
|
||||
const where = {} as T;
|
||||
if (filters.to) {
|
||||
(where as { to?: unknown }).to = {
|
||||
contains: filters.to,
|
||||
mode: "insensitive",
|
||||
};
|
||||
}
|
||||
if (filters.template) {
|
||||
(where as { template?: unknown }).template = {
|
||||
contains: filters.template,
|
||||
mode: "insensitive",
|
||||
};
|
||||
}
|
||||
return where;
|
||||
}
|
||||
|
||||
export const emailRepo = {
|
||||
/** EmailJob (retry queue) per status — terbaru dulu. */
|
||||
async listJobs(statuses: EmailJobStatus[], filters: EmailLogFilters) {
|
||||
const where = buildWhere<Prisma.EmailJobWhereInput>(filters);
|
||||
where.status = { in: statuses };
|
||||
return prisma.emailJob.findMany({
|
||||
where,
|
||||
orderBy: { updatedAt: "desc" },
|
||||
take: LIST_LIMIT,
|
||||
});
|
||||
},
|
||||
|
||||
/** EmailSent (log email berhasil terkirim) — terbaru dulu. */
|
||||
async listSent(filters: EmailLogFilters) {
|
||||
const where = buildWhere<Prisma.EmailSentWhereInput>(filters);
|
||||
return prisma.emailSent.findMany({
|
||||
where,
|
||||
orderBy: { sentAt: "desc" },
|
||||
take: LIST_LIMIT,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Statistik kesehatan pengiriman email — dipakai kartu ringkasan
|
||||
* `/admin/emails` dan `/admin/system`.
|
||||
* - `queued` : job menunggu dikirim (PENDING/PROCESSING).
|
||||
* - `failed24h` : job gagal dalam 24 jam terakhir.
|
||||
* - `deadLetter` : job gagal yang sudah habis 5 attempt — cron berhenti
|
||||
* retry, butuh aksi manual admin.
|
||||
*/
|
||||
async stats() {
|
||||
const since24h = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
||||
const [queued, failed24h, deadLetter] = await Promise.all([
|
||||
prisma.emailJob.count({
|
||||
where: { status: { in: ["PENDING", "PROCESSING"] } },
|
||||
}),
|
||||
prisma.emailJob.count({
|
||||
where: { status: "FAILED", updatedAt: { gte: since24h } },
|
||||
}),
|
||||
prisma.emailJob.count({
|
||||
where: { status: "FAILED", attempts: { gte: 5 } },
|
||||
}),
|
||||
]);
|
||||
return { queued, failed24h, deadLetter };
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user