paper-dynasty-gameplay-webapp/CLAUDE.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

230 lines
8.3 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** 🚧 NEXT
- Extract business logic from `../discord-app/command_logic/logic_gameplay.py`
- Implement GameService, GameplayService, AIService
- Migrate core gameplay models from Discord app
- Add comprehensive service unit tests
## 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
## 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
### Unit Tests (`tests/unit/`)
- **Services**: Test business logic with mocked database sessions
- **Engine**: Test stateless game simulation functions
- **Models**: Test data validation and relationships using `db_session` + factories
### Integration Tests (`tests/integration/`)
- Service interactions with real database (isolated transactions)
- Authentication flows and session management
- Must use `db_session` fixture and factory classes
### End-to-End Tests (`tests/e2e/`)
- 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