paper-dynasty-gameplay-webapp/.claude/model-migration-plan.md
Cal Corum 559fe73f07 CLAUDE: Complete Player model migration with service layer and integration test infrastructure
## Player Model Migration
- Migrate Player model from Discord app following Model/Service Architecture pattern
- Extract all business logic from Player model to PlayerService
- Create pure data model with PostgreSQL relationships (Cardset, PositionRating)
- Implement comprehensive PlayerFactory with specialized methods for test data

## PlayerService Implementation
- Extract 5 business logic methods from original Player model:
  - get_batter_card_url() - batting card URL retrieval
  - get_pitcher_card_url() - pitching card URL retrieval
  - generate_name_card_link() - markdown link generation
  - get_formatted_name_with_description() - name formatting
  - get_player_description() - description from object or dict
- Follow BaseService pattern with dependency injection and logging

## Comprehensive Testing
- 35 passing Player tests (14 model + 21 service tests)
- PlayerFactory with specialized methods (batting/pitching cards, positions)
- Test isolation following factory pattern and db_session guidelines
- Fix PostgreSQL integer overflow in test ID generation

## Integration Test Infrastructure
- Create integration test framework for improving service coverage
- Design AIService integration tests targeting uncovered branches
- Demonstrate real database query testing with proper isolation
- Establish patterns for testing complex game scenarios

## Service Coverage Analysis
- Current service coverage: 61% overall
- PlayerService: 100% coverage (excellent migration example)
- AIService: 60% coverage (improvement opportunities identified)
- Integration test strategy designed to achieve 90%+ coverage

## Database Integration
- Update Cardset model to include players relationship
- Update PositionRating model with proper Player foreign key
- Maintain all existing relationships and constraints
- Demonstrate data isolation and automatic cleanup in tests

## Test Suite Status
- 137 tests passing, 0 failures (maintained 100% pass rate)
- Added 35 new tests while preserving all existing functionality
- Integration test infrastructure ready for coverage improvements

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-29 16:20:29 -05:00

266 lines
10 KiB
Markdown

# Model Migration Plan: Data Models + Business Logic Extraction
## Overview
This document tracks the migration of models from Discord app to web app, with careful separation of data models from business logic. All extracted business logic is tracked to ensure proper implementation in services.
## Migration Principle
**Models = Pure Data | Services = Business Logic**
- Models: Field definitions, relationships, basic validators
- Services: Complex logic, UI formatting, game management, AI decisions
---
## Phase 1: Foundation Data Models
### 1. `ManagerAi` - AI Configuration Data ✅ COMPLETE
**Model Migration**:
- ✅ Keep: AI parameter fields (steal, running, hold, etc.)
- ✅ Keep: Database relationships
- ✅ Remove: All decision methods
**Business Logic to Extract**:
| Original Method | Target Service | New Method | Status |
|-----------------|---------------|------------|---------|
| `check_jump()` | AIService | `check_steal_opportunity()` | ✅ DONE |
| `tag_from_second()` | AIService | `check_tag_from_second()` | ✅ DONE |
| `tag_from_third()` | AIService | `check_tag_from_third()` | ✅ DONE |
| `throw_at_uncapped()` | AIService | `decide_throw_target()` | ✅ DONE |
| `uncapped_advance()` | AIService | `decide_runner_advance()` | ✅ DONE |
| `defense_alignment()` | AIService | `set_defensive_alignment()` | ✅ DONE |
| `gb_decide_run()` | AIService | `decide_groundball_running()` | ✅ DONE |
| `gb_decide_throw()` | AIService | `decide_groundball_throw()` | ✅ DONE |
| `replace_pitcher()` | AIService | `should_replace_pitcher()` | ✅ DONE |
**Implementation Notes**:
- ✅ Pure data model created in `app/models/manager_ai.py`
- ✅ All business logic extracted to `app/services/ai_service.py`
- ✅ AI response models created in `app/models/ai_responses.py`
- ✅ Comprehensive unit tests created and passing
- ✅ PostgreSQL integration working
### 2. `Cardset` - Card Set Metadata ✅ COMPLETE
**Model Migration**:
- ✅ Keep: Basic metadata (id, name, ranked_legal)
- ✅ Keep: Relationships to games/players
**Business Logic to Extract**: None (pure data model)
**Implementation Notes**:
- ✅ Pure data model created in `app/models/cardset.py`
- ✅ No business logic extraction needed (already pure data)
- ✅ Comprehensive unit tests created and passing (23 tests)
- ✅ Factory pattern implemented for test data generation
### 3. `Team` - Team Identity Data ✅ COMPLETE
**Model Migration**:
- ✅ Keep: Team data fields (abbrev, names, wallet, etc.)
- ✅ Keep: Simple `description` property
- ✅ Remove: `embed` property (Discord UI)
**Business Logic to Extract**:
| Original Method/Property | Target Service | New Method | Status |
|-------------------------|---------------|------------|---------|
| `embed` property | UIService | `format_team_display()` | ✅ DONE |
**Implementation Notes**:
- ✅ Pure data model created in `app/models/team.py`
- ✅ Discord `embed` property extracted to `app/services/ui_service.py`
- ✅ UIService integrated with dependency injection in service container
- ✅ Comprehensive unit tests created and passing (25 tests)
- ✅ Team factory created for test data generation
- ✅ No business logic extraction needed beyond embed formatting
---
## Phase 2: Player and Card Data
### 4. `Player` - Player Metadata ✅ COMPLETE
**Model Migration**:
- ✅ Keep: Player metadata (name, cost, positions, etc.)
- ✅ Remove: `name_with_desc` property (moved to service)
- ✅ Remove: `name_card_link()` method (moved to service)
**Business Logic to Extract**:
| Original Method/Property | Target Service | New Method | Status |
|-------------------------|---------------|------------|---------|
| `name_card_link()` | PlayerService | `generate_name_card_link()` | ✅ DONE |
| `batter_card_url` | PlayerService | `get_batter_card_url()` | ✅ DONE |
| `pitcher_card_url` | PlayerService | `get_pitcher_card_url()` | ✅ DONE |
| `name_with_desc` | PlayerService | `get_formatted_name_with_description()` | ✅ DONE |
| `player_description()` function | PlayerService | `get_player_description()` | ✅ DONE |
**Implementation Notes**:
- ✅ Pure data model created in `app/models/player.py`
- ✅ All business logic extracted to `app/services/player_service.py`
- ✅ Comprehensive unit tests created and passing (35 tests)
- ✅ Factory pattern implemented for test data generation
- ✅ PostgreSQL integration working with proper relationships
- ✅ Cardset and PositionRating relationships established
### 5-8. Card and Rating Models
**Models**: `BattingCard`, `PitchingCard`, `BattingRatings`, `PitchingRatings`, `BatterScouting`, `PitcherScouting`, `Card`, `PositionRating`
**Migration**: Pure data models - no business logic extraction needed
---
## Phase 3: Game Structure (Critical)
### 9. `Game` - Game State and Management ⭐
**Model Migration**:
- ✅ Keep: Game metadata (teams, season, settings)
- ✅ Keep: Database relationships
- ❌ Remove: `channel_id` (Discord-specific)
- ❌ Extract: All business logic methods
**Business Logic to Extract**:
| Original Method/Property | Target Service | New Method | Status |
|-------------------------|---------------|------------|---------|
| `initialize_play()` | GameService | `initialize_game()` | 📋 TODO |
| `current_play_or_none()` | GameService | `get_current_play()` | 📋 TODO |
| `team_lineup()` | GameService | `format_team_lineup()` | 📋 TODO |
| `cardset_param_string` | GameService | `build_cardset_params()` | 📋 TODO |
| `human_team` property | GameService | `get_human_team()` | 📋 TODO |
| `league_name` property | GameService | `get_league_name()` | 📋 TODO |
**Critical Implementation Notes**:
- `initialize_play()` contains complex game setup logic (lines 171-230)
- `team_lineup()` handles lineup formatting with Discord links
- Game state management methods are core to gameplay
### 10-11. Link Models
**Models**: `GameCardsetLink`, `RosterLink`, `Lineup`
**Migration**: Pure relationship models - no extraction needed
---
## Phase 4: Gameplay State (Heaviest Extraction)
### 12. `Play` - Gameplay State and Statistics ⭐
**Model Migration**:
- ✅ Keep: Game state data (scores, outs, runners)
- ✅ Keep: Statistical tracking fields
- ✅ Keep: Relationships to lineups/game
- ❌ Extract: All computed properties and methods
**Business Logic to Extract**:
| Original Method/Property | Target Service | New Method | Status |
|-------------------------|---------------|------------|---------|
| `init_ai()` | GameplayService | `initialize_play_ai()` | 📋 TODO |
| `ai_run_diff` property | GameplayService | `calculate_run_differential()` | 📋 TODO |
| `ai_is_batting` property | GameplayService | `is_ai_batting()` | 📋 TODO |
| `could_walkoff` property | GameplayService | `check_walkoff_situation()` | 📋 TODO |
| `scorebug_ascii` property | UIService | `format_scoreboard()` | 📋 TODO |
**Critical Implementation Notes**:
- `scorebug_ascii` creates ASCII scoreboard display (lines 1223-1243)
- AI integration properties are used throughout gameplay
- Statistical calculations affect game flow
---
## New Web-Specific Models to Add
### Web Session and User Management
| Model | Purpose | Status |
|-------|---------|---------|
| `WebSession` | User session management | 📋 TODO |
| `UserPreferences` | User settings and preferences | 📋 TODO |
| `GameViewState` | UI state for live game viewing | 📋 TODO |
| `Notification` | Web notification queue | 📋 TODO |
---
## Service Implementation Tracker
### AIService - AI Decision Making
- [ ] `check_steal_opportunity()` - Complex steal decision logic
- [ ] `check_tag_from_second()` - Tag-up decisions from 2nd
- [ ] `check_tag_from_third()` - Tag-up decisions from 3rd
- [ ] `decide_throw_target()` - Uncapped runner throw decisions
- [ ] `decide_runner_advance()` - Uncapped advance decisions
- [ ] `set_defensive_alignment()` - Defensive positioning
- [ ] `decide_groundball_running()` - Groundball running decisions
- [ ] `decide_groundball_throw()` - Groundball throw decisions
- [ ] `should_replace_pitcher()` - Pitcher replacement logic
### GameService - Game Management
- [ ] `initialize_game()` - Game setup and first play creation
- [ ] `get_current_play()` - Current play retrieval
- [ ] `format_team_lineup()` - Lineup display formatting
- [ ] `build_cardset_params()` - Cardset parameter building
- [ ] `get_human_team()` - Human team identification
- [ ] `get_league_name()` - League name formatting
### GameplayService - Live Game Logic
- [ ] `initialize_play_ai()` - AI setup for plays
- [ ] `calculate_run_differential()` - Score differential calculation
- [ ] `is_ai_batting()` - AI batting turn detection
- [ ] `check_walkoff_situation()` - Walkoff scenario detection
### UIService - User Interface Formatting
- [ ] `format_team_display()` - Team display for web UI
- [ ] `format_player_link()` - Player links for web
- [ ] `get_batter_card_image()` - Batter card image URLs
- [ ] `get_pitcher_card_image()` - Pitcher card image URLs
- [ ] `format_scoreboard()` - Live scoreboard display
---
## Migration Validation Checklist
### ✅ Model Purity
- [ ] No business logic methods in models
- [ ] Only field definitions and relationships
- [ ] Basic validators for data integrity only
- [ ] No Discord dependencies
### ✅ Service Completeness
- [ ] All extracted methods implemented in services
- [ ] Services have comprehensive unit tests
- [ ] Service methods handle all edge cases from original
- [ ] Service integration tested
### ✅ Functionality Preservation
- [ ] All game mechanics preserved
- [ ] AI decision-making logic intact
- [ ] Statistical tracking complete
- [ ] UI formatting adapted for web
---
## Notes and Decisions
### Key Architectural Decisions:
1. **AI Logic Location**: All AI decision-making moves to AIService to enable easy testing and modification
2. **UI Separation**: All formatting logic moves to UIService to support multiple interfaces
3. **Game State Management**: Core game logic moves to GameService/GameplayService for business rule centralization
### Risk Areas:
1. **Game.initialize_play()**: Complex method with lineup validation and AI setup
2. **Play model**: Heavily used throughout gameplay with many computed properties
3. **AI integration**: AI methods are called throughout game flow and must be properly service-integrated
### Success Metrics:
- All models are pure data containers
- All business logic has corresponding service methods
- No functionality lost in migration
- Services are independently testable