Commit Graph

371 Commits

Author SHA1 Message Date
Cal Corum
0163f24000 Fix null card_id in RosterLink causing IntegrityError
Previously, if get_card_or_none returned None (when a card ID from the
Google Sheet doesn't exist in the database), the code would create a
RosterLink with card=None, causing card_id to be null which violates
the NOT NULL constraint on the primary key.

Now we check if this_card is None before creating the RosterLink and
raise a CardNotFoundException with a helpful error message to guide
the user to fix their roster sheet.

Fixes the error: null value in column "card_id" of relation "rosterlink"
violates not-null constraint

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-15 09:15:07 -06:00
Cal Corum
51004ea143 Fix bot crash when substituting player without eligible position
Bug: When a user attempted to substitute a player who didn't have the required
position rating, the bot would display an error message but leave the database
session in an inconsistent state. The old player was marked inactive and flushed
to the session, but when the position check failed, the function returned early
without rolling back the session. This left the session dirty, causing crashes
on subsequent operations.

Fix: Added session.rollback() before returning when PositionNotFoundException
is caught, ensuring the database session is cleanly reset.

Location: utilities/dropdown.py:479-480 in SelectBatterSub.callback()

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-12 16:02:35 -06:00
Cal Corum
440f017c92 Add HTTP health check endpoint for container monitoring
Implements a comprehensive health check system using aiohttp to support
container orchestration and external monitoring systems.

Features:
- /health endpoint: Basic liveness check (is process running?)
- /ready endpoint: Readiness check (is bot connected to Discord?)
- /metrics endpoint: Detailed bot metrics (guilds, users, cogs, latency)

Changes:
- Add aiohttp to requirements.txt
- Create health_server.py module with HTTP server
- Update paperdynasty.py to run health server alongside bot
- Update docker-compose.yml with HTTP-based healthcheck
- Fix deploy.sh Docker image name

Benefits:
- Auto-restart on bot hangs/deadlocks
- Foundation for external monitoring (Prometheus, Grafana, etc.)
- Detailed diagnostics for troubleshooting
- Industry-standard health check pattern

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-12 14:44:53 -06:00
Cal Corum
af49704272 Catchup files 2025-11-11 13:22:06 -06:00
Cal Corum
5d841419b0 CLAUDE: Fix Event ID 9 gauntlet UnboundLocalError for team_id variable
When a gauntlet game ended for Event ID 9, the post_result function would crash with:
"UnboundLocalError: cannot access local variable 'team_id' where it is not associated with a value"

Event ID 9 was missing team_id initialization, while all other events (3,4,5,6,7,8)
properly set team_id. Added team_id = None to match the pattern used by Events 5, 6, and 8.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 12:57:12 -06:00
Cal Corum
fb8450f2d2 05 Live Updates 2025-11-10 17:13:02 -06:00
Cal Corum
e1f59cc49e CLAUDE: Fix Event ID 9 gauntlet rewards missing cardset assignment
Event ID 9 (Live 25) gauntlet rewards were being given without cardset_id
assigned, causing Team Choice packs to be unconfigured and unusable.

Root cause: Line 1923 checked if event ID was in [3, 4, 5, 6, 8], but
Event ID 9 was missing from this list. This caused the entire reward
assignment block (lines 1923-1957) including Event 9's cardset logic
(lines 1945-1948) to be skipped.

Event 9 should assign:
- cardset_id 27 for standard packs (2005 Live)
- cardset_id 26 for Promo Choice packs (pack_type_id 9)

Added 9 to the event ID list at line 1923 to enable proper cardset
assignment for Event 9 gauntlet rewards.

Fixes: Team Choice packs from Event 9 gauntlet missing cardset_id

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 16:01:46 -06:00
Cal Corum
f7f37c9d95 CLAUDE: Handle Team Choice packs with no team/cardset assigned
Users were receiving "This interaction failed" when trying to open Team
Choice packs that had neither pack_team nor pack_cardset assigned in the
database.

The previous fix only handled packs WITH cardset but WITHOUT team. This
adds handling for completely unconfigured Team Choice packs.

Now shows a helpful error message: "This Team Choice pack needs to be
assigned a team and cardset. Please contact an admin to configure this pack."

This prevents the KeyError exception that was being thrown at
helpers.py:1692 when open_choice_pack() received a pack with pack_team=None.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 15:09:26 -06:00
Cal Corum
81373a9b42 CLAUDE: Fix Team Choice pack hanging by using interaction.followup.send()
When opening a Team Choice pack without a pre-assigned team, the bot would:
1. Edit the interaction to remove the pack selection view
2. Send team selection (AL/NL) via interaction.channel.send()
3. Return without sending a followup to the interaction
4. Discord left waiting for a response that never came

Changed interaction.channel.send() to interaction.followup.send() with
a helpful message explaining what's happening. This properly responds to
the interaction and allows the team selection dropdown to function.

The issue occurred at discord_ui/selectors.py:188 in SelectOpenPack callback.

Fixes: /open-packs command hangs when selecting 'Team Choice' pack type

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 09:53:50 -06:00
Cal Corum
021573bc65 DOCS: Add production cogs documentation for future reference
Created comprehensive documentation distinguishing between:
- Production cogs currently loaded (cogs.players, etc.)
- Work-in-progress refactored cogs (cogs/players_new)
- Which bug fixes apply to production vs future releases
- Migration checklist for when players_new goes live

This prevents confusion when making fixes - developers need to know
whether to update cogs/players.py (production) or cogs/players_new/
(WIP) or both.

Key insights:
- gauntlet commands are in cogs/players.py (production)
- cogs/players_new is NOT loaded in paperdynasty.py yet
- Recent fixes applied to both for consistency
- Migration requires updating COGS list in paperdynasty.py

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 09:46:11 -06:00
Cal Corum
1e75f1baba CLAUDE: Add news-ticker message when gauntlet runs end with 2 losses
Users reported that end-of-run messages to #pd-news-ticker were no longer
appearing when gauntlet teams lost their second game. The news-ticker
announcement was only happening for 10-win completions, not 2-loss endings.

Changes:
- Updated end_run() to accept bot and main_team parameters
- Added send_to_channel() call when losses == 2 (natural run end)
- Skips news-ticker for manual resets (force_end=True)
- Updated post_result() to pass bot and main_team to end_run()
- Updated manual reset calls to explicitly pass force_end=True

Now when a gauntlet team loses their second game, #pd-news-ticker will
show: "The **[Team]** have completed their **[Event]** Gauntlet run
with a final record of [wins]-[losses]."

The draft completion message to news-ticker was already working correctly
at cogs/players_new/gauntlet.py:178-183.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 09:17:55 -06:00
Cal Corum
c2bbf94925 CLAUDE: Fix get_roster_sheet() to handle both dict and Team objects
Fixed TypeError: 'Team' object is not subscriptable error occurring at the
end of /gauntlet start command when sending completion messages.

The get_roster_sheet() function was using dict syntax (team["gsheet"]) but
was receiving Team objects from gauntlet commands. Updated the function to
handle both dict and Team object formats using isinstance() check.

This follows the same pattern as get_context_user() and owner_only() for
handling multiple input types gracefully.

Fixes: Command 'start' raised an exception: TypeError: 'Team' object is
not subscriptable (reported at end of gauntlet draft completion)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 09:11:37 -06:00
Cal Corum
943dcc9b74 CLAUDE: Add get_context_user() helper for hybrid command compatibility
Created get_context_user() helper function to safely extract the user from
either Context or Interaction objects. This prevents AttributeError issues
when hybrid commands are invoked as slash commands.

Hybrid commands receive commands.Context (with .author) when invoked with
prefix commands, but discord.Interaction (with .user) when invoked as slash
commands. The helper function handles both cases transparently.

Updated all affected hybrid commands:
- /branding-pd (cogs/players.py, cogs/players_new/team_management.py)
- /pullroster (cogs/players.py, cogs/players_new/team_management.py)
- /newsheet (cogs/economy_new/team_setup.py)
- /lastpack (cogs/economy_new/packs.py)

This follows the same pattern as the owner_only() fix and provides a
consistent, maintainable solution for all hybrid commands.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 09:07:09 -06:00
Cal Corum
c0f9466e54 CLAUDE: Fix /reset-image AttributeError by updating owner_only function
The owner_only() function was accessing ctx.author.id, which caused an
AttributeError when called with Interaction objects from slash commands
(which use .user instead of .author).

Updated both utils.py and helpers/utils.py to handle both Context and
Interaction objects by checking for .user first, then falling back to
.author for backward compatibility with traditional commands.

Fixes: Command 'reset-image' raised an exception: AttributeError:
'Interaction' object has no attribute 'author'

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 08:21:17 -06:00
Cal Corum
c043948238 CLAUDE: Fix gauntlet game creation and Event 9 issues
Multiple fixes to resolve PlayNotFoundException and lineup initialization errors:

1. gauntlets.py:
   - Fixed Team object subscriptable errors (use .id instead of ['id'])
   - Added fallback cardsets (24, 25, 26) for Event 9 RP shortage
   - Fixed draft_team type handling (can be Team object or dict)

2. cogs/gameplay.py:
   - Fixed gauntlet game creation flow to read field player lineup from sheets
   - Catches LineupsMissingException when SP not yet selected
   - Instructs user to run /gamestate after SP selection

3. utilities/dropdown.py:
   - Fixed SelectStartingPitcher to create own session instead of using closed session
   - Store game/team IDs instead of objects to avoid detached session issues
   - Added exception handling for failed legality check API calls

These changes fix the issue where gauntlet games would fail to initialize
because the SP lineup entry wasn't being committed to the database.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 18:56:38 -06:00
Cal Corum
07195f9ad3 CLAUDE: Add Event ID 9 (Live 25) gauntlet configuration
Fixed missing draft configuration for Event ID 9 "Live 25" gauntlet that was causing crashes when users tried to start a gauntlet run.

Changes:
- Added cardset configuration for Event 9 (cardsets 27, 28, 29)
- Added Event 9 to max_counts progressive difficulty logic
- Added Event 9 to draft_loop() events list
- Opponent configuration for Event 9 was already present

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 13:03:41 -06:00
Cal Corum
904dae9a47 Gauntlet Pack Type Update 2025-11-09 06:34:14 -06:00
Cal Corum
0e3b98eb65 S10 Updates + PR Bugfix 2025-11-09 06:12:46 -06:00
Cal Corum
80e94498fa CLAUDE: Add safe WPA lookup with fallback to prevent KeyError crashes
Implements defensive error handling for WPA (Win Probability Added) calculations when rare game states are missing from the static lookup table. The safe_wpa_lookup() function uses a three-tier fallback strategy: exact lookup, bases-empty fallback, and 0.0 default value.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 18:25:59 -05:00
Cal Corum
660c6ad904 Added search functionality to /player command 2025-10-08 14:45:41 -05:00
Cal Corum
b1d05309ef Cogs to Packages Groundwork 2025-08-17 08:46:55 -05:00
Cal Corum
c98c202224 Update gameplay_queries.py
Decision bug fixes
2025-07-23 08:58:41 -05:00
Cal Corum
3debfd6e82 Catchup commit
Includes discord_ui refactor, testing overhaul, addition of
2025-07-22 09:22:19 -05:00
Cal Corum
dd23d3657a Team Choice pack bug - not including cardset 2025-06-04 22:30:41 -05:00
Cal Corum
65abc8ed55 Remove outdate image links
Add S3 image links
Pull all fielding ratings at game start
2025-06-04 09:54:13 -05:00
Cal Corum
a4adf50ca1 Added discord bot object to complete game function 2025-06-01 09:44:16 -05:00
Cal Corum
b3fa68b80e Bug fixes for uncapped doubles 2025-05-30 21:16:51 -05:00
Cal Corum
6adf6e34b1 Gauntlet 8 team updates 2025-05-30 21:15:41 -05:00
Cal Corum
17680a2348 Added /substitution defense 2025-05-30 01:19:45 -05:00
Cal Corum
e9c9a3f392 dictionary to object bug fix 2025-05-29 21:54:46 -05:00
Cal Corum
e366564bef Adding gauntlet 8
Season 9 updates
Uncapped runs scored bug fixed
2025-05-29 21:54:16 -05:00
Cal Corum
6a355def4b Season 9 Updates 2025-05-03 19:38:29 -05:00
Cal Corum
cffc9380f1 Replacing 1998 Live with 1998 Season 2025-04-14 16:28:14 -05:00
Cal Corum
cb2637086e Live scorecard fix
Gauntlet entry string fix
2025-03-31 13:54:39 -05:00
Cal Corum
9218bd6047 Update cache reset command
Decrease cache limit to 3 days
Add kickstart live scorecard function
2025-03-09 14:20:30 -05:00
Cal Corum
92c7f47692 Advance trail runner when thrown at and safe 2025-03-09 13:21:08 -05:00
Cal Corum
36fd848b62 Bug fix: pitchers auto-fatigue one out too late 2025-03-09 13:07:09 -05:00
Cal Corum
a416e90db9 New postion sub logic 2025-03-09 00:59:10 -06:00
Cal Corum
35a62362ce Fix card cache bug 2025-03-09 00:58:47 -06:00
Cal Corum
cf4157a59d Increase scorebug timeout to 8 seconds 2025-03-09 00:58:15 -06:00
Cal Corum
8e35812cd3 Increase concurrent db connections
Decrease timeout on Scorebug buttons to reduce open connections
2025-03-03 22:13:40 -06:00
Cal Corum
579bde6c03 Updated lineup string 2025-02-28 22:48:34 -06:00
Cal Corum
8b8fa65023 Add lineup embed field without links 2025-02-28 22:24:11 -06:00
Cal Corum
61df90b2ea Update caching of pitcher and batter scouting 2025-02-23 23:23:59 -06:00
Cal Corum
9d831a9512 Post gamestate publicly if human team GM runs command 2025-02-23 23:20:54 -06:00
Cal Corum
f8aad38739 Update cache refresh logic to replace vs delete 2025-02-23 22:50:58 -06:00
Cal Corum
557404301a Fix fatigue bugs 2025-02-11 00:58:45 -06:00
Cal Corum
4d59247e5c Fix Steal + Overthrow on OBC 5 2025-02-11 00:10:53 -06:00
Cal Corum
b454912393 Remove 3B hold check for runner on 2nd 2025-02-10 23:51:56 -06:00
Cal Corum
50895fef90 Show charts on SPD checks
Fix gb chart with OBC 5, 7
Add 1998 to player command
2025-02-10 23:44:05 -06:00