Commit Graph

77 Commits

Author SHA1 Message Date
Cal Corum
32cb5da632 CLAUDE: Refactor voice cleanup service to use @tasks.loop pattern
Problem:
- Voice cleanup service used manual while loop instead of @tasks.loop
- Did not wait for bot readiness before starting
- Startup verification could miss stale entries
- Manual channel deletions did not unpublish associated scorecards

Changes:
- Refactored VoiceChannelCleanupService to use @tasks.loop(minutes=1)
- Added @before_loop decorator with await bot.wait_until_ready()
- Updated bot.py to use setup_voice_cleanup() pattern
- Fixed scorecard unpublishing for manually deleted channels
- Fixed scorecard unpublishing for wrong channel type scenarios
- Updated cleanup interval from 60 seconds to 1 minute (same behavior)
- Changed cleanup reason message from "15+ minutes" to "5+ minutes" (matches actual threshold)

Benefits:
- Safe startup: cleanup waits for bot to be fully ready
- Reliable stale cleanup: startup verification guaranteed to run
- Complete cleanup: scorecards unpublished in all scenarios
- Consistent pattern: follows same pattern as other background tasks
- Better error handling: integrated with discord.py task lifecycle

Testing:
- All 19 voice command tests passing
- Updated test fixtures to handle new task pattern
- Fixed test assertions for new cleanup reason message

Documentation:
- Updated commands/voice/CLAUDE.md with new architecture
- Documented all four cleanup scenarios for scorecards
- Added task lifecycle information
- Updated configuration section

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 00:05:35 -05:00
Cal Corum
950f3ed640 Add pitcher injury numbers to AB rolls 2025-10-23 23:47:45 -05:00
Cal Corum
7c91af2f80 Make /scorebug ephemeral 2025-10-23 19:51:51 -05:00
Cal Corum
4b4f8d20ea
Merge pull request #8 from calcorum/bug-transactions
Bug transactions
2025-10-23 16:41:30 -05:00
Cal Corum
36b8876b8a CLAUDE: Change transaction diagnostic logging from INFO to DEBUG
Changed all diagnostic logging statements added for transaction bug tracking
from INFO level to DEBUG level. This reduces log noise during normal operations
while preserving detailed diagnostics when needed.

Changes:
- All 🔍 DIAGNOSTIC messages changed to DEBUG level
- All  player found messages changed to DEBUG level
- All roster validation tracking changed to DEBUG level
- WARNING (⚠️) and ERROR () messages preserved at their levels

Files modified:
- commands/transactions/dropadd.py - Player roster detection diagnostics
- commands/transactions/ilmove.py - Player roster detection diagnostics
- services/transaction_builder.py - Transaction validation tracking
- views/transaction_embed.py - Submission handler mode tracking

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 16:09:12 -05:00
Cal Corum
8ebbc26a0d CLAUDE: Add automatic transaction logging to #transaction-log channel
Implemented automatic posting of transaction notifications to #transaction-log
channel when transactions are submitted via /dropadd or /ilmove commands.

**New Utility:**
- `utils/transaction_logging.py` - Centralized transaction logging function
  - `post_transaction_to_log()` - Posts transaction embed to #transaction-log
  - Uses team's ML affiliate for consistent branding
  - Displays team thumbnail, colors, and player moves
  - Shows season from transaction data (not hardcoded)
  - Format matches legacy transaction log embeds

**Integration Points:**
- `/dropadd` (scheduled transactions) - Posts when submitted
- `/ilmove` (immediate transactions) - Posts when executed
- Both use shared `post_transaction_to_log()` function

**Embed Format:**
```
Week 18 Transaction
[Team Name]
Player Moves:
- **PlayerName** (sWAR) from OLDTEAM to NEWTEAM
- **PlayerName** (sWAR) from OLDTEAM to NEWTEAM
[Team Thumbnail]
Footer: "SBa Season 12" with SBA logo
```

**Features:**
- Automatic ML affiliate lookup for consistent team display
- Team colors and thumbnails in embeds
- Season number from transaction data
- Graceful error handling (logs warnings, doesn't block submission)
- Matches legacy embed format exactly

**Files Changed:**
- NEW: `utils/transaction_logging.py` - Transaction logging utility
- MODIFIED: `views/transaction_embed.py` - Added logging calls on submission

**Testing:**
- Transaction builder tests pass (31/31)
- No new test failures introduced
- Logging is non-blocking (submission succeeds even if logging fails)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 12:24:37 -05:00
Cal Corum
74c5059aba CLAUDE: Fix player drops going to wrong team (DENIL id 503 instead of FA id 498)
Fixed critical bug where player drops/releases were assigned to team id 503 (DENIL)
instead of the correct Free Agency team (id 498). The transaction_builder.py had
a hardcoded team ID instead of using the config value.

**Root Cause:**
- Line 446 in services/transaction_builder.py hardcoded `id=503` for Free Agency
- Correct Free Agency team ID is 498 (from config.free_agent_team_id)
- Team 503 is DENIL, causing dropped players to appear on wrong roster

**Fix:**
- Changed to use `config.free_agent_team_id` (498) dynamically
- All drop/release transactions now correctly target Free Agency

**Affected Players in Production:**
- Luis Torrens, Jake Meyers, Lance Lynn, Seranthony Dominguez
- These players need manual correction in production database

**Testing:**
- All 31 transaction_builder tests pass
- Validates correct team assignment for drop operations

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 12:13:34 -05:00
Cal Corum
d7dc9ed2bf Refactor x-check chart data 2025-10-22 20:41:21 -05:00
Cal Corum
268ac9a547
Merge pull request #7 from calcorum/bug-live-scoreboard
Bug live scoreboard
2025-10-22 19:27:09 -05:00
Cal Corum
08434eb340 Clear Injury bug fix 2025-10-22 19:20:43 -05:00
Cal Corum
a80b84ae25 CLAUDE: Add /admin-clear-scorecards command for manual channel management
- Added new admin-only command to manually clear #live-sba-scores
- Clears all messages from the channel (up to 100)
- Sets @everyone view permission to False (hides channel)
- Bot retains access via role permissions
- Provides detailed feedback on operation success
- Updated /admin-help to include new command

Use cases:
- Manual cleanup of stale scorebug displays
- Testing channel visibility functionality
- Emergency channel management
- Forcing channel to hidden state

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 17:03:43 -05:00
Cal Corum
8907841ec6 CLAUDE: Refactor scorebug display and add dynamic channel visibility
- Created utils/scorebug_helpers.py with shared scorebug functions
  - create_scorebug_embed(): Unified embed creation for command and background task
  - create_team_progress_bar(): Win probability visualization

- Fixed win probability bar to show dark blocks weighted toward winning team
  - Arrow extends from the side with advantage
  - Home winning: "POR ░▓▓▓▓▓▓▓▓▓► WV  95.0%"
  - Away winning: "POR ◄▓▓▓▓▓▓▓░░░ WV  30.0%"

- Changed embed color from score-based to win probability-based
  - Embed shows color of team favored to win, not necessarily winning
  - Creates fun psychological element showing momentum/advantage

- Added dynamic channel visibility for #live-sba-scores
  - Channel visible to @everyone when active games exist
  - Channel hidden when no games are active
  - Bot retains access via role permissions
  - Added set_channel_visibility() to utils/discord_helpers.py

- Eliminated ~220 lines of duplicate code across files
  - Removed duplicate embed creation from commands/gameplay/scorebug.py
  - Removed duplicate embed creation from tasks/live_scorebug_tracker.py

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 16:58:21 -05:00
Cal Corum
f87994b188
Merge pull request #6 from calcorum/refactor-listeners
Refactored listener logic and added SpoilerListener
2025-10-22 15:03:21 -05:00
Cal Corum
913827b5f3 Refactored listener logic and added SpoilerListener 2025-10-22 14:59:19 -05:00
Cal Corum
003d8e32b6
Merge pull request #5 from calcorum/bug-ab-chaos
Bug ab chaos
2025-10-21 23:39:36 -05:00
Cal Corum
0a8a643e02 Fixing raise or return for roll validation 2025-10-21 23:35:43 -05:00
Cal Corum
8972aacf3b Adding chaos to /ab rolls 2025-10-21 23:30:15 -05:00
Cal Corum
e3e1674842
Merge pull request #4 from calcorum/bug/miltransactions
Bug/miltransactions
2025-10-21 20:31:42 -05:00
Cal Corum
6c63c61213 CLAUDE: Add Free Agency destination to /ilmove command
Enhancement: Allow releasing players to Free Agency via /ilmove

Changes:
- Added "Free Agency" as destination choice in command options
- Updated destination_map to include "fa" -> RosterType.FREE_AGENCY
- Added logic to fetch FA team from config (free_agent_team_id: 498)
- Set to_team correctly: FA team when releasing, user team otherwise

This allows users to immediately release players to Free Agency for current week,
complementing the existing ML/MiL/IL destination options.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-21 20:22:57 -05:00
Cal Corum
f2b7f8102c CLAUDE: Fix /dropadd rejecting Minor League players from same organization
Bug: /dropadd was incorrectly rejecting players from Minor League affiliates
Root Cause: Ownership check used team.id comparison instead of organizational check
Fix: Use team.is_same_organization() to properly handle ML/MiL/IL affiliates

Before: player.team.id != builder.team.id (fails for WVMiL when user owns WV)
After: not builder.team.is_same_organization(player.team) (correctly identifies same org)

This brings /dropadd in line with /ilmove implementation which already used
the correct organizational check pattern.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-21 20:11:31 -05:00
Cal Corum
267f14576a Hotfix: await team call
Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-21 14:58:30 -05:00
Cal Corum
225cbb8c3e
Merge pull request #3 from calcorum/enhancement/unpublish-scorecard
Enhancement/unpublish scorecard
2025-10-21 14:47:08 -05:00
Cal Corum
7937e51c6d CLAUDE: Add smart text splitting for Discord embed fields
App Version: 2.0.4
Created reusable text_utils module with split_text_for_fields() function
to handle rare play results that exceed Discord's 1024 character field limit.

Changes:
- New utils/text_utils.py with intelligent text splitting on delimiters
- Updated commands/dice/rolls.py to split long rare play results into multiple fields
- Automatic part indicators for multi-chunk results (e.g., "Part 1/2")
- Handles outfield rare plays (~1135 chars) by splitting into 2 fields
- Maintains single field for shorter infield/pitcher rare plays

Benefits:
- Fixes Discord field limit issue for outfield rare plays
- Reusable utility for any future long-text scenarios
- Clean breaks on semantic boundaries (between result types)
- No multiple embeds needed - everything in single embed

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-21 14:46:24 -05:00
Cal Corum
3cc52169b1 Fix catcher error chart and re-implement rare plays 2025-10-21 14:40:31 -05:00
Cal Corum
a8fbf55c9e Add sba_logo_url to the config and update /standings formatting 2025-10-21 14:40:03 -05:00
Cal Corum
f6a7967e49 CLAUDE: Fix stale injury records blocking /injury set-new
Added data consistency check to automatically clear stale injury records
where is_active=True but il_return=None. This prevents old injury records
from blocking new injury creation when players should not be injured.

- Detects mismatch between injury table and player il_return field
- Auto-clears stale injury records with warning log
- Allows legitimate injuries with matching il_return to block command
- Logs both warning (stale data found) and info (cleared) for debugging

Fixes issue where Ronald Acuna Jr had active injury record but no il_return.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-21 13:06:17 -05:00
Cal Corum
5e1ccf75ab Allow any user to toggle player stats 2025-10-21 13:06:03 -05:00
Cal Corum
17f05fad90 CLAUDE: Fix UnboundLocalError in /injury clear command
Fixed bug where responder_team variable was only assigned conditionally
but always referenced, causing UnboundLocalError when clearing injuries
for major league players.

- Initialize responder_team = None before conditional check
- Ensures variable is defined for both ML and non-ML teams
- Conditional expression on line 674 now works correctly

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-21 12:59:49 -05:00
Cal Corum
61e5c7999b - Cleaning up IDE errors 2025-10-21 10:58:08 -05:00
Cal Corum
5616cfec3a CLAUDE: Add automatic scorecard unpublishing when voice channels are cleaned up
This enhancement automatically unpublishes scorecards when their associated
voice channels are deleted by the cleanup service, ensuring data synchronization
and reducing unnecessary API calls to Google Sheets for inactive games.

Implementation:
- Added gameplay commands package with scorebug/scorecard functionality
- Created ScorebugService for reading live game data from Google Sheets
- VoiceChannelTracker now stores text_channel_id for voice-to-text association
- VoiceChannelCleanupService integrates ScorecardTracker for automatic cleanup
- LiveScorebugTracker monitors published scorecards and updates displays
- Bot initialization includes gameplay commands and live scorebug tracker

Key Features:
- Voice channels track associated text channel IDs
- cleanup_channel() unpublishes scorecards during normal cleanup
- verify_tracked_channels() unpublishes scorecards for stale entries on startup
- get_voice_channel_for_text_channel() enables reverse lookup
- LiveScorebugTracker logging improved (debug level for missing channels)

Testing:
- Added comprehensive test coverage (2 new tests, 19 total pass)
- Tests verify scorecard unpublishing in cleanup and verification scenarios

Documentation:
- Updated commands/voice/CLAUDE.md with scorecard cleanup integration
- Updated commands/gameplay/CLAUDE.md with background task integration
- Updated tasks/CLAUDE.md with automatic cleanup details

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-21 07:18:21 -05:00
Cal Corum
77d6ca2bb5
Merge pull request #2 from calcorum/feature/chart-reload-command
Feature/chart reload command
2025-10-20 22:10:39 -05:00
Cal Corum
58b0c2d221 CLAUDE: Add multi-image support for charts
Image Version: 2.0.3

Added ability to add charts with multiple images and manage them incrementally.

Service Layer Changes (chart_service.py):
- Added add_image_to_chart() method to append URLs to existing charts
- Added remove_image_from_chart() method to remove specific URLs
- Validation to prevent duplicate URLs in charts
- Protection against removing the last image from a chart

Command Layer Changes (charts.py):
- Modified /chart-manage add to accept comma-separated URLs
  - Parse and strip URLs from comma-delimited string
  - Shows image count in success message
  - Displays first image in response embed
- Added /chart-manage add-image command for incremental additions
- Added /chart-manage remove-image command to remove specific URLs
- All commands use chart autocomplete for easy selection
- Admin/Help Editor permission checks on all management commands

Usage Examples:
  # Add chart with multiple images in one command
  /chart-manage add defense "Defense Chart" gameplay "https://example.com/def1.png, https://example.com/def2.png"

  # Add additional images later
  /chart-manage add-image defense https://example.com/def3.png

  # Remove specific image
  /chart-manage remove-image defense https://example.com/def2.png

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 22:00:19 -05:00
Cal Corum
151e5b9646 CLAUDE: Add /chart-manage reload command to refresh charts from disk
Added new command to resolve caching issue where manual edits to
charts.json were not reflected in the bot without a restart.

Changes:
- Added /chart-manage reload command to ChartManageGroup
- Calls chart_service.reload_charts() to refresh in-memory cache
- Shows success message with chart and category counts
- Requires admin or Help Editor role permissions
- Uses @logged_command decorator for automatic logging

Fixes: Chart updates not appearing until bot restart
Resolves: Permission denied issue with charts.json (ownership fixed separately)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 21:08:43 -05:00
Cal Corum
ca325142d8 CLAUDE: Add comprehensive CLAUDE.md documentation files for AI agent guidance
Adding 17 CLAUDE.md files across the project to provide detailed context
and implementation guidelines for AI development agents:

Root Documentation:
- CLAUDE.md - Main project guide with Git workflow requirements

Component Documentation:
- commands/CLAUDE.md - Command architecture and patterns
- models/CLAUDE.md - Pydantic models and validation
- services/CLAUDE.md - Service layer and API interactions
- tasks/CLAUDE.md - Background tasks and automation
- tests/CLAUDE.md - Testing strategies and patterns
- utils/CLAUDE.md - Utility functions and decorators
- views/CLAUDE.md - Discord UI components and embeds

Command Package Documentation:
- commands/help/CLAUDE.md - Help system implementation
- commands/injuries/CLAUDE.md - Injury management commands
- commands/league/CLAUDE.md - League-wide commands
- commands/players/CLAUDE.md - Player information commands
- commands/profile/CLAUDE.md - User profile commands
- commands/teams/CLAUDE.md - Team information commands
- commands/transactions/CLAUDE.md - Transaction management
- commands/utilities/CLAUDE.md - Utility commands
- commands/voice/CLAUDE.md - Voice channel management

Key Updates:
- Updated .gitignore to track CLAUDE.md files in version control
- Added Git Workflow section requiring branch-based development
- Documented all architectural patterns and best practices
- Included comprehensive command/service implementation guides

These files provide essential context for AI agents working on the codebase,
ensuring consistent patterns, proper error handling, and maintainable code.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 20:30:07 -05:00
Cal Corum
64e60232dd
Merge pull request #1 from calcorum/readme-to-claude-auto
Readme to claude auto
2025-10-20 20:25:31 -05:00
Cal Corum
20b79fc8ff CLAUDE: Fix /voice-channel private to fetch current week games instead of week 1
The command was incorrectly using get_team_schedule(weeks=1) which fetches
the first week of the season rather than the current week's games. Changed
to use get_week_schedule(current_week) with proper team filtering.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 20:24:42 -05:00
Cal Corum
36ecd1b3ff CLAUDE: Add /ilmove command for real-time roster moves with organizational affiliate support
Implemented comprehensive /ilmove command system for immediate roster changes (IL moves,
activations, etc.) that execute instantly for the current week, complementing the existing
/dropadd system which schedules moves for next week.

New Features:
- /ilmove command: Interactive transaction builder for THIS week (immediate execution)
- /clearilmove command: Clear current IL move transaction builder
- Dual-mode transaction system: Scheduled (/dropadd) vs Immediate (/ilmove)

Key Fixes:
- Organizational team matching: Minor League players (WVMiL) now correctly recognized as
  valid targets for their Major League organization (WV)
- Transaction POST format: Fixed to use correct batch API format with count/moves structure
- RosterType to team affiliate mapping: Moves to IL now correctly assign players to WVIL
  instead of WV, and moves from MiL correctly reference WVMiL as source team
- Player team updates: Added update_player_team() method for immediate team assignments

Technical Changes:
- commands/transactions/ilmove.py: New command with organizational validation
- commands/transactions/__init__.py: Register ILMoveCommands cog
- services/transaction_service.py: create_transaction_batch() with correct batch format
- services/player_service.py: update_player_team() for immediate updates
- services/transaction_builder.py: RosterType affiliate resolution with async team lookups
- views/transaction_embed.py: Dual-mode support with context-aware instructions

Code Reuse:
- 95% code sharing between /dropadd and /ilmove via shared TransactionBuilder
- Same validation, UI, and move tracking - only submission differs
- Context-aware command_name parameter for dynamic UI instructions

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 20:15:12 -05:00
Cal Corum
1575d4f096 CLAUDE: Add /jump command and improve dice rolling with team colors, plus admin and type safety fixes
Added /jump command for baserunner stealing mechanics with pickoff/balk detection.
Enhanced dice rolling commands with team color support in embeds.
Improved /admin-sync with local/global options and prefix command fallback.
Fixed type safety issues in admin commands and injury management.
Updated config for expanded draft rounds and testing mode.

Key changes:
- commands/dice/rolls.py: New /jump and !j commands with special cases for pickoff (d20=1) and balk (d20=2)
- commands/dice/rolls.py: Added team/channel color support to /ab and dice embeds
- commands/dice/rolls.py: Added pitcher position to /fielding command with proper range/error charts
- commands/admin/management.py: Enhanced /admin-sync with local/clear options and !admin-sync prefix fallback
- commands/admin/management.py: Fixed Member type checking and channel type validation
- commands/injuries/management.py: Fixed responder team detection for injury clearing
- models/custom_command.py: Made creator_id optional for execute endpoint compatibility
- config.py: Updated draft_rounds to 32 and enabled testing mode
- services/transaction_builder.py: Adjusted ML roster limit to 26

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 15:10:48 -05:00
Cal Corum
62c658fb57 CLAUDE: Add automated weekly transaction freeze/thaw system
Implements comprehensive automated system for weekly transaction freeze periods
with priority-based contested player resolution.

New Features:
- Weekly freeze/thaw task (Monday 00:00 freeze, Saturday 00:00 thaw)
- Priority resolution for contested transactions (worst teams get first priority)
- Admin league management commands (/freeze-begin, /freeze-end, /advance-week)
- Enhanced API client to handle string-based transaction IDs (moveids)
- Service layer methods for transaction cancellation, unfreezing, and bulk operations
- Offseason mode configuration flag to disable freeze operations

Technical Changes:
- api/client.py: URL-encode object_id parameter to handle colons in moveids
- bot.py: Initialize and shutdown transaction freeze task
- config.py: Add offseason_flag to BotConfig
- services/league_service.py: Add update_current_state() for week/freeze updates
- services/transaction_service.py: Add cancel/unfreeze methods with bulk support
- tasks/transaction_freeze.py: Main freeze/thaw automation with error recovery
- commands/admin/league_management.py: Manual admin controls for freeze system

Infrastructure:
- .gitlab-ci.yml and .gitlab/: GitLab CI/CD pipeline configuration
- .mcp.json: MCP server configuration
- Dockerfile.versioned: Versioned Docker build support
- .dockerignore: Added .gitlab/ to ignore list

Testing:
- tests/test_tasks_transaction_freeze.py: Comprehensive freeze task tests

The system uses team standings to fairly resolve contested players (multiple teams
trying to acquire the same player), with worst-record teams getting priority.
Includes comprehensive error handling, GM notifications, and admin reporting.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 12:16:13 -05:00
Cal Corum
82abf3d9e6 CLAUDE: Add toggleable stats to /player command and injury system improvements
Add interactive PlayerStatsView with toggle buttons to show/hide batting and
pitching statistics independently in the /player command. Stats are hidden by
default with clean, user-friendly buttons (💥 batting,  pitching) that update
the embed in-place. Only the command caller can toggle stats, and buttons
timeout after 5 minutes.

Player Stats Toggle Feature:
- Add views/players.py with PlayerStatsView class
- Update /player command to use interactive view
- Stats hidden by default, shown on button click
- Independent batting/pitching toggles
- User-restricted interactions with timeout handling

Injury System Enhancements:
- Add BatterInjuryModal and PitcherRestModal for injury logging
- Add player_id extraction validator to Injury model
- Fix injury creation to merge API request/response data
- Add responders parameter to BaseView for multi-user interactions

API Client Improvements:
- Handle None values correctly in PATCH query parameters
- Convert None to empty string for nullable fields in database

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 23:26:08 -05:00
Cal Corum
9fca0bc279 CLAUDE: Add confirmation flow and autocomplete to /injury clear
- Added confirmation embed before clearing injury
  - Shows player info, team, expected return, games missed
  - User prompted: "Is {Player} cleared to return?"
  - Buttons: "Clear Injury" / "Cancel"
  - 3-minute timeout for response
  - Team GMs can also confirm/cancel

- Added player autocomplete to /injury clear command
  - Uses same autocomplete as /injury roll
  - Prioritizes user's team players

- Updated commands/injuries/CLAUDE.md documentation
  - Documented new confirmation flow
  - Added autocomplete parameter details
  - Clarified user flow and responders

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 16:26:25 -05:00
Cal Corum
216f8112d2 rename all readme files 2025-10-17 08:00:59 -05:00
Cal Corum
e8b8878781 Fixing get_config replacement issue 2025-10-17 08:00:24 -05:00
Cal Corum
e689aadbd8 CLAUDE: Fix double emoji issue in Discord embeds
Fixed 13 instances where EmbedTemplate methods were receiving titles
with emojis, resulting in double emojis (e.g., "  Command Created").

Changes:
- tasks/custom_command_cleanup.py: Removed emojis from warning/error titles (2 fixes)
- views/help_commands.py: Removed emoji from success title (1 fix)
- views/custom_commands.py: Removed emojis from titles or switched to
  create_base_embed() for custom emojis (10 fixes)

The following template methods auto-add emoji prefixes:
- EmbedTemplate.success() → adds 
- EmbedTemplate.error() → adds 
- EmbedTemplate.warning() → adds ⚠️
- EmbedTemplate.info() → adds ℹ️
- EmbedTemplate.loading() → adds 

For custom emojis, use EmbedTemplate.create_base_embed() with explicit
color parameter.

All 69 related tests passing.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 23:09:21 -05:00
Cal Corum
3aa95ef98c CLAUDE: Refine injury roll display and cleanup imports
## Injury Command Enhancements

### Pitcher-Specific Injury Display
- Added rest requirement note for pitcher injuries with game duration
- Shows "X games plus their current rest requirement" for pitchers
- Removed redundant footer text from FATIGUED result
- Cleaner, more concise pitcher injury messaging

### Bot Configuration
- Registered injuries command package in bot.py
- Added proper import and setup for InjuryGroup

### Code Cleanup
- Fixed misplaced import in views/embeds.py (moved to top)
- Standardized import ordering across command files
- Minor formatting improvements

## Files Changed
- commands/injuries/management.py: Pitcher rest requirement display
- bot.py: Injuries package registration
- views/embeds.py: Import cleanup
- Various: Import standardization

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 22:20:13 -05:00
Cal Corum
0c6f7c8ffe CLAUDE: Fix GroupCog interaction bug and GIF display issues
This commit addresses critical bugs in the injury command system and
establishes best practices for Discord command groups.

## Critical Fixes

### 1. GroupCog → app_commands.Group Migration
- **Problem**: `commands.GroupCog` has a duplicate interaction processing bug
  causing "404 Unknown interaction" errors when deferring responses
- **Root Cause**: GroupCog triggers command handler twice, consuming the
  interaction token before the second execution can respond
- **Solution**: Migrated InjuryCog to InjuryGroup using `app_commands.Group`
  pattern (same as ChartManageGroup and ChartCategoryGroup)
- **Result**: Reliable command execution, no more 404 errors

### 2. GiphyService GIF URL Fix
- **Problem**: Giphy service returned web page URLs (https://giphy.com/gifs/...)
  instead of direct image URLs, preventing Discord embed display
- **Root Cause**: Code accessed `data.url` instead of `data.images.original.url`
- **Solution**: Updated both `get_disappointment_gif()` and `get_gif()` methods
  to use correct API response path for embeddable GIF URLs
- **Result**: GIFs now display correctly in Discord embeds

## Documentation

### Command Groups Best Practices (commands/README.md)
Added comprehensive section documenting:
- **Critical Warning**: Never use `commands.GroupCog` - use `app_commands.Group`
- **Technical Explanation**: Why GroupCog fails (duplicate execution bug)
- **Migration Guide**: Step-by-step conversion from GroupCog to Group
- **Comparison Table**: Key differences between the two approaches
- **Working Examples**: References to ChartManageGroup, InjuryGroup patterns

## Architecture Changes

### Injury Commands (`commands/injuries/`)
- Converted from `commands.GroupCog` to `app_commands.Group`
- Registration via `bot.tree.add_command()` instead of `bot.add_cog()`
- Removed workarounds for GroupCog duplicate interaction issues
- Clean defer/response pattern with `@logged_command` decorator

### GiphyService (`services/giphy_service.py`)
- Centralized from `commands/soak/giphy_service.py`
- Now returns direct GIF image URLs for Discord embeds
- Maintains Trump GIF filtering (legacy behavior)
- Added gif_url to log output for debugging

### Configuration (`config.py`)
- Added `giphy_api_key` and `giphy_translate_url` settings
- Environment variable support via `GIPHY_API_KEY`
- Default values provided for out-of-box functionality

## Files Changed
- commands/injuries/: New InjuryGroup with app_commands.Group pattern
- services/giphy_service.py: Centralized service with GIF URL fix
- commands/soak/giphy_service.py: Backwards compatibility wrapper
- commands/README.md: Command groups best practices documentation
- config.py: Giphy configuration settings
- services/__init__.py: GiphyService exports

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 22:15:42 -05:00
Cal Corum
2926664d2d CLAUDE: Remove constants.py and migrate to config-based constants
Eliminates redundant constants.py file by moving all constants to config.py.
All constants (except baseball positions) are now accessible via get_config().

Changes:
- config.py: Added baseball position sets as module-level constants
  * PITCHER_POSITIONS, POSITION_FIELDERS, ALL_POSITIONS remain static
  * All other constants now accessed via BotConfig instance

- constants.py: Deleted (redundant with config.py)

- Updated 27 files to use get_config() instead of constants module:
  * Commands: admin, help, league (3), players, profile, teams (3),
    transactions (3), utilities, voice
  * Services: league, player, team, trade_builder, transaction_builder
  * Utils: autocomplete, team_utils
  * Views: embeds
  * Tests: test_constants, test_services (3 files)
  * Examples: enhanced_player, migration_example

- tests/test_constants.py: Rewritten to test config values
  * All 14 tests pass
  * Now validates BotConfig defaults instead of constants module

Import Changes:
- Old: `from constants import SBA_CURRENT_SEASON`
- New: `from config import get_config` → `get_config().sba_current_season`
- Positions: `from config import PITCHER_POSITIONS, ALL_POSITIONS`

Benefits:
- Single source of truth (config.py only)
- Cleaner architecture - no redundant wrapper
- All constants configurable via environment variables
- Reduced maintenance overhead
- Type safety with Pydantic validation

All configuration tests pass. Core refactoring complete.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 10:52:05 -05:00
Cal Corum
0808d3421c CLAUDE: Convert constants to configurable environment variables
Makes all application constants (except baseball positions) configurable
via environment variables for greater deployment flexibility.

Changes:
- config.py: Added 18 new configurable fields to BotConfig
  * Discord limits (embed/field/description limits)
  * League settings (weeks, games, modern stats era)
  * Current season constants (SBA/PD)
  * API configuration (version, timeout, retries)
  * Draft settings (pick minutes, rounds)
  * Special team IDs (free agent team)
  * Role/channel names (help editor, players, news channel)
  * Base URLs (SBA website)

- constants.py: Refactored to load from config
  * All constants now read from get_config()
  * Position sets remain static (PITCHER_POSITIONS, etc.)
  * Added documentation about configurability

- .env.example: Added all new environment variables
  * Organized into logical sections with headers
  * Includes default values from config.py
  * Clear documentation for each setting

Benefits:
- Environment-specific configuration without code changes
- Easy deployment across dev/staging/production
- Season rollover requires only env variable updates
- Team-specific customization (channels, roles, URLs)
- Docker-friendly configuration management

Backward Compatible: All defaults match previous hardcoded values

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 10:40:22 -05:00
Cal Corum
5924249481 CLAUDE: Add comprehensive Docker deployment infrastructure
Implements production-ready Docker setup with multi-stage builds and
separate development/production configurations.

New Files:
- Dockerfile: Multi-stage build with Python 3.13
  * Builder stage: Compiles dependencies with build tools
  * Runtime stage: Minimal image (~150-200MB) with non-root user
  * Health checks and security hardening
- docker-compose.yml: Production config (pulls from Docker Hub)
  * Image: manticorum67/major-domo-discordapp:latest
  * Resource limits: 512MB RAM, 1 CPU
  * Volumes: /app/data (ro), /app/logs (rw)
- docker-compose.dev.yml: Development config (builds locally)
  * Higher resource limits: 1GB RAM, 2 CPU
  * DEBUG log level by default
- .dockerignore: Excludes unnecessary files from build context
- build-and-push.sh: Interactive build/push script for Docker Hub
- DOCKER.md: Comprehensive deployment guide (13K)
- BUILD_AND_PUSH.md: Docker Hub build/push guide (7.7K)

Configuration Updates:
- config.py: Updated sheets_credentials_path to /app/data location
- requirements.txt: Pinned all package versions for reproducibility
- .env.example: Added Docker-specific configuration

Key Features:
- Multi-stage build for optimized image size
- Non-root user (botuser, UID 1000) for security
- Separate dev/prod compose files
- Volume mounts for persistence (/app/data, /app/logs)
- Health checks and automatic restarts
- Resource limits and log rotation
- Docker Hub integration for production deployments

Docker Hub Repository: manticorum67/major-domo-discordapp

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 00:54:56 -05:00
Cal Corum
2409c27c1d CLAUDE: Add comprehensive scorecard submission system
Implements full Google Sheets scorecard submission with:
- Complete game data extraction (68 play fields, pitching decisions, box score)
- Transaction rollback support at 3 states (plays/game/complete)
- Duplicate game detection with confirmation dialog
- Permission-based submission (GMs only)
- Automated results posting to news channel
- Automatic standings recalculation
- Key plays display with WPA sorting

New Components:
- Play, Decision, Game models with full validation
- SheetsService for Google Sheets integration
- GameService, PlayService, DecisionService for data management
- ConfirmationView for user confirmations
- Discord helper utilities for channel operations

Services Enhanced:
- StandingsService: Added recalculate_standings() method
- CustomCommandsService: Fixed creator endpoint path
- Team/Player models: Added helper methods for display

Configuration:
- Added SHEETS_CREDENTIALS_PATH environment variable
- Added SBA_NETWORK_NEWS_CHANNEL and role constants
- Enabled pygsheets dependency

Documentation:
- Comprehensive README updates across all modules
- Added command, service, model, and view documentation
- Detailed workflow and error handling documentation

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 00:21:32 -05:00