Commit Graph

14 Commits

Author SHA1 Message Date
Cal Corum
be3dbf1f8d Add dem_week parameter to player team updates
- Add optional dem_week parameter to PlayerService.update_player_team()
- Transaction freeze sets dem_week to current.week + 2
- /ilmove command sets dem_week to current.week
- Draft picks (manual and auto) set dem_week to current.week + 2
- Backwards compatible - admin commands don't set dem_week
- Add 4 unit tests for dem_week scenarios
- Enhanced logging shows dem_week values

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-01 21:12:06 -06:00
Cal Corum
95d18d603e Fix /draft command to post player cards to result channel
The manual /draft command was only posting draft cards to the ping_channel,
but not to the result_channel. The auto-draft task correctly posted to both
channels. This fix ensures manual draft picks also post player cards to the
configured result channel for consistent draft result tracking.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-12 19:08:23 -06:00
Cal Corum
08fbd0a812 Fix /draft autocomplete sending display text instead of value
When users select from autocomplete dropdown, Discord sometimes sends
the display text (e.g., "Mason Miller (RP) - 2.50 sWAR") instead of
the value ("Mason Miller"). Added _parse_player_name() to strip the
position and sWAR info from the input.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 18:59:33 -06:00
Cal Corum
20e861d92e Add on-clock announcement with role ping after /draft picks
Previously, only the draft monitor task posted on-clock announcements
when auto-drafting. Now the /draft command also posts an on-clock
announcement with team role ping after each pick advances.

Changes:
- Added _post_on_clock_announcement method to DraftPicksCog
- Called after advance_pick() in _process_draft_pick
- Posts embed with team info, sWAR, recent picks, and role ping
- Imports roster_service and get_team_salary_cap for sWAR calculation

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 18:53:57 -06:00
Cal Corum
ff62529ee3 Add draft pause/resume functionality
- Add paused field to DraftData model
- Add pause_draft() and resume_draft() methods to DraftService
- Add /draft-admin pause and /draft-admin resume commands
- Block picks in /draft command when draft is paused
- Skip auto-draft in draft_monitor when draft is paused
- Update status embeds to show paused state
- Add comprehensive tests for pause/resume

When paused:
- Timer is stopped (set to False)
- Deadline is set far in future
- All /draft picks are blocked
- Auto-draft monitor skips processing

When resumed:
- Timer is restarted with fresh deadline
- Picks are allowed again

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 19:58:37 -06:00
Cal Corum
9093055bb5 Add Google Sheets integration for draft pick tracking
- Add DraftSheetService with write_pick(), write_picks_batch(),
  clear_picks_range(), and get_sheet_url() methods
- Integrate sheet writes in /draft command (fire-and-forget pattern)
- Integrate sheet writes in draft_monitor.py for auto-draft picks
- Add /draft-admin resync-sheet command for bulk recovery
- Add sheet link to /draft-status embed
- Add draft_sheet_keys config with env var overrides per season
- Add get_picks_with_players() to draft_pick_service for resync
- Add 13 unit tests for DraftSheetService (all passing)
- Update CLAUDE.md documentation files

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 11:18:27 -06:00
Cal Corum
8f486a8424 Add skipped pick support to /draft command
Teams can now make up missed draft picks when not on the clock:
- Added get_skipped_picks_for_team() to draft_pick_service
- /draft checks for skipped picks when user isn't on the clock
- Uses earliest (lowest overall) skipped pick first
- Shows footer noting "Making up skipped pick" on success
- Does NOT advance draft when using skipped pick
- Fixed duplicate embed when command run in ping channel

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-10 23:16:10 -06:00
Cal Corum
483f1f492f Fix draft pick API parsing and enhance admin command feedback
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>
2025-12-10 15:33:52 -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
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
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
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
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
5d922ead76 CLAUDE: Add core draft command with global pick lock
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>
2025-10-24 14:58:09 -05:00