- Added missing await keyword on line 2981 in logic_gameplay.py
- SPD hit result was calling singles() without await, causing RuntimeWarning
- All groundball tests passing (24/24)
- Bump version to 1.7.7
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Bug: The is_game_over() function contained a debug print statement that was
printing "1: " to stdout on every call. This was causing massive log spam
in Docker container output (thousands of lines) and making it difficult to
diagnose actual issues.
Fix: Remove the print(f'1: ') statement from line 3251.
Bumps version to 1.7.4
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previously, if get_card_or_none returned None (when a card ID from the
Google Sheet doesn't exist in the database), the code would create a
RosterLink with card=None, causing card_id to be null which violates
the NOT NULL constraint on the primary key.
Now we check if this_card is None before creating the RosterLink and
raise a CardNotFoundException with a helpful error message to guide
the user to fix their roster sheet.
Fixes the error: null value in column "card_id" of relation "rosterlink"
violates not-null constraint
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements defensive error handling for WPA (Win Probability Added) calculations when rare game states are missing from the static lookup table. The safe_wpa_lookup() function uses a three-tier fallback strategy: exact lookup, bases-empty fallback, and 0.0 default value.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Handle gamestates without full lineups
Added /set command for lineup and SP
Fixed uncapped hit bugs
Added league_name property to Games
Fix get_team for gauntlets
Fixed SelectSP dropdown bug