Commit Graph

220 Commits

Author SHA1 Message Date
cal
30e1992780 Update .gitea/workflows/docker-build.yml
All checks were successful
Build Docker Image / build (pull_request) Successful in 1m29s
2026-02-14 14:59:03 +00:00
Cal Corum
0f08b3b8b5 Bump version to 2.29.8, fix stale deploy script reference in CLAUDE.md
Some checks failed
Build Docker Image / build (pull_request) Failing after 1m1s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 08:55:30 -06:00
Cal Corum
05bb28c8c4 Fix thaw report posting to use channel ID instead of nonexistent channel names
The Saturday thaw report was silently failing because it searched for
channels named 'bot-admin', 'admin', or 'bot-logs' which don't exist.
Now uses a configurable channel ID (overridable via THAW_REPORT_CHANNEL_ID).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 08:52:15 -06:00
Cal Corum
2c6cc499fa Audit and compress CLAUDE.md from 775 to 67 lines
Some checks failed
Build Docker Image / build (pull_request) Failing after 15s
Remove historical changelogs, redundant documentation references,
and content already covered by parent/sub-directory CLAUDE.md files.
Update deployment section to reflect Gitea Actions workflow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 14:24:22 -06:00
cal
d40ddb76be Merge pull request 'ci: switch Docker build cache to type=registry' (#5) from ci/registry-cache into main
All checks were successful
Build Docker Image / build (push) Successful in 4m7s
2026-02-11 22:14:23 +00:00
cal
d72595cef7 ci: switch Docker build cache from type=gha to type=registry
Some checks failed
Build Docker Image / build (pull_request) Failing after 16s
The gha cache backend silently fails on Gitea Actions due to Docker
networking issues between the Buildx builder container and the
act_runner cache server. Registry-based caching stores layers on
Docker Hub, which is more reliable for self-hosted runners.
2026-02-11 22:12:21 +00:00
cal
0ed0446607 Merge pull request 'Raise exception on spreadsheet errors instead of silently skipping' (#4) from fix/validate-spreadsheet-decision-data into main
All checks were successful
Build Docker Image / build (push) Successful in 44s
Reviewed-on: #4
2026-02-06 13:55:52 +00:00
cal
085e76134b Update VERSION
All checks were successful
Build Docker Image / build (pull_request) Successful in 34s
2026-02-06 07:54:33 -06:00
Cal Corum
1d08dc1755 Raise exception on spreadsheet errors instead of silently skipping
**Problem:**
The _is_spreadsheet_error() check was logging a warning and silently skipping
rows with formula errors (#REF!, #N/A, etc.). This could lead to incomplete
game data being submitted without the user knowing.

**Solution:**
Raise SheetsException immediately when spreadsheet errors are detected,
providing:
- Exact row number and field name
- Actual error value found in the cell
- Common error type explanations
- Clear action required to fix

**Impact:**
- Users get immediate feedback about spreadsheet errors
- No partial/incomplete data submitted to API
- Clear instructions on what needs to be fixed
- Better data integrity

**Example Error Message:**
```
 Spreadsheet Error Detected

**Location:** Row 7, Column 'pitcher_id'
**Value Found:** `#REF!`

This cell contains a formula error that must be fixed before submission.

**Action Required:** Fix cell pitcher_id in row 7 and resubmit.
```

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-06 07:54:33 -06:00
cal
ff3f9a0d1d Merge pull request 'fix: Validate and sanitize pitching decision data from Google Sheets' (#3) from fix/validate-spreadsheet-decision-data into main
All checks were successful
Build Docker Image / build (push) Successful in 1m10s
Reviewed-on: #3
2026-02-06 13:38:36 +00:00
cal
2be93dfc8a Update VERSION
All checks were successful
Build Docker Image / build (pull_request) Successful in 2m32s
2026-02-06 13:35:49 +00:00
Cal Corum
92eb9055f1 fix: Validate and sanitize pitching decision data from Google Sheets
Some checks failed
Build Docker Image / build (pull_request) Failing after 19s
Added robust validation to handle spreadsheet errors and invalid data
when reading pitching decisions from scorecards.

Problem:
- POST /api/v3/decisions was failing with 422 errors
- Google Sheets cells containing "#N/A" were passed directly to API
- API correctly rejected invalid team_id values like "#N/A" string
- No validation of integer fields or required fields

Root Cause:
- sheets_service.py:read_pitching_decisions() read values without
  validation or type checking
- Spreadsheet formula errors (#N/A, #REF!, etc.) passed through
- Invalid data types not caught until API validation failed

Solution:
1. Added _is_spreadsheet_error() to detect formula errors
2. Added _sanitize_int_field() to validate and convert integers
3. Enhanced read_pitching_decisions() to:
   - Detect and skip rows with spreadsheet errors
   - Validate integer fields (pitcher_id, team_id, etc.)
   - Ensure required fields (pitcher_id, team_id) are present
   - Log warnings for invalid data with row numbers
   - Only return valid, sanitized decision data

Impact:
- Prevents 422 errors from bad spreadsheet data
- Provides clear warnings in logs when data is invalid
- Gracefully skips invalid rows instead of crashing
- Helps identify scorecard data entry errors

Testing:
- Handles #N/A, #REF!, #VALUE!, #DIV/0! and other errors
- Converts "123.0" strings to integers correctly
- Validates required fields before sending to API
- Logs row numbers for debugging bad data

Production logs showed:
  "Input should be a valid integer, unable to parse string as
   an integer", input: "#N/A" for team_id field

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 21:44:06 -06:00
cal
e0af40804d Merge pull request 'chore-cc-update' (#2) from chore-cc-update into main
All checks were successful
Build Docker Image / build (push) Successful in 1m29s
Reviewed-on: #2
2026-02-06 02:46:46 +00:00
Cal Corum
42b9fa5df2 Fix /player autocomplete timeout by using current season only
All checks were successful
Build Docker Image / build (pull_request) Successful in 57s
The all_seasons=True parameter causes the API search query to take 15+ seconds,
exceeding Discord's 3-second autocomplete timeout. Changed to all_seasons=False
to search only the current season, which is fast enough.

Users can still access historical players by manually typing the name and using
the season parameter in the /player command.

Fixes: discord.errors.NotFound 404 (error code: 10062): Unknown interaction

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 20:45:09 -06:00
cal
0bc1ebc354 Update VERSION
All checks were successful
Build Docker Image / build (pull_request) Successful in 2m37s
2026-02-06 02:26:32 +00:00
cal
9f6db12d5a Update VERSION
Some checks failed
Build Docker Image / build (pull_request) Failing after 13s
2026-02-06 02:25:13 +00:00
Cal Corum
310e685670 Update format of /cc response 2026-02-05 20:23:49 -06:00
cal
9f11401f8b Merge pull request 'bugfix/injury-team-null-errors' (#1) from bugfix/injury-team-null-errors into main
All checks were successful
Build Docker Image / build (push) Successful in 1m44s
Reviewed-on: #1
2026-02-05 22:54:26 +00:00
cal
e03ba79fa5 Update VERSION
All checks were successful
Build Docker Image / build (pull_request) Successful in 2m54s
2026-02-05 22:50:06 +00:00
Cal Corum
ac3cbebb9f Remove unused .mcp.json config file
Some checks failed
Build Docker Image / build (pull_request) Failing after 18s
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 15:14:36 -06:00
Cal Corum
bfe78fb7ac Clean up legacy CI/CD files and one-time scripts
Removed legacy CI/CD infrastructure:
- GitLab CI config (.gitlab-ci.yml, .gitlab/ directory)
- Manual build scripts (build-and-push.sh, BUILD_AND_PUSH.md)
- Unused Dockerfile variant (Dockerfile.versioned)

Removed outdated documentation:
- AGENTS.md (superseded by comprehensive CLAUDE.md files)

Removed one-time recovery scripts:
- scripts/ directory (week 19 transaction recovery - completed)
- test_real_data.py (ad-hoc testing script)

Note: Runtime artifacts (.coverage, htmlcov/, __pycache__/, etc.) are already
properly excluded via .gitignore and were not tracked in git.

All CI/CD is now handled by .gitea/workflows/docker-build.yml

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 15:09:24 -06:00
Cal Corum
c7f55d79e3 Fix injury commands player.team None errors and add Gitea CI/CD
- Fix /injury roll and /injury clear commands crashing when player.team is None
- Add team fetching logic after search_players() for all injury commands
- The search_players() API endpoint returns team as ID only (not nested object)
- Added null checks and explicit team fetching using team_service.get_team()

- Add Gitea Actions workflow for automated Docker builds
- Implements semantic version validation on PRs
- Builds and pushes to Docker Hub on main branch merges
- Sends Discord notifications on success/failure
- Generates 3 image tags: latest, v{VERSION}, v{VERSION}-{COMMIT}

Fixes AttributeError: 'NoneType' object has no attribute 'roster_type'
Fixes AttributeError: 'NoneType' object has no attribute 'thumbnail'

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 14:16:22 -06:00
Cal Corum
ab8bfa115f Fix /injury roll command crash when player.team is None
The search_players() API endpoint returns team as an ID only (not nested object),
causing player.team to be None. Added null check before accessing team.thumbnail.

Fixes AttributeError: 'NoneType' object has no attribute 'thumbnail'

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-04 21:50:43 -06:00
Cal Corum
6935465210 Bump version to 2.29.2 2026-02-01 21:28:31 -06:00
Cal Corum
060287b7ca Fix API parameter name: use 'demotion_week' instead of 'dem_week'
The API expects 'demotion_week' as the query parameter name, not 'dem_week'.
Updated service to send correct parameter name and tests to verify.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-01 21:27:52 -06:00
Cal Corum
c7820eaea0 Bump version to 2.29.1 2026-02-01 21:16:48 -06:00
Cal Corum
788b7b30fc Fix missing Optional import in transaction_freeze.py
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-01 21:16:25 -06:00
Cal Corum
dca629a279 Bump version to 2.29.0 2026-02-01 21:15:51 -06:00
Cal Corum
00f8f4f0aa Merge branch 'feature/add-dem-week-to-player-updates' 2026-02-01 21:13:09 -06:00
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
f4523b99f2 Clear confirmation message content on delete result
Prevents double emoji display by clearing the " Confirmed!" content
when showing the delete result embed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 16:40:03 -06:00
Cal Corum
b5365f01f9 Fix custom command delete permission check using wrong ID field
Changed from command.creator_id (database ID) to command.creator.discord_id
to properly compare against the deleter's Discord user ID.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 16:10:52 -06:00
Cal Corum
4fb3bcef51 Bump version to 2.28.1
Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-28 16:02:31 -06:00
Cal Corum
2ab82aa2bf Fix custom command delete not actually deleting from database
The delete confirmation was showing success but never calling the delete
service. Added the actual delete_command() call when user confirms.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-28 16:02:26 -06:00
Cal Corum
484042e8ae Bump version to 2.28.0
Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-28 15:45:47 -06:00
Cal Corum
cf5df1a619 Fix custom command mentions not triggering notifications
- Use channel.send() instead of followup.send() for custom command output
  (webhook-based followup messages don't trigger mention notifications)
- Add ephemeral "Sending..." confirmation to satisfy interaction response
- Add utils/mentions.py for converting text @mentions to Discord format
- Add tests for mention conversion utility

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-28 15:45:38 -06:00
Cal Corum
d6ec2a11ec Add AGENTS.md with coding guidelines for AI agents
Comprehensive guide covering:
- Build/lint/test commands including single test execution
- Code style: imports, formatting, types, naming, error handling
- Discord patterns: @logged_command, autocomplete, embed emojis
- Service layer abstraction rules
- Model patterns (from_api_data, required IDs)
- Testing with aioresponses and complete model data
- Critical rules for git, services, and commits

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-23 15:13:25 -06:00
Cal Corum
2881207ca4 Update CLAUDE.md docs for all-season player search feature
- Document new autocomplete behavior (deduplicated, all-season search)
- Add PlayerService.search_players() method signature with all_seasons parameter
- Update search logic flow documentation

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-23 14:36:03 -06:00
Cal Corum
471cb88d1f Bump version to 2.27.0 2026-01-23 14:23:19 -06:00
Cal Corum
bf079eab83 Add all-season player search with deduplicated autocomplete
- PlayerService.search_players() now supports all_seasons=True to search across all 13 seasons
- Autocomplete shows unique player names (most recent season's team) instead of duplicates
- Command defaults to most recent season when no season parameter specified
- Users can specify season parameter for historical data

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-23 14:23:16 -06:00
Cal Corum
249c17a64c Add production deployment documentation to CLAUDE.md
- Production server: ssh akamai
- Container path: /root/container-data/major-domo
- Service name: discord-app
- Full release workflow documented

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 13:40:55 -06:00
Cal Corum
a891bb962a Bump version to 2.26.0
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 13:38:37 -06:00
Cal Corum
f007c5b870 Fix frozen flag bug and add Transaction Thaw Report for admins
Bug Fix:
- Fixed /dropadd transactions being marked frozen=True during thaw period
- Now uses current_state.freeze to set frozen flag correctly
- Transactions entered Sat-Sun are now unfrozen and execute Monday

New Feature - Transaction Thaw Report:
- Added data structures for thaw reporting (ThawReport, ThawedMove,
  CancelledMove, ConflictResolution, ConflictContender)
- Modified resolve_contested_transactions() to return conflict details
- Added _post_thaw_report() to post formatted report to admin channel
- Report shows thawed moves, cancelled moves, and conflict resolution
- Handles Discord's 2000 char limit with _send_long_report()

Tests:
- Updated test_views_transaction_embed.py for frozen flag behavior
- Added test for thaw period (freeze=False) scenario
- Updated test_tasks_transaction_freeze.py for new return values
- All tests passing

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 13:35:48 -06:00
Cal Corum
fb76f1edb3 Fix profile commands package not returning expected tuple
The setup_profile_commands() function was returning None instead of the
expected (successful, failed, failed_modules) tuple, causing bot startup
to log "Failed to load profile package: cannot unpack non-iterable NoneType".

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 16:25:38 -06:00
Cal Corum
ee434c98f1 Fix weekly freeze/thaw automation - API params not being sent
Root cause: league_service.update_current_state() was calling self.patch()
without use_query_params=True. The API expected query params but received
JSON body, so database updates for week/freeze silently failed.

Changes:
- Add use_query_params=True to league_service.py:99
- Fix service layer violation in transaction_freeze.py - now uses
  player_service.update_player_team() instead of direct API client
- Bump version to 2.25.8

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 14:00:54 -06:00
Cal Corum
023810538a Bump version to 2.25.7 2026-01-07 22:45:19 -06:00
Cal Corum
6b35a14066 Add dev-only loaded dice command for testing /ab rolls
- New !loaded <d6> <2d6> <d20> [user_id] command for predetermined dice
- Loaded values consumed on next /ab roll (one-shot)
- Supports targeting other users by ID for testing
- Admin-restricted prefix commands (!loaded, !unload, !checkload)
- Self-contained in commands/dev/ package

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 22:45:01 -06:00
Cal Corum
889b3a4e2d Fix sWAR cap validation for /ilmove and /dropadd commands
- Add sWAR cap validation to TransactionBuilder.validate_transaction()
- Use team-specific salary_cap from Team.salary_cap field
- Fall back to config.swar_cap_limit (32.0) if team has no custom cap
- Add major_league_swar_cap field to RosterValidationResult
- Update major_league_swar_status to show / with cap limit
- Add 4 new tests for sWAR cap validation

This fixes a bug where IL moves could put a team over their sWAR cap
because the validation only checked roster counts, not sWAR limits.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-06 13:17:05 -06:00
Cal Corum
4bdfe3ee0a Fix injury commands failing to find certain players
Changed /injury roll, /injury set-new, and /injury clear to use
search_players() instead of get_players_by_name(). The /players?name=
API endpoint fails to find some players (e.g., Gunnar Henderson) while
the /players/search?q= endpoint works correctly.

This fixes the "Player Not Found" error when users try to clear
injuries for players that exist in the database.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 20:15:14 -06:00
Cal Corum
a056dced5c Bump version to 2.25.4
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 14:24:20 -06:00