## 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>
38 lines
1.4 KiB
Python
38 lines
1.4 KiB
Python
"""
|
|
Cardset model - Pure data model for card set metadata.
|
|
|
|
Migrated from Discord app with no business logic extraction needed.
|
|
Contains only field definitions and relationships.
|
|
"""
|
|
|
|
from sqlmodel import SQLModel, Field, Relationship
|
|
from sqlalchemy import Column, BigInteger
|
|
from typing import List, TYPE_CHECKING
|
|
from pydantic import field_validator
|
|
|
|
if TYPE_CHECKING:
|
|
# from .game_cardset_link import GameCardsetLink # Will be uncommented when GameCardsetLink model is created
|
|
from .player import Player
|
|
|
|
|
|
class CardsetBase(SQLModel):
|
|
"""Base model for Cardset metadata."""
|
|
|
|
id: int | None = Field(default=None, sa_column=Column(BigInteger(), primary_key=True, autoincrement=False))
|
|
name: str = Field(index=True, description="Name of the card set")
|
|
ranked_legal: bool = Field(default=False, description="Whether this cardset is legal for ranked play")
|
|
|
|
@field_validator('name')
|
|
@classmethod
|
|
def validate_name_not_empty(cls, v: str) -> str:
|
|
"""Validate that name is not empty."""
|
|
if not v or not v.strip():
|
|
raise ValueError("Name cannot be empty")
|
|
return v
|
|
|
|
|
|
class Cardset(CardsetBase, table=True):
|
|
"""Cardset model for card set metadata storage."""
|
|
|
|
# game_links: List["GameCardsetLink"] = Relationship(back_populates="cardset", cascade_delete=True) # Will be uncommented when GameCardsetLink model is created
|
|
players: List["Player"] = Relationship(back_populates="cardset") |