o2o-castad-backend/app/sns/models.py

184 lines
6.3 KiB
Python

"""
SNS 모듈 SQLAlchemy 모델 정의
SNS 업로드 작업 관리 모델입니다.
"""
from datetime import datetime
from typing import TYPE_CHECKING, Optional
from sqlalchemy import Boolean, DateTime, ForeignKey, Index, Integer, String, Text, func
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.database.session import Base
if TYPE_CHECKING:
from app.user.models import SocialAccount, User
class SNSUploadTask(Base):
"""
SNS 업로드 작업 테이블
SNS 플랫폼에 콘텐츠를 업로드하는 작업을 관리합니다.
즉시 업로드 또는 예약 업로드를 지원합니다.
Attributes:
id: 고유 식별자 (자동 증가)
user_uuid: 사용자 UUID (User.user_uuid 참조)
task_id: 외부 작업 식별자 (비디오 생성 작업 등)
is_scheduled: 예약 작업 여부 (True: 예약, False: 즉시)
scheduled_at: 예약 발행 일시 (분 단위까지)
social_account_id: 소셜 계정 외래키 (SocialAccount.id 참조)
url: 업로드할 미디어 URL
caption: 게시물 캡션/설명
status: 발행 상태 (pending: 예약 대기, completed: 완료, error: 에러)
uploaded_at: 실제 업로드 완료 일시
created_at: 작업 생성 일시
발행 상태 (status):
- pending: 예약 대기 중 (예약 작업이거나 처리 전)
- processing: 처리 중
- completed: 발행 완료
- error: 에러 발생
Relationships:
user: 작업 소유 사용자 (User 테이블 참조)
social_account: 발행 대상 소셜 계정 (SocialAccount 테이블 참조)
"""
__tablename__ = "sns_upload_task"
__table_args__ = (
Index("idx_sns_upload_task_user_uuid", "user_uuid"),
Index("idx_sns_upload_task_task_id", "task_id"),
Index("idx_sns_upload_task_social_account_id", "social_account_id"),
Index("idx_sns_upload_task_status", "status"),
Index("idx_sns_upload_task_is_scheduled", "is_scheduled"),
Index("idx_sns_upload_task_scheduled_at", "scheduled_at"),
Index("idx_sns_upload_task_created_at", "created_at"),
{
"mysql_engine": "InnoDB",
"mysql_charset": "utf8mb4",
"mysql_collate": "utf8mb4_unicode_ci",
},
)
# ==========================================================================
# 기본 식별자
# ==========================================================================
id: Mapped[int] = mapped_column(
Integer,
primary_key=True,
nullable=False,
autoincrement=True,
comment="고유 식별자",
)
# ==========================================================================
# 사용자 및 작업 식별
# ==========================================================================
user_uuid: Mapped[str] = mapped_column(
String(36),
ForeignKey("user.user_uuid", ondelete="CASCADE"),
nullable=False,
comment="사용자 UUID (User.user_uuid 참조)",
)
task_id: Mapped[Optional[str]] = mapped_column(
String(100),
nullable=True,
comment="외부 작업 식별자 (비디오 생성 작업 ID 등)",
)
# ==========================================================================
# 예약 설정
# ==========================================================================
is_scheduled: Mapped[bool] = mapped_column(
Boolean,
nullable=False,
default=False,
comment="예약 작업 여부 (True: 예약 발행, False: 즉시 발행)",
)
scheduled_at: Mapped[Optional[datetime]] = mapped_column(
DateTime,
nullable=True,
comment="예약 발행 일시 (분 단위까지 지정)",
)
# ==========================================================================
# 소셜 계정 연결
# ==========================================================================
social_account_id: Mapped[int] = mapped_column(
Integer,
ForeignKey("social_account.id", ondelete="CASCADE"),
nullable=False,
comment="소셜 계정 외래키 (SocialAccount.id 참조)",
)
# ==========================================================================
# 업로드 콘텐츠
# ==========================================================================
url: Mapped[str] = mapped_column(
String(2048),
nullable=False,
comment="업로드할 미디어 URL",
)
caption: Mapped[Optional[str]] = mapped_column(
Text,
nullable=True,
comment="게시물 캡션/설명",
)
# ==========================================================================
# 발행 상태
# ==========================================================================
status: Mapped[str] = mapped_column(
String(20),
nullable=False,
default="pending",
comment="발행 상태 (pending: 예약 대기, processing: 처리 중, completed: 완료, error: 에러)",
)
# ==========================================================================
# 시간 정보
# ==========================================================================
uploaded_at: Mapped[Optional[datetime]] = mapped_column(
DateTime,
nullable=True,
comment="실제 업로드 완료 일시",
)
created_at: Mapped[datetime] = mapped_column(
DateTime,
nullable=False,
server_default=func.now(),
comment="작업 생성 일시",
)
# ==========================================================================
# Relationships
# ==========================================================================
user: Mapped["User"] = relationship(
"User",
foreign_keys=[user_uuid],
primaryjoin="SNSUploadTask.user_uuid == User.user_uuid",
)
social_account: Mapped["SocialAccount"] = relationship(
"SocialAccount",
foreign_keys=[social_account_id],
)
def __repr__(self) -> str:
return (
f"<SNSUploadTask("
f"id={self.id}, "
f"user_uuid='{self.user_uuid}', "
f"social_account_id={self.social_account_id}, "
f"status='{self.status}', "
f"is_scheduled={self.is_scheduled}"
f")>"
)