Shop room: players open a shop from its journal entry - #170
Merged
Merged
Conversation
Shop journals get an "Open shop" title-bar button. The GM's opens the GM room; a player's asks the active GM's client for the room, which serves it only when that player can see the journal entry but not edit it. With no GM online the window says the shop is closed. A player's journal-opened room stays open when the GM stops showing the shop. Fixes #169 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JRAx4Ex5fEHkxVB5Yaqw86
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.
Fixes #169
Security implication: players get a new way to ask the GM's client for a shop room. The GM's client serves it only when that player can see the shop's journal entry but not edit it, because a player who owns an entry could write its shop link themselves. Goods are the same player-filtered list Chronicle's room route returns. Buying still runs as the player's matched Chronicle member.
Consumer-verified: Chronicle
internal/plugins/syncapi/shop_api_handler.goGetShopRoomleaves out dm_only and player-hidden goods.Foundry compatibility: hooks
renderJournalEntrySheet(v13/v14) andrenderJournalSheet(v12). Not yet run in a live world; the TESTING.md checks cover it.Mockup: Sign-offs card "Shops in Foundry: open a shop from its journal entry" (foundry-shop-journal, v2). This PR waits on that card.
What this changes
Before: players could see a shop only while the GM was showing it from the Chronicle Sync window.
After: a shop's journal entry has an Open shop button in its title bar. The GM's button opens the GM room. A player's button opens the room on that player's screen only, and their basket works the same as before. With no GM online, the window says "The shop is closed". When the GM stops showing a shop, a room the player opened from the journal stays open. The GM's "Show to players" button is unchanged.
Why
Key Maker asked for the shop to live in its journal entry and be visible only to players who have access to it (#169).
How it works: the player's client sends a new
openrequest over the existing encrypted relay (_shop-room-data.mjsaccepts it with no body).ShopWidget._relayBuychecks the player's access to the journal. It then answers from the GM's open window, or from an unrendered room kept for that purpose. A room answer is allowed a larger size cap (MAX_ROOM_REPLY_CHARS), which no caller can raise. Buying is allowed for a shown shop, or for one whose journal the player can see.Known limit: a room a player opened from the journal doesn't update live when someone else buys. It refreshes after that player's own purchase, or when they reopen it.
Test plan
node --test tools/test-*.mjs: 1173 pass, 0 fail, 2 skipped (the vendored-copy check needs CHRONICLE_DIR; with it set, test-shop-room is 16/16)openrequest carries nothing but the shop; a room answer fits the room cap, a buying answer keeps the small cap, and no caller can lift the capTenet self-check
.ai.mdand TESTING.md updatedGenerated by Claude Code