from typing import TYPE_CHECKING from sqlalchemy import ForeignKey, Column, Table, Index from sqlalchemy.orm import mapped_column, Mapped, relationship from models import BaseModel from models.mixins import IdMixin, SoftDeleteMixin if TYPE_CHECKING: from models import Project, Deal deals_deal_tags = Table( "deals_deal_tags", BaseModel.metadata, Column("deal_id", ForeignKey("deals.id"), primary_key=True), Column("deal_tag_id", ForeignKey("deal_tags.id"), primary_key=True), ) class DealTagColor(BaseModel, IdMixin): __tablename__ = "deal_tag_colors" label: Mapped[str] = mapped_column(unique=True) color: Mapped[str] = mapped_column(unique=True) background_color: Mapped[str] = mapped_column(unique=True) is_deleted: Mapped[bool] = mapped_column(default=False) class DealTag(BaseModel, IdMixin, SoftDeleteMixin): __tablename__ = "deal_tags" name: Mapped[str] = mapped_column() project_id: Mapped[int] = mapped_column(ForeignKey("projects.id")) project: Mapped["Project"] = relationship( back_populates="tags", lazy="noload", ) deals: Mapped[list["Deal"]] = relationship( secondary="deals_deal_tags", lazy="noload", back_populates="tags", ) tag_color_id: Mapped[int] = mapped_column(ForeignKey("deal_tag_colors.id")) tag_color: Mapped[DealTagColor] = relationship(lazy="immediate") __table_args__ = ( Index("idx_deal_name_project_id", "name", "project_id", "is_deleted"), )