"""Pydantic schemas for user deck building features.""" from pydantic import BaseModel, Field from typing import Optional, List, Dict, Any from datetime import datetime from enum import Enum # ===== Enum Types ===== class DeckStatus(str, Enum): DRAFT = "DRAFT" FINAL = "FINAL" class DeckZone(str, Enum): MAIN = "main" SIDEBOARD = "sideboard" class SuggestionType(str, Enum): SIMILAR = "SIMILAR" PAIRING = "PAIRING" ALTERNATIVE = "ALTERNATIVE" # ===== Deck Schemas ===== class UserDeckCreate(BaseModel): """Deck creation request.""" name: str = Field(..., min_length=1, max_length=255) folder_id: Optional[int] = None format: Optional[str] = Field("standard", max_length=50) notes: Optional[str] = None is_precedent: bool = False precedent_name: Optional[str] = None class UserDeckUpdate(BaseModel): """Deck update request.""" name: Optional[str] = None folder_id: Optional[int] = None format: Optional[str] = None notes: Optional[str] = None status: Optional[DeckStatus] = None is_precedent: Optional[bool] = None precedent_name: Optional[str] = None class UserDeckResponse(BaseModel): """Deck response with card count.""" id: int user_id: int name: str status: str folder_id: Optional[int] format: Optional[str] notes: Optional[str] is_precedent: bool precedent_name: Optional[str] created_at: datetime updated_at: datetime card_count: int = 0 is_owner: bool = False class Config: from_attributes = True class UserDeckListResponse(BaseModel): """List of user decks.""" decks: List[UserDeckResponse] total: int page: int page_size: int total_pages: int # ===== Deck Card Schemas ===== class DeckCardCreate(BaseModel): """Add card to deck.""" card_id: int quantity: int = Field(1, ge=1) zone: DeckZone = DeckZone.MAIN position: Optional[int] = None class DeckCardUpdate(BaseModel): """Update card in deck.""" quantity: Optional[int] = None zone: Optional[DeckZone] = None position: Optional[int] = None class DeckCardResponse(BaseModel): """Deck card response.""" id: int deck_id: int card_id: int quantity: int zone: str position: Optional[int] created_at: datetime class Config: from_attributes = True class DeckCardWithDetailsResponse(DeckCardResponse): """Deck card with card details.""" card_name: str = "" card_type_line: str = "" card_image: Optional[str] = None class DeckCardListResponse(BaseModel): """List of deck cards.""" cards: List[DeckCardWithDetailsResponse] total: int # ===== Deck Precedent Schemas ===== class PrecedentCreate(BaseModel): """Create deck precedent.""" name: str = Field(..., min_length=1, max_length=255) description: Optional[str] = None format: Optional[str] = Field("standard", max_length=50) is_public: bool = True class PrecedentUpdate(BaseModel): """Update deck precedent.""" name: Optional[str] = None description: Optional[str] = None format: Optional[str] = None is_public: Optional[bool] = None class PrecedentResponse(BaseModel): """Deck precedent response.""" id: int name: str description: Optional[str] format: Optional[str] is_public: bool created_by: Optional[int] created_at: datetime updated_at: datetime card_count: int = 0 class Config: from_attributes = True class PrecedentListResponse(BaseModel): """List of deck precedents.""" precedents: List[PrecedentResponse] total: int # ===== Card Suggestion Schemas ===== class SuggestionCreate(BaseModel): """Create card suggestion.""" card_id: int source_card_id: Optional[int] = None suggestion_type: SuggestionType = SuggestionType.SIMILAR confidence: Optional[float] = Field(None, ge=0.0, le=1.0) notes: Optional[str] = None class SuggestionResponse(BaseModel): """Card suggestion response.""" id: int deck_id: int card_id: int source_card_id: Optional[int] suggestion_type: str confidence: Optional[float] notes: Optional[str] created_at: datetime card_name: str = "" class Config: from_attributes = True class SuggestionListResponse(BaseModel): """List of card suggestions.""" suggestions: List[SuggestionResponse] total: int # ===== Deck Action Schemas ===== class DeckFinalizeRequest(BaseModel): """Request to finalize a deck.""" status: DeckStatus = DeckStatus.FINAL class DeckFinalizeResponse(BaseModel): """Response after finalizing a deck.""" deck_id: int status: str message: str class DeckDeleteResponse(BaseModel): """Response after deleting a deck.""" deck_id: int message: str # ===== Search Schemas ===== class CardSearchRequest(BaseModel): """Card search request.""" query: str = Field(..., min_length=1, max_length=100) limit: int = Field(50, ge=1, le=200) offset: int = Field(0, ge=0) class CardSearchResponse(BaseModel): """Card search response.""" cards: List[Dict[str, Any]] total: int page: int page_size: int total_pages: int # ===== Generic Schemas ===== class MessageResponse(BaseModel): """Generic message response.""" message: str class CountResponse(BaseModel): """Generic count response.""" count: int