""" Dashboard Models 대시보드 전용 SQLAlchemy 모델을 정의합니다. """ from datetime import datetime from typing import Optional from sqlalchemy import BigInteger, DateTime, Index, String, UniqueConstraint, func from sqlalchemy.orm import Mapped, mapped_column from app.database.session import Base class Dashboard(Base): """ 채널별 영상 업로드 기록 테이블 YouTube 업로드 완료 시 채널 ID(platform_user_id)와 함께 기록합니다. SocialUpload.social_account_id는 재연동 시 변경되므로, 이 테이블로 채널 기준 안정적인 영상 필터링을 제공합니다. Attributes: id: 고유 식별자 (자동 증가) user_uuid: 사용자 UUID (User.user_uuid 참조) platform: 플랫폼 (youtube/instagram) platform_user_id: 채널 ID (재연동 후에도 불변) platform_video_id: 영상 ID platform_url: 영상 URL title: 영상 제목 uploaded_at: SocialUpload 완료 시각 created_at: 레코드 생성 시각 """ __tablename__ = "dashboard" __table_args__ = ( UniqueConstraint( "platform_video_id", "platform_user_id", name="uq_vcu_video_channel", ), Index("idx_vcu_user_platform", "user_uuid", "platform_user_id"), Index("idx_vcu_uploaded_at", "uploaded_at"), { "mysql_engine": "InnoDB", "mysql_charset": "utf8mb4", "mysql_collate": "utf8mb4_unicode_ci", }, ) # ========================================================================== # 기본 식별자 # ========================================================================== id: Mapped[int] = mapped_column( BigInteger, primary_key=True, nullable=False, autoincrement=True, comment="고유 식별자", ) # ========================================================================== # 관계 필드 # ========================================================================== user_uuid: Mapped[str] = mapped_column( String(36), nullable=False, comment="사용자 UUID (User.user_uuid 참조)", ) # ========================================================================== # 플랫폼 정보 # ========================================================================== platform: Mapped[str] = mapped_column( String(20), nullable=False, comment="플랫폼 (youtube/instagram)", ) platform_user_id: Mapped[str] = mapped_column( String(100), nullable=False, comment="채널 ID (재연동 후에도 불변)", ) # ========================================================================== # 플랫폼 결과 # ========================================================================== platform_video_id: Mapped[str] = mapped_column( String(100), nullable=False, comment="영상 ID", ) platform_url: Mapped[Optional[str]] = mapped_column( String(500), nullable=True, comment="영상 URL", ) # ========================================================================== # 메타데이터 # ========================================================================== title: Mapped[str] = mapped_column( String(200), nullable=False, comment="영상 제목", ) # ========================================================================== # 시간 정보 # ========================================================================== uploaded_at: Mapped[datetime] = mapped_column( DateTime, nullable=False, comment="SocialUpload 완료 시각", ) created_at: Mapped[datetime] = mapped_column( DateTime, nullable=False, server_default=func.now(), comment="레코드 생성 시각", ) def __repr__(self) -> str: return ( f"" )