import uuid from datetime import datetime from sqlalchemy import DateTime, ForeignKey, String, Text from sqlalchemy.dialects.postgresql import JSONB, UUID from sqlalchemy.orm import Mapped, mapped_column, relationship from api.models.base import Base, TimestampMixin, new_uuid class ManagedRepo(Base, TimestampMixin): __tablename__ = "managed_repos" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=new_uuid ) domain_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("domains.id", ondelete="RESTRICT"), nullable=False, index=True ) slug: Mapped[str] = mapped_column(String(100), unique=True, nullable=False, index=True) name: Mapped[str] = mapped_column(String(200), nullable=False) local_path: Mapped[str | None] = mapped_column(Text, nullable=True) host_paths: Mapped[dict] = mapped_column(JSONB, nullable=False, default=dict, server_default="{}") remote_url: Mapped[str | None] = mapped_column(Text, nullable=True) description: Mapped[str | None] = mapped_column(Text, nullable=True) status: Mapped[str] = mapped_column(String(20), nullable=False, default="active") topic_id: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), ForeignKey("topics.id", ondelete="SET NULL"), nullable=True ) sbom_source: Mapped[str | None] = mapped_column(Text, nullable=True) last_sbom_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True ) last_state_synced_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True ) domain: Mapped["Domain"] = relationship( # noqa: F821 "Domain", back_populates="repos", lazy="selectin" ) goals: Mapped[list["RepoGoal"]] = relationship( # noqa: F821 "RepoGoal", back_populates="repo", lazy="selectin" ) @property def domain_slug(self) -> str: return self.domain.slug if self.domain is not None else ""