Upload app/models/tag_link.py

This commit is contained in:
2026-06-04 00:06:19 +00:00
committed by leocrm-bot
parent 53513546ed
commit 394a910941
+50
View File
@@ -0,0 +1,50 @@
"""TagLink model: polymorphic many-to-many between tags and accounts/contacts/deals."""
from __future__ import annotations
from enum import Enum
from typing import TYPE_CHECKING
from sqlalchemy import ForeignKey, Integer, String, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.models.base import Base, OrgScopedMixin, SoftDeleteMixin, TimestampMixin
if TYPE_CHECKING:
from app.models.tag import Tag
class TagLinkParentType(str, Enum):
"""Polymorphic parent type for tag links (no DB FK, validated in service layer)."""
account = "account"
contact = "contact"
deal = "deal"
class TagLink(Base, TimestampMixin, SoftDeleteMixin, OrgScopedMixin):
__tablename__ = "tag_links"
__table_args__ = (
UniqueConstraint(
"tag_id", "parent_type", "parent_id", name="uq_tag_link"
),
)
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
tag_id: Mapped[int] = mapped_column(
ForeignKey("tags.id"), nullable=False, index=True
)
parent_type: Mapped[TagLinkParentType] = mapped_column(
String(32), nullable=False, index=True
)
# parent_id is intentionally NOT a DB FK because of polymorphic parent.
# Service layer (tag_service.link_tag) validates existence.
parent_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True)
tag: Mapped["Tag"] = relationship("Tag", back_populates="links", lazy="joined")
def __repr__(self) -> str:
return f"<TagLink id={self.id} tag={self.tag_id} parent={self.parent_type}:{self.parent_id}>"
__all__ = ["TagLink", "TagLinkParentType"]