""" Card management routes """ from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from sqlalchemy import or_ from pydantic import BaseModel from typing import List, Optional from app.database import get_db from app.models.card import Card from app.models.user import User from app.routers.auth import get_current_user router = APIRouter() # Pydantic models class CardResponse(BaseModel): id: int name: str set_name: Optional[str] set_code: Optional[str] card_number: Optional[str] rarity: Optional[str] game: str mana_cost: Optional[str] cmc: Optional[int] card_type: Optional[str] colors: Optional[List[str]] oracle_text: Optional[str] flavor_text: Optional[str] power: Optional[str] toughness: Optional[str] artist: Optional[str] image_url: Optional[str] # Legacy field stock_image_url: Optional[str] # New official image URL artwork_crop_coords: Optional[dict] # Coordinates for artwork cropping current_price: Optional[float] market_price: Optional[float] verified: bool class Config: from_attributes = True class CardCreate(BaseModel): name: str game: str set_name: Optional[str] = None set_code: Optional[str] = None card_number: Optional[str] = None rarity: Optional[str] = None mana_cost: Optional[str] = None cmc: Optional[int] = None card_type: Optional[str] = None colors: Optional[List[str]] = None oracle_text: Optional[str] = None flavor_text: Optional[str] = None power: Optional[str] = None toughness: Optional[str] = None artist: Optional[str] = None image_url: Optional[str] = None # Routes @router.get("/", response_model=List[CardResponse]) async def get_cards( skip: int = 0, limit: int = 100, search: Optional[str] = None, game: Optional[str] = None, set_name: Optional[str] = None, db: Session = Depends(get_db) ): """Get cards with optional filtering and search""" query = db.query(Card) # Apply filters if game: query = query.filter(Card.game == game) if set_name: query = query.filter(Card.set_name == set_name) if search: query = query.filter( or_( Card.name.contains(search), Card.oracle_text.contains(search), Card.card_type.contains(search) ) ) cards = query.offset(skip).limit(limit).all() return cards @router.get("/{card_id}", response_model=CardResponse) async def get_card(card_id: int, db: Session = Depends(get_db)): """Get a specific card by ID""" card = db.query(Card).filter(Card.id == card_id).first() if not card: raise HTTPException(status_code=404, detail="Card not found") return card @router.post("/", response_model=CardResponse) async def create_card( card_data: CardCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """Create a new card (authenticated users only)""" new_card = Card(**card_data.dict()) db.add(new_card) db.commit() db.refresh(new_card) return new_card @router.get("/search/name/{card_name}", response_model=List[CardResponse]) async def search_cards_by_name( card_name: str, game: Optional[str] = None, db: Session = Depends(get_db) ): """Search cards by name""" query = db.query(Card).filter(Card.name.contains(card_name)) if game: query = query.filter(Card.game == game) cards = query.limit(20).all() # Limit results for performance return cards @router.get("/sets/{game}") async def get_sets(game: str, db: Session = Depends(get_db)): """Get all sets for a specific game""" sets = db.query(Card.set_name, Card.set_code).filter( Card.game == game, Card.set_name.isnot(None) ).distinct().all() return [{"name": s.set_name, "code": s.set_code} for s in sets]