Updated CLAUDE.md with accurate current state information: Migration Status: - Phase 2: Core Game Services marked as ✅ COMPLETE - Phase 3: Game Engine & Routes marked as 🚧 NEXT - Updated service implementation status Service Documentation: - AIService: Complete (369 lines, 72% coverage, 51 tests) - PlayerService: Complete (53 lines, 100% coverage) - UIService: Complete (18 lines, 83% coverage) - BaseService: Complete (19 lines, 84% coverage) - Added detailed capability descriptions Model Documentation: - Updated implemented models list - Added AI response model descriptions - Documented relationships and functionality Testing Documentation: - Current coverage: 65% overall, 206 total tests - AIService: 51 tests (22 unit + 29 integration) - Detailed integration testing approach - Updated test distribution across suites Documentation now accurately reflects substantial progress made in service implementation, model development, and comprehensive testing infrastructure. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
325 lines
13 KiB
Markdown
325 lines
13 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
This is the **Paper Dynasty Web App**, a baseball simulation game migrated from a Discord bot (`../discord-app/`) to a standalone web application using **FastAPI + Model/Service Architecture**. The migration follows a service-oriented approach that prioritizes testability, maintainability, and scalability.
|
|
|
|
## Development Commands
|
|
|
|
### Environment Setup
|
|
```bash
|
|
# Start PostgreSQL database container
|
|
docker compose up -d postgres
|
|
|
|
# Activate virtual environment
|
|
source venv/bin/activate
|
|
|
|
# Install dependencies (including PostgreSQL driver)
|
|
pip install -r requirements.txt
|
|
|
|
# Copy environment configuration
|
|
cp .env.example .env
|
|
# Edit .env file if needed
|
|
|
|
# Run development server
|
|
python -m app.main
|
|
# Server runs on http://localhost:8001
|
|
```
|
|
|
|
### Testing
|
|
```bash
|
|
# Run all tests
|
|
pytest
|
|
|
|
# Run tests with coverage
|
|
pytest --cov=app
|
|
|
|
# Run specific test module
|
|
pytest tests/unit/services/test_game_service.py
|
|
|
|
# Run specific test
|
|
pytest tests/unit/services/test_game_service.py::test_create_game_success
|
|
```
|
|
|
|
### Database
|
|
```bash
|
|
# Start/stop PostgreSQL container
|
|
docker compose up -d postgres # Start pddev-postgres container
|
|
docker compose stop postgres # Stop container
|
|
docker compose down -v # Stop and remove data (fresh start)
|
|
|
|
# Create database tables (once models are implemented)
|
|
python -c "from app.services.service_container import create_db_and_tables; create_db_and_tables()"
|
|
|
|
# Generate migration (once Alembic is configured)
|
|
alembic revision --autogenerate -m "Description"
|
|
|
|
# Apply migrations
|
|
alembic upgrade head
|
|
|
|
# Connect to database directly
|
|
docker compose exec postgres psql -U paper_dynasty_user -d paper_dynasty
|
|
```
|
|
|
|
## Architecture Overview
|
|
|
|
### Model/Service Architecture Pattern
|
|
|
|
This project implements a **service-oriented architecture** with clear separation of concerns:
|
|
|
|
- **Models** (`app/models/`): Pure data models using SQLModel
|
|
- **Services** (`app/services/`): Business logic layer with dependency injection
|
|
- **Controllers** (`app/routers/`): Thin FastAPI route handlers that delegate to services
|
|
- **Engine** (`app/engine/`): Stateless game simulation functions
|
|
- **Repositories** (`app/repositories/`): Optional data access layer for complex queries
|
|
|
|
### Service Layer Design
|
|
|
|
All services inherit from `BaseService` and follow these patterns:
|
|
- Constructor dependency injection via SQLModel Session
|
|
- Standardized logging with `f'{__name__}.{self.__class__.__name__}'` format
|
|
- Business logic separated from HTTP concerns
|
|
- Unit testable with mocked dependencies
|
|
|
|
### Dependency Injection
|
|
|
|
Services are injected into routes using FastAPI's `Depends()` system via `service_container.py`:
|
|
```python
|
|
from app.services.service_container import GameServiceDep
|
|
|
|
@router.post("/games/start")
|
|
async def start_game(game_service: GameServiceDep):
|
|
# Service contains business logic, route handles HTTP concerns
|
|
```
|
|
|
|
### Migration from Discord App
|
|
|
|
When migrating code from `../discord-app/`:
|
|
1. **Extract business logic** from Discord command handlers into services
|
|
2. **Remove Discord dependencies** (discord.py, interaction objects)
|
|
3. **Create service methods** with pure business logic
|
|
4. **Add comprehensive unit tests** for service methods
|
|
5. **Create thin route handlers** that delegate to services
|
|
|
|
## Current Migration Status
|
|
|
|
**Phase 1: Service Foundation** ✅ COMPLETE
|
|
- FastAPI project structure established
|
|
- Base service classes and dependency injection configured
|
|
- Logging with rotating handlers implemented
|
|
- Virtual environment and core dependencies installed
|
|
|
|
**Phase 2: Core Game Services** ✅ COMPLETE
|
|
- ✅ AIService fully implemented (369 lines, 72% test coverage)
|
|
- Complete steal opportunity decision logic
|
|
- Defensive alignment and positioning
|
|
- Tag-up and runner advance decisions
|
|
- Pitcher replacement logic
|
|
- ✅ PlayerService fully implemented (53 lines, 100% test coverage)
|
|
- Player data management and formatting
|
|
- Name handling with descriptions
|
|
- ✅ UIService implemented (18 lines, 83% test coverage)
|
|
- User interface helper functions
|
|
- ✅ Core gameplay models migrated: Player, Team, Cardset, ManagerAi, PositionRating
|
|
- ✅ Comprehensive test suite: 206 tests (65% overall coverage)
|
|
- 51 AI Service tests (unit + integration)
|
|
- Robust integration testing with real database queries
|
|
|
|
**Phase 3: Game Engine & Routes** 🚧 NEXT
|
|
- Implement game simulation engine and gameplay mechanics
|
|
- Create FastAPI routes and controllers for web interface
|
|
- Add authentication and session management
|
|
- Integrate services with HTTP endpoints
|
|
|
|
## Key Files and Patterns
|
|
|
|
### Service Container (`app/services/service_container.py`)
|
|
- Manages database sessions and service lifecycles
|
|
- Provides dependency injection for FastAPI routes
|
|
- Configure SQLModel engine for PostgreSQL/SQLite
|
|
|
|
### Base Service (`app/services/base_service.py`)
|
|
- Abstract base class for all services
|
|
- Standardized logging and validation patterns
|
|
- Session management and error handling
|
|
|
|
### Constants (`app/config/constants.py`)
|
|
- Migrated constants from Discord app (not assumed values)
|
|
- Environment-based configuration via Settings class
|
|
- Game constants, MLB teams, rarity values from original source
|
|
|
|
### Logging Configuration (`app/config/logging_config.py`)
|
|
- Rotating file handlers per user requirements
|
|
- Console and file output with structured formatting
|
|
- Service-specific logger naming patterns
|
|
|
|
## Implemented Services
|
|
|
|
### AIService (`app/services/ai_service.py`)
|
|
**Status**: ✅ Complete (369 lines, 72% test coverage, 51 tests)
|
|
|
|
Core AI decision-making for baseball gameplay mechanics:
|
|
- **Steal Opportunities**: `check_steal_opportunity()` - Complex conditional logic for steal decisions to 2nd, 3rd, and home
|
|
- **Defensive Alignment**: `set_defensive_alignment()` - Hold runners, infield positioning based on game state
|
|
- **Tag Decisions**: `check_tag_from_second()`, `check_tag_from_third()` - Fly ball tag-up logic
|
|
- **Runner Advances**: `decide_runner_advance()` - Uncapped situation running decisions
|
|
- **Pitcher Management**: `should_replace_pitcher()` - Fatigue and situational pitcher replacement
|
|
- **Groundball Decisions**: `decide_groundball_running()`, `decide_groundball_throw()` - Fielding choices
|
|
|
|
**Key Features**:
|
|
- Real database queries for defensive ratings
|
|
- Complex aggression calculations based on game state
|
|
- Comprehensive bounds checking and error handling
|
|
- Migrated from Discord app with full business logic preservation
|
|
|
|
### PlayerService (`app/services/player_service.py`)
|
|
**Status**: ✅ Complete (53 lines, 100% test coverage)
|
|
|
|
Player data management and formatting:
|
|
- **Player Creation**: Database-backed player instantiation
|
|
- **Name Formatting**: `get_formatted_name_with_description()` - Consistent player name display
|
|
- **Data Validation**: Proper player attribute handling
|
|
|
|
### UIService (`app/services/ui_service.py`)
|
|
**Status**: ✅ Complete (18 lines, 83% test coverage)
|
|
|
|
User interface helper functions:
|
|
- **Formatting Utilities**: Display helpers for web interface
|
|
- **Data Presentation**: Consistent UI data formatting
|
|
|
|
### Base Service (`app/services/base_service.py`)
|
|
**Status**: ✅ Complete (19 lines, 84% test coverage)
|
|
|
|
Abstract foundation for all services:
|
|
- **Session Management**: SQLModel database session handling
|
|
- **Logging**: Standardized `f'{__name__}.{self.__class__.__name__}'` format
|
|
- **Operation Tracking**: `_log_operation()` and `_log_error()` methods
|
|
- **Dependency Injection**: Constructor-based session injection
|
|
|
|
## Implemented Models
|
|
|
|
### Core Models (`app/models/`)
|
|
- **Player** (`player.py`): Complete player data model with positions relationship
|
|
- **Team** (`team.py`): Team management with MLB club associations
|
|
- **Cardset** (`cardset.py`): Card set definitions and metadata
|
|
- **ManagerAi** (`manager_ai.py`): AI personality and aggression settings
|
|
- **PositionRating** (`position_rating.py`): Defensive ratings by position and variant
|
|
|
|
### AI Response Models (`app/models/ai_responses.py`)
|
|
Structured response objects for AI decisions:
|
|
- `JumpResponse`: Steal opportunity decisions with safety thresholds
|
|
- `TagResponse`: Tag-up decisions with minimum safe values
|
|
- `ThrowResponse`: Fielding throw target decisions
|
|
- `UncappedRunResponse`: Advanced base running decisions
|
|
- `DefenseResponse`: Defensive alignment and hold decisions
|
|
- `RunResponse`: Basic running decisions
|
|
|
|
## Testing Strategy
|
|
|
|
**🚨 CRITICAL: All tests must follow test isolation guidelines to prevent data persistence issues.**
|
|
|
|
### Test Isolation Requirements (MANDATORY)
|
|
|
|
**For ALL tests that interact with the database:**
|
|
|
|
1. **Use centralized `db_session` fixture** from `conftest.py` - never create custom session fixtures
|
|
2. **Use factory classes** for all test data - never hardcode IDs or use static values
|
|
3. **Import factories** from `tests.factories` package
|
|
4. **Ensure test independence** - each test must work in isolation and repeatedly
|
|
|
|
**Example of CORRECT test pattern:**
|
|
```python
|
|
from tests.factories.team_factory import TeamFactory
|
|
|
|
def test_create_team(db_session): # ✅ Use db_session fixture
|
|
team = TeamFactory.create(db_session, abbrev="LAD") # ✅ Use factory
|
|
assert team.id is not None
|
|
```
|
|
|
|
**NEVER do this (causes data persistence issues):**
|
|
```python
|
|
@pytest.fixture
|
|
def session(): # ❌ Custom fixture
|
|
pass
|
|
|
|
def test_create_team(session):
|
|
team = Team(id=1, abbrev="LAD") # ❌ Hardcoded ID
|
|
```
|
|
|
|
**📖 See detailed documentation:**
|
|
- `tests/README.md` - Complete testing guidelines
|
|
- `tests/factories/README.md` - Factory pattern documentation
|
|
- `tests/TEST_ISOLATION_GUIDE.md` - Comprehensive isolation best practices
|
|
|
|
### Current Test Coverage Status
|
|
- **Total Tests**: 206 tests across all suites
|
|
- **Overall Coverage**: 65% (804 statements, 285 missed)
|
|
- **Service Coverage**:
|
|
- AIService: 72% (369 lines, 51 tests - unit + integration)
|
|
- PlayerService: 100% (53 lines, comprehensive coverage)
|
|
- UIService: 83% (18 lines)
|
|
- BaseService: 84% (19 lines)
|
|
|
|
### Unit Tests (`tests/unit/`)
|
|
- **Services**: Test business logic with mocked dependencies
|
|
- AIService: 22 unit tests covering core decision logic
|
|
- PlayerService: Comprehensive unit test coverage
|
|
- UIService: Basic functionality testing
|
|
- **Models**: Test data validation and relationships using `db_session` + factories
|
|
- Player, Team, Cardset, ManagerAi, PositionRating models
|
|
- **Engine**: Reserved for stateless game simulation functions
|
|
|
|
### Integration Tests (`tests/integration/`)
|
|
- **AIService Integration**: 29 focused integration tests
|
|
- Real database queries for defensive ratings
|
|
- Complex conditional branch coverage
|
|
- Error handling with actual data constraints
|
|
- Cross-service interaction testing
|
|
- Service interactions with real database (isolated transactions)
|
|
- Must use `db_session` fixture and factory classes
|
|
|
|
### End-to-End Tests (`tests/e2e/`)
|
|
- **Status**: 🚧 Reserved for future web interface testing
|
|
- Complete user journeys through web interface
|
|
- Game creation and gameplay flows
|
|
- Use factory classes for any test data setup
|
|
|
|
## Development Guidelines
|
|
|
|
### Service Development
|
|
- All services extend `BaseService`
|
|
- Use dependency injection for service-to-service communication
|
|
- Log operations with `self._log_operation()` and `self._log_error()`
|
|
- Follow "Raise or Return" pattern (no optional return values)
|
|
|
|
### Documentation Maintenance
|
|
- **Update README.md files** when making substantial changes to any directory
|
|
- Each directory with significant content has a README.md explaining its purpose and patterns
|
|
- Keep documentation current with architecture decisions and new patterns
|
|
- Update relevant README when adding new services, routes, or changing patterns
|
|
- **Reference per-directory README.md files** - Future AI agents should read the README in each directory to understand its purpose, patterns, and responsibilities before making changes
|
|
|
|
### File Size Management
|
|
- **Keep all files as small as feasibly possible** for maximum maintainability
|
|
- Break large files into smaller, focused modules
|
|
- Single responsibility principle applies to files as well as classes
|
|
- Prefer multiple small service files over monolithic service classes
|
|
- Split complex models into separate files when they serve different domains
|
|
|
|
### Code Migration
|
|
- Always check `../discord-app/` for actual implementation before assuming logic
|
|
- Extract Discord command handlers into service methods
|
|
- Test service logic independently of web framework
|
|
- Keep routes thin - delegate business logic to services
|
|
|
|
### Database
|
|
- Currently configured for SQLite development
|
|
- PostgreSQL driver (`psycopg2-binary`) commented out until proper DB setup
|
|
- Use SQLModel for all data models
|
|
|
|
### Logging
|
|
- Use rotating file handlers as per user requirements
|
|
- Format: `f'{__name__}.{className or functionName}'`
|
|
- Log service operations and errors consistently |