deckhearth/backend/app/models/deck.py

120 lines
4.2 KiB
Python
Raw Normal View History

"""
Deck models for deck building and management
"""
from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey, Text, Float
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from app.database import Base
class Deck(Base):
__tablename__ = "decks"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, nullable=False)
description = Column(Text)
format = Column(String) # Standard, Modern, Legacy, Commander, etc.
game = Column(String, nullable=False) # MTG, Pokemon, YuGiOh, etc.
# Deck status and sharing
is_public = Column(Boolean, default=False)
is_complete = Column(Boolean, default=False)
is_favorite = Column(Boolean, default=False)
# Commander/Partner info (for MTG)
commander_card_id = Column(Integer, ForeignKey("cards.id"))
partner_card_id = Column(Integer, ForeignKey("cards.id"))
# Deck statistics
total_cards = Column(Integer, default=0)
avg_mana_cost = Column(Float)
estimated_value = Column(Float)
# AI and optimization data
ai_suggestions = Column(Text) # JSON string of AI suggestions
win_rate = Column(Float) # If user tracks games
last_played = Column(DateTime)
# Ownership
owner_id = Column(Integer, ForeignKey("users.id"), nullable=False)
# Metadata
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Relationships
owner = relationship("User", back_populates="decks")
commander = relationship("Card", foreign_keys=[commander_card_id])
partner = relationship("Card", foreign_keys=[partner_card_id])
deck_cards = relationship("DeckCard", back_populates="deck", cascade="all, delete-orphan")
@property
def mainboard_cards(self):
"""Get only mainboard cards"""
return [dc for dc in self.deck_cards if not dc.is_sideboard]
@property
def sideboard_cards(self):
"""Get only sideboard cards"""
return [dc for dc in self.deck_cards if dc.is_sideboard]
def calculate_stats(self):
"""Calculate deck statistics"""
mainboard = self.mainboard_cards
if not mainboard:
return
# Total cards
self.total_cards = sum(dc.quantity for dc in mainboard)
# Average mana cost
total_cmc = sum(dc.card.cmc * dc.quantity for dc in mainboard if dc.card.cmc)
self.avg_mana_cost = total_cmc / self.total_cards if self.total_cards > 0 else 0
# Estimated value
total_value = 0
for dc in self.deck_cards:
if dc.card.current_price:
total_value += dc.card.current_price * dc.quantity
self.estimated_value = total_value
def __repr__(self):
return f"<Deck(id={self.id}, name='{self.name}', format='{self.format}')>"
class DeckCard(Base):
__tablename__ = "deck_cards"
id = Column(Integer, primary_key=True, index=True)
deck_id = Column(Integer, ForeignKey("decks.id"), nullable=False)
card_id = Column(Integer, ForeignKey("cards.id"), nullable=False)
# Deck composition
quantity = Column(Integer, default=1)
is_sideboard = Column(Boolean, default=False)
is_commander = Column(Boolean, default=False) # For commander format
# Card preferences
preferred_printing = Column(String) # Specific set preference
foil_preference = Column(Boolean, default=False)
# Deck building notes
category = Column(String) # Removal, Ramp, Win-con, etc.
notes = Column(Text)
ai_suggestion = Column(Boolean, default=False) # Was this card suggested by AI?
# Ownership tracking
owned = Column(Boolean, default=False) # Does user own this card?
need_to_acquire = Column(Boolean, default=True)
# Metadata
added_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Relationships
deck = relationship("Deck", back_populates="deck_cards")
card = relationship("Card", back_populates="deck_cards")
def __repr__(self):
return f"<DeckCard(deck_id={self.deck_id}, card_id={self.card_id}, quantity={self.quantity})>"