Public: anyone can read this; the crew can change it.

A table you can open and sit at: schema, seats and state, replacing the notes demo #7

shipped production is serving it opened this has it
opened this

Intent. Replace the template's notes with the game's own state — tables, seats and a redacted view of a table — so the app's actions, API, page, MCP tools and terminal all speak about tables from here on.

Done looks like

  • [ ] Migrations appended to src/db.ts (never editing one that ran): game (id, title, status open|playing|settled|impounded, host_id, host_name, seed, seats_max 4–6, quorum, turn_seconds, deadline_seconds, created_at, started_at, settled_at), seat (id, game_id, player_id, player_name, ordinal, charge_json, score, joined_at) with UNIQUE(game_id, player_id) and UNIQUE(game_id, ordinal), and act (id, game_id, seat_id, kind, accord_json, at) ready for the turn engine.
  • [ ] Actions in src/actions.ts, each (db, who, input) in and data or a named failure out: listTables, openTable (a signed-in person only; title validated 1–60 chars; seats_max 4–6), joinTable (a seat is a forge identity; no second seat at the same table; refused once playing or full), leaveTable (only before the table starts), startTable (host or admin, 4+ seated, deals from src/board.ts with a seed stored on the game, fixes seat order, sets the deadline), and tableState.
  • [ ] tableState redacts by viewer, and tests prove it: a guest and a non-seated user see the charter, seats, status and act log but no charge; a seated player sees their own charge and nobody else's; after settlement everyone sees everything.
  • [ ] The notes table, actions, tools, routes and page sections are gone; GET / lists tables, GET /api/tables and GET /api/tables/:id answer, the MCP tools and src/tty.ts still call real actions, and the app boots with / under 50ms.
  • [ ] emit("table.opened" | "seat.joined" | "table.started", …) and the page region carries the matching data-live.
  • [ ] Tests in src/actions.test.ts cover every refusal by name: anon opening, joining twice, joining a full or started table, starting with three seats, starting as a non-host.

Files src/db.ts, src/actions.ts, src/actions.test.ts, src/routes.ts, src/page.ts, src/mcp.ts, src/tty.ts, src/server.test.ts, README.md.

Risks This is the run where the demo goes away — keep every door compiling and bun test green in the same commit. Charges are secret state in a column: the redaction belongs in the action, not in the page, or the next door leaks it.

Brief that fits @ledger — state changes as rows with a reason, and authorization written first. (A person assigns.)

commented

Amended by the planner. startTable moves to #8 with the rest of the turn engine, so this issue does not need src/board.ts: it ends with a table that can be opened, joined, left and read, still in status open. Everything else in the body stands, minus the startTable bullet and its seed/deal wording.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs