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> |
||
|---|---|---|
| .. | ||
| __init__.py | ||
| base.py | ||
| batting_stats.py | ||
| current.py | ||
| custom_command.py | ||
| division.py | ||
| draft_data.py | ||
| draft_list.py | ||
| draft_pick.py | ||
| game.py | ||
| manager.py | ||
| pitching_stats.py | ||
| player.py | ||
| README.md | ||
| roster.py | ||
| sbaplayer.py | ||
| standings.py | ||
| team.py | ||
| transaction.py | ||
Models Directory
The models directory contains Pydantic data models for Discord Bot v2.0, providing type-safe representations of all SBA (Strat-o-Matic Baseball Association) entities. All models inherit from SBABaseModel and follow consistent validation patterns.
Architecture
Pydantic Foundation
All models use Pydantic v2 with:
- Automatic validation of field types and constraints
- Serialization/deserialization for API interactions
- Type safety with full IDE support
- JSON schema generation for documentation
- Field validation with custom validators
Base Model (base.py)
The foundation for all SBA models:
class SBABaseModel(BaseModel):
model_config = {
"validate_assignment": True,
"use_enum_values": True,
"arbitrary_types_allowed": True,
"json_encoders": {datetime: lambda v: v.isoformat() if v else None}
}
id: Optional[int] = None
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = None
Breaking Changes (August 2025)
Database entities now require id fields since they're always fetched from the database:
Playermodel:id: int = Field(..., description="Player ID from database")Teammodel:id: int = Field(..., description="Team ID from database")
Model Categories
Core Entities
League Structure
team.py- Team information, abbreviations, divisionsdivision.py- Division structure and organizationmanager.py- Team managers and ownershipstandings.py- Team standings and rankings
Player Data
player.py- Core player information and identifierssbaplayer.py- Extended SBA-specific player databatting_stats.py- Batting statistics and performance metricspitching_stats.py- Pitching statistics and performance metricsroster.py- Team roster assignments and positions
Game Operations
game.py- Individual game results and schedulingtransaction.py- Player transactions (trades, waivers, etc.)
Draft System
draft_pick.py- Individual draft pick informationdraft_data.py- Draft round and selection datadraft_list.py- Complete draft lists and results
Custom Features
custom_command.py- User-created Discord commands
Legacy Models
current.py- Legacy model definitions for backward compatibility
Model Validation Patterns
Required Fields
Models distinguish between required and optional fields:
class Player(SBABaseModel):
id: int = Field(..., description="Player ID from database") # Required
name: str = Field(..., description="Player full name") # Required
team_id: Optional[int] = None # Optional
position: Optional[str] = None # Optional
Field Constraints
Models use Pydantic validators for data integrity:
class BattingStats(SBABaseModel):
at_bats: int = Field(ge=0, description="At bats (non-negative)")
hits: int = Field(ge=0, le=Field('at_bats'), description="Hits (cannot exceed at_bats)")
@field_validator('batting_average')
@classmethod
def validate_batting_average(cls, v):
if v is not None and not 0.0 <= v <= 1.0:
raise ValueError('Batting average must be between 0.0 and 1.0')
return v
Custom Validators
Models implement business logic validation:
class Transaction(SBABaseModel):
transaction_type: str
player_id: int
from_team_id: Optional[int] = None
to_team_id: Optional[int] = None
@model_validator(mode='after')
def validate_team_requirements(self):
if self.transaction_type == 'trade':
if not self.from_team_id or not self.to_team_id:
raise ValueError('Trade transactions require both from_team_id and to_team_id')
return self
API Integration
Data Transformation
Models provide methods for API interaction:
class Player(SBABaseModel):
@classmethod
def from_api_data(cls, data: Dict[str, Any]):
"""Create model instance from API response data."""
if not data:
raise ValueError(f"Cannot create {cls.__name__} from empty data")
return cls(**data)
def to_dict(self, exclude_none: bool = True) -> Dict[str, Any]:
"""Convert model to dictionary for API requests."""
return self.model_dump(exclude_none=exclude_none)
Serialization Examples
Models handle various data formats:
# From API JSON
player_data = {"id": 123, "name": "Player Name", "team_id": 5}
player = Player.from_api_data(player_data)
# To API JSON
api_payload = player.to_dict(exclude_none=True)
# JSON string serialization
json_string = player.model_dump_json()
# From JSON string
player_copy = Player.model_validate_json(json_string)
Testing Requirements
Model Validation Testing
All model tests must provide complete data:
def test_player_creation():
# ✅ Correct - provides required ID field
player = Player(
id=123,
name="Test Player",
team_id=5,
position="1B"
)
assert player.id == 123
def test_incomplete_data():
# ❌ This will fail - missing required ID
with pytest.raises(ValidationError):
Player(name="Test Player") # Missing required id field
Test Data Patterns
Use helper functions for consistent test data:
def create_test_player(**overrides) -> Player:
"""Create a test player with default values."""
defaults = {
"id": 123,
"name": "Test Player",
"team_id": 1,
"position": "1B"
}
defaults.update(overrides)
return Player(**defaults)
def test_player_with_stats():
player = create_test_player(name="Star Player")
assert player.name == "Star Player"
assert player.id == 123 # Default from helper
Field Types and Constraints
Common Field Patterns
Identifiers
id: int = Field(..., description="Database primary key")
player_id: int = Field(..., description="Foreign key to player")
team_id: Optional[int] = Field(None, description="Foreign key to team")
Names and Text
name: str = Field(..., min_length=1, max_length=100)
abbreviation: str = Field(..., min_length=2, max_length=5)
description: Optional[str] = Field(None, max_length=500)
Statistics
games_played: int = Field(ge=0, description="Games played (non-negative)")
batting_average: Optional[float] = Field(None, ge=0.0, le=1.0)
era: Optional[float] = Field(None, ge=0.0, description="Earned run average")
Dates and Times
game_date: Optional[datetime] = None
created_at: Optional[datetime] = None
season_year: int = Field(..., ge=1900, le=2100)
Model Relationships
Foreign Key Patterns
Models reference related entities via ID fields:
class Player(SBABaseModel):
id: int
team_id: Optional[int] = None # References Team.id
class BattingStats(SBABaseModel):
player_id: int # References Player.id
season: int
team_id: int # References Team.id
Nested Objects
Some models contain nested structures:
class CustomCommand(SBABaseModel):
name: str
creator: Manager # Nested Manager object
response: str
class DraftPick(SBABaseModel):
pick_number: int
player: Optional[Player] = None # Optional nested Player
team: Team # Required nested Team
Validation Error Handling
Common Validation Errors
- Missing required fields - Provide all required model fields
- Type mismatches - Ensure field types match model definitions
- Constraint violations - Check field validators and constraints
- Invalid nested objects - Validate all nested model data
Error Examples
try:
player = Player(name="Test") # Missing required id
except ValidationError as e:
print(e.errors())
# [{'type': 'missing', 'loc': ('id',), 'msg': 'Field required'}]
try:
stats = BattingStats(hits=5, at_bats=3) # hits > at_bats
except ValidationError as e:
print(e.errors())
# Constraint violation error
Performance Considerations
Model Instantiation
- Use
model_validate()for external data - Use
model_construct()for trusted internal data (faster) - Cache model instances when possible
- Avoid repeated validation of the same data
Memory Usage
- Models are relatively lightweight
- Nested objects can increase memory footprint
- Consider using
__slots__for high-volume models - Use
exclude_none=Trueto reduce serialization size
Development Guidelines
Adding New Models
- Inherit from SBABaseModel for consistency
- Define required fields explicitly with proper types
- Add field descriptions for documentation
- Include validation rules for data integrity
- Provide
from_api_data()class method if needed - Write comprehensive tests covering edge cases
Model Evolution
- Backward compatibility - Add optional fields for new features
- Migration patterns - Handle schema changes gracefully
- Version management - Document breaking changes
- API alignment - Keep models synchronized with API
Testing Strategy
- Unit tests for individual model validation
- Integration tests with service layer
- Edge case testing for validation rules
- Performance tests for large data sets
Next Steps for AI Agents:
- Review existing model implementations for patterns
- Understand the validation rules and field constraints
- Check the service layer integration in
/services - Follow the testing patterns with complete model data
- Consider the API data format when creating new models