from datetime import UTC, datetime from sqlalchemy.dialects.postgresql import JSONB from app import db class Card(db.Model): """Card model for Kanban cards""" __tablename__ = "cards" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(200), nullable=False) description = db.Column(db.Text) closed = db.Column(db.Boolean, default=False) due = db.Column(db.DateTime) due_complete = db.Column(db.Boolean, default=False) pos = db.Column(db.Float) # position for sorting id_short = db.Column(db.Integer) # short ID for URLs # Foreign keys board_id = db.Column( db.Integer, db.ForeignKey("boards.id", ondelete="CASCADE"), nullable=False, index=True, ) list_id = db.Column( db.Integer, db.ForeignKey("lists.id", ondelete="CASCADE"), nullable=False, index=True, ) # Timestamps date_last_activity = db.Column(db.DateTime) created_at = db.Column(db.DateTime, default=lambda: datetime.now(UTC)) updated_at = db.Column( db.DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC), ) # JSON fields badges = db.Column(JSONB) # card badges/stats cover = db.Column(JSONB) # cover settings desc_data = db.Column(JSONB) # Relationships checklists = db.relationship( "Checklist", backref="card", cascade="all, delete-orphan", lazy="dynamic" ) labels = db.relationship( "CardLabel", backref="card", cascade="all, delete-orphan", lazy="dynamic" ) comments = db.relationship( "Comment", backref="card", cascade="all, delete-orphan", lazy="dynamic" ) def to_dict(self): """Convert card to dictionary""" return { "id": self.id, "name": self.name, "description": self.description, "closed": self.closed, "due": self.due.isoformat() if self.due else None, "due_complete": self.due_complete, "pos": self.pos, "id_short": self.id_short, "board_id": self.board_id, "list_id": self.list_id, "date_last_activity": self.date_last_activity.isoformat() if self.date_last_activity else None, "created_at": self.created_at.isoformat() if self.created_at else None, "updated_at": self.updated_at.isoformat() if self.updated_at else None, "badges": self.badges, "cover": self.cover, "desc_data": self.desc_data, } def __repr__(self): return f""