feat(leads): edit campaigns, per-button feedback, and a run history - #132
Merged
Merged
Conversation
Three gaps that showed up together once campaigns could pitch something other than an audit. Existing campaigns could not be changed. The panel only ever created one, so a campaign built before the pitch setting existed was stuck on the audit pitch with no way to move it. Editing loads the campaign back into the form; saving already upserted on (project, name), so keeping the name edits in place rather than creating a duplicate. Every button shared one transition. Clicking any of them disabled all of them, none changed its label, and the result appeared in a single line at the top of the panel, far from the row it belonged to — so on a panel with several campaigns there was no way to tell which one had just run, or whether anything had happened at all. Each button now reports its own progress and its own outcome, next to its own campaign. Campaigns kept one string, last_run_note, overwritten every fifteen minutes. A tick that errored was invisible by the next one, and "has this ever found anything?" had no answer. Runs are now recorded, with their errors, and the last few are readable per campaign. Campaigns waiting on a seed login also say so on the row, pointing at the panel that fixes it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vu1nz Security Review0 finding(s) in PR #? No security issues found. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three gaps that showed up together once campaigns could pitch something other than an audit (#129).
Existing campaigns couldn't be changed
The panel only ever created a campaign — there was no edit path. So a campaign built before the pitch setting existed was stuck on the audit pitch with no way to move it off, which made #129 unusable for campaigns that already existed.
Editing loads the campaign back into the form, pitch fields included.
saveCampaignActionalready upserts on(project_id, name), so keeping the name edits in place rather than creating a duplicate.Buttons gave no feedback
Every button shared one
useTransition. Clicking any of them disabled all of them, none changed its label, and the result landed in a single line at the top of the panel — far from the row it belonged to. On a panel with several campaigns there was no way to tell which one had just run, or whether anything had happened.Each button now tracks its own in-flight state (
Run now→Running…) and reports its own outcome inline, next to its own campaign.No history
Campaigns kept one string,
last_run_note, overwritten every fifteen minutes. A tick that errored was invisible by the time the next one ran, and "has this campaign ever found anything?" had no answer.Runs are now recorded to
outreach_campaign_runswith their counts and full error lists, and the last few are readable per campaign behind a History toggle. The table is read-only from a session — it's a record of what the runner did, and stays honest by not being writable from the browser.Also
Campaigns parked on a gated seed show a
waiting_for_authbadge on the row, pointing at the Seed logins panel that unblocks them.Migration
20260728030000_outreach_campaign_runs.sql— new table only, nothing altered. Already applied to prod.Checks
tsc --noEmitclean🤖 Generated with Claude Code