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) { 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 }); }