Files
wiki-tcg/backend/routers/decks.py
2026-04-01 18:31:33 +02:00

98 lines
3.5 KiB
Python

import uuid
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session, selectinload
from game.card import compute_deck_type
from core.database import get_db
from core.dependencies import get_current_user
from core.models import Card as CardModel
from core.models import Deck as DeckModel
from core.models import DeckCard as DeckCardModel
from core.models import User as UserModel
router = APIRouter()
class DeckUpdate(BaseModel):
name: Optional[str] = Field(None, max_length=64)
card_ids: Optional[List[str]] = None
@router.get("/decks")
def get_decks(user: UserModel = Depends(get_current_user), db: Session = Depends(get_db)):
decks = db.query(DeckModel).options(
selectinload(DeckModel.deck_cards).selectinload(DeckCardModel.card)
).filter(
DeckModel.user_id == user.id,
DeckModel.deleted == False
).order_by(DeckModel.created_at).all()
result = []
for deck in decks:
cards = [dc.card for dc in deck.deck_cards]
result.append({
"id": str(deck.id),
"name": deck.name,
"card_count": len(cards),
"total_cost": sum(card.cost for card in cards),
"times_played": deck.times_played,
"wins": deck.wins,
"losses": deck.losses,
"deck_type": compute_deck_type(cards),
})
return result
@router.post("/decks")
def create_deck(user: UserModel = Depends(get_current_user), db: Session = Depends(get_db)):
count = db.query(DeckModel).filter(DeckModel.user_id == user.id).count()
deck = DeckModel(id=uuid.uuid4(), user_id=user.id, name=f"Deck #{count + 1}")
db.add(deck)
db.commit()
return {"id": str(deck.id), "name": deck.name, "card_count": 0}
@router.patch("/decks/{deck_id}")
def update_deck(deck_id: str, body: DeckUpdate, user: UserModel = Depends(get_current_user), db: Session = Depends(get_db)):
deck = db.query(DeckModel).filter(DeckModel.id == uuid.UUID(deck_id), DeckModel.user_id == user.id).first()
if not deck:
raise HTTPException(status_code=404, detail="Deck not found")
if body.name is not None:
deck.name = body.name
if body.card_ids is not None:
db.query(DeckCardModel).filter(DeckCardModel.deck_id == deck.id).delete()
for card_id in body.card_ids:
db.add(DeckCardModel(deck_id=deck.id, card_id=uuid.UUID(card_id)))
if deck.times_played > 0:
deck.wins = 0
deck.losses = 0
deck.times_played = 0
db.commit()
return {"id": str(deck.id), "name": deck.name}
@router.delete("/decks/{deck_id}")
def delete_deck(deck_id: str, user: UserModel = Depends(get_current_user), db: Session = Depends(get_db)):
deck = db.query(DeckModel).filter(DeckModel.id == uuid.UUID(deck_id), DeckModel.user_id == user.id).first()
if not deck:
raise HTTPException(status_code=404, detail="Deck not found")
if deck.times_played > 0:
deck.deleted = True
else:
db.delete(deck)
db.commit()
return {"message": "Deleted"}
@router.get("/decks/{deck_id}/cards")
def get_deck_cards(deck_id: str, user: UserModel = Depends(get_current_user), db: Session = Depends(get_db)):
deck = db.query(DeckModel).filter(DeckModel.id == uuid.UUID(deck_id), DeckModel.user_id == user.id).first()
if not deck:
raise HTTPException(status_code=404, detail="Deck not found")
deck_cards = db.query(DeckCardModel).options(
selectinload(DeckCardModel.card)
).filter(DeckCardModel.deck_id == deck.id).all()
return [{"id": str(dc.card_id), "cost": dc.card.cost} for dc in deck_cards]