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
You've hit your weekly limit · resets Sep 20, 2am (UTC)
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)
API Error: Can't reach the API server — check your internet or DNS (EAI_AGAIN)
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)
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.
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.
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.
(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.
statsHtmlrendersstandings(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
EXPLAIN QUERY PLANshows.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.statsHtmlreturns the same fragment shape it does today.src/db.test.tswould fail without this: rank is right with ties, with zero matches, with one player and with a page past the end;src/server.test.tsproves the eleventh player sees themselves after posting, that?page=abc,?page=-3and?page=99999are 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.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.tsonly if paging needs a style,README.md, andsrc/terminal/screen.tsonly 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,
statsHtmlis 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.