Skip to main content

TypeAlias.CampaignStatus

type CampaignStatus = ObjectEnum<typeof CampaignStatus>;

Lifecycle status of a marketing campaign.

  • draft: under preparation in the wizard. The only mutable state — name, channels, targeting, content and schedule can still change, and the campaign can be deleted. Transitions to scheduled (planned send) or sending (immediate send).
  • scheduled: a future sendAt is set and a delayed job is queued. The campaign waits for its due date. Can be cancelled back to draft before the job fires. If the delayed trigger vanishes (Redis loss/flush, a double-fault rollback), the campaign would otherwise stay scheduled forever: an hourly recovery sweep detects a past-due schedule whose job is gone (scheduleJobLost flag) and auto-re-arms it to fire immediately. See CampaignScheduleRecoverConsumer.
  • sending: the audience snapshot is frozen (audienceSnapshotCount set, CampaignDelivery rows created) and sentAt is stamped. Transient state while the deliveries drain. Irreversible — the snapshot is never recomputed and it never goes back to draft. If the send job fails terminally (attempts: 1, crash/OOM), the campaign is left stranded in sending: it is detected by an hourly sweep (warn log) and resumable via POST /:id/resume, which re-enqueues the idempotent send job (already delivered recipients are skipped). See CampaignSendConsumer.
  • sent: every delivery has been processed (sent / excluded / failed). The conversion window runs from sentAt. Failed deliveries can be retried without changing this status.
  • finished: the conversion window has closed and the stats are frozen. Terminal.