Skip to content

v1.5.3

Choose a tag to compare

@ProjectRio ProjectRio released this 24 Feb 06:56
· 44 commits to main since this release
7a7ce2a

v1.5.3

Bug Fixes

Glicko-2: Winner RD and Volatility Never Updated

calc_elo() was assigning winner_ladder.rd = winner_ladder.rd and winner_ladder.vol = winner_ladder.vol (self-assignment), so the winner's RD and volatility never changed after any game. Fixed to use winner_player.rd and winner_player.vol. This is a major bug that affected all player ELOs in all game modes.

recalc_elo(): Integer Truncation Mismatch

Ladder ratings are stored as Integer columns, so each DB commit truncates Glicko-2 floats. recalc_elo() was accumulating full-precision floats across all games, producing different results than process_game() which commits game-by-game. Fixed by explicitly truncating to int after each game during recalculation.

Ladder Query: admin_accept = NULL → admin_accept IS NULL

The ladder CTE in tag.py used = NULL instead of IS NULL, causing the admin_accept condition to always evaluate to UNKNOWN in SQL and effectively excluding all user-accepted games from the ladder. Fixed in four places.

db_setup.py: TrustedUser Group Never Created

The banned variable was reassigned to the TrustedUser group object before being added to the session, so banned was never added and TrustedUser was added twice. Fixed to use a separate trusted_user variable.

Status Codes Standardized


New Features

Manual Game Submission via /populate_db/

Admins and Trusted Users can now submit existing stat files directly via POST /populate_db/?submitter_rio_key=<key>. The stat file JSON is unchanged; usernames in the Home Player/Away Player fields are resolved against the database and swapped for rio_keys before ingestion proceeds.

/manual_submit_game/ — Full Rewrite

The manual game history submission endpoint now:

  • Performs additional game validations
  • Correctly scopes submitter authorization: site Admins/TrustedUsers, community admins, and the players themselves can all submit; ELO is only calculated immediately when an admin submits
  • Uses flush() / single commit() for atomicity

/update_game_status/ — Full Rewrite

Game acceptance confirmation endpoint now:

  • Accepts only game_history_id instead of game_id since game_id for manual submissions is always None
  • Allows site Admins and TrustedUsers (not just community admins) to override game status
  • Uses flush()/single commit() with rollback on error

/move_games/ (renamed from /reassign_game_history_game_mode/)

  • Major bug fixes to the endpoint
  • Accepts a single game_id (int) or a list game_ids (list of ints) in one request
  • Validates all games and community membership before making any changes
  • Recalculates ELO once per affected TagSet rather than once per game
  • Returns descriptive 400/404 errors instead of 409 for everything

/upload_status/ (new)

Public endpoint showing ingestion pipeline health: pending file count, defect file count, and ongoing games. Admin callers additionally receive filenames, file sizes, error messages, and game metadata from defect files.

/system_status/ (new)

Public health-check endpoint ({"status": "ok"}). Admin callers receive full CPU, memory, disk, disk I/O, network I/O, and database connectivity stats via psutil.

/populate_db/process/ (new, admin-only)

Admin endpoint to immediately flush all pending game files for processing. Primarily used in integration tests to avoid waiting for the APScheduler tick.

/user/delete (new, Admin-only)

Delete a user account with safety guards: blocks deletion if the user has any game history, is in an ongoing game, or sponsors a community. Cleans up all FK references (groups, community memberships, IP records, API key) before deleting.

Stale Ongoing Game Pruning

The APScheduler job now prunes OngoingGame rows older than 2 hours on every tick, preventing stale entries from accumulating.


Improvements

recalc_elo Refactored to a Pure Internal Function

recalc_elo() is no longer an endpoint itself; it's a plain function that uses flush() and defers commit to the caller. A thin recalc_elo_endpoint() wraps it for the /recalc_elo/ route. This makes it composable (used by /update_game_status/, /move_games/, /manual_submit_game/) without nested transactions.

Linescore Optimization

_build_linescores() and _build_scoring_plays() merged into a single build_linescore_and_scoring_plays() function that runs one DB query for both. Scoreless innings are now correctly filled with 0 using innings_played rather than being omitted. Walk-off innings now correctly display 'X' instead of 0.

get_user_by_username() Added to user_util.py

New helper for case-insensitive, normalized username lookups via SQLAlchemy 2.0 style select().

New Dependency: psutil==5.9.7

Required by /system_status/ for server resource metrics.