paper-dynasty-gameplay-webapp/app/models/README.md
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

228 lines
6.2 KiB
Markdown

# Models Directory
This directory contains pure data models for the Paper Dynasty web app, migrated from the Discord app following the **Model/Service Architecture** pattern.
## Architecture Principle
**Models = Pure Data | Services = Business Logic**
- **Models**: Field definitions, relationships, basic validators only
- **Services**: Complex logic, UI formatting, game management, AI decisions
## Migration Status
### ✅ Completed Models
| Model | Status | Description | Business Logic Extracted |
|-------|--------|-------------|--------------------------|
| `ManagerAi` | ✅ Complete | AI configuration data | → `AIService` (9 methods) |
| `Cardset` | ✅ Complete | Card set metadata | None (pure data) |
### 🚧 In Progress
| Model | Status | Description | Business Logic to Extract |
|-------|--------|-------------|--------------------------|
| `Team` | 📋 Next | Team identity data | → `UIService` (embed property) |
| `Player` | 📋 Planned | Player metadata | → `UIService` (Discord markdown) |
### 📋 Future Phases
- **Phase 3**: Game structure (Game, Play models)
- **Phase 4**: Card and rating models
- **Phase 5**: Web-specific models (sessions, preferences)
## Model Patterns
### Pure Data Model Structure
```python
# Base model for validation and field definitions
class ModelBase(SQLModel):
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True, description="Field description")
@field_validator('name')
@classmethod
def validate_name(cls, v: str) -> str:
# Basic validation only
if not v or not v.strip():
raise ValueError("Name cannot be empty")
return v
# Table model for database operations
class Model(ModelBase, table=True):
# relationships: List["RelatedModel"] = Relationship(...)
pass
```
### What STAYS in Models
**Field definitions and types**
```python
name: str = Field(index=True)
ranked_legal: bool = Field(default=False)
```
**Database relationships**
```python
players: List["Player"] = Relationship(back_populates="cardset")
```
**Basic field validation**
```python
@field_validator('name')
def validate_name_not_empty(cls, v: str) -> str:
if not v.strip():
raise ValueError("Name cannot be empty")
return v
```
### What MOVES to Services
**Complex business logic**
```python
# BEFORE (in model)
def check_steal_opportunity(self, game, to_base):
# Complex AI decision logic...
# AFTER (in service)
def check_steal_opportunity(self, manager_ai, game, to_base):
# Same logic but in AIService
```
**UI formatting**
```python
# BEFORE (in model)
@property
def embed(self) -> discord.Embed:
# Discord-specific formatting...
# AFTER (in service)
def format_team_display(self, team) -> dict:
# Platform-agnostic formatting
```
**Game mechanics**
```python
# BEFORE (in model)
def initialize_play(self, session):
# Complex game setup logic...
# AFTER (in service)
def initialize_game(self, game_id) -> Play:
# Same logic but in GameService
```
## Testing Strategy
All models use the factory pattern with transaction rollback:
```python
# test_model.py
def test_model_creation(db_session):
model = ModelFactory.create(db_session, field="value")
assert model.field == "value"
# Automatic rollback ensures isolation
```
See `tests/README.md` for complete testing documentation.
## File Organization
```
models/
├── __init__.py # Export all models
├── manager_ai.py # ✅ AI configuration (complete)
├── cardset.py # ✅ Card set metadata (complete)
├── team.py # 🚧 Team identity (next)
├── player.py # 📋 Player metadata (planned)
├── game.py # 📋 Game structure (planned)
├── play.py # 📋 Gameplay state (planned)
└── ai_responses.py # AI decision response models
```
## Migration Guidelines
When migrating a model from `../discord-app/`:
### 1. Analyze Original Model
```bash
# Find the model in Discord app
grep -r "class ModelName" ../discord-app/
```
### 2. Separate Data from Logic
- **Keep**: Field definitions, relationships, basic validation
- **Extract**: Methods, computed properties, complex logic
### 3. Create Pure Data Model
```python
class ModelBase(SQLModel):
# Only field definitions and basic validation
class Model(ModelBase, table=True):
# Only relationships
```
### 4. Extract Business Logic
```python
class ModelService(BaseService):
def extracted_method(self, model_instance, params):
# Migrated business logic
```
### 5. Create Comprehensive Tests
```python
# Validation tests (no database)
def test_model_validation():
model = ModelFactory.build(invalid_field="bad")
# Test validation
# Database tests (with rollback)
def test_model_persistence(db_session):
model = ModelFactory.create(db_session)
# Test database operations
```
### 6. Update Migration Plan
- Mark model as complete in `.claude/model-migration-plan.md`
- Update this README with new model status
## Dependencies
Models depend on:
- `sqlmodel` - Database ORM and validation
- `pydantic` - Field validation and serialization
- `sqlalchemy` - Advanced database features
Models should NOT depend on:
- `discord.py` - Platform-specific library
- `fastapi` - Web framework
- Service classes - Business logic layer
## Best Practices
### DO:
- ✅ Keep models as simple data containers
- ✅ Use descriptive field documentation
- ✅ Add basic validation for data integrity
- ✅ Follow naming conventions from original models
- ✅ Create comprehensive factory-based tests
### DON'T:
- ❌ Add business logic methods to models
- ❌ Include platform-specific dependencies
- ❌ Create computed properties with complex logic
- ❌ Hard-code values that belong in services
- ❌ Skip validation or tests
## Future Considerations
As we complete the migration:
1. **Web-specific models** will be added for session management
2. **Performance optimization** may require relationship tuning
3. **Database migrations** will be managed via Alembic
4. **API serialization** will use Pydantic's serialization features
The goal is to have a clean, testable, platform-agnostic data layer that can support web, mobile, and future interfaces.