deckhearth/backend/app/routers/collections.py

197 lines
No EOL
5.5 KiB
Python

"""
Collection management routes
"""
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import List, Optional
from app.database import get_db
from app.models.collection import Collection, CollectionCard
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 CollectionResponse(BaseModel):
id: int
name: str
description: Optional[str]
is_public: bool
total_cards: int
total_value: float
class Config:
from_attributes = True
class CollectionCreate(BaseModel):
name: str
description: Optional[str] = None
is_public: bool = False
class CollectionCardResponse(BaseModel):
id: int
card_id: int
card_name: str
quantity: int
condition: str
foil: bool
language: str
location: Optional[str]
notes: Optional[str]
purchase_price: Optional[float]
class Config:
from_attributes = True
class CollectionCardCreate(BaseModel):
card_id: int
quantity: int = 1
condition: str = "NM"
foil: bool = False
language: str = "English"
location: Optional[str] = None
notes: Optional[str] = None
purchase_price: Optional[float] = None
# Routes
@router.get("/", response_model=List[CollectionResponse])
async def get_my_collections(
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""Get current user's collections"""
collections = db.query(Collection).filter(Collection.owner_id == current_user.id).all()
return collections
@router.get("/{collection_id}", response_model=CollectionResponse)
async def get_collection(
collection_id: int,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""Get a specific collection"""
collection = db.query(Collection).filter(
Collection.id == collection_id,
Collection.owner_id == current_user.id
).first()
if not collection:
raise HTTPException(status_code=404, detail="Collection not found")
return collection
@router.post("/", response_model=CollectionResponse)
async def create_collection(
collection_data: CollectionCreate,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""Create a new collection"""
new_collection = Collection(
**collection_data.dict(),
owner_id=current_user.id
)
db.add(new_collection)
db.commit()
db.refresh(new_collection)
return new_collection
@router.get("/{collection_id}/cards", response_model=List[CollectionCardResponse])
async def get_collection_cards(
collection_id: int,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""Get all cards in a collection"""
# Verify ownership
collection = db.query(Collection).filter(
Collection.id == collection_id,
Collection.owner_id == current_user.id
).first()
if not collection:
raise HTTPException(status_code=404, detail="Collection not found")
# Get collection cards with card names
cards = db.query(CollectionCard, Card.name.label('card_name')).join(
Card, CollectionCard.card_id == Card.id
).filter(CollectionCard.collection_id == collection_id).all()
result = []
for cc, card_name in cards:
cc_dict = cc.__dict__.copy()
cc_dict['card_name'] = card_name
result.append(CollectionCardResponse(**cc_dict))
return result
@router.post("/{collection_id}/cards", response_model=CollectionCardResponse)
async def add_card_to_collection(
collection_id: int,
card_data: CollectionCardCreate,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""Add a card to a collection"""
# Verify collection ownership
collection = db.query(Collection).filter(
Collection.id == collection_id,
Collection.owner_id == current_user.id
).first()
if not collection:
raise HTTPException(status_code=404, detail="Collection not found")
# Verify card exists
card = db.query(Card).filter(Card.id == card_data.card_id).first()
if not card:
raise HTTPException(status_code=404, detail="Card not found")
# Check if card already exists in collection
existing_card = db.query(CollectionCard).filter(
CollectionCard.collection_id == collection_id,
CollectionCard.card_id == card_data.card_id,
CollectionCard.condition == card_data.condition,
CollectionCard.foil == card_data.foil
).first()
if existing_card:
# Update quantity if card already exists with same condition/foil
existing_card.quantity += card_data.quantity
db.commit()
db.refresh(existing_card)
# Add card name for response
existing_card_dict = existing_card.__dict__.copy()
existing_card_dict['card_name'] = card.name
return CollectionCardResponse(**existing_card_dict)
else:
# Create new collection card entry
new_collection_card = CollectionCard(
collection_id=collection_id,
**card_data.dict()
)
db.add(new_collection_card)
db.commit()
db.refresh(new_collection_card)
# Add card name for response
new_card_dict = new_collection_card.__dict__.copy()
new_card_dict['card_name'] = card.name
return CollectionCardResponse(**new_card_dict)