major-domo-v2/models/roster.py
Cal Corum c01f88e7e3 CLAUDE: Comprehensive bot improvements and test infrastructure
This commit includes various enhancements across the bot architecture:

**New Infrastructure:**
- Added tests/factories.py - Factory classes for creating test data objects
- Added PRE_LAUNCH_ROADMAP.md - Project planning and roadmap documentation

**Model Enhancements:**
- Updated models/roster.py - Enhanced roster data structures
- Updated models/team.py - Improved team model definitions

**Service Layer Improvements:**
- Enhanced services/player_service.py - Better player data handling
- Updated services/roster_service.py - Roster management improvements
- Enhanced services/team_service.py - Team data service refinements
- Updated services/transaction_service.py - Transaction processing enhancements

**Command Updates:**
- Updated commands/teams/info.py - Team information command improvements
- Enhanced commands/voice/tracker.py - Voice channel tracking refinements

**Background Tasks:**
- Updated tasks/custom_command_cleanup.py - Automated cleanup improvements

**View Components:**
- Enhanced views/transaction_embed.py - Transaction embed UI improvements

**Test Coverage Enhancements:**
- Updated tests/test_commands_voice.py - Voice command test improvements
- Enhanced tests/test_dropadd_integration.py - Integration test coverage
- Updated tests/test_services_player_service.py - Player service test coverage
- Enhanced tests/test_services_transaction_builder.py - Transaction builder tests
- Updated tests/test_transactions_integration.py - Transaction integration tests
- Enhanced tests/test_views_transaction_embed.py - UI component test coverage

These changes collectively improve the bot's reliability, maintainability, and test coverage while adding essential infrastructure for continued development.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-02 11:35:26 -05:00

121 lines
4.5 KiB
Python

"""
Roster models for SBA team roster management
Represents team rosters and roster-related data.
"""
from typing import Optional, List
from pydantic import Field
from models.base import SBABaseModel
from models.player import Player
class TeamRoster(SBABaseModel):
"""Represents a complete team roster for a specific week."""
team_id: int = Field(..., description="Team ID from database")
team_abbrev: str = Field(..., description="Team abbreviation")
season: int = Field(..., description="Season number")
week: int = Field(..., description="Week number")
# Roster sections
active_players: List[Player] = Field(default_factory=list, description="Active roster players")
il_players: List[Player] = Field(default_factory=list, description="Injured list players")
minor_league_players: List[Player] = Field(default_factory=list, description="Minor league players")
# Roster statistics
total_wara: float = Field(default=0.0, description="Total active roster WARA")
salary_total: Optional[float] = Field(None, description="Total salary if applicable")
@property
def all_players(self) -> List[Player]:
"""All players on the roster regardless of status."""
return self.active_players + self.il_players + self.minor_league_players
@property
def total_players(self) -> int:
"""Total number of players on roster."""
return len(self.all_players)
@property
def active_count(self) -> int:
"""Number of active players."""
return len(self.active_players)
@property
def il_count(self) -> int:
"""Number of players on IL."""
return len(self.il_players)
@property
def minor_league_count(self) -> int:
"""Number of minor league players."""
return len(self.minor_league_players)
def get_players_by_position(self, position: str) -> List[Player]:
"""Get all active players at a specific position."""
return [p for p in self.active_players if p.primary_position == position]
def find_player(self, player_name: str) -> Optional[Player]:
"""Find a player by name on the roster."""
for player in self.all_players:
if player.name.lower() == player_name.lower():
return player
return None
@classmethod
def from_api_data(cls, data: dict) -> 'TeamRoster':
"""
Create TeamRoster instance from API data.
Expected format from API:
{
'team_id': 123,
'team_abbrev': 'NYY',
'season': 12,
'week': 5,
'active': {'players': [...], 'WARa': 45.2},
'shortil': {'players': [...], 'WARa': 2.1},
'longil': {'players': [...], 'WARa': 12.5}
}
"""
# Create a new dict with the required fields
roster_data = {
'team_id': data.get('team_id'),
'team_abbrev': data.get('team_abbrev', ''),
'season': data.get('season', 12),
'week': data.get('week', 0),
'active_players': [],
'il_players': [],
'minor_league_players': [],
'total_wara': 0.0
}
# Convert player sections - handle API structure
section_mapping = {
'active': 'active_players',
'longil': 'minor_league_players', # Long IL = Minor League
'shortil': 'il_players' # Short IL = Injured List
}
for api_section, model_field in section_mapping.items():
if api_section in data and isinstance(data[api_section], dict):
players_data = data[api_section].get('players', [])
players = []
for player_data in players_data:
# Enhance player data with required fields if missing
enhanced_player_data = player_data.copy()
enhanced_player_data.setdefault('season', data.get('season', 12))
enhanced_player_data.setdefault('team_id', data.get('team_id'))
enhanced_player_data.setdefault('wara', enhanced_player_data.get('WARa', 0.0))
# Use Player.from_api_data to handle proper parsing
player = Player.from_api_data(enhanced_player_data)
players.append(player)
roster_data[model_field] = players
# Handle WARA totals
if 'active' in data and isinstance(data['active'], dict):
roster_data['total_wara'] = data['active'].get('WARa', 0.0)
return cls(**roster_data)