- 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>
39 lines
1.5 KiB
Python
39 lines
1.5 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 # Will be uncommented when Player model is created
|
|
pass
|
|
|
|
|
|
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") # Will be uncommented when Player model is created |