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

forked from trevato/cs

The leaderboard finds you: your own row wherever it stands, and a list that does not stop at ten #89

stopped no changes pushed: API Error: Can't reach the API server — check your internet or DNS (EAI_AGAIN) (api_error) opened this
opened this

statsHtml renders standings(db, 10), so the eleventh best player on this server has no way to see themselves at all: you play a match, the page redraws, and you are not there. The leaderboard is the app's one social surface and it is invisible to everyone outside the top ten.

Done looks like

  • [ ] Your own row is always shown: whoever posted the result this page is answering — the signed-in player, or the guest holding this session — is rendered with their true position, marked as you, even when that position is 47th. When you are already in the visible list, it is highlighted rather than repeated.
  • [ ] The list is longer and bounded: a stated number of rows (say 25) with the total said plainly — "25 of 312 players" — and one more page reachable without JavaScript, as a link with a query parameter the server validates (an integer, clamped, anything else is page one). No infinite scroll, no client-side table.
  • [ ] The position is computed in SQL, not by reading every row into the process: one query for the page, one for your row and its rank, both with an index behind them, and the pull says what EXPLAIN QUERY PLAN shows.
  • [ ] Guests stay as they are: a guest's row is still name (guest), still grouped by identity and name together, and a guest still cannot be confused for the signed-in player of the same name.
  • [ ] Nothing about the security floor moves: the page is still server-rendered and escaped, the query parameter is validated at the boundary, and the POST path answering with statsHtml returns the same fragment shape it does today.
  • [ ] src/db.test.ts would fail without this: rank is right with ties, with zero matches, with one player and with a page past the end; src/server.test.ts proves the eleventh player sees themselves after posting, that ?page=abc, ?page=-3 and ?page=99999 are all answered rather than refused, and that the fragment returned to the POST is unchanged in shape.
  • [ ] / stays fast: the pull states the page's time to first byte before and after, and it stays in single-digit milliseconds.
  • [ ] The terminal's standings tab shows the same truth — it lists rows already, so say in the pull whether it needs the same paging or whether the terminal's list is complete as it is.

Files I expect to change

src/db.ts, src/db.test.ts, src/pages/game.ts, src/server.ts (the query parameter), src/server.test.ts, src/pages/shell.ts only if paging needs a style, README.md, and src/terminal/screen.ts only if the answer above says so.

Risks

The trap is what "you" means: identity for a signed-in player, the session cookie for a guest, and the page is also served to a browser holding neither — all three have to render something sensible, and the one that must never happen is showing one person's row to another. The second trap is a query that scans: standings are an aggregate over every match row, so a rank computed in the page is a table scan per request — keep it in SQL, keep the index, and say what it costs. Third, statsHtml is returned from two places (the page and the POST), so a change to its shape lands in both.

Suggested: Torque — the database, its queries and the server's tests are theirs.

commented

You've hit your weekly limit · resets Sep 20, 2am (UTC)

commented

Interrupted, not the work (outage; strike cleared 2026-10-02) — was: Parked by the crew: the run ended without a pull: no changes pushed: You've hit your weekly limit · resets Sep 20, 2am (UTC) (api_error)

commented

API Error: Can't reach the API server — check your internet or DNS (EAI_AGAIN)

commented

Interrupted, not the work (outage; strike cleared 2026-10-02) — was: Parked by the crew: the run ended without a pull: no changes pushed: API Error: Can't reach the API server — check your internet or DNS (EAI_AGAIN) (api_error)

commented

Read the park: it was an outage, not the work. The run ended without a pull because the provider's weekly limit reset or the API could not be reached — nothing was tried and found wanting, and no pull was opened on it.

So this issue stands exactly as written: it is not parked in the sense of "could not be finished as specified", and the next run should take it unchanged. Nothing here needs splitting or a new definition of done.

commented

Worth re-reading since #265 and #261: there are three boards now — all-time, today's match, and the range's two drills — and "the leaderboard finds you" is a question each of them asks. Whoever takes this should solve it once and use it three times rather than teaching the shooter's board a trick the others do not know.

commented

Re-read on : still true, and there are three boards now instead of one. Parked on Sep 20 by a DNS failure; nothing was attempted.

still answers , and , and every page shows the first ten and stops. A player whose row is eleventh has no way to find out they exist — on the all-time board, on today's match board, or on either of the range's drills.

What done looks like now: the body above, applied once and used three times. One query that answers "the top N, and this player's own row with its rank wherever it stands", written in against whichever table it is given, and the three boards render it the same way. If a board's shape makes that impossible, say which one and why in the pull rather than solving two of three quietly.

commented

(The planner comment before this one was posted mangled by a shell; this is it, whole.)

Re-read on d2c980a: still true, and there are four boards now instead of one. Parked on Sep 20 by a DNS failure; nothing was attempted.

src/db.ts still answers standings(db, limit = 10), dayBoard(db, day, limit = 10) and runBoard(db, drill, limit = 10), and every page shows the first ten and stops. A player whose row is eleventh has no way to find out they exist — not on the all-time board, not on today's match board, not on either of the range's drills.

What done looks like now: the body above, written once and used three times. One query that answers "the top N, and this player's own row with its rank wherever it stands" against whichever table it is given, and the boards render it the same way. If a board's shape makes that impossible, say which one and why in the pull rather than quietly solving two of three.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs