"""Board database model.""" from datetime import datetime from typing import TYPE_CHECKING from uuid import UUID, uuid4 from sqlalchemy import Boolean, DateTime, ForeignKey, String, Text from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.dialects.postgresql import UUID as PGUUID from sqlalchemy.orm import Mapped, mapped_column, relationship from app.database.base import Base if TYPE_CHECKING: from app.database.models.board_image import BoardImage from app.database.models.group import Group from app.database.models.share_link import ShareLink from app.database.models.user import User class Board(Base): """ Board model representing a reference board (canvas) containing images. A board is owned by a user and contains images arranged on an infinite canvas with a specific viewport state (zoom, pan, rotation). """ __tablename__ = "boards" id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4) user_id: Mapped[UUID] = mapped_column( PGUUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False ) title: Mapped[str] = mapped_column(String(255), nullable=False) description: Mapped[str | None] = mapped_column(Text, nullable=True) viewport_state: Mapped[dict] = mapped_column( JSONB, nullable=False, default=lambda: {"x": 0, "y": 0, "zoom": 1.0, "rotation": 0}, ) created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=datetime.utcnow) updated_at: Mapped[datetime] = mapped_column( DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow ) is_deleted: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False) # Relationships user: Mapped["User"] = relationship("User", back_populates="boards") board_images: Mapped[list["BoardImage"]] = relationship( "BoardImage", back_populates="board", cascade="all, delete-orphan" ) groups: Mapped[list["Group"]] = relationship("Group", back_populates="board", cascade="all, delete-orphan") share_links: Mapped[list["ShareLink"]] = relationship( "ShareLink", back_populates="board", cascade="all, delete-orphan" ) def __repr__(self) -> str: """String representation of Board.""" return f""