strat-gameplay-webapp/.claude/implementation/02-week6-player-models-overview.md
Cal Corum f9aa653c37 CLAUDE: Reorganize Week 6 documentation and separate player model specifications
Split player model architecture into dedicated documentation files for clarity
and maintainability. Added Phase 1 status tracking and comprehensive player
model specs covering API models, game models, mappers, and testing strategy.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-25 23:48:57 -05:00

12 KiB

Week 6: Player Models & League Integration - Overview

Created: 2025-10-25 Status: Planning Complete, Ready for Implementation Prerequisites: Week 5 Complete (Game engine working) Focus: League-specific player models and API integration


Quick Summary

Implement two-layer player model system:

  1. API Models - Exact match to external league APIs (PD & SBA)
  2. Game Models - Optimized for gameplay with only essential fields

This allows us to:

  • Deserialize API responses with full type safety
  • Work with clean, minimal data in game engine
  • Support both leagues with different data structures

Architecture

┌─────────────────────────────────────────────────────────────┐
│                   External League APIs                       │
│   ┌──────────────────────┐  ┌──────────────────────┐       │
│   │  PD API              │  │  SBA API             │       │
│   │  - Player            │  │  - Player            │       │
│   │  - Batting Ratings   │  │                      │       │
│   │  - Pitching Ratings  │  │                      │       │
│   └──────────────────────┘  └──────────────────────┘       │
└────────────────┬──────────────────────┬─────────────────────┘
                 │                      │
                 ↓                      ↓
┌─────────────────────────────────────────────────────────────┐
│              API Response Models (api_models.py)             │
│   ┌──────────────────────┐  ┌──────────────────────┐       │
│   │  PdPlayerApi         │  │  SbaPlayerApi        │       │
│   │  PdBattingRatingsApi │  │  (with nested Team,  │       │
│   │  PdPitchingRatingsApi│  │   Manager, Division) │       │
│   └──────────────────────┘  └──────────────────────┘       │
└────────────────┬──────────────────────┬─────────────────────┘
                 │                      │
                 ↓                      ↓
┌─────────────────────────────────────────────────────────────┐
│          Mapper Layer (PlayerMapper class)                   │
│              Transforms: API → Game Models                   │
│   - Extracts essential fields                               │
│   - Flattens nested structures                              │
│   - Normalizes position data (pos_1-8 → List[str])         │
└────────────────┬──────────────────────┬─────────────────────┘
                 │                      │
                 ↓                      ↓
┌─────────────────────────────────────────────────────────────┐
│           Game Models (player_models.py)                     │
│   ┌──────────────────────┐  ┌──────────────────────┐       │
│   │  PdPlayer            │  │  SbaPlayer           │       │
│   │  - Basic fields      │  │  - Basic fields      │       │
│   │  - Batting ratings   │  │  - Simplified data   │       │
│   │  - Pitching ratings  │  │                      │       │
│   └──────────────────────┘  └──────────────────────┘       │
└────────────────┬──────────────────────┬─────────────────────┘
                 │                      │
                 ↓                      ↓
┌─────────────────────────────────────────────────────────────┐
│                  Game Engine & Play Resolver                 │
│   - Uses game models during play resolution                 │
│   - PD: Uses outcome probabilities from ratings             │
│   - SBA: Uses simplified result charts                      │
└─────────────────────────────────────────────────────────────┘

Why Two Layers?

Problem

  • External APIs return massive nested JSON (team, division, cardset, rarity, etc.)
  • Game engine only needs minimal data (name, positions, ratings)
  • PD needs 3 API calls per player (player + batting ratings + pitching ratings)

Solution

Layer 1: API Models - Match external structure exactly

  • Full type safety when deserializing
  • All nested objects as Pydantic models
  • Easy to maintain when API changes

Layer 2: Game Models - Only what's needed for gameplay

  • Clean, minimal data
  • Fast serialization for WebSocket
  • Easy to work with in game logic

Mapper Layer - Transform between them

  • Extract essential fields
  • Combine multiple API calls (PD: player + ratings)
  • Normalize differences between leagues

Detailed Documentation

This plan is split across multiple focused files:

Core Specifications

  1. API Models - PD

    • All PD API response models
    • JSON examples
    • Nested structures (Cardset, Rarity, MlbPlayer)
    • Batting & pitching ratings
  2. API Models - SBA

    • SBA API response models
    • JSON examples
    • Nested structures (Team, Manager, Division)
  3. Game Models

    • BasePlayer abstract class
    • SbaPlayer (game-optimized)
    • PdPlayer (game-optimized with ratings)
    • Field selection rationale
  4. Mappers & Factories

    • PlayerMapper (API → Game)
    • PlayerFactory (create by league)
    • Transformation logic
    • Position normalization
  5. API Client

    • LeagueApiClient HTTP client
    • Methods for each endpoint
    • Error handling
    • Usage examples
  6. Testing Strategy

    • Unit test specifications
    • Integration test plans
    • Mock data strategy

Implementation Order

Phase 1: API Models (Day 1)

  1. Create api_models.py
  2. Define all PD API models
  3. Define all SBA API models
  4. Unit tests with real JSON samples

Phase 2: Game Models (Day 1-2)

  1. Create player_models.py
  2. Define BasePlayer abstract
  3. Define SbaPlayer
  4. Define PdPlayer with ratings
  5. Unit tests

Phase 3: Mappers (Day 2)

  1. Create PlayerMapper class
  2. Implement PD mapping (combine 3 API calls)
  3. Implement SBA mapping
  4. Unit tests with transformation examples

Phase 4: API Client (Day 2-3)

  1. Create api_client.py
  2. Implement LeagueApiClient with httpx
  3. Implement PD endpoints
  4. Implement SBA endpoints
  5. Integration tests with mocked responses

Phase 5: Integration (Day 3)

  1. Update league_configs.py with API base URLs
  2. Update PlayResolver to use PD ratings
  3. End-to-end integration tests
  4. Performance testing

Key Design Decisions

Decision 1: Two-Layer Approach

Chosen: API models + Game models (with mapper)

Alternatives Considered:

  • Single model matching API ( too much unnecessary data in game engine)
  • Single game model with manual dict parsing ( no type safety on API responses)

Rationale: Separation of concerns, type safety, performance

Decision 2: Nested Pydantic Models

Chosen: Full Pydantic models for all nested objects (Team, Cardset, etc.)

Alternatives Considered:

  • Dict[str, Any] for nested data ( loses type safety)
  • Flatten everything to top level ( complex mapping logic)

Rationale: Type safety, IDE autocomplete, validation

Decision 3: Position Handling

Chosen: Extract pos_1 through pos_8positions: List[str]

Rationale: Cleaner interface, easier to work with in game logic

Decision 4: PD Ratings Storage

Chosen: Store ratings as part of PdPlayer model (vs L and vs R)

Rationale: Always needed for play resolution, keep together

Decision 5: API Base URLs

Actual URLs (from your data):

  • PD: https://pd.manticorum.com/
  • SBA: https://api.sba.manticorum.com/

File Structure

After implementation, project structure will be:

backend/app/
├── models/
│   ├── api_models.py          # NEW - External API response models
│   ├── player_models.py       # NEW - Game-optimized player models
│   ├── game_models.py         # Existing - Game state models
│   └── db_models.py           # Existing - Database ORM models
│
├── data/
│   ├── __init__.py
│   └── api_client.py          # NEW - HTTP client for league APIs
│
├── config/
│   ├── __init__.py
│   ├── base_config.py         # To create
│   ├── league_configs.py      # To create (with API URLs)
│   └── result_charts.py       # To create
│
└── core/
    ├── play_resolver.py       # UPDATE - Use PD ratings for resolution
    └── ...                    # Existing files

tests/
├── unit/
│   ├── models/
│   │   ├── test_api_models.py      # NEW
│   │   └── test_player_models.py   # NEW
│   └── data/
│       └── test_mappers.py         # NEW
│
└── integration/
    └── data/
        └── test_api_client.py      # NEW

Success Criteria

Functional Requirements

  • Can fetch PD player from API and deserialize to PdPlayerApi
  • Can fetch PD batting ratings and deserialize
  • Can fetch PD pitching ratings and deserialize
  • Can fetch SBA player from API and deserialize to SbaPlayerApi
  • Can map PD API models → PdPlayer game model
  • Can map SBA API models → SbaPlayer game model
  • PlayerFactory creates correct player type by league_id
  • Positions correctly extracted from pos_1-8 fields
  • PD ratings correctly attached to PdPlayer

Non-Functional Requirements

  • All API models pass Pydantic validation with real JSON
  • Unit test coverage > 90%
  • API client handles errors gracefully
  • Serialization/deserialization < 10ms per player
  • Type hints validated by mypy

Timeline & Effort

Estimated Total: 2-3 days (16-24 hours)

Breakdown:

  • API Models: 4-6 hours
  • Game Models: 3-4 hours
  • Mappers: 2-3 hours
  • API Client: 4-6 hours
  • Testing: 3-5 hours

Dependencies:

  • httpx library (already in requirements.txt )
  • Access to PD and SBA APIs (have URLs )
  • Real JSON samples (provided by user )

Next Steps

  1. Read detailed specifications in player-model-specs/ directory
  2. Start with API models (PD first, then SBA)
  3. Implement game models
  4. Create mapper layer
  5. Build API client
  6. Write comprehensive tests
  7. Update PlayResolver to use ratings

Current Status: 📝 Planning Complete - Ready to start implementation Last Updated: 2025-10-25 Week: 6 of Phase 2