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

A number the crew can trust: /status, for the person who has to know whether tables are actually being played #72

open not picked up yet opened this
opened this

Intent. Give the crew one page that answers "is this app healthy and is anyone playing?" without an ssh session and without reading the database by hand.

Why now. The app is about to hold games that run for days across deploys. Today nothing but console.error says anything: there is no count of tables by state, no idea how many turns lapsed overnight, no schema version at runtime, no number of open event streams (#67 is about to cap them and will want the number to pick the cap), and no uptime. HEAD / already works as the forge's liveness check and should stay exactly that; this is the other question.

Done looks like

  • [ ] status(db, who) in src/actions.ts — an action like every other, refusing anon and non-admin with the named failures, so no door decides who may read it.
  • [ ] What it returns, all of it derived and none of it stored: tables by status; seats taken; acts in the last 24 hours; the oldest table still playing; the schema version (check in src/db.ts already has it); open event streams and events kept on the bus; the commit and the environment from src/env.ts; process uptime and resident memory.
  • [ ] GET /status renders it in the layout, in the parts vocabulary — no new markup for a number — and GET /api/status answers the same data as JSON. Both private, no-store.
  • [ ] It costs one round of small queries and answers in single-digit milliseconds on a database with a thousand acts; no table scan that grows with the ledger, and no query in a loop.
  • [ ] It says nothing secret: no seed, no charge, no player name, no title — counts and versions only. A test asserts the serialised answer contains no seed and no charge for a table mid-game.
  • [ ] A key in src/tty.ts shows the same thing for an admin at the terminal, because what a person can do on the page they can do there.
  • [ ] Tests that fail without it: a guest gets signin_required, a signed-in player forbidden, an admin the counts; the counts move when a table is opened and a seat is taken.

Files I expect to change. src/actions.ts, src/routes.ts, src/db.ts (exporting what check already computes), src/live.ts (a count of listeners and kept events), src/tty.ts, src/pages/ for the page, src/actions.test.ts, src/server.test.ts, README.md.

Risks. Keep it a read: nothing here writes, resets or prunes. admin is the forge's word (who.ts), not a password. Do not turn it into metrics for a scraper — one page, one JSON answer, no new endpoint per number — and do not let it become the place where someone later adds a live tail of the event bus, which is a payload rule waiting to be broken. It needs a count out of src/live.ts, which #67 also touches; whichever lands second rebases.

Who. @mason, reviewed by @sentinel. Ready now.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs