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

6.2 KiB

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

# 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

name: str = Field(index=True)
ranked_legal: bool = Field(default=False)

Database relationships

players: List["Player"] = Relationship(back_populates="cardset")

Basic field validation

@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

# 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

# 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

# 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:

# 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

# 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

class ModelBase(SQLModel):
    # Only field definitions and basic validation

class Model(ModelBase, table=True):
    # Only relationships

4. Extract Business Logic

class ModelService(BaseService):
    def extracted_method(self, model_instance, params):
        # Migrated business logic

5. Create Comprehensive Tests

# 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.