Demo Guests and devtools on local and preview stacks #394
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
spec
wayfinder:grilling
wayfinder:map
wayfinder:prototype
wayfinder:research
wayfinder:task
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
amaurycoudr/chess-project#394
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Problem Statement
The owner wants to look at the Guest-history features ("My games" and the stored Game page with PGN export and copy link, spec #355) on a preview or locally, without first playing whole Games to their end in two browsers. Every Guest's secret lives only in the browser that minted it, and the database holds only its hash (ADR 0034), so there is no way today to open a stack as a Guest who already has decided Games.
Solution
Each local and preview stack carries a fixed set of decided Games owned by two Demo Guests, whose secrets are fixed, public demo values. On those stacks, the TanStack devtools show a "Guest" panel that switches the browser to a Demo Guest in one click, or to a secret pasted by hand from another browser. Production carries neither the data nor the devtools: the same image is deployed everywhere (ADR 0036), so the gate is a runtime env flag set per stack, never a build flag.
User Stories
pnpm dev, so that "My games" is never empty when I work on it.db:seed, so that I can restore the demo Games after wiping or editing them.pnpm devleaves exactly the same demo rows.Seams
gameprocedures and the newdevtoolsprocedure, as the existingrpc-*integration tests do. A unit test on the seed's definition, and integration tests. Covers stories 1, 2, 4, 5, 6, 7, 8, 9, 10.CODING_STANDARDS.mdrule 8): the devtools mount behind the probe, and the Guest panel inside it. View tests. Covers stories 11, 12, 13, 14, 15.deploy/verify.shon a real stack: the seed step's exit state, and the probe's status by stack. Covers stories 3 and 16.No e2e seam: no Player perceives this feature in production, and the feature sits outside
apps/e2e's purpose as the oracle for the Room.Implementation Decisions
DEVTOOLS_ENABLED. It is on only when it is exactlytrue; any other value or no value means off, failing closed like an empty origin allowlist (ADR 0028).loadConfigreads it like the other API settings. It is set in the preview-only compose overlay, whichup.shalready applies tochess-pr-*stacks only, on both theappandseedservices, and inapps/api/.env.localthroughpnpm env:sync. Production's compose never sets it. There is no hostname check: the stack regex that picks the overlay is already what tells a preview from production.migrate, outside Nest, with the same env-file handling. It exposes the Demo Guests (label and secret) and the demo Games as data, plus a run function. That function refuses unlessDEVTOOLS_ENABLEDis on, naming the flag in its error, and upserts by fixed ids: Guests by their secret's hash, Games by a fixed id each. Scripts:db:seed(built, for the image) and a dev variant. The API'sdevscript runs the seed aftermigrate:dev. It prints the next steps: which Guests exist and how to switch to them.GuestSchemaever checks the format. They are public by design: only demo data is reachable with them.gamestable's CHECK constraints. The lines that already exist in the Room fixtures (stalemate, threefold, insufficient material, fifty-move, Fool's mate) are the prior art, and moving them into a shared place is a fair prefactor.startedAtandendedAtare fixed, relative to a fixed date, never to now, so reruns stay idempotent.seedservice in the preview overlay runs the image's built seed.up.shruns it aftermigrateand beforeappon preview stacks only, with its exit code failing the deploy, the same way it treatsmigrate(ADR 0032).verify.shallows theseedcontainer on previews, and checks that it exited cleanly. It also checks thatGET /rpc/devtoolsanswers 200 on a preview and 404 on production.devtoolsgroup in@chess/contracts(ADR 0027), with one procedure,GET /devtools, whose output is{ demoGuests: [{ label, secret }] }. It sits under/rpc, so the origin guard applies (a GET without Origin passes, per ADR 0028).devtoolsNest feature module, imported by the app module only when the config's flag is on. When it is off, the route does not exist and/rpc/devtoolsanswers 404. The controller returns the seed module's Demo Guests. Nest stays out of the seed module (ADR 0027's layering).removeDevtoolsOnBuild: false. The root route no longer mounts the TanStack devtools unconditionally: it calls the probe once at boot, through the contract client and TanStack Query (ADR 0012). Only on a 200 does it dynamicallyimport()the devtools and mount them with the Router, Query and Guest panels. On 404 it mounts nothing and downloads no devtools chunk. Local dev goes through the same probe, with noimport.meta.env.DEVbranch.keepGuest()and invalidate the Query cache, so the views refetch with the newx-guestheader. There is no "Forget" and no "back to my Guest": a private window resets, and a local or preview Guest is throwaway.DEVTOOLS_ENABLEDflag set by the preview overlay, never a build flag, because previews and production run one image. It is written withdomain-modelingand added to the ADR index.Testing Decisions
rpc-gamesandrpc-game-readsintegration tests (in-process Postgres,rpc.fixtures) for seeding and reading back;room-decided.testand the Room fixtures for the ending lines;game.listreturns its Games inendedAtorder, with the expected results;game.get, and is absent from A's list;true;/rpc/devtoolsanswers the Demo Guests when the flag is on, and 404 when it is off.x-guestheader of the next request, and My games refetches.Out of Scope
?secret=route.Further Notes
implement-spec: the seed, then devtools on previews, then the Guest panel.apps/e2e: itsbuilttarget reads.env.local, which will now turn devtools on. Check that the devtools trigger overlaps none of the elements the suite clicks.mentioned in issue #395
mentioned in issue #396
mentioned in issue #397
marked this issue as related to #395
marked this issue as related to #396
marked this issue as related to #397
mentioned in merge request !522
mentioned in merge request !523