import enum import uuid from sqlalchemy import Enum, ForeignKey, String, Text from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column, relationship from api.models.base import Base, TimestampMixin, new_uuid class TopicStatus(str, enum.Enum): active = "active" paused = "paused" archived = "archived" class Topic(Base, TimestampMixin): __tablename__ = "topics" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=new_uuid ) slug: Mapped[str] = mapped_column(String(100), unique=True, nullable=False, index=True) title: Mapped[str] = mapped_column(String(255), nullable=False) description: Mapped[str | None] = mapped_column(Text, nullable=True) domain_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("domains.id", ondelete="RESTRICT"), nullable=False, index=True, ) status: Mapped[TopicStatus] = mapped_column( Enum(TopicStatus), nullable=False, default=TopicStatus.active ) domain: Mapped["Domain"] = relationship( # noqa: F821 "Domain", back_populates="topics", lazy="selectin" ) workstreams: Mapped[list["Workstream"]] = relationship( # noqa: F821 "Workstream", back_populates="topic", lazy="selectin" ) decisions: Mapped[list["Decision"]] = relationship( # noqa: F821 "Decision", back_populates="topic", lazy="selectin" ) progress_events: Mapped[list["ProgressEvent"]] = relationship( # noqa: F821 "ProgressEvent", back_populates="topic", lazy="selectin" ) @property def domain_slug(self) -> str | None: """Returns the domain slug string for serialization.""" if self.domain is not None: return self.domain.slug return None