paper-dynasty-gameplay-webapp/app/models/manager_ai.py
Cal Corum 1c24161e76 CLAUDE: Achieve 100% test pass rate with comprehensive AI service testing
- Fix TypeError in check_steal_opportunity by properly mocking catcher defense
- Correct tag_from_third test calculation to account for all adjustment conditions
- Fix pitcher replacement test by setting appropriate allowed runners threshold
- Add comprehensive test coverage for AI service business logic
- Implement VS Code testing panel configuration with pytest integration
- Create pytest.ini for consistent test execution and warning management
- Add test isolation guidelines and factory pattern implementation
- Establish 102 passing tests with zero failures

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-28 17:55:34 -05:00

38 lines
1.9 KiB
Python

"""
ManagerAi model - Pure data model for AI manager configuration.
Migrated from Discord app with business logic extracted to AIService.
Contains only field definitions and relationships.
"""
from sqlmodel import SQLModel, Field, Relationship
from sqlalchemy import Column, BigInteger
from typing import List, TYPE_CHECKING
if TYPE_CHECKING:
# from .play import Play # Will be uncommented when Play model is created
pass
class ManagerAiBase(SQLModel):
"""Base model for ManagerAi configuration data."""
id: int | None = Field(default=None, sa_column=Column(BigInteger(), primary_key=True, autoincrement=True))
name: str = Field(index=True)
steal: int = Field(default=5, ge=1, le=10, description="AI steal aggression level")
running: int = Field(default=5, ge=1, le=10, description="AI base running aggression")
hold: int = Field(default=5, ge=1, le=10, description="AI pitcher hold tendency")
catcher_throw: int = Field(default=5, ge=1, le=10, description="AI catcher throw decision")
uncapped_home: int = Field(default=5, ge=1, le=10, description="AI uncapped advance to home")
uncapped_third: int = Field(default=5, ge=1, le=10, description="AI uncapped advance to third")
uncapped_trail: int = Field(default=5, ge=1, le=10, description="AI trailing runner decisions")
bullpen_matchup: int = Field(default=5, ge=1, le=10, description="AI bullpen usage preference")
behind_aggression: int = Field(default=5, ge=1, le=10, description="AI aggression when behind")
ahead_aggression: int = Field(default=5, ge=1, le=10, description="AI aggression when ahead")
decide_throw: int = Field(default=5, ge=1, le=10, description="AI throw decision making")
class ManagerAi(ManagerAiBase, table=True):
"""ManagerAi model for AI configuration storage."""
# plays: List["Play"] = Relationship(back_populates="managerai") # Will be uncommented when Play model is created