- 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>
- Add expand_mil_week config (default: 15) for MiL expansion timing
- Add early/late ML and MiL roster limits as config items
- Add offseason roster limits (69/69) for relaxed roster building
- Fix free_agent_team_id to correct value (547)
- Transaction builder now uses config values instead of hard-coded limits
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previously, only the trade initiator could access the trade builder
because lookups used their Discord user ID. Now any GM whose team
participates in a trade can add players, view, and manage the trade.
Changes:
- Add _team_to_trade_key secondary index mapping team IDs to trade keys
- Add get_trade_builder_by_team() for team-based lookups
- Add clear_trade_builder_by_team() for team-based clearing
- Update add_team/remove_team to maintain secondary index
- Refactor 5 trade commands to use team-based lookups
- Add 9 new tests for multi-GM access functionality
🤖 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>
Implemented comprehensive team branding management system allowing team owners
to update colors and logos for major league, minor league, and dice rolls.
Features:
- Modal-based interactive form input with validation
- Hex color validation with normalization (6 chars, optional # prefix)
- Image URL accessibility testing with aiohttp (5 second timeout)
- Preview + confirmation workflow with ConfirmationView
- Support for both major league and minor league affiliate updates
- Dice color customization for game rolls
- Discord role color sync (non-blocking with graceful fallback)
- Comprehensive error handling and user feedback
Technical Implementation:
- BrandingModal class with 5 optional fields
- Concurrent URL validation using asyncio.gather
- Fixed team_service.update_team() to use PATCH with query parameters
- Enhanced TeamService documentation with correct method signatures
- 33 comprehensive tests (100% passing)
Bug Fixes:
- Fixed modal send timing (immediate response vs deferred)
- Fixed interaction handling for cancel button
- Fixed database API communication (PATCH query params vs PUT JSON)
Files:
- commands/teams/branding.py (NEW - ~500 lines)
- commands/teams/__init__.py (added BrandingCommands registration)
- commands/teams/CLAUDE.md (added comprehensive documentation)
- tests/test_commands_teams_branding.py (NEW - 33 tests)
- services/team_service.py (fixed update_team to use query params)
- VERSION (2.19.2 → 2.20.0)
Docker: manticorum67/major-domo-discord-app-v2:2.20.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Corrected API endpoint paths from 'custom_command_creators' to 'custom_commands/creators' to match the database API routing structure.
**Issue**: Users unable to create custom commands due to 404 errors
**Root Cause**: Bot calling /api/v3/custom_command_creators instead of /api/v3/custom_commands/creators
**Solution**: Updated 5 endpoint references in custom_commands_service.py
Fixes:
- Line 547: create_item_in_table() call
- Lines 732, 748: client.put() calls for creator updates
- Lines 762, 768: get_items_from_table_with_params() calls for creator queries
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Initial version: 2.19.1
This file tracks the current version for Docker builds. When building
and pushing new versions, this file will be updated and the commit
will be tagged with the version number.
🤖 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>
The /cc-create command was immediately creating the custom command after the modal
was submitted, instead of waiting for the user to click the "Create Command" button
in the confirmation view.
Issue: Command handler was calling create_command() service immediately after modal
submission, before user confirmed via the preview buttons.
Fix: Removed premature command creation logic from the command handler. The modal's
on_submit method already shows a preview with confirmation buttons, and the
CustomCommandCreateConfirmationView.confirm_create button handler properly creates
the command only when the user clicks "Create Command".
Flow now correctly:
1. User submits modal with command details
2. Preview displays with "Create Command" and "Cancel" buttons
3. Command is only created when user clicks "Create Command" button
4. User can cancel without creating anything
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated the /admin-process-transactions command to follow the proper
service layer architecture instead of accessing API clients directly.
Changes:
- Use transaction_service.get_all_items() to fetch transactions
- Use player_service.update_player_team() to update player rosters
- Work with Transaction model objects instead of raw API dictionaries
- Added player_service import
This follows the established pattern of using service layer methods
for all API interactions, improving code consistency and maintainability.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add /admin-process-transactions command that allows admins to manually
process all transactions for the current week (or a specified week).
This serves as a fallback mechanism if the Monday morning automated
task fails to run transactions.
Features:
- Processes all non-frozen, non-cancelled transactions for a week
- Optional week parameter (defaults to current week)
- Real-time progress updates every 5 transactions
- Detailed success/failure reporting with error details
- Uses same API logic as the automated Monday task
- Includes rate limiting (100ms delay between transactions)
- Comprehensive logging for audit trail
The command is restricted to league administrators via @league_admin_only
decorator and uses @logged_command for standardized logging.
Updated /admin-help to include the new command in the League Management
section.
🤖 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>
## Problem
The weekly freeze/thaw system had a state flag initialization bug that prevented
both Monday freeze operations and Saturday thaw operations from executing.
## Root Cause (Introduced in commit 07f69eb on Oct 25, 2025)
The `weekly_warning_sent` boolean flag was being used for TWO different purposes:
1. Preventing duplicate freeze/thaw operations (state machine)
2. Preventing duplicate error notifications
The flag was initialized to `False`, but the Monday freeze condition required
it to be `True`:
- Line 205: `if ... and self.weekly_warning_sent:` (required True)
- Line 160: `self.weekly_warning_sent = False` (initialized to False)
This created a deadlock:
- Monday freeze: Never ran (flag was False, needed True)
- Saturday thaw: Never ran (freeze flag in DB never set to True)
## Impact
- First failure: Monday October 27, 2025
- Affected weeks: 2+ weeks of missed freeze/thaw operations
- Result: Week did NOT increment, transactions did NOT execute
## Solution
Separated the two concerns and replaced boolean flag with week tracking:
1. **Deduplication**: Track `last_freeze_week` and `last_thaw_week` (int | None)
- Monday: Execute if `last_freeze_week != current.week`
- Saturday: Execute if `last_thaw_week != current.week`
- Prevents duplicate operations during same hour (loop runs every minute)
2. **Error notifications**: Separate `error_notification_sent` boolean flag
- Only used for preventing duplicate error notifications
- Clear separation of concerns
## Validation
Created and ran validation script simulating 7 scenarios across multiple weeks:
- ✅ Monday freeze executes on first check
- ✅ Monday freeze skips on subsequent checks same hour
- ✅ Saturday thaw executes on first check
- ✅ Saturday thaw skips on subsequent checks same hour
- ✅ Next Monday freeze executes for new week
- ✅ Week numbers increment correctly (19→20→21→22)
- ✅ All state transitions work as expected
## Files Changed
- tasks/transaction_freeze.py:157-167 - Separated state tracking from error flags
- tasks/transaction_freeze.py:211-231 - Fixed freeze/thaw conditions with week tracking
- tasks/transaction_freeze.py:248-250 - Updated error notification flag name
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated commands/injuries/CLAUDE.md to reflect playoff week validation:
Documentation Changes:
- Updated /injury set-new parameters to show week range 1-21
- Added "Week and Game Validation" section with playoff-specific limits
- Updated automatic calculations note for variable games per week
- Added playoff examples (weeks 19-21 with proper game numbers)
- Added new "Configuration" section documenting playoff constants
- Added week/game limits table showing all season phases
- Updated Key Improvements to mention playoff support
- Updated Last Updated to October 2025
Validation Details Now Documented:
- Regular Season (Weeks 1-18): 1-4 games per week
- Playoff Round 1 (Week 19): 1-5 games (best of 5)
- Playoff Round 2 (Week 20): 1-7 games (best of 7)
- Playoff Round 3 (Week 21): 1-7 games (best of 7)
Configuration Section:
Documents the playoff constants from config.py and explains:
- How constants are used in views/modals.py validation
- Week/game enforcement logic
- Series types for each playoff round
This complements the config.py changes from commit aad9c00.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added constants to config.py to support playoff week validation:
- playoff_weeks_per_season: 3 (weeks 19-21)
- playoff_round_one_games: 5 (best of 5 series)
- playoff_round_two_games: 7 (best of 7 series)
- playoff_round_three_games: 7 (best of 7 series)
These constants are used in injury roll modals (views/modals.py) to:
1. Allow injury rolls during playoff weeks (extends max_week validation)
2. Validate game numbers based on playoff round (different series lengths)
Validation logic:
- Regular season (weeks 1-18): Max 4 games per week
- Playoff Round 1 (week 19): Max 5 games (best of 5)
- Playoff Round 2 (week 20): Max 7 games (best of 7)
- Playoff Round 3 (week 21): Max 7 games (best of 7)
This ensures injury rolls can be submitted with proper week/game validation
throughout the entire season including playoffs.
🤖 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>
Added 16 tests covering all aspects of injury modal validation including
regular season and playoff-specific game limits.
Test Coverage:
- BatterInjuryModal week validation (5 tests)
* Regular season weeks (1-18) acceptance
* Playoff weeks (19-21) acceptance
* Invalid weeks rejection (0, 22+)
- BatterInjuryModal game validation (6 tests)
* Regular season: games 1-4 valid, game 5+ rejected
* Playoff round 1 (week 19): games 1-5 valid, game 6+ rejected
* Playoff round 2 (week 20): games 1-7 valid
* Playoff round 3 (week 21): games 1-7 valid
- PitcherRestModal validation (4 tests)
* Same week validation as BatterInjuryModal
* Same game validation as BatterInjuryModal
- Config-driven validation (1 test)
* Verifies custom config values are respected
All tests use proper mocking patterns:
- PropertyMock for TextInput.value (read-only property)
- Correct patch paths for config and services
- Complete model data for Pydantic validation
Test Results: 16/16 passing ✅🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed bug where injury rolls during playoff weeks (19-21) were being rejected
with "weeks 1-18 only" error message.
Changes:
- Updated BatterInjuryModal and PitcherRestModal week validation
- Now uses config.weeks_per_season + config.playoff_weeks_per_season for max week
- Added dynamic game validation based on playoff round:
* Regular season (weeks 1-18): 4 games per week
* Playoff round 1 (week 19): 5 games
* Playoff round 2 (week 20): 7 games
* Playoff round 3 (week 21): 7 games
- Replaced hardcoded values with config-based calculations
Config values used:
- weeks_per_season (18)
- playoff_weeks_per_season (3)
- games_per_week (4)
- playoff_round_one_games (5)
- playoff_round_two_games (7)
- playoff_round_three_games (7)
Now injuries can be properly logged during all phases of the season including
playoffs with correct game validation for each round.
🤖 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>
The API now has a DELETE /draftlist/team/{team_id} endpoint
that properly clears a team's draft list.
Updated clear_list() to use the new endpoint instead of trying
to POST an empty list, which was failing with "list index out of range"
error because the API expected at least one entry to determine team_id.
This resolves the "Clear Failed" error when using /draft-list-clear.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Multiple fixes for draft list functionality:
1. **Model Fix (draft_list.py):**
- API returns nested Team and Player objects, not just IDs
- Changed team_id/player_id from fields to @property methods
- Extract IDs from nested objects via properties
- Fixes Pydantic validation errors on GET operations
2. **Service Fix (draft_list_service.py):**
- Override _extract_items_and_count_from_response() for API quirk
- GET returns items under 'picks' key (not 'draftlist')
- Changed add_to_list() return type from single entry to full list
- Return verification list instead of trying to create new DraftList
- Fixes "Failed to add" error from validation issues
3. **Command Enhancement (list.py):**
- Display full draft list on successful add (not just confirmation)
- Show position where player was added
- Reuse existing create_draft_list_embed() for consistency
- Better UX - user sees complete context after adding player
API Response Format:
GET: {"count": N, "picks": [{team: {...}, player: {...}}]}
POST: {"count": N, "draft_list": [{team_id: X, player_id: Y}]}
This resolves:
- Empty list after adding player (Pydantic validation)
- "Add Failed" error despite successful operation
- Poor UX with minimal success feedback
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Root cause: Draft list API has NO individual CRUD endpoints.
Only endpoints available:
- GET (retrieve list)
- POST (bulk replacement - deletes all, inserts new list)
All modification operations (add, remove, clear, reorder, move) were
incorrectly using BaseService CRUD methods (create, delete, patch) which
don't exist for this endpoint.
Fixes:
- add_to_list(): Use bulk replacement with rank insertion logic
- remove_player_from_list(): Rebuild list without player
- clear_list(): POST empty list
- reorder_list(): POST list with new rank order
- move_entry_up(): Swap ranks and POST
- move_entry_down(): Swap ranks and POST
- remove_from_list(): Deprecated (no DELETE endpoint)
All operations now:
1. GET current list
2. Build updated list with modifications
3. POST entire updated list (bulk replacement)
This resolves all draft list modification failures including:
- "Add Failed" when adding players
- Remove operations failing silently
- Reorder/move operations failing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Root cause: API mismatch between bot service and database endpoint.
The draft list POST endpoint uses bulk replacement pattern:
- Expects: {"count": N, "draft_list": [...]}
- Deletes entire team's list
- Inserts all entries in bulk
The bot service was incorrectly using BaseService.create() which sends
a single entry object, causing the API to reject the request.
Fix:
- Rewrite add_to_list() to use bulk replacement pattern
- Get current list
- Add new entry with proper rank insertion
- Shift existing entries if inserting in middle
- POST entire updated list to API
- Return created entry as DraftList object
This resolves "Add Failed" error when adding players to draft queue.
Note: Direct client.post() call is appropriate here since the API
endpoint doesn't follow standard CRUD patterns (uses bulk replacement).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Two critical bugs in draft picks command:
1. Swapped arguments to get_team_by_owner():
- Was passing (season, owner_id)
- Should be (owner_id, season)
- This caused "Not a GM" error for all users
2. Using old field name ping_channel_id:
- Model was updated to use ping_channel
- Draft card posting still used old field name
Fixes:
- commands/draft/picks.py:136-139: Corrected argument order
- commands/draft/picks.py:258-261: Updated to use ping_channel
This resolves the "Not a GM" error when running /draft command.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Root cause: Field naming mismatch between bot model and database schema.
The database stores channel IDs in columns named 'result_channel' and
'ping_channel', but the bot's DraftData model incorrectly used
'result_channel_id' and 'ping_channel_id'.
Additionally, the draft data PATCH endpoint requires query parameters
instead of JSON body (like player, game, transaction, and injury endpoints).
Changes:
- models/draft_data.py: Renamed fields to match database schema
- result_channel_id → result_channel
- ping_channel_id → ping_channel
- services/draft_service.py: Added use_query_params=True to PATCH calls
- views/draft_views.py: Updated embed to use correct field names
- tasks/draft_monitor.py: Updated channel lookups to use correct field names
- tests/test_models.py: Updated test assertions to match new field names
This fixes:
- Channel configuration now saves correctly via /draft-admin channels
- Ping channel settings persist across bot restarts
- Result channel settings persist across bot restarts
- All draft data updates work properly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix Pydantic validation errors when channel IDs are not configured:
Issue:
- result_channel_id and ping_channel_id were required fields
- Database may not have these values configured yet
- /draft-admin info command failed with validation errors
Fixes:
1. models/draft_data.py:
- Make result_channel_id and ping_channel_id Optional[int]
- Update validator to handle None values
- Prevents validation errors on missing channel data
2. views/draft_views.py:
- Handle None channel IDs in admin info embed
- Display "Not configured" instead of invalid channel mentions
- Prevents formatting errors when channels not set
Testing:
- Validated model accepts None for channel IDs
- Validated model accepts int for channel IDs
- Validated model converts string channel IDs to int
- All validation tests pass
This allows draft system to work before channels are configured
via /draft-admin channels command.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement all remaining draft commands for comprehensive draft management:
New Commands:
- /draft-admin (Group) - Admin controls for draft management
* info - View current draft configuration
* timer - Enable/disable draft timer
* set-pick - Set current pick number
* channels - Configure Discord channels
* reset-deadline - Reset pick deadline
- /draft-status - View current draft state
- /draft-on-clock - Detailed "on the clock" information with recent/upcoming picks
- /draft-list - View team's auto-draft queue
- /draft-list-add - Add player to queue
- /draft-list-remove - Remove player from queue
- /draft-list-clear - Clear entire queue
- /draft-board - View draft picks by round
New Files:
- commands/draft/admin.py - Admin commands (app_commands.Group pattern)
- commands/draft/status.py - Status viewing commands
- commands/draft/list.py - Auto-draft queue management
- commands/draft/board.py - Draft board viewing
Features:
- Admin-only permissions for draft management
- FA player autocomplete for draft list
- Complete draft state visibility
- Round-by-round draft board viewing
- Lock status integration
- Timer and deadline management
Updated:
- commands/draft/__init__.py - Register all new cogs and group
All commands use @logged_command decorator for consistent logging and error handling.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add draft command package to bot startup sequence:
- Create setup_draft() function in commands/draft/__init__.py
- Follow standard package pattern with resilient loading
- Import and register in bot.py command packages list
Changes:
- commands/draft/__init__.py: Add setup function and cog exports
- bot.py: Import setup_draft and add to command_packages
The /draft command will now load automatically when the bot starts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Update documentation across services, tasks, and commands:
Services Documentation (services/CLAUDE.md):
- Added Draft System Services section with all three services
- Documented why NO CACHING is used for draft services
- Explained architecture integration (global lock, background monitor)
- Documented hybrid linear+snake draft format
Tasks Documentation (tasks/CLAUDE.md):
- Added Draft Monitor task documentation
- Detailed self-terminating behavior and resource efficiency
- Explained global lock integration with commands
- Documented auto-draft process and channel requirements
Commands Documentation (commands/draft/CLAUDE.md):
- Complete reference for /draft command
- Global pick lock implementation details
- Pick validation flow (7-step process)
- FA player autocomplete pattern
- Cap space validation algorithm
- Race condition prevention strategy
- Troubleshooting guide and common issues
- Integration with background task
- Future commands roadmap
All documentation follows established patterns from existing
CLAUDE.md files with comprehensive examples and code snippets.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement /draft slash command with comprehensive pick validation:
Core Features:
- Global pick lock (asyncio.Lock) prevents concurrent picks
- 30-second stale lock auto-override for crash recovery
- FA player autocomplete with position and sWAR display
- Complete pick validation (GM status, turn order, cap space)
- Player team updates and draft pick recording
- Success/error embeds following EmbedTemplate patterns
Architecture:
- Uses @logged_command decorator (no manual error handling)
- Service layer integration (no direct API access)
- TeamService caching for GM validation (80% API reduction)
- Global lock in cog instance (not database - local only)
- Draft monitor task can acquire same lock for auto-draft
Validation Flow:
1. Check global lock (reject if active pick <30s)
2. Validate user is GM (cached lookup)
3. Get draft state and current pick
4. Validate user's turn or has skipped pick
5. Validate player is FA and cap space available
6. Execute pick with atomic updates
7. Post success and advance to next pick
Ready for /draft-status and /draft-admin commands next.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive embed and UI components for draft system:
- On the clock embed: Shows current pick with team info, deadline, recent/upcoming picks
- Draft status embed: Current state, timer status, lock status
- Player draft card: Player info when drafted
- Draft list embed: Team's auto-draft queue display
- Draft board embed: Round-by-round pick display
- Admin info embed: Detailed configuration for admins
- Error/success embeds: Pick validation feedback
All components follow EmbedTemplate patterns with consistent
styling and proper color usage. Ready for command integration.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>