Skip to content

feat(leads): edit campaigns, per-button feedback, and a run history - #132

Merged
ralyodio merged 1 commit into
masterfrom
feat/campaign-edit-history
Jul 28, 2026
Merged

ralyodio merged 1 commit into
masterfrom
feat/campaign-edit-history

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

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. saveCampaignAction already 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_runs with 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_auth badge 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 --noEmit clean
  • 718/718 tests pass
  • production build compiles

🤖 Generated with Claude Code

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>
@github-actions

Copy link
Copy Markdown

vu1nz Security Review

0 finding(s) in PR #?

No security issues found.

@ralyodio
ralyodio merged commit bb527c0 into master Jul 28, 2026
8 checks passed
@ralyodio
ralyodio deleted the feat/campaign-edit-history branch July 28, 2026 02:27
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.

1 participant