- 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>
8.3 KiB
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
# 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
# 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
# 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:
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/:
- Extract business logic from Discord command handlers into services
- Remove Discord dependencies (discord.py, interaction objects)
- Create service methods with pure business logic
- Add comprehensive unit tests for service methods
- 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:
- Use centralized
db_sessionfixture fromconftest.py- never create custom session fixtures - Use factory classes for all test data - never hardcode IDs or use static values
- Import factories from
tests.factoriespackage - Ensure test independence - each test must work in isolation and repeatedly
Example of CORRECT test pattern:
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):
@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 guidelinestests/factories/README.md- Factory pattern documentationtests/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_sessionfixture 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()andself._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