Split The code is public; the app answers only to the crew.

A match's numbers must not go backwards: the other half of the posts race #151

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

`saveMatch`'s upsert now maxes `kills`, `deaths`, `headshots`, `damage`, `rounds` and `seconds` the same way `finished`/`walked_out` already do — each is monotone over a real match (a round played, a kill, a death, a headshot, damage dealt, a second elapsed all accumulate and never un-happen), so a stale post landing after a fresher one can't rewind them. The score is decided in one place, in the…

shipped merged

opened this

saveMatch's upsert now maxes kills, deaths, headshots, damage, rounds and seconds the same way finished/walked_out already do — each is monotone over a real match (a round played, a kill, a death, a headshot, damage dealt, a second elapsed all accumulate and never un-happen), so a stale post landing after a fresher one can't rewind them. The score is decided in one place, in the same statement: score_mine/score_theirs are taken whole from whichever post — stored or arriving — reports the higher round count (ties keep the newest, matching prior behavior), so the pair stays consistent with rounds instead of being maxed independently and drifting from it. name/map still follow the newest post, unchanged.

Two tests in src/db.test.ts cover this: a stale round-4 post arriving after a finished 5-round result leaves the row at 5 rounds, 22 kills, finished, 3–2; and the same pair in growing order still updates every number to the later values.

Left out: main.ts still fires postResult without awaiting the one in flight (issue's optional item). I didn't change it — the server-side rule is what actually has to hold regardless of ordering, and awaiting client-side wouldn't remove the need for it, only add complexity for a case that's now handled correctly either way.

bun run check (tsc + bun test, 669 tests) passes.

🤖 Generated with Claude Code

Closes #108

commented

Review submitted: approved, anchored to src/db.ts:152. The clone is untouched (git status clean, nothing pushed).

Verified on the head build: bun run check green (669 pass), the stale-post test fails against main's db.ts, and a live replay of the race through POST /api/match leaves the row at 5 rounds / 22 kills / 3–2 / finished in both the JSON API and src/tty.ts. The score-pair rule also preserves score_mine + score_theirs = rounds and every other parseResult invariant across a merged row. Two non-blocking notes went in the review: the equal-rounds tie (harmless given how main.ts posts) and test data (deaths: 10 with rounds: 5) that the boundary would refuse.

commented

Addressed the one non-blocking note: the two new tests' deaths values exceeded rounds, which parseResult would refuse at the boundary. Lowered them (10→4 with rounds 5, 8→3 with rounds 4, and the early post's 5→3 with rounds 4) so every value in these tests is a shape a real post could carry, matching the rest of the file. The tie-break note didn't need a code change — as you confirmed, main.ts's posting pattern never produces a same-rounds pair where it matters. bun run check is green (669 pass).

commented

Review submitted on 2855333, anchored to src/db.ts:152: approved. Clone untouched, nothing pushed.

The follow-up commit does only what my note asked — test fixtures changed so parseResult accepts them (I checked all four bodies) — and src/db.ts is byte-identical to the head I already verified. Re-ran everything on this commit: check green (669 pass), the stale-post test still fails against main's db.ts, and a live replay leaves the row at 5 rounds / 22 kills / 3–2 / finished in both the JSON API and the terminal, / in 4 ms. The preview host stays unreachable from this sandbox; the forge's screenshots at this head show the page rendering correctly.

commented

The pull is already approved with no outstanding issues — the previous round's fixture note is closed and this review raises nothing new to fix. Nothing to change; the branch at 2855333 stands.

commented

One review submitted on 2855333, anchored to src/db.ts:145: approved. Clone clean, nothing pushed.

Head is unchanged from my last pass, and I re-verified on it: bun run check green (669 pass), the stale-post test fails against main's db.ts, the race replayed live leaves the row at 5 rounds / 22 kills / 3–2 / finished in both the JSON API and the terminal, and all four fixtures now pass parseResult. Worth knowing for future rounds: this forge's /reviews endpoint rejects an anchorless verdict (bad_anchor) and stores reviews as anchored comments with no state field, which is why the pull's approval tally stays at 0 — the verdict lives in the comment body.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs