fix: reconcile totalRecipients in CampaignService to prevent stuck campaigns
closes #348
This commit is contained in:
@@ -505,6 +505,48 @@ export class CampaignService {
|
|||||||
limit,
|
limit,
|
||||||
cursor: nextCursor,
|
cursor: nextCursor,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// Last batch: reconcile totalRecipients to the actual number of emails created.
|
||||||
|
// Dynamic segments re-evaluate on each batch query, so contacts that left the
|
||||||
|
// segment after totalRecipients was calculated are silently skipped. Without this
|
||||||
|
// reconciliation, sentCount can never reach the original totalRecipients and the
|
||||||
|
// campaign remains stuck in SENDING forever.
|
||||||
|
const [actualEmailCount, alreadySentCount] = await Promise.all([
|
||||||
|
prisma.email.count({where: {campaignId}}),
|
||||||
|
prisma.email.count({where: {campaignId, sentAt: {not: null}}}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await prisma.campaign.update({
|
||||||
|
where: {id: campaignId},
|
||||||
|
data: {totalRecipients: actualEmailCount},
|
||||||
|
});
|
||||||
|
|
||||||
|
// If all emails were already processed by the time the last batch finished
|
||||||
|
// (race: worker was faster than the batch chain), finalize the campaign now.
|
||||||
|
if (actualEmailCount === 0 || alreadySentCount >= actualEmailCount) {
|
||||||
|
const finalCampaign = await prisma.campaign.findUnique({
|
||||||
|
where: {id: campaignId},
|
||||||
|
include: {project: {select: {name: true}}},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (finalCampaign && finalCampaign.status === CampaignStatus.SENDING) {
|
||||||
|
await prisma.campaign.update({
|
||||||
|
where: {id: campaignId},
|
||||||
|
data: {status: CampaignStatus.SENT, sentCount: alreadySentCount},
|
||||||
|
});
|
||||||
|
|
||||||
|
signale.success(
|
||||||
|
`[CAMPAIGN] Campaign ${finalCampaign.name} finalized after last batch: ${alreadySentCount}/${actualEmailCount} emails sent`,
|
||||||
|
);
|
||||||
|
|
||||||
|
await NtfyService.notifyCampaignSendCompleted(
|
||||||
|
finalCampaign.name,
|
||||||
|
finalCampaign.project.name,
|
||||||
|
finalCampaign.projectId,
|
||||||
|
alreadySentCount,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user