Add comprehensive "soaking" easter egg feature that detects mentions
and responds with GIFs showing escalating disappointment based on
recency (reversed from legacy - more recent = more disappointed).
Features:
- Detects "soak", "soaking", "soaked", "soaker" (case-insensitive)
- 7 disappointment tiers with 5 varied search phrases each
- Giphy API integration with Trump filter and fallback handling
- JSON-based persistence tracking all mentions with history
- /lastsoak command showing detailed information
- 25 comprehensive unit tests (all passing)
Architecture:
- commands/soak/giphy_service.py - Tiered GIF fetching
- commands/soak/tracker.py - JSON persistence with history
- commands/soak/listener.py - Message detection and response
- commands/soak/info.py - /lastsoak info command
- tests/test_commands_soak.py - Full test coverage
Uses existing Giphy API key from legacy implementation.
Zero new dependencies, follows established patterns.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added defensive error handling to prevent crashes when custom command
creators are missing from the database.
Changes Made:
1. services/custom_commands_service.py:
- Added try/except blocks in get_popular_commands()
- Added try/except blocks in get_commands_needing_warning()
- Added try/except blocks in get_commands_eligible_for_deletion()
- Catches BotException when get_creator_by_id() fails
- Logs warning with command details and continues processing
- Skips problematic commands instead of failing entire operation
2. commands/help/main.py:
- Removed redundant emoji from success message title
- EmbedTemplate.success() already includes check mark emoji
3. tests/test_models_help_command.py:
- Updated test assertions to match new message format
4. tests/test_services_help_commands.py:
- Updated test expectations for error handling behavior
Impact:
- Prevents service crashes when creator data is orphaned or deleted
- Maintains functionality for commands with valid creator data
- Provides visibility into data integrity issues via warning logs
- Ensures automated cleanup tasks can complete successfully
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The /set-image command was failing to persist player image updates to the
database. Investigation revealed a mismatch between how the bot sent PATCH
data versus how the database API expected it.
Root Cause:
- Database API endpoint (/api/v3/players/{id}) expects PATCH data as URL
query parameters, not JSON body
- Bot was sending: PATCH /api/v3/players/12288 {"vanity_card": "url"}
- API expected: PATCH /api/v3/players/12288?vanity_card=url
Changes Made:
1. api/client.py:
- Added use_query_params parameter to patch() method
- When enabled, sends data as URL query parameters instead of JSON body
- Maintains backward compatibility (defaults to JSON body)
2. services/base_service.py:
- Added use_query_params parameter to patch() method
- Passes parameter through to API client
3. services/player_service.py:
- Updated update_player() to use use_query_params=True
- Added documentation note about query parameter requirement
4. commands/profile/images.py:
- Fixed autocomplete to use correct utility function
- Changed from non-existent player_autocomplete_with_team_priority
- Now uses player_autocomplete from utils/autocomplete.py
Documentation Updates:
5. commands/profile/README.md:
- Updated API Integration section
- Documented PATCH endpoint uses query parameters
- Added note about automatic handling in player_service
6. services/README.md:
- Added PATCH vs PUT operations documentation
- Documented use_query_params parameter
- Included usage examples for both modes
Testing:
- Verified /set-image command now successfully persists image URLs
- Confirmed API returns updated player with vanity_card populated
- Validated both fancy-card and headshot updates work correctly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add /set-image command for updating player fancy cards and headshots.
Features:
- Single command with fancy-card/headshot choice parameter
- Comprehensive URL validation (format + accessibility testing)
- Permission system (users can edit org players, admins can edit all)
- Preview embed with confirmation dialog before database update
- Player name autocomplete prioritizing user's team
- HTTP HEAD request to verify URL accessibility and content-type
Implementation:
- New commands/profile/ package with ImageCommands cog
- Two-stage URL validation (format check + accessibility test)
- Permission checking via Team.is_same_organization()
- Interactive confirmation view with 180s timeout
- Updates player.vanity_card or player.headshot field
Testing:
- 23 comprehensive tests covering validation and permissions
- Uses aioresponses for HTTP mocking (project standard)
- Test coverage for admin/user permissions and organization checks
Documentation:
- Comprehensive README.md with usage guide and troubleshooting
- Updated PRE_LAUNCH_ROADMAP.md to mark feature complete
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive admin-managed help system for league documentation,
resources, FAQs, and guides. Replaces planned /links command with a
more flexible and powerful solution.
Features:
- Full CRUD operations via Discord commands (/help, /help-create, /help-edit, /help-delete, /help-list)
- Permission-based access control (admins + Help Editor role)
- Markdown-formatted content with category organization
- View tracking and analytics
- Soft delete with restore capability
- Full audit trail (creator, editor, timestamps)
- Autocomplete for topic discovery
- Interactive modals and paginated list views
Implementation:
- New models/help_command.py with Pydantic validation
- New services/help_commands_service.py with full CRUD API integration
- New views/help_commands.py with interactive modals and views
- New commands/help/ package with command handlers
- Comprehensive README.md documentation in commands/help/
- Test coverage for models and services
Configuration:
- Added HELP_EDITOR_ROLE_NAME constant to constants.py
- Updated bot.py to load help commands
- Updated PRE_LAUNCH_ROADMAP.md to mark system as complete
- Updated CLAUDE.md documentation
Requires database migration for help_commands table.
See .claude/DATABASE_MIGRATION_HELP_COMMANDS.md for details.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add /weather command with smart team resolution and D20 rolling system
- Add /charts command with autocomplete and category organization
- Implement ChartService for JSON-based chart management
- Add comprehensive test coverage for new commands
- Update test factories with complete model fixtures
- Enhance voice channel tracker with improved logging
- Update PRE_LAUNCH_ROADMAP.md to reflect completed features
- Minor improvements to imports and service initialization
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit fixes two critical bugs in the trade system and adds a new
feature for automatic channel updates.
## Bug Fixes
### 1. Trade Channel Creation Permission Error (Discord API 50013)
**Issue**: Trade channels failed to create with "Missing Permissions" error
**Root Cause**: Bot was attempting to grant itself manage_channels and
manage_permissions in channel-specific overwrites. Discord prohibits bots
from self-granting elevated permissions in channel overwrites.
**Fix**: Removed manage_channels and manage_permissions from bot's
channel-specific overwrites in trade_channels.py. Server-level permissions
are sufficient for all channel management operations.
**Files Changed**:
- commands/transactions/trade_channels.py (lines 74-77)
### 2. TeamService Method Name AttributeError
**Issue**: Bot crashed with AttributeError when adding players to trades
**Root Cause**: Code called non-existent method team_service.get_team_by_id()
The correct method name is team_service.get_team()
**Fix**: Updated method call in trade_builder.py and all test mocks
**Files Changed**:
- services/trade_builder.py (line 201)
- tests/test_services_trade_builder.py (all test mocks)
## New Features
### Smart Trade Channel Updates
**Feature**: When trade commands are executed outside the dedicated trade
channel, the trade embed is automatically posted to the trade channel
(non-ephemeral) for visibility to all participants.
**Behavior**:
- Commands in trade channel: Only ephemeral response to user
- Commands outside trade channel: Ephemeral response + public post to channel
- Applies to: /trade add-team, /trade add-player, /trade supplementary, /trade view
**Implementation**:
- Added _get_trade_channel() helper method
- Added _is_in_trade_channel() helper method
- Added _post_to_trade_channel() helper method
- Updated 4 trade commands to use smart posting logic
**Files Changed**:
- commands/transactions/trade.py (new helper methods + 4 command updates)
## Documentation Updates
Updated comprehensive documentation for:
- Trade channel permission requirements and troubleshooting
- TeamService correct method names with examples
- Smart channel update feature and behavior
- Bug fix details and prevention strategies
**Files Changed**:
- commands/transactions/README.md
- services/README.md
## Testing
- All 18 trade builder tests pass
- Updated test assertions to match new error message format
🤖 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>
This commit implements significant improvements to the transaction management system:
**Major Changes:**
1. Enhanced /dropadd command workflow:
- All responses are now ephemeral for better user privacy
- Every call now shows the transaction builder (not just first move)
- Improved autocomplete with team context prioritization (user's players first)
2. Added team ownership validation:
- Prevents adding players from other teams (except Free Agents with abbrev='FA')
- Enhanced error messages with specific team information
- Changed _add_quick_move return type to tuple[bool, str] for better error handling
3. Removed redundant /transactionstatus command:
- Command functionality fully replaced by /dropadd without parameters
- Simplified workflow reduces user confusion
- All related tests updated accordingly
**Technical Improvements:**
- Enhanced player autocomplete with team prioritization and better formatting
- Improved roster detection logic checking actual roster data vs team_id
- Better error handling with specific, actionable error messages
- Updated all test cases to handle new tuple return types
- Added comprehensive test coverage for team ownership validation
**Test Coverage:**
- All 30 tests passing (17 dropadd + 13 transaction embed tests)
- New tests for team ownership validation scenarios
- Updated existing tests for new return type patterns
The /dropadd command now serves as the single point of entry for all transaction operations while providing a cleaner, more intuitive user experience.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Update voice channel commands to require Major League team ownership for both public and private channels:
## Key Changes
- **Major League Team Validation**: Added `_get_user_major_league_team()` method to filter teams by `RosterType.MAJOR_LEAGUE`
- **Enhanced Requirements**: Both `/voice-channel public` and `/voice-channel private` now require Major League team ownership
- **Improved Error Messages**: Updated error messages to clearly indicate Major League team requirement
- **Schedule Integration**: Private channels now properly validate Major League teams for weekly game schedules
## Technical Implementation
- **Team Filtering**: Uses `team.roster_type() == RosterType.MAJOR_LEAGUE` to identify 3-character abbreviation teams
- **Service Integration**: Leverages existing team service and roster type logic from team model
- **Backward Compatibility**: Maintains existing `_get_user_team()` method for potential future use
## Team Type Validation
- **Major League**: 3-character abbreviations (NYY, BOS, LAD) - **Required for voice channels**
- **Minor League**: 4+ characters ending in "MIL" (NYYMIL, BOSMIL) - **Not eligible**
- **Injured List**: Ending in "IL" (NYYIL, BOSIL) - **Not eligible**
## Updated Tests
- **Mock Team Updates**: Added `roster_type()` method mocking to test team objects
- **Async Service Mocking**: Fixed team service mocks to return proper async results
- **Error Message Assertions**: Updated test assertions for new error messages
- **Type Safety**: Enhanced mock objects with proper Discord voice channel specifications
## Documentation Updates
- **README.md**: Added comprehensive team validation logic explanation
- **Architecture Documentation**: Detailed team type requirements and rationale
- **Code Examples**: Included implementation snippets for team filtering logic
**Rationale**: Voice channels are for scheduled gameplay between Major League teams. Minor League and Injured List teams don't participate in weekly games, so restricting access ensures proper schedule integration.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive voice channel system for Discord gameplay with:
## New Features
- `/voice-channel public` - Create public voice channels with random codenames
- `/voice-channel private` - Create private team vs team channels with role permissions
- Automatic cleanup after configurable empty duration (default: 5 minutes)
- Restart-resilient JSON persistence for channel tracking
- Background monitoring service with graceful error handling
## Technical Implementation
- **Voice Commands Package** (`commands/voice/`)
- `channels.py` - Main slash command implementation with modern command groups
- `cleanup_service.py` - Background service for automatic channel deletion
- `tracker.py` - JSON-based persistent channel tracking
- `__init__.py` - Package setup with resilient loading
- **Bot Integration** - Voice cleanup service integrated into bot lifecycle
- **Service Dependencies** - Integration with team, league, and schedule services
- **Permission System** - Team-based Discord role permissions for private channels
## Key Features
- **Public Channels**: Random codenames, open speaking permissions
- **Private Channels**: "{Away} vs {Home}" naming, team role restrictions
- **Auto-cleanup**: Configurable intervals with empty duration thresholds
- **Restart Resilience**: JSON file persistence survives bot restarts
- **Error Handling**: Comprehensive validation and graceful degradation
- **Migration Support**: Deprecated old prefix commands with helpful messages
## Documentation & Testing
- Comprehensive README.md following project patterns
- Full test suite with 15+ test methods covering all scenarios
- Updated CLAUDE.md files with voice command documentation
- Clean IDE diagnostics with proper type safety
## Integration Points
- Team service for user validation and role lookup
- League service for current season/week information
- Schedule service for opponent detection in private channels
- Background task management in bot startup/shutdown
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements comprehensive dice rolling system for gameplay:
## New Features
- `/roll` and `!roll` commands for XdY dice notation with multiple roll support
- `/ab` and `!atbat` commands for baseball at-bat dice shortcuts (1d6;2d6;1d20)
- `/fielding` and `!f` commands for Super Advanced fielding with full position charts
## Technical Implementation
- Complete dice command package in commands/dice/
- Full range and error charts for all 8 defensive positions (1B,2B,3B,SS,LF,RF,CF,C)
- Pre-populated position choices for user-friendly slash command interface
- Backwards compatibility with prefix commands (!roll, !r, !dice, !ab, !atbat, !f, !fielding, !saf)
- Type-safe implementation following "Raise or Return" pattern
## Testing & Quality
- 30 comprehensive tests with 100% pass rate
- Complete test coverage for all dice functionality, parsing, validation, and error handling
- Integration with bot.py command loading system
- Maintainable data structures replacing verbose original implementation
## User Experience
- Consistent embed formatting across all commands
- Detailed fielding results with range and error analysis
- Support for complex dice combinations and multiple roll formats
- Clear error messages for invalid inputs
🤖 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>