The fa_lock_week config existed but was never enforced. Now /dropadd blocks
adding players FROM Free Agency when current_week >= fa_lock_week (14).
Dropping players TO FA remains allowed after the deadline.
Also consolidates two league_service.get_current_state() calls into one
shared fetch at the top of add_move() to eliminate a redundant API round-trip.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The TransactionBuilder cached pre-existing transactions on first load
and never refreshed them. This meant transactions submitted by other
sessions (or newly visible after API fixes) were invisible for the
lifetime of the builder session, causing incorrect roster projections.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Simplify review found that force_refresh=True on every validate_transaction()
call caused redundant API fetches on every embed render and button press.
Instead, invalidate the roster cache after successful submit_transaction() so
the next operation fetches fresh data. This preserves the cache for normal
interaction flows while still preventing stale data after submissions.
Also adds type annotation for roster_svc DI parameter.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TransactionBuilder cached roster data indefinitely via _roster_loaded flag,
causing validation to use stale counts when builders persisted across multiple
/ilmove invocations. Now validate_transaction() always fetches fresh roster
data. Also adds dependency injection for roster_service to improve testability.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
load_existing_transactions only queried for the base team abbreviation
(e.g. "POR"), missing trades involving MiL/IL affiliates ("PORMIL",
"PORIL"). This caused false "too many players" errors when a pending
trade would have cleared a roster spot.
- get_team_transactions now accepts Union[str, List[str]] for team_abbrev
- load_existing_transactions queries all org affiliates [BASE, BASEMiL, BASEIL]
- Added 5 tests covering the fix and backwards compatibility
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ran `ruff check --select F401 --fix` to auto-remove 221 unused imports,
manually removed 4 unused `import discord` from package __init__.py files,
and fixed test import for DISAPPOINTMENT_TIERS to reference canonical location.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>
Prevents players who are already claimed in another team's pending
transaction (frozen=false, cancelled=false) from being added to a new
transaction for the same week.
Changes:
- Add is_player_in_pending_transaction() to TransactionService
- Make TransactionBuilder.add_move() async with validation
- Add check_pending_transactions flag (default True for /dropadd)
- Skip validation for /ilmove and trades (check_pending_transactions=False)
- Add tests/conftest.py for proper test isolation
- Add 4 new tests for pending transaction validation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- 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>
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>
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>
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>
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>
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>
Major fixes and improvements:
Trade System Fixes:
- Fix duplicate player moves in trade embed Player Exchanges section
- Resolve "WVMiL not participating" error for Minor League destinations
- Implement organizational authority model for ML/MiL/IL team relationships
- Update Trade.cross_team_moves to deduplicate using moves_giving only
Team Model Enhancements:
- Rewrite roster_type() method using sname as definitive source per spec
- Fix edge cases like "BHMIL" (Birmingham IL) vs "BHMMIL"
- Update _get_base_abbrev() to use consistent sname-based logic
- Add organizational lookup support in trade participation
Autocomplete System:
- Fix major_league_team_autocomplete invalid roster_type parameter
- Implement client-side filtering using Team.roster_type() method
- Add comprehensive test coverage for all autocomplete functions
- Centralize autocomplete logic to shared utils functions
Test Infrastructure:
- Add 25 new tests for trade models and trade builder
- Add 13 autocomplete function tests with error handling
- Fix existing test failures with proper mocking patterns
- Update dropadd tests to use shared autocomplete functions
Documentation Updates:
- Document trade model enhancements and deduplication fix
- Add autocomplete function documentation with usage examples
- Document organizational authority model and edge case handling
- Update README files with recent fixes and implementation notes
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>