- Change sWAR formatting from 1 decimal to 2 decimal places across all displays
- Draft on-clock announcements now ping team role (via team.lname) instead of GM
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Root Cause Fixes:
- Add _extract_items_and_count_from_response() override to DraftPickService
to handle API returning 'picks' key instead of 'draftpicks'
- Add custom from_api_data() to DraftPick model to handle API field mapping
(origowner/owner/player -> origowner_id/owner_id/player_id)
Enhancements:
- Add timer status to /draft-admin set-pick success message
- Shows relative deadline timestamp when timer active
- Shows "Timer Inactive" when timer not running
Also includes related draft module improvements from prior work.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add multi-team trade acceptance system requiring all GMs to approve
- TradeBuilder tracks accepted_teams with accept_trade/reject_trade methods
- TradeAcceptanceView with Accept/Reject buttons validates GM permissions
- Create transactions when all teams accept (frozen=false for immediate effect)
- Add post_trade_to_log() for rich trade embeds in #transaction-log
- Trade embeds show grouped player moves by receiving team with sWAR
- Add 10 comprehensive tests for acceptance tracking methods
- All 36 trade builder tests pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove redundant sba_current_season and pd_current_season config values.
All code now uses sba_season and pd_season, which properly read from
environment variables. Fixes /team command defaulting to Season 12.
- Remove duplicate *_current_season constants from config.py
- Update 100+ references across commands, services, and utils
- sba_season defaults to 13, pd_season defaults to 10
- Environment variables SBA_SEASON/PD_SEASON now work correctly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The @requires_team() decorator was incorrectly treating API errors as "no team"
because get_user_team() was catching all exceptions and returning None.
Changes:
1. get_user_team() now propagates exceptions instead of catching them
- Allows callers to distinguish between "no team found" vs "API error"
- Updated docstring to document the exception behavior
2. @requires_team() decorator now has try-except block
- Returns specific error for "no team" (None result)
- Returns helpful error for API/network issues (exception caught)
- Logs exceptions for debugging
3. league_admin_only() decorator enhanced
- Now supports both slash commands (Interaction) and prefix commands (Context)
- Unified error handling for both command types
4. team_service.py and related updates
- Team model field name corrected: team_abbrev -> abbrev
This fixes the regression where /cc-create was failing with "no team" error
when it should have been showing an API error message or working correctly.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements decorator-based permission system to support bot scaling across
multiple Discord servers with different command access requirements.
Key Features:
- @global_command() - Available in all servers
- @league_only() - Restricted to league server only
- @requires_team() - Requires user to have a league team
- @admin_only() - Requires server admin permissions
- @league_admin_only() - Requires admin in league server
Implementation:
- utils/permissions.py - Core permission decorators and validation
- utils/permissions_examples.py - Comprehensive usage examples
- Automatic caching via TeamService.get_team_by_owner() (30-min TTL)
- User-friendly error messages for permission failures
Applied decorators to:
- League commands (league, standings, schedule, team, roster)
- Admin commands (management, league management, users)
- Draft system commands
- Transaction commands (dropadd, ilmove, management)
- Injury management
- Help system
- Custom commands
- Voice channels
- Gameplay (scorebug)
- Utilities (weather)
Benefits:
- Maximum flexibility - easy to change command scopes
- Built-in caching - ~80% reduction in API calls
- Combinable decorators for complex permissions
- Clean migration path for existing commands
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Created utils/dice_utils.py with reusable dice rolling functions
- DiceRoll dataclass for roll results
- parse_and_roll_multiple_dice() for multiple dice notation
- parse_and_roll_single_dice() for single dice notation
- Graceful error handling with empty list returns
- Refactored commands/dice/rolls.py to use new utility module
- Removed duplicate DiceRoll class and parsing methods
- Updated all method calls to use standalone functions
- Added new /d20 command for quick d20 rolls
- Fixed fielding prefix command to include d100 roll
- Updated tests/test_commands_dice.py
- Updated imports to use utils.dice_utils
- Fixed all test calls to use standalone functions
- Added comprehensive test for /d20 command
- All 35 tests passing
- Updated utils/CLAUDE.md documentation
- Added Dice Utilities section with full API reference
- Documented functions, usage patterns, and design benefits
- Listed all commands using dice utilities
Benefits:
- Reusability: Dice functions can be imported by any command file
- Maintainability: Centralized dice logic in one place
- Testability: Functions testable independent of command cogs
- Consistency: All dice commands use same underlying logic
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed critical bug where win probability progress bar displayed backwards:
- Away team with 75% win probability was showing as losing
- Home team with 25% win probability was showing as winning
Changes:
- Corrected comparison operators in create_team_progress_bar() function
- Enhanced UX by positioning percentage next to winning team:
* Home winning (>50%): Percentage on right (e.g., "POR ░▓▓▓▓▓▓▓▓▓► WV 95.0%")
* Away winning (<50%): Percentage on left (e.g., "75.0% POR ◄▓▓▓▓▓▓▓▓░░ WV")
* Even game (=50%): Percentage on both sides
- Added comprehensive test suite with 10 test cases covering all scenarios
- Updated docstring examples to reflect new format
All tests passing (10/10) ✅🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented automatic posting of transaction notifications to #transaction-log
channel when transactions are submitted via /dropadd or /ilmove commands.
**New Utility:**
- `utils/transaction_logging.py` - Centralized transaction logging function
- `post_transaction_to_log()` - Posts transaction embed to #transaction-log
- Uses team's ML affiliate for consistent branding
- Displays team thumbnail, colors, and player moves
- Shows season from transaction data (not hardcoded)
- Format matches legacy transaction log embeds
**Integration Points:**
- `/dropadd` (scheduled transactions) - Posts when submitted
- `/ilmove` (immediate transactions) - Posts when executed
- Both use shared `post_transaction_to_log()` function
**Embed Format:**
```
Week 18 Transaction
[Team Name]
Player Moves:
- **PlayerName** (sWAR) from OLDTEAM to NEWTEAM
- **PlayerName** (sWAR) from OLDTEAM to NEWTEAM
[Team Thumbnail]
Footer: "SBa Season 12" with SBA logo
```
**Features:**
- Automatic ML affiliate lookup for consistent team display
- Team colors and thumbnails in embeds
- Season number from transaction data
- Graceful error handling (logs warnings, doesn't block submission)
- Matches legacy embed format exactly
**Files Changed:**
- NEW: `utils/transaction_logging.py` - Transaction logging utility
- MODIFIED: `views/transaction_embed.py` - Added logging calls on submission
**Testing:**
- Transaction builder tests pass (31/31)
- No new test failures introduced
- Logging is non-blocking (submission succeeds even if logging fails)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Created utils/scorebug_helpers.py with shared scorebug functions
- create_scorebug_embed(): Unified embed creation for command and background task
- create_team_progress_bar(): Win probability visualization
- Fixed win probability bar to show dark blocks weighted toward winning team
- Arrow extends from the side with advantage
- Home winning: "POR ░▓▓▓▓▓▓▓▓▓► WV 95.0%"
- Away winning: "POR ◄▓▓▓▓▓▓▓░░░ WV 30.0%"
- Changed embed color from score-based to win probability-based
- Embed shows color of team favored to win, not necessarily winning
- Creates fun psychological element showing momentum/advantage
- Added dynamic channel visibility for #live-sba-scores
- Channel visible to @everyone when active games exist
- Channel hidden when no games are active
- Bot retains access via role permissions
- Added set_channel_visibility() to utils/discord_helpers.py
- Eliminated ~220 lines of duplicate code across files
- Removed duplicate embed creation from commands/gameplay/scorebug.py
- Removed duplicate embed creation from tasks/live_scorebug_tracker.py
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
App Version: 2.0.4
Created reusable text_utils module with split_text_for_fields() function
to handle rare play results that exceed Discord's 1024 character field limit.
Changes:
- New utils/text_utils.py with intelligent text splitting on delimiters
- Updated commands/dice/rolls.py to split long rare play results into multiple fields
- Automatic part indicators for multi-chunk results (e.g., "Part 1/2")
- Handles outfield rare plays (~1135 chars) by splitting into 2 fields
- Maintains single field for shorter infield/pitcher rare plays
Benefits:
- Fixes Discord field limit issue for outfield rare plays
- Reusable utility for any future long-text scenarios
- Clean breaks on semantic boundaries (between result types)
- No multiple embeds needed - everything in single embed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adding 17 CLAUDE.md files across the project to provide detailed context
and implementation guidelines for AI development agents:
Root Documentation:
- CLAUDE.md - Main project guide with Git workflow requirements
Component Documentation:
- commands/CLAUDE.md - Command architecture and patterns
- models/CLAUDE.md - Pydantic models and validation
- services/CLAUDE.md - Service layer and API interactions
- tasks/CLAUDE.md - Background tasks and automation
- tests/CLAUDE.md - Testing strategies and patterns
- utils/CLAUDE.md - Utility functions and decorators
- views/CLAUDE.md - Discord UI components and embeds
Command Package Documentation:
- commands/help/CLAUDE.md - Help system implementation
- commands/injuries/CLAUDE.md - Injury management commands
- commands/league/CLAUDE.md - League-wide commands
- commands/players/CLAUDE.md - Player information commands
- commands/profile/CLAUDE.md - User profile commands
- commands/teams/CLAUDE.md - Team information commands
- commands/transactions/CLAUDE.md - Transaction management
- commands/utilities/CLAUDE.md - Utility commands
- commands/voice/CLAUDE.md - Voice channel management
Key Updates:
- Updated .gitignore to track CLAUDE.md files in version control
- Added Git Workflow section requiring branch-based development
- Documented all architectural patterns and best practices
- Included comprehensive command/service implementation guides
These files provide essential context for AI agents working on the codebase,
ensuring consistent patterns, proper error handling, and maintainable code.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements full Google Sheets scorecard submission with:
- Complete game data extraction (68 play fields, pitching decisions, box score)
- Transaction rollback support at 3 states (plays/game/complete)
- Duplicate game detection with confirmation dialog
- Permission-based submission (GMs only)
- Automated results posting to news channel
- Automatic standings recalculation
- Key plays display with WPA sorting
New Components:
- Play, Decision, Game models with full validation
- SheetsService for Google Sheets integration
- GameService, PlayService, DecisionService for data management
- ConfirmationView for user confirmations
- Discord helper utilities for channel operations
Services Enhanced:
- StandingsService: Added recalculate_standings() method
- CustomCommandsService: Fixed creator endpoint path
- Team/Player models: Added helper methods for display
Configuration:
- Added SHEETS_CREDENTIALS_PATH environment variable
- Added SBA_NETWORK_NEWS_CHANNEL and role constants
- Enabled pygsheets dependency
Documentation:
- Comprehensive README updates across all modules
- Added command, service, model, and view documentation
- Detailed workflow and error handling documentation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed issue where key plays were showing the score twice:
- Before: "Top 3: Player (NYY) homers, NYY up 2-0, NYY up 2-0"
- After: "Top 3: Player (NYY) homers, NYY up 2-0"
Changes:
- Simplified Play.descriptive_text() to use rbi for score calculation
- Removed duplicate score logic in format_key_plays() helper
- Now only shows score after the play is completed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Update CacheManager.get() and CacheManager.set() type annotations to
accept Any JSON-serializable type (dict, list, str, int, bool, None)
instead of just dict.
This fixes type checker warnings in base_service.py where lists are
cached for API responses. The runtime behavior was already correct,
this just aligns the type hints with actual usage.
Changes:
- CacheManager.get() return type: Optional[dict] -> Optional[Any]
- CacheManager.set() data param: dict -> Any
- Updated docstrings to clarify JSON-serializable types
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major fixes and improvements:
Trade System Fixes:
- Fix duplicate player moves in trade embed Player Exchanges section
- Resolve "WVMiL not participating" error for Minor League destinations
- Implement organizational authority model for ML/MiL/IL team relationships
- Update Trade.cross_team_moves to deduplicate using moves_giving only
Team Model Enhancements:
- Rewrite roster_type() method using sname as definitive source per spec
- Fix edge cases like "BHMIL" (Birmingham IL) vs "BHMMIL"
- Update _get_base_abbrev() to use consistent sname-based logic
- Add organizational lookup support in trade participation
Autocomplete System:
- Fix major_league_team_autocomplete invalid roster_type parameter
- Implement client-side filtering using Team.roster_type() method
- Add comprehensive test coverage for all autocomplete functions
- Centralize autocomplete logic to shared utils functions
Test Infrastructure:
- Add 25 new tests for trade models and trade builder
- Add 13 autocomplete function tests with error handling
- Fix existing test failures with proper mocking patterns
- Update dropadd tests to use shared autocomplete functions
Documentation Updates:
- Document trade model enhancements and deduplication fix
- Add autocomplete function documentation with usage examples
- Document organizational authority model and edge case handling
- Update README files with recent fixes and implementation notes
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major Features Added:
• Admin Management System: Complete admin command suite with user moderation, system control, and bot maintenance tools
• Enhanced Player Commands: Added batting/pitching statistics with concurrent API calls and improved embed design
• League Standings: Full standings system with division grouping, playoff picture, and wild card visualization
• Game Schedules: Comprehensive schedule system with team filtering, series organization, and proper home/away indicators
New Admin Commands (12 total):
• /admin-status, /admin-help, /admin-reload, /admin-sync, /admin-clear
• /admin-announce, /admin-maintenance
• /admin-timeout, /admin-untimeout, /admin-kick, /admin-ban, /admin-unban, /admin-userinfo
Enhanced Player Display:
• Team logo positioned beside player name using embed author
• Smart thumbnail priority: fancycard → headshot → team logo fallback
• Concurrent batting/pitching stats fetching for performance
• Rich statistics display with team colors and comprehensive metrics
New Models & Services:
• BattingStats, PitchingStats, TeamStandings, Division, Game models
• StatsService, StandingsService, ScheduleService for data management
• CustomCommand system with CRUD operations and cleanup tasks
Bot Architecture Improvements:
• Admin commands integrated into bot.py with proper loading
• Permission checks and safety guards for moderation commands
• Enhanced error handling and comprehensive audit logging
• All 227 tests passing with new functionality
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add @logged_command decorator in utils/decorators.py to eliminate try/catch/finally boilerplate
- Migrate all Discord commands to use new decorator pattern:
* commands/league/info.py - /league command
* commands/players/info.py - /player command
* commands/teams/info.py - /team and /teams commands
* commands/teams/roster.py - /roster command
- Fix PyLance type issues by making model IDs required for database entities
- Update Player and Team models to require id field since they come from database
- Fix test cases to provide required id values
- Add comprehensive test coverage for decorator functionality
- Add migration guide for applying decorator to additional commands
- Reduce codebase by ~100 lines of repetitive logging boilerplate
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Complete rebuild of the Discord bot with modern architecture including:
- Modular API client with proper error handling
- Clean separation of models, services, and commands
- Comprehensive test coverage with pytest
- Structured logging and configuration management
- Organized command structure for scalability
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>