Public: anyone can read this; the crew can change it.
forked from trevato/cs
A result says which map it was played on, so the leaderboard is comparing like with like #240
Check · Review · Land · Live done — Landed and live in production.
`parseResult` now takes a `map` field and validates it through `src/mapname.ts`: `de_forge` or `gen_<base36>`, anything else refused with the 422 the route already answers. A body with no map is still a result and records `de_forge`, so a client from before this keeps working — `src/server.test.ts`'s own fixture still posts none, which is that path under test end to end. `generated` is refused alo…
shipped production is serving it deploy ae07c2d
Sign in to join this conversation.
new above
offline
parseResultnow takes amapfield and validates it throughsrc/mapname.ts:de_forgeorgen_<base36>, anything else refused with the 422 the route already answers. A body with no map is still a result and recordsde_forge, so a client from before this keeps working —src/server.test.ts's own fixture still posts none, which is that path under test end to end.generatedis refused along with the junk: it is a wish for a new map, not a map anybody played on, which is whyplayedOnismapFrom's stricter twin rather than the same function — a control full of junk is a person mistyping and gets de_forge, a stored record full of junk is a claim nobody can check later and gets refused.src/db.tsgains the column with a migration in the shape of the identity one beside it: additive,NOT NULL DEFAULT 'de_forge', so yesterday's database opens today with every row it had and calls them de_forge. The recent-matches feed on/names the map as a link to that layout — text escaped, href built from this app's own string viamapFromand never the stored bytes — and the terminal's match list gains a 12-widemapcolumn beforewhen(worst case, a live match on a generated map, runs to 84 columns; no existing column moved), with the line under the cursor naming the map to paste into Map name when it was a generated one, because the id alone does not fetch that layout. The standings query is untouched: this records the fact, it does not split the board.The map is the browser's word like every number beside it —
resultOfposts the name of the level the world is actually standing on, and the server checks its shape and nothing more; a client can lie about which map it played exactly as it can about its kills. What to look at in the preview: the Recent matches list after playing one match on de_forge and one withgen_14u5j6gin Map name, and the same two rows in the terminal (FORGE_APP_SSH).bun testis 1078 green, andbun run scripts/mutate-result.tskills all 27 mutants including the two new map rules — its two stalematchIdmutants (they still looked for the regex that moved intosrc/matchid.ts) are replaced by one that breaks theisMatchIdcall. One thing found rather than changed:static/held twoapp.*.jsbundles, which madebun testred onmainbefore this branch; the rebuild here sweeps the stale one.🤖 Generated with Claude Code
Closes #150