Phase 3: Schema Layer - Pydantic v2 migration, deduplication, and missing schemas
- Migrated all schemas to Pydantic v2 syntax (model_config, ConfigDict) - Fixed mutable default in ProtoMessageBase using Field(default_factory=datetime.now) - Consolidated CardCollection and Wishlist schemas in user_card_collection.py - Created game_schemas.py with GameCreate, GameResponse, GameJoinRequest, etc. - Created mtg_card_schemas.py with MtgCardResponse, MtgCardSearchRequest, etc. - Added CardImportBatchCreate, CardImportBatchResponse, UserCardImportCreate/Response schemas - Fixed duplicate UserCardImportRecord class between card_import_batch.py and user_card_import_record.py - Updated __init__.py with comprehensive schema exports - Created verify_schemas.py for schema-model matching verification
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
"""Pydantic schemas for MTG card data."""
|
||||
from pydantic import BaseModel, Field, ConfigDict
|
||||
from typing import Optional, List, Dict, Any
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class MtgCardResponse(BaseModel):
|
||||
"""MTG card response with full details."""
|
||||
id: int
|
||||
source_id: Optional[int] = None
|
||||
name: str
|
||||
mana_cost: Optional[str] = None
|
||||
type_line: Optional[str] = None
|
||||
oracle_text: Optional[str] = None
|
||||
power: Optional[str] = None
|
||||
toughness: Optional[str] = None
|
||||
rarity: Optional[str] = None
|
||||
layout: Optional[str] = None
|
||||
artist: Optional[str] = None
|
||||
flavor_text: Optional[str] = None
|
||||
numbers: Optional[str] = None
|
||||
identifiers: Optional[Dict[str, Any]] = None
|
||||
images: Optional[Dict[str, Any]] = None
|
||||
image: Optional[str] = None
|
||||
card_parts: Optional[List[str]] = None
|
||||
keywords: Optional[List[str]] = None
|
||||
legalities: Optional[Dict[str, str]] = None
|
||||
set_code: Optional[str] = None
|
||||
set_name: Optional[str] = None
|
||||
synced_at: Optional[datetime] = None
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class MtgCardSearchRequest(BaseModel):
|
||||
"""MTG card search request."""
|
||||
query: str = Field(..., min_length=1, max_length=100)
|
||||
set_code: Optional[str] = None
|
||||
rarity: Optional[str] = None
|
||||
type_line: Optional[str] = None
|
||||
limit: int = Field(50, ge=1, le=200)
|
||||
offset: int = Field(0, ge=0)
|
||||
|
||||
|
||||
class MtgCardSearchResponse(BaseModel):
|
||||
"""MTG card search response."""
|
||||
cards: List[MtgCardResponse]
|
||||
total: int
|
||||
page: int
|
||||
page_size: int
|
||||
total_pages: int
|
||||
|
||||
|
||||
class MtgSetResponse(BaseModel):
|
||||
"""MTG set response."""
|
||||
id: int
|
||||
code: str
|
||||
name: str
|
||||
release_date: Optional[datetime] = None
|
||||
card_count: Optional[int] = None
|
||||
type: Optional[str] = None
|
||||
border: Optional[str] = None
|
||||
mcm_id: Optional[int] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class MtgCardMirrorResponse(BaseModel):
|
||||
"""Mirrored card data for user decks."""
|
||||
id: int
|
||||
source_id: Optional[int] = None
|
||||
name: str
|
||||
mana_cost: Optional[str] = None
|
||||
type_line: Optional[str] = None
|
||||
oracle_text: Optional[str] = None
|
||||
power: Optional[str] = None
|
||||
toughness: Optional[str] = None
|
||||
rarity: Optional[str] = None
|
||||
layout: Optional[str] = None
|
||||
artist: Optional[str] = None
|
||||
flavor_text: Optional[str] = None
|
||||
numbers: Optional[str] = None
|
||||
identifiers: Optional[Dict[str, Any]] = None
|
||||
images: Optional[Dict[str, Any]] = None
|
||||
image: Optional[str] = None
|
||||
card_parts: Optional[str] = None
|
||||
keywords: Optional[str] = None
|
||||
legalities: Optional[Dict[str, str]] = None
|
||||
set_code: Optional[str] = None
|
||||
set_name: Optional[str] = None
|
||||
synced_at: Optional[datetime] = None
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class DeckCardLinkResponse(BaseModel):
|
||||
"""Deck-card link response."""
|
||||
id: int
|
||||
deck_id: int
|
||||
card_id: int
|
||||
quantity: int
|
||||
zone: str
|
||||
card: MtgCardMirrorResponse
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class DeckWithCardsResponse(BaseModel):
|
||||
"""Deck response with card links."""
|
||||
id: int
|
||||
name: str
|
||||
content: str
|
||||
format: str
|
||||
status: str
|
||||
folder_id: Optional[int] = None
|
||||
owner_id: int
|
||||
creation_date: datetime
|
||||
card_links: List[DeckCardLinkResponse] = []
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
Reference in New Issue
Block a user