fix(webapp): an archived campaign stops creating sessions and goes quiet #516

Merged
claude-bot merged 4 commits from fix/479-archived-campaign-outbound into main 2026-09-06 01:42:44 +00:00
Collaborator

Closes #479. Phase 1 of the v4.3.0 build order (#514), shipping early as v4.2.3.

The root was session creation. materialize_session_series now joins the campaign it was already fetching one row at a time for a timezone, and skips a series whose campaign is archived, or trashed, which turned out to share the hole: get_live_campaign returned None for a trashed campaign and the loop materialised into it anyway. The series is not deactivated, so un-archiving resumes with nothing to backfill.

Suppression is a separate predicate, campaign_service.campaign_accepts_outbound, applied at exactly five sites: session reminder, at-risk warning, three-day vote nudge, recap email, end-of-session attendance post. Each logs the campaign id once at info. The line is unprompted, not Discord-facing: a vote a player casts and a card a GM reveals still say what they were asked to say, because swallowing a button press would be a worse bug than the one fixed. The reminder check precedes the SessionReminderSent claim and the vote check precedes the vote_reminder_sent_at stamp, so an archived campaign never burns a marker it did not use.

process_audio, generate_journal_entry and warn_before_audio_deletion are untouched and have a test each. The tests were proven to bite by making the exact wrong change the issue warns about (or campaign.is_archived inside get_live_campaign): those three go red and nothing else does.

Already-materialised future sessions: warn, not refuse. They stay and go quiet. POST /campaigns/{id}/archive now returns silenced_future_sessions on an additive subclass of CampaignResponse, the count of confirmed or in-progress sessions still ahead, and stamps it into the audit context. No UI here; #382 can render it.

No migration, no /api/bot/* change. New tests/test_archived_campaign_outbound.py (13 tests); full backend suite 2349 passed / 13 skipped; ruff clean.

🤖 Generated with Claude Code

Closes #479. Phase 1 of the v4.3.0 build order (#514), shipping early as v4.2.3. **The root was session creation.** `materialize_session_series` now joins the campaign it was already fetching one row at a time for a timezone, and skips a series whose campaign is archived, or trashed, which turned out to share the hole: `get_live_campaign` returned `None` for a trashed campaign and the loop materialised into it anyway. The series is not deactivated, so un-archiving resumes with nothing to backfill. **Suppression is a separate predicate**, `campaign_service.campaign_accepts_outbound`, applied at exactly five sites: session reminder, at-risk warning, three-day vote nudge, recap email, end-of-session attendance post. Each logs the campaign id once at info. The line is *unprompted*, not *Discord-facing*: a vote a player casts and a card a GM reveals still say what they were asked to say, because swallowing a button press would be a worse bug than the one fixed. The reminder check precedes the `SessionReminderSent` claim and the vote check precedes the `vote_reminder_sent_at` stamp, so an archived campaign never burns a marker it did not use. `process_audio`, `generate_journal_entry` and `warn_before_audio_deletion` are untouched and have a test each. The tests were proven to bite by making the exact wrong change the issue warns about (`or campaign.is_archived` inside `get_live_campaign`): those three go red and nothing else does. **Already-materialised future sessions: warn, not refuse.** They stay and go quiet. `POST /campaigns/{id}/archive` now returns `silenced_future_sessions` on an additive subclass of `CampaignResponse`, the count of confirmed or in-progress sessions still ahead, and stamps it into the audit context. No UI here; #382 can render it. No migration, no `/api/bot/*` change. New `tests/test_archived_campaign_outbound.py` (13 tests); full backend suite 2349 passed / 13 skipped; ruff clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
claude-bot scheduled this pull request to auto merge when all checks succeed 2026-09-06 01:05:46 +00:00
rbrooks force-pushed fix/479-archived-campaign-outbound from 3a43a4e3b5
Some checks failed
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 53s
CI / Docker image build (pull_request) Successful in 26s
CI / Bot/backend version sync (pull_request) Successful in 38s
CI / Backend lint (ruff) (pull_request) Successful in 46s
CI / Frontend tests, audit, and build (pull_request) Successful in 1m42s
CI / Bot tests and audit (pull_request) Successful in 1m52s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been cancelled
CI / Backend migration, tests, and audit (pull_request) Has been cancelled
to b2e8afb156
Some checks failed
CI / Frontend tests, audit, and build (pull_request) Has been cancelled
CI / Backend migration, tests, and audit (pull_request) Has been cancelled
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Has been cancelled
CI / Bot tests and audit (pull_request) Has been cancelled
CI / Backend lint (ruff) (pull_request) Has been cancelled
CI / Bot/backend version sync (pull_request) Has been cancelled
CI / Docker image build (pull_request) Has been cancelled
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been cancelled
2026-09-06 01:12:34 +00:00
Compare
rbrooks force-pushed fix/479-archived-campaign-outbound from b2e8afb156
Some checks failed
CI / Frontend tests, audit, and build (pull_request) Has been cancelled
CI / Backend migration, tests, and audit (pull_request) Has been cancelled
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Has been cancelled
CI / Bot tests and audit (pull_request) Has been cancelled
CI / Backend lint (ruff) (pull_request) Has been cancelled
CI / Bot/backend version sync (pull_request) Has been cancelled
CI / Docker image build (pull_request) Has been cancelled
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been cancelled
to 0aab58675b
All checks were successful
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 1m23s
CI / Frontend tests, audit, and build (pull_request) Successful in 2m46s
CI / Bot/backend version sync (pull_request) Successful in 1m0s
CI / Backend lint (ruff) (pull_request) Successful in 1m7s
CI / Bot tests and audit (pull_request) Successful in 1m28s
CI / Docker image build (pull_request) Successful in 4m23s
CI / Backend migration, tests, and audit (pull_request) Successful in 7m26s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Successful in 22m26s
2026-09-06 01:12:55 +00:00
Compare
claude-bot deleted branch fix/479-archived-campaign-outbound 2026-09-06 01:42:44 +00:00
Sign in to join this conversation.
No description provided.