Skip to content

feat(campaign-builder): allow unstarting campaign - #250

Open
ajohn25 wants to merge 1 commit into
mainfrom
feat-unstart
Open

feat(campaign-builder): allow unstarting campaign#250
ajohn25 wants to merge 1 commit into
mainfrom
feat-unstart

Conversation

@ajohn25

@ajohn25 ajohn25 commented Aug 16, 2026

Copy link
Copy Markdown
Collaborator

Description

This adds an unstart button to the campaign builder page - when a started campaign is shown and no messages have been sent for the campaign yet

Additionally, it keeps the archive button on the page when a campaign is started

Motivation and Context

Admins sometimes start a campaign by accident and end up having to copy the campaign when for example they uploaded the wrong list. Additionally, archiving a campaign after it's started is a common workflow, so having the Archive button hidden didn't really make sense

How Has This Been Tested?

This has been tested locally

Screenshots (if appropriate):

Documentation Changes

Checklist:

  • My change requires a change to the documentation.
  • I have included updates for the documentation accordingly.

Base automatically changed from chore-simplify-archive to main August 26, 2026 15:50
);
}

const [campaign] = await r

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we we also stop any queued autosend jobs here? Thinking about the case where messages already waiting in the queue could still be sent after the campaign is unstarted, even though no message records exist yet

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch! I think rather than deleting the jobs, we should just check autosend_status = unstarted as a condition alongside the message one, I think it's fair to say once they hit "start sending" the campaign is truly started and we won't let them unstart at that point

};

export const hasSentMessages = async (campaignId: string) => {
const { rows } = await r.reader.raw(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious about the use of r.reader.raw here instead of r.knex.raw. This might be intentional, but wouldn’t it make sense to check the primary db so we don’t miss a recently created message?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep totally makes sense. tbh i think the way it's been used in the codebase for the most part has been very simplistic "reads -> reader, writes -> knex" so i'll fix this and make a followup issue for more comprehensive review of other places this could happen which is definitely needed 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants