admin roadmap done, reupload request, submission history, manual override
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import { prisma } from "@/lib/prisma";
|
||||
|
||||
const HOUR_MS = 60 * 60 * 1000;
|
||||
const DAY_MS = 24 * HOUR_MS;
|
||||
|
||||
export interface StaleSummary {
|
||||
/** Payment MIDTRANS status AWAITING > 25 jam (lewat expiresAt) — webhook gagal? */
|
||||
stalePaymentsCount: number;
|
||||
/** Booking AWAITING_PAY tapi trip sudah lewat hari ini — peserta lupa bayar. */
|
||||
awaitingPayPastDepartureCount: number;
|
||||
/** Payout HELD tapi heldUntil sudah lebih 1 hari lewat — cron release tidak jalan? */
|
||||
overduePayoutsCount: number;
|
||||
/** Refund APPROVED > 7 hari belum di-process — admin lupa? */
|
||||
stuckRefundsCount: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deteksi entity yang nyangkut di state non-final terlalu lama. Dipanggil dari
|
||||
* `/admin/system` page on-demand (bukan cron) supaya selalu show realtime.
|
||||
*
|
||||
* Threshold draft — review setelah jalan 1-2 minggu (false positive vs miss).
|
||||
*/
|
||||
export const systemHealthService = {
|
||||
async detectStale(): Promise<StaleSummary> {
|
||||
const now = new Date();
|
||||
const twentyFiveHoursAgo = new Date(now.getTime() - 25 * HOUR_MS);
|
||||
const oneDayAgo = new Date(now.getTime() - DAY_MS);
|
||||
const sevenDaysAgo = new Date(now.getTime() - 7 * DAY_MS);
|
||||
const todayStart = new Date(now);
|
||||
todayStart.setUTCHours(0, 0, 0, 0);
|
||||
|
||||
const [
|
||||
stalePayments,
|
||||
awaitingPayPast,
|
||||
overduePayouts,
|
||||
stuckRefunds,
|
||||
] = await Promise.all([
|
||||
prisma.payment.count({
|
||||
where: {
|
||||
provider: "MIDTRANS",
|
||||
status: "AWAITING",
|
||||
createdAt: { lte: twentyFiveHoursAgo },
|
||||
},
|
||||
}),
|
||||
prisma.booking.count({
|
||||
where: {
|
||||
status: "AWAITING_PAY",
|
||||
trip: { date: { lt: todayStart } },
|
||||
},
|
||||
}),
|
||||
prisma.payout.count({
|
||||
where: {
|
||||
status: "HELD",
|
||||
heldUntil: { lte: oneDayAgo },
|
||||
},
|
||||
}),
|
||||
prisma.refund.count({
|
||||
where: {
|
||||
status: "APPROVED",
|
||||
reviewedAt: { lte: sevenDaysAgo },
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
return {
|
||||
stalePaymentsCount: stalePayments,
|
||||
awaitingPayPastDepartureCount: awaitingPayPast,
|
||||
overduePayoutsCount: overduePayouts,
|
||||
stuckRefundsCount: stuckRefunds,
|
||||
};
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user