Week 6 Progress: 75% Complete ## Components Implemented ### 1. League Configuration System ✅ - Created BaseGameConfig abstract class for league-agnostic rules - Implemented SbaConfig and PdConfig with league-specific settings - Immutable configs (frozen=True) with singleton registry - 28 unit tests, all passing Files: - backend/app/config/base_config.py - backend/app/config/league_configs.py - backend/tests/unit/config/test_league_configs.py ### 2. PlayOutcome Enum ✅ - Universal enum for all play outcomes (both SBA and PD) - Helper methods: is_hit(), is_out(), is_uncapped(), is_interrupt() - Supports standard hits, uncapped hits, interrupt plays, ballpark power - 30 unit tests, all passing Files: - backend/app/config/result_charts.py - backend/tests/unit/config/test_play_outcome.py ### 3. Player Model Refinements ✅ - Fixed PdPlayer.id field mapping (player_id → id) - Improved field docstrings for image types - Fixed position checking logic in SBA helper methods - Added safety checks for missing image data Files: - backend/app/models/player_models.py (updated) ### 4. Documentation ✅ - Updated backend/CLAUDE.md with Week 6 section - Documented card-based resolution mechanics - Detailed config system and PlayOutcome usage ## Architecture Decisions 1. **Card-Based Resolution**: Both SBA and PD use same mechanics - 1d6 (column) + 2d6 (row) + 1d20 (split resolution) - PD: Digitized cards with auto-resolution - SBA: Manual entry from physical cards 2. **Immutable Configs**: Prevent accidental modification using Pydantic frozen 3. **Universal PlayOutcome**: Single enum for both leagues reduces duplication ## Testing - Total: 58 tests, all passing - Config tests: 28 - PlayOutcome tests: 30 ## Remaining Work (25%) - Update dice system (check_d20 → chaos_d20) - Integrate PlayOutcome into PlayResolver - Add Play.metadata support for uncapped hits 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
108 lines
2.9 KiB
Python
108 lines
2.9 KiB
Python
"""
|
|
League-specific configuration implementations.
|
|
|
|
Provides concrete configs for SBA and PD leagues with their unique rules,
|
|
API endpoints, and feature flags.
|
|
|
|
Author: Claude
|
|
Date: 2025-10-28
|
|
"""
|
|
import logging
|
|
from typing import Dict
|
|
from app.config.base_config import BaseGameConfig
|
|
|
|
logger = logging.getLogger(f'{__name__}.LeagueConfigs')
|
|
|
|
|
|
class SbaConfig(BaseGameConfig):
|
|
"""
|
|
SBA League configuration.
|
|
|
|
Features:
|
|
- Manual result selection after dice roll
|
|
- Simple player data model
|
|
- Standard baseball rules
|
|
"""
|
|
|
|
league_id: str = "sba"
|
|
|
|
# SBA-specific features
|
|
player_selection_mode: str = "manual" # Players manually select from chart
|
|
|
|
def get_result_chart_name(self) -> str:
|
|
"""Use SBA standard result chart."""
|
|
return "sba_standard_v1"
|
|
|
|
def supports_manual_result_selection(self) -> bool:
|
|
"""SBA players manually pick results from chart."""
|
|
return True
|
|
|
|
def get_api_base_url(self) -> str:
|
|
"""SBA API base URL."""
|
|
return "https://api.sba.manticorum.com"
|
|
|
|
|
|
class PdConfig(BaseGameConfig):
|
|
"""
|
|
Paper Dynasty League configuration.
|
|
|
|
Features:
|
|
- Flexible result selection (manual or auto via scouting)
|
|
- Complex scouting data model
|
|
- Cardset validation
|
|
- Advanced analytics
|
|
"""
|
|
|
|
league_id: str = "pd"
|
|
|
|
# PD-specific features
|
|
player_selection_mode: str = "flexible" # Manual or auto via scouting model
|
|
use_scouting_model: bool = True # Use detailed ratings for auto-resolution
|
|
cardset_validation: bool = True # Validate cards against approved cardsets
|
|
|
|
# Advanced features
|
|
detailed_analytics: bool = True # Track advanced stats (WPA, RE24, etc.)
|
|
wpa_calculation: bool = True # Calculate win probability added
|
|
|
|
def get_result_chart_name(self) -> str:
|
|
"""Use PD standard result chart."""
|
|
return "pd_standard_v1"
|
|
|
|
def supports_manual_result_selection(self) -> bool:
|
|
"""PD supports manual selection (though auto is also available)."""
|
|
return True
|
|
|
|
def get_api_base_url(self) -> str:
|
|
"""PD API base URL."""
|
|
return "https://pd.manticorum.com"
|
|
|
|
|
|
# ==================== Config Registry ====================
|
|
|
|
LEAGUE_CONFIGS: Dict[str, BaseGameConfig] = {
|
|
"sba": SbaConfig(),
|
|
"pd": PdConfig()
|
|
}
|
|
|
|
|
|
def get_league_config(league_id: str) -> BaseGameConfig:
|
|
"""
|
|
Get configuration for specified league.
|
|
|
|
Args:
|
|
league_id: League identifier ('sba' or 'pd')
|
|
|
|
Returns:
|
|
League-specific config instance
|
|
|
|
Raises:
|
|
ValueError: If league_id is not recognized
|
|
"""
|
|
config = LEAGUE_CONFIGS.get(league_id)
|
|
if not config:
|
|
logger.error(f"Unknown league ID: {league_id}")
|
|
raise ValueError(f"Unknown league: {league_id}. Valid leagues: {list(LEAGUE_CONFIGS.keys())}")
|
|
|
|
logger.debug(f"Retrieved config for league: {league_id}")
|
|
return config
|