Feat/1767 season rollover leaderboard snapshot - #1781
Merged
Olowodarey merged 4 commits intoAug 29, 2026
Merged
Olowodarey merged 4 commits into
Olowodarey merged 4 commits into
Conversation
Adds the SeasonLeaderboardSnapshot entity that will hold one immutable row per (season, user) captured at rollover time, per Arena1X#1767.
Table with FKs to seasons/users, unique (season_id, user_id), and an index on (season_id, rank) for ordered reads.
processSeasonRollover previously finalized the ending season (its own transaction) and only afterwards saved rollover_processed_at, with no leaderboard snapshot at all — a crash between those steps could leave standings finalized without ever recording rollover_processed_at, and there was no immutable record of final standings for reward payout or audit. Fold freeze + snapshot + open-next into one DB transaction: finalize the ending season, write its final standings into the new season_leaderboard_snapshots table, reset season_points, then activate the next season — all committed together or rolled back together. Idempotent: rollover_processed_at is re-checked inside the transaction (closing the race between two concurrent ticks), and snapshotLeaderboard skips if a snapshot for the season already exists, so a retry can never duplicate rows past the unique (season, user) constraint.
Covers exactly-one-snapshot-per-season, no duplicate snapshot when the rollover transaction is retried, and a full rollback (season standings untouched) when the snapshot write fails mid-transaction.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Atomic season rollover with leaderboard snapshot
season-rollover.scheduler.tsfinalized a season and savedrollover_processed_atas separate steps, with no immutable record of theclosed season's final standings. A crash mid-write could leave standings
finalized without the idempotency marker, and there was nothing to pay
rewards or audit against.
Changes
SeasonLeaderboardSnapshotentity + migration for an immutableseason_leaderboard_snapshotstable (unique onseason, user).processSeasonRollovernow runs freeze → snapshot → reset points → opennext season as one DB transaction — commits or rolls back together.
rollover_processed_atis re-checked inside the transaction,and the snapshot step is skipped if one already exists for the season, so
a retry can never duplicate rows.
rollback when the snapshot write fails.
Testing
npm test(backend) — 1490/1490 passingnpm run lint(backend) — 0 errorsnpm run build(backend) — cleannpm run migration:check-timestamps— passedCloses #1767