feat: player-visible quest log (#115) #193
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/115-quest-log"
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 #115. Second feature of v3.7.0 Table Tools.
Extends the existing
PlotThread(GM plot threads) so it doubles as the player-facing quest log — no parallel model,player_visiblegates who sees what.Backend (
6d4a0d1)QuestStatusenum (rumored/active/completed/failed/abandoned) +player_visible/player_summarycolumns. Drops the oldresolvedbool, data-migratingresolved=true → completed(migrationf2a3b4c5d6e7, verified upgrade→downgrade→upgrade round-trip on a reset test DB).require_gm; GM view keeps privatenotes).list_threadsnow orders open statuses before closed.GET /campaigns/{id}/questsreturning a separateQuestResponsebuilt by explicit field mapping — structurally cannot leaknotesor other GM-only columns. Filtersplayer_visible=true.GET /api/bot/guilds/{guild_id}/quests(active + visible, safe fields) +api_client.get_guild_quests()+ a/questsslash command with a friendly zero-quest message. Purely additive → noBOT_CONTRACT_VERSIONbump.Frontend (
<this PR head>)ThreadTrackermigrated fromresolvedtostatus(badge + status select; "closed" = completed/failed/abandoned drives show/hide + counts + dimming). Per-rowplayer_visiblequick-toggle and aplayer_summaryfield, clearly distinct from GM-private notes.QuestLogon the campaign page (all members): grouped Active / Rumored, resolved statuses under a collapsed section, links to sessions + wiki entries, never shows notes.Tests
test_quests.py, incl. a raw-JSON-keys assertion thatnotesnever appears in the player or bot response, plus visibility-filter coverage. Full suite 466 pass; migration round-trip verified.QuestLog; 206 pass, eslint clean, vite build green.Notes
gm_client+player_clientfixtures, which shareapp.dependency_overrides(last wins → GM requests ran as the player → spurious 403). Rewrote them to seed the other user's rows viadband use one client per test (matching the #112 convention), and added a GM-only PATCH-wiring test.resolvedis a deliberate single-source-of-truth call; all references (backend endpoints + frontend ThreadTracker) were updated in the same branch, so no half-migrated state ships.🤖 Generated with Claude Code
Extends PlotThread so GM plot threads double as player-facing quests, rather than adding a parallel model. Backend: - New QuestStatus enum (rumored/active/completed/failed/abandoned) + player_visible / player_summary columns; drops the old `resolved` bool, migrating resolved=true -> completed (migration f2a3b4c5d6e7, round-trips). - GM thread endpoints gain the new fields (still require_gm; ThreadResponse keeps GM `notes`). - New member-readable GET /campaigns/{id}/quests returning a separate QuestResponse built by explicit field mapping — structurally cannot leak GM `notes` or other private columns. Filters player_visible=true. - list_threads ordering now surfaces open statuses before closed ones. Bot (additive — no BOT_CONTRACT_VERSION bump): - GET /api/bot/guilds/{guild_id}/quests (active + player_visible only, safe fields). - api_client.get_guild_quests() + /quests slash command listing active quests, with a friendly zero-quest message. Tests: +10 in test_quests.py incl. a raw-JSON-keys assertion that `notes` never appears in the player or bot response, and visibility-filter coverage. Full backend suite 466 pass; migration upgrade/downgrade/upgrade verified. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>- ThreadTracker (CampaignPlanning): migrate from the dropped `resolved` bool to the `status` enum (rumored/active/completed/failed/abandoned). Per-row status badge + status <select> in the editor; "closed" = completed/failed/abandoned drives the show/hide toggle, counts, and dimmed styling. Adds a per-row `player_visible` quick-toggle and a `player_summary` field (labelled distinct from GM-private notes). - QuestLog (new, CampaignDetail): read-only player-facing quest log via GET /campaigns/{id}/quests — grouped Active / Rumored, with completed/failed/abandoned under a collapsed "Resolved quests" section. Links to introduced/resolved sessions and linked wiki entries. Never shows notes. Visible to all members. - api/planning.js: add fetchQuests. Tests: +4 QuestLog; CampaignDetail test mocks fetchQuests. 206 pass, eslint clean, vite build succeeds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>