mantimon-tcg/backend/app/schemas/collection.py
Cal Corum 58349c126a Phase 3: Collections + Decks - Services and DI architecture
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>
2026-01-28 11:27:14 -06:00

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")