PR #106 added await to scorecard_tracker calls but the tracker
methods were still sync, causing TypeError in production:
- /scorebug: "object NoneType can't be used in 'await' expression"
- live_scorebug_tracker: "object list can't be used in 'await' expression"
Also fixes 5 missing awaits in cleanup_service.py and updates tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The data/ volume was mounted :ro to protect Google Sheets credentials,
but this also prevented all state trackers from persisting JSON files
(scorecards, voice channels, trade channels, soak data), causing silent
save failures and stale data accumulating across restarts.
- Mount only the credentials file as :ro (file-level mount)
- Add a separate :rw storage/ volume for runtime state files
- Move all tracker default paths from data/ to storage/
- Add STATE_HOST_PATH env var (defaults to ./storage)
- Update SHEETS_CREDENTIALS_HOST_PATH semantics: now a file path
(e.g. ./data/major-domo-service-creds.json) instead of a directory
- Add storage/ to .gitignore
Closes#85
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
#40: ScorecardTracker cached data in memory at startup — background task never
saw newly published scorecards. Fixed by reloading from disk on every read.
#39: Win percentage defaulted to 50% when unavailable, showing a misleading
50/50 bar. Now defaults to None with "unavailable" message in embed. Parsing
handles decimal (0.75), percentage string, and empty values. Also fixed
orientation bug where win% was always shown as home team's even when the
sheet reports the away team as the leader.
Additionally: live scorebug tracker now distinguishes between "all games
confirmed final" and "sheet read failures" — transient Google Sheets errors
no longer hide the live scores channel.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This enhancement automatically unpublishes scorecards when their associated
voice channels are deleted by the cleanup service, ensuring data synchronization
and reducing unnecessary API calls to Google Sheets for inactive games.
Implementation:
- Added gameplay commands package with scorebug/scorecard functionality
- Created ScorebugService for reading live game data from Google Sheets
- VoiceChannelTracker now stores text_channel_id for voice-to-text association
- VoiceChannelCleanupService integrates ScorecardTracker for automatic cleanup
- LiveScorebugTracker monitors published scorecards and updates displays
- Bot initialization includes gameplay commands and live scorebug tracker
Key Features:
- Voice channels track associated text channel IDs
- cleanup_channel() unpublishes scorecards during normal cleanup
- verify_tracked_channels() unpublishes scorecards for stale entries on startup
- get_voice_channel_for_text_channel() enables reverse lookup
- LiveScorebugTracker logging improved (debug level for missing channels)
Testing:
- Added comprehensive test coverage (2 new tests, 19 total pass)
- Tests verify scorecard unpublishing in cleanup and verification scenarios
Documentation:
- Updated commands/voice/CLAUDE.md with scorecard cleanup integration
- Updated commands/gameplay/CLAUDE.md with background task integration
- Updated tasks/CLAUDE.md with automatic cleanup details
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>