feat: 'Previously on…' pre-session recap in reminders (#110) #198
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/110-previously-on-recap"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #110. The final v3.7.0 Table Tools issue. 🎬
Adds a "Previously on…" recap to the final pre-session Discord reminder — the last approved session's summary + a few open player-facing quests — so players get a refresher exactly when they want it. Stored summary verbatim, no LLM.
Backend (
1007bb6)recap_in_reminder(bool, default on — harmless, the block self-skips when there's no approved summary). Migrationf9a0b1c2d3e4(round-trips)._build_reminder_recap: newest session withaudio_processing_status in (trashed, approved)+ non-emptysummary(excluding the upcoming session), truncated to ≤1024 chars on a word boundary;open_threads= up to 5 threads filtered at the SQL level toplayer_visible=true AND status in (active, rumored). Returns{}when there's nothing to show (graceful skip).offset == min(offsets) && recap_in_reminder), spread into thesession_reminderextravia**recap; non-final offsets (7-day, 24h) stay byte-identical to today. Never logs summary/thread text.Bot (additive — no
BOT_CONTRACT_VERSIONbump)_handle_reminderrenders "📖 Previously on…" and "🧵 Open threads" embed fields when present (fit_embed-budgeted); absent → embed exactly as today.Frontend (
c4523ab)Two correctness points (things a generic recap couldn't get right)
open_threadsrespectsplayer_visible— #110's spec predated #115 (which replacedPlotThread.resolvedwithstatus/player_visible); since this posts to the players' channel, the filter is applied in SQL so GM-private threads can never leak (explicit test asserts a GM-private + a completed thread are excluded).Tests
test_previously_on_recap.py) — final-offset-only wiring, excerpt selection/exclusion/truncation, the player_visible+status thread filter + cap, and therecap_in_reminder=falseopt-out. Full suite 528 pass; migration round-trip verified.test_notifications.py) — field present/absent/empty. Bot suite 192 pass (run explicitly, since additive reminder-payload changes have tripped the bot's exact-call tests before).CampaignDetail). 263 pass, eslint clean, vite build green.Note
Recap is attached only on the bot-notify path, not the webhook/email fallback (webhook is the no-
guild_iddegraded path) — those payloads are untouched and unaffected.🤖 Generated with Claude Code
Attaches a recap block to the FINAL pre-session Discord reminder: the last approved session's summary + a few open player-facing quests. Uses the stored summary verbatim (no LLM). Additive and graceful. Backend: - Campaign gains recap_in_reminder (bool, default true); migration f9a0b1c2d3e4 (round-trips). - _build_reminder_recap: newest session with audio status trashed/approved + non-empty summary (excluding the upcoming one), truncated to <=1024 chars on a word boundary; open_threads = up to 5 threads filtered at the SQL level to player_visible=true AND status in (active, rumored) — so GM-private threads can never leak into the players' channel (post-#115 correctness). Returns {} when there's nothing to show. - Wired to the smallest offset only (offset == min(offsets) && recap_in_reminder), spread into the session_reminder extra via **recap; non-final offsets stay byte-identical. Never logs summary/thread text. Bot (additive — no BOT_CONTRACT_VERSION bump): - _handle_reminder renders "📖 Previously on…" and "🧵 Open threads" embed fields when present (fit_embed-budgeted); absent → embed unchanged. Tests: backend +12 (final-offset-only, excerpt selection/truncation, the player_visible+status thread filter, opt-out); bot +4 (field present/absent). Full backend suite 528 pass; bot suite 192 pass; migration round-trip verified. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>