from __future__ import annotations import datetime import uuid from typing import List, Dict, Any from sqlalchemy import ( ForeignKey, TIMESTAMP, String, ) from sqlalchemy.orm import ( Mapped, mapped_column, relationship, ) from sqlalchemy.types import JSON from app.adapters.db.orm import Model from app.adapters.opus_clip.enums import ProjectStage from app.assets.utils import get_assets_url from fansifter_common.adapters.db.types import ChoiceType class OpusClipProject(Model): """ Represents a project, which is built upon an Asset. """ __tablename__ = "project" # --- Columns --- id: Mapped[str] = mapped_column( String, primary_key=True, init=False, default_factory=uuid.uuid4 ) external_id: Mapped[str] = mapped_column(String) name: Mapped[str] = mapped_column(String) description: Mapped[str] = mapped_column(String) parameters: Mapped[Dict[str, Any]] = mapped_column(JSON) status: Mapped[ProjectStage] = mapped_column(ChoiceType(ProjectStage)) created_at: Mapped[datetime.datetime] = mapped_column(TIMESTAMP) updated_at: Mapped[datetime.datetime] = mapped_column(TIMESTAMP) asset_id: Mapped[str] = mapped_column(String) clips: Mapped[List[OpusClipClip]] = relationship( back_populates="project", default_factory=list, lazy="select" ) class OpusClipClip(Model): __tablename__ = "clip" id: Mapped[str] = mapped_column(String, primary_key=True) external_id: Mapped[str] = mapped_column(String) created_at: Mapped[datetime.datetime] = mapped_column(TIMESTAMP) attributes: Mapped[Dict[str, Any]] = mapped_column(JSON) title: Mapped[str] description: Mapped[str] s3_key: Mapped[str] project_id: Mapped[str] = mapped_column(ForeignKey("project.id")) project: Mapped[OpusClipProject] = relationship(back_populates="clips", init=False) def url(self, global_participant_id: str) -> str: key = f"clips/{global_participant_id}/{self.project_id}/{self.id}.mp4" return get_assets_url(key)