Commit Graph

160 Commits

Author SHA1 Message Date
Cal Corum
1af7c82353 Fix off-by-one error in draft recent picks display
The get_recent_picks service method was subtracting 1 from overall_end,
but callers were already passing currentpick - 1. This caused the "Last 5
picks" list on the OnTheClock embed to skip the most recently completed
pick (showing picks 2-6 before current instead of 1-5).

Removed the extra subtraction in the service method since callers already
handle the exclusivity of the overall_end parameter.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-12 19:14:53 -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
7744e77e83 Fix missing guild variable in draft monitor on-clock announcement
Bug: The _post_on_clock_announcement method referenced 'guild' without
defining it, causing the role ping to silently fail when posting
on-clock announcements after auto-draft picks.

Fix: Added guild lookup from bot.get_guild(config.guild_id) at the
start of the method.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 18:46:16 -06:00
Cal Corum
e3122fa23a Fix sWAR display precision and draft team role pings
- Change sWAR formatting from 1 decimal to 2 decimal places across all displays
- Draft on-clock announcements now ping team role (via team.lname) instead of GM

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 18:41:46 -06:00
Cal Corum
a814aadd61 Optimize draft sheet batch writes to single API call
- Changed write_picks_batch() from 105 individual API calls to 1 batch call
- Builds 2D array covering full pick range and writes in single update_values()
- Eliminates Google Sheets 429 rate limiting during resync operations
- Reduces resync time from ~2 minutes to seconds

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-12 15:01:48 -06:00
Cal Corum
637f1a015f Release v2.24.0 - Draft System Enhancements
Features:
- Skipped pick support: Teams can make up missed picks
- Google Sheets integration: Auto-sync picks to shared sheet
- Draft pause/resume: Admins can pause/resume draft with timer control
- Auto-draft improvements: Auto-start monitor, post picks to result channel
- Sheet links in draft embeds: Quick access to draft board

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 20:28:01 -06:00
Cal Corum
5d393f4f53
Merge pull request #20 from calcorum/fix/draft-pick-api-parsing
Draft System Enhancements: Skipped Picks, Google Sheets, Pause/Resume
2025-12-11 20:26:01 -06:00
Cal Corum
bf70aed890 Add Google Sheet link to draft embeds
Added sheet_url parameter to draft embed functions:
- create_draft_board_embed - "View Full Board" link
- create_admin_draft_info_embed - "View Sheet" link
- create_on_the_clock_embed - "View Full Board" link
- create_on_clock_announcement_embed - "View Full Board" link

Updated all callers to pass the sheet URL from config.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 20:10:16 -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
c2136c966e
Merge pull request #21 from calcorum/fix/help-command-name-validation
Add input validation for help command name and category
2025-12-11 19:14:12 -06:00
Cal Corum
213e754673 Add input validation for help command name and category
The help command creation modal was accepting names with spaces and
special characters (e.g., "scorecard links"), which passed to the API
but caused Pydantic validation errors when reading the records back.

Changes:
- Add regex validation in modal on_submit for topic name and category
- Only allow lowercase letters, numbers, dashes, and underscores
- Show clear error messages with valid examples when validation fails
- Normalize name/category to lowercase before storing

This prevents invalid records from being created in the database.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-11 19:11:42 -06:00
Cal Corum
647ae1ca15 Post auto-draft picks to result channel with draft card embed
Auto-draft picks now post the same draft card embed to the result
channel that regular /draft picks do, with a footer indicating the
pick was auto-drafted from the draft list.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-11 13:04:29 -06:00
Cal Corum
602c87590e Fix auto-draft player availability check with nested API parsing
DraftList.from_api_data() now properly calls Player.from_api_data()
for nested player objects, ensuring player.team_id is correctly
extracted from the nested team object. Also fixed validate_cap_space()
unpacking to accept all 3 return values.

Bug: Auto-draft was marking all players as "not available" because
player.team_id was None (None != 547 always True).

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-11 12:53:07 -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
0294f89f4a Update CLAUDE.md files for recent draft system changes
commands/draft/CLAUDE.md:
- Mark all draft commands as implemented (not "pending")
- Document /draft-admin subcommands and auto-start behavior
- Add /draft-on-clock command documentation
- Update status to December 2025

tasks/CLAUDE.md:
- Document smart polling intervals (30s/15s/5s)
- Add auto-start behavior from /draft-admin commands
- Document on-clock announcement embed features
- Update to December 2025

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-10 23:18:25 -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
ada4feef3e Add draft monitor auto-start and on-clock announcement embed
- Start draft monitor when timer enabled via /draft-admin timer
- Auto-start monitor when /draft-admin set-pick is used with active timer
- Add _ensure_monitor_running() helper for consistent monitor management
- Create on-clock announcement embed with:
  - Team name, pick info, and deadline
  - Team sWAR and cap space
  - Last 5 picks
  - Top 5 roster players by sWAR
- Implement smart polling intervals:
  - 30s when >60s remaining
  - 15s when 30-60s remaining
  - 5s when <30s remaining
- Add get_top_free_agents() to player service
- Fix DraftAdminGroup to accept bot parameter

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-10 23:04:39 -06:00
Cal Corum
c43f32fb41 Improve draft list command feedback and messaging
- Update footer text to list available commands instead of confusing
  "manage" message (/draft-list only views, doesn't manage)
- Show updated queue after /draft-list-remove (matches /draft-list-add UX)
- Add helpful footer to /draft-list-clear success message

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-10 15:58:39 -06:00
Cal Corum
f3351b10c7 Fix double emoji in embed titles
- draft_views.py: Use create_base_embed() instead of info() for
  Draft Administration embed to keep custom ⚙️ emoji
- charts.py: Same fix for Chart Categories embed with 📊 emoji

EmbedTemplate.info/success/error/warning/loading() methods auto-add
emoji prefixes, so custom emojis should use create_base_embed() instead.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 15:42:13 -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
c138276797
Merge pull request #19 from calcorum/feature/trade-multi-gm-access
Multi-GM Trade Access and Test Suite Fixes
2025-12-09 16:05:41 -06:00
Cal Corum
da38c0577d Fix test suite failures across 18 files (785 tests passing)
Major fixes:
- Rename test_url_accessibility() to check_url_accessibility() in
  commands/profile/images.py to prevent pytest from detecting it as a test
- Rewrite test_services_injury.py to use proper client mocking pattern
  (mock service._client directly instead of HTTP responses)
- Fix Giphy API response structure in test_commands_soak.py
  (data.images.original.url not data.url)
- Update season config from 12 to 13 across multiple test files
- Fix decorator mocking patterns in transaction/dropadd tests
- Skip integration tests that require deep decorator mocking

Test patterns applied:
- Use AsyncMock for service._client instead of aioresponses for service tests
- Mock at the service level rather than HTTP level for better isolation
- Use explicit call assertions instead of exact parameter matching

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 16:01:56 -06:00
Cal Corum
5a5da37c9c Add comprehensive draft services test suite and API fixes (v2.23.0)
- Fix DraftPickService to send full model body on PATCH (API requirement)
- Fix DraftListService to use client-side sorting (API doesn't support sort param)
- Fix parameter names: round_start/end -> pick_round_start/end
- Add 53 tests covering DraftService, DraftPickService, DraftListService
- Add draft model tests for DraftData, DraftPick, DraftList
- Add OpenAPI spec URL to CLAUDE.md for API reference

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 15:11:51 -06:00
Cal Corum
d44685e2c5 Fix test failures for SOAK listener and DraftList model
- Update SOAK listener tests to match refactored simple string detection
  (removed SOAK_PATTERN regex import, now uses ' soak' in text.lower())
- Fix DraftList model tests to provide nested Team/Player objects
  (model requires full objects, not just IDs)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 18:23:01 -06:00
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