chore: initial project import
Some checks failed
CI - Production Readiness / Verify (push) Has been cancelled

This commit is contained in:
Wira Basalamah
2026-04-21 09:29:29 +07:00
commit adde003fba
222 changed files with 37657 additions and 0 deletions

79
lib/campaign-utils.ts Normal file
View File

@ -0,0 +1,79 @@
import { CampaignStatus, DeliveryStatus } from "@prisma/client";
import { prisma } from "@/lib/prisma";
export const DEFAULT_MAX_SEND_ATTEMPTS = 3;
export const RETRY_BACKOFF_SECONDS = [10, 30, 120];
export function getRetryDelaySeconds(attempt: number) {
if (attempt <= 1) {
return RETRY_BACKOFF_SECONDS[0];
}
if (attempt - 1 < RETRY_BACKOFF_SECONDS.length) {
return RETRY_BACKOFF_SECONDS[attempt - 1];
}
return RETRY_BACKOFF_SECONDS[RETRY_BACKOFF_SECONDS.length - 1];
}
export function renderCampaignMessage(templateBody: string, values: Record<string, string>) {
return templateBody.replace(/\{\{\s*(\d+)\s*\}\}/g, (match, token) => {
const key = String(token);
return values[key] ?? match;
});
}
export async function recalculateCampaignTotals(campaignId: string) {
const recipients = await prisma.campaignRecipient.findMany({
where: { campaignId },
select: { sendStatus: true }
});
const totalRecipients = recipients.length;
const totalSent = recipients.filter((recipient) => recipient.sendStatus !== DeliveryStatus.QUEUED).length;
const totalDelivered = recipients.filter((recipient) =>
recipient.sendStatus === DeliveryStatus.DELIVERED || recipient.sendStatus === DeliveryStatus.READ
).length;
const totalRead = recipients.filter((recipient) => recipient.sendStatus === DeliveryStatus.READ).length;
const totalFailed = recipients.filter((recipient) => recipient.sendStatus === DeliveryStatus.FAILED).length;
const totalQueued = recipients.filter((recipient) => recipient.sendStatus === DeliveryStatus.QUEUED).length;
const isDone = totalQueued === 0;
const status = isDone
? totalFailed > 0
? totalSent > 0
? CampaignStatus.PARTIAL_FAILED
: CampaignStatus.FAILED
: CampaignStatus.COMPLETED
: totalFailed > 0
? CampaignStatus.PARTIAL_FAILED
: CampaignStatus.PROCESSING;
const updateData: {
totalRecipients: number;
totalSent: number;
totalDelivered: number;
totalRead: number;
totalFailed: number;
status: CampaignStatus;
finishedAt?: Date | null;
} = {
totalRecipients,
totalSent,
totalDelivered,
totalRead,
totalFailed,
status
};
if (isDone) {
updateData.finishedAt = new Date();
}
await prisma.broadcastCampaign.update({
where: { id: campaignId },
data: updateData
});
}