Commit Graph

184 Commits

Author SHA1 Message Date
Cal Corum
7e041ef175
Merge pull request #18 from calcorum/feature/trade-multi-gm-access
Add trade acceptance workflow with transaction logging (v2.22.0)
2025-12-04 14:03:45 -06:00
Cal Corum
b6b403b8d5 Update transaction docs for trade acceptance workflow
- Document trade acceptance workflow added in v2.22.0
- Add trade transaction logging documentation
- Update workflow steps to include Accept/Reject UI
- Move completed features from Future to Recent Enhancements

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 13:57:17 -06:00
Cal Corum
b8b55e90a3 Add trade acceptance workflow with transaction logging (v2.22.0)
- 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>
2025-12-04 13:46:10 -06:00
Cal Corum
55c56bee76 Add configurable roster limits with offseason support
- 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>
2025-12-04 11:06:36 -06:00
Cal Corum
9aba3074c6 Add multi-GM trade access via dual-key indexing
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>
2025-12-04 10:36:48 -06:00
Cal Corum
1d6fef51ab Consolidate season config variables to single source (v2.21.0)
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>
2025-12-02 16:12:16 -06:00
Cal Corum
5133dc3d0f Add /branding command for team color/logo management (v2.20.0)
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>
2025-11-25 10:39:52 -06:00
Cal Corum
570f2e5e5a Fix /cc-create endpoint path mismatch (v2.19.2)
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>
2025-11-24 21:20:28 -06:00
Cal Corum
feff5b5a2b Add VERSION file for docker build tracking
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>
2025-11-15 09:24:36 -06:00
Cal Corum
0fb80d5804
Merge pull request #16 from calcorum/bugfix/cc-create-double-creation
Bugfix/cc create double creation
2025-11-14 09:47:52 -06:00
Cal Corum
0c001b6dab Fix @requires_team decorator API error handling
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>
2025-11-14 09:31:14 -06:00
Cal Corum
bb82e56355 Fix /cc-create command creating twice instead of waiting for confirmation
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>
2025-11-14 08:28:45 -06:00
Cal Corum
8d6bc1c681 Update league_management.py
Pylance cleanup
2025-11-06 22:11:56 -06:00
Cal Corum
90f6bea858 Transaction command name cleanup 2025-11-06 22:10:38 -06:00
Cal Corum
244558175a Pylance cleanup 2025-11-06 21:55:20 -06:00
Cal Corum
3583cbb92c
Merge pull request #15 from calcorum/claude/admin-command-weekly-transactions-011CUsYbhHsFWsL883TCv9tA
CLAUDE: Add admin command to manually process weekly transactions
2025-11-06 21:52:31 -06:00
Cal Corum
cbd501e8e5 VS Code Settings 2025-11-06 21:50:47 -06:00
Claude
8c7df1044d
CLAUDE: Refactor admin-process-transactions to use service layer
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>
2025-11-07 03:36:52 +00:00
Claude
07f93a6795
CLAUDE: Add admin command to manually process weekly transactions
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>
2025-11-07 00:03:32 +00:00
Cal Corum
8b77da51d8 CLAUDE: Add flexible permission system for multi-server support
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>
2025-11-06 11:29:29 -06:00
Cal Corum
dc8b68b64d
Merge pull request #14 from calcorum/claude/investigate-monday-thaw-failure-011CUpu7tUE4P8qeTwRZhfYW 2025-11-05 13:31:09 -06:00
Claude
57b4dc0ce9
CLAUDE: Fix critical bug preventing Monday freeze/thaw from executing
## 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>
2025-11-05 17:56:44 +00:00
Cal Corum
1286a5952b
Merge pull request #13 from calcorum/dev-daily
Dev daily
2025-10-29 13:53:01 -05:00
Cal Corum
1f2b3e58ed All pings on /cc 2025-10-29 13:00:14 -05:00
Cal Corum
a26d1bccd6 CLAUDE: Update injury commands documentation for playoff support
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>
2025-10-29 01:48:15 -05:00
Cal Corum
4abbb8e6b5
Merge pull request #12 from calcorum/dev-daily
Dev daily
2025-10-29 01:23:39 -05:00
Cal Corum
aad9c00b1a CLAUDE: Add playoff configuration constants for injury roll validation
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>
2025-10-29 01:20:13 -05:00
Cal Corum
9991b5f4a0 CLAUDE: Refactor dice rolling into reusable utility module and add /d20 command
- 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>
2025-10-29 01:15:11 -05:00
Cal Corum
15d0513740 CLAUDE: Add comprehensive tests for injury modal playoff week validation
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>
2025-10-29 01:00:57 -05:00
Cal Corum
2bfc87ac1b CLAUDE: Fix injury roll validation to support playoff weeks
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>
2025-10-29 00:56:39 -05:00
Cal Corum
87fb4491a9 CLAUDE: Fix scorebug win probability display logic and enhance percentage positioning
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>
2025-10-29 00:39:41 -05:00
Cal Corum
32a6773dbc
Merge pull request #11 from calcorum/main
Dev-Daily catchup to Main
2025-10-29 00:21:03 -05:00
Cal Corum
70d865ddc1
Merge pull request #10 from calcorum/bug(transactions)-weekly-moves
Bug(transactions) weekly moves
2025-10-29 00:17:22 -05:00
Cal Corum
03baf3a031 Follow-up updates for bug fix
Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 14:28:33 -05:00
Cal Corum
6cf6dfc639 CLAUDE: Automate player roster updates in transaction freeze/thaw system
Implements automatic player team updates during Monday freeze period when
week increments. Previously, player roster updates required manual PATCH
requests after transaction processing.

## Changes Made

### Implementation (tasks/transaction_freeze.py)
- Added asyncio import for rate limiting
- Created _execute_player_update() helper method (lines 447-511)
  - Executes PATCH /players/{id}?team_id={new_team} via API
  - Comprehensive logging with player/team context
  - Returns boolean success/failure status
- Updated _run_transactions() to execute player PATCHes (lines 348-379)
  - Processes ALL transactions for new week (regular + frozen winners)
  - 100ms rate limiting between requests
  - Success/failure tracking with detailed logs

### Timing
- Monday 00:00: Week increments, freeze begins, **player PATCHes execute**
- Monday-Saturday: Teams submit frozen transactions (no execution)
- Saturday 00:00: Resolve contests, update DB records only
- Next Monday: Winning frozen transactions execute as part of new week

### Performance
- Rate limiting: 100ms between requests (prevents API overload)
- Typical execution: 31 transactions = ~3.1 seconds
- Graceful failure handling: Continues processing on individual errors

### Documentation
- Updated tasks/CLAUDE.md with implementation details
- Created TRANSACTION_EXECUTION_AUTOMATION.md with:
  - Complete implementation guide
  - Week 19 manual execution example (31 transactions, 100% success)
  - Error handling strategies and testing approaches

### Test Fixes (tests/test_tasks_transaction_freeze.py)
Fixed 10 pre-existing test failures:
- Fixed unfreeze/cancel expecting moveid not id (3 tests)
- Fixed AsyncMock coroutine issues in notification tests (3 tests)
- Fixed Loop.coro access for weekly loop tests (5 tests)

**Test Results:** 30/33 passing (90.9%)
- All business logic tests passing
- 3 remaining failures are unrelated logging bugs in error handling

## Production Ready
- Zero breaking changes to existing functionality
- Comprehensive error handling and logging
- Rate limiting prevents API overload
- Successfully tested with 31 real transactions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 14:25:00 -05:00
Cal Corum
fb78b4b8c6 CLAUDE: Add draft period restriction to interactive draft commands
Restrict interactive draft commands to offseason only (week <= 0) while keeping read-only commands available year-round.

Changes:
- Add @requires_draft_period decorator to utils/decorators.py
- Apply decorator to /draft and all /draft-list-* commands
- Keep /draft-board, /draft-status, /draft-on-clock unrestricted
- Update commands/draft/CLAUDE.md with restriction documentation

Technical details:
- Decorator checks league_service.get_current_state().week <= 0
- Shows user-friendly error: "Draft commands are only available in the offseason"
- Follows existing @logged_command decorator pattern
- No Discord command cache delays - instant restriction

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-25 20:29:16 -05:00
Cal Corum
d3824d7295
Merge pull request #9 from calcorum/feature-draft-system
Feature draft system
2025-10-25 20:03:13 -05:00
Cal Corum
69ab4f60c3 CLAUDE: Use DELETE endpoint for clearing draft list
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>
2025-10-25 19:50:30 -05:00
Cal Corum
5f69d495ab CLAUDE: Fix draft list operations and improve add success display
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>
2025-10-25 19:35:50 -05:00
Cal Corum
07f69ebd77 Fix freeze reposting bug 2025-10-25 10:04:19 -05:00
Cal Corum
0d64407217 CLAUDE: Rewrite all draft list operations for bulk replacement API
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>
2025-10-24 23:07:54 -05:00
Cal Corum
b0a5b19346 CLAUDE: Fix draft list add operation for bulk replacement API
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>
2025-10-24 23:03:26 -05:00
Cal Corum
111a2959a0 Make draft-list commands ephemeral 2025-10-24 22:59:17 -05:00
Cal Corum
43d166e417 CLAUDE: Fix draft command argument order and field name bugs
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>
2025-10-24 22:56:51 -05:00
Cal Corum
7370fa7006 CLAUDE: Fix draft channel configuration not persisting
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>
2025-10-24 22:52:57 -05:00
Cal Corum
005c031062 CLAUDE: Fix DraftData validation errors for optional channel IDs
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>
2025-10-24 22:40:12 -05:00
Cal Corum
4cb64253c4 CLAUDE: Add complete draft command suite
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>
2025-10-24 22:25:30 -05:00
Cal Corum
4dd9b21322 CLAUDE: Integrate draft commands into bot.py
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>
2025-10-24 22:17:09 -05:00
Cal Corum
ea7b356db9 CLAUDE: Refactor draft system to eliminate hard-coded magic numbers
Replace all hard-coded values with centralized config constants for better
maintainability and flexibility:

Added config constants:
- draft_team_count (16)
- draft_linear_rounds (10)
- swar_cap_limit (32.00)
- cap_player_count (26)
- draft_total_picks property (derived: rounds × teams)

Critical fixes:
- FA team ID (498) now uses config.free_agent_team_id in:
  * tasks/draft_monitor.py - Auto-draft validation
  * commands/draft/picks.py - Pick validation and autocomplete
- sWAR cap limit display now uses config.swar_cap_limit

Refactored modules:
- utils/draft_helpers.py - All calculation functions
- services/draft_service.py - Pick advancement logic
- views/draft_views.py - Display formatting

Benefits:
- Eliminates risk of silent failures from hard-coded IDs
- Centralizes all draft constants in one location
- Enables easy draft format changes via config
- Improves testability with mockable config
- Zero breaking changes - fully backwards compatible

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 22:14:17 -05:00
Cal Corum
0e54a81bbe CLAUDE: Add comprehensive draft system documentation
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>
2025-10-24 15:16:39 -05:00