Implemented with Repository Protocol pattern for offline fork support: - CollectionService with PostgresCollectionRepository - DeckService with PostgresDeckRepository - DeckValidator with DeckConfig + CardService injection - Starter deck definitions (5 types: grass, fire, water, psychic, lightning) - Pydantic schemas for collection and deck APIs - Unit tests for DeckValidator (32 tests passing) Architecture follows pure dependency injection - no service locator patterns. Added CLAUDE.md documenting DI requirements and patterns. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
88 lines
2.9 KiB
Python
88 lines
2.9 KiB
Python
"""Collection schemas for Mantimon TCG.
|
|
|
|
This module defines Pydantic models for collection-related API requests
|
|
and responses. Collections track which cards a user owns.
|
|
|
|
Example:
|
|
entry = CollectionEntryResponse(
|
|
card_definition_id="a1-001-bulbasaur",
|
|
quantity=3,
|
|
source=CardSource.BOOSTER,
|
|
obtained_at=datetime.now(UTC)
|
|
)
|
|
"""
|
|
|
|
from datetime import datetime
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
from app.db.models.collection import CardSource
|
|
|
|
|
|
class CollectionEntryResponse(BaseModel):
|
|
"""Response model for a single collection entry.
|
|
|
|
Represents one card type in a user's collection with quantity.
|
|
|
|
Attributes:
|
|
card_definition_id: ID of the card definition (e.g., "a1-001-bulbasaur").
|
|
quantity: Number of copies owned.
|
|
source: How the first copy was obtained.
|
|
obtained_at: When the card was first added to collection.
|
|
"""
|
|
|
|
card_definition_id: str = Field(..., description="Card definition ID")
|
|
quantity: int = Field(..., ge=1, description="Number of copies owned")
|
|
source: CardSource = Field(..., description="How the card was obtained")
|
|
obtained_at: datetime = Field(..., description="When first obtained")
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class CollectionResponse(BaseModel):
|
|
"""Response model for a user's full collection.
|
|
|
|
Contains aggregate statistics and list of all owned cards.
|
|
|
|
Attributes:
|
|
total_unique_cards: Number of distinct card types owned.
|
|
total_card_count: Total number of cards (sum of all quantities).
|
|
entries: List of all collection entries.
|
|
"""
|
|
|
|
total_unique_cards: int = Field(..., ge=0, description="Distinct card types owned")
|
|
total_card_count: int = Field(..., ge=0, description="Total cards owned")
|
|
entries: list[CollectionEntryResponse] = Field(
|
|
default_factory=list, description="All collection entries"
|
|
)
|
|
|
|
|
|
class CollectionAddRequest(BaseModel):
|
|
"""Request model for adding cards to a collection.
|
|
|
|
Used by admin endpoints to grant cards to users.
|
|
|
|
Attributes:
|
|
card_definition_id: ID of the card to add.
|
|
quantity: Number of copies to add (default 1).
|
|
source: How the card was obtained.
|
|
"""
|
|
|
|
card_definition_id: str = Field(..., description="Card definition ID to add")
|
|
quantity: int = Field(default=1, ge=1, le=99, description="Number of copies to add")
|
|
source: CardSource = Field(..., description="Source of the card")
|
|
|
|
|
|
class CollectionCardResponse(BaseModel):
|
|
"""Response model for a single card lookup in collection.
|
|
|
|
Returns quantity for a specific card in a user's collection.
|
|
|
|
Attributes:
|
|
card_definition_id: ID of the card.
|
|
quantity: Number of copies owned (0 if not owned).
|
|
"""
|
|
|
|
card_definition_id: str = Field(..., description="Card definition ID")
|
|
quantity: int = Field(..., ge=0, description="Number of copies owned")
|