""" 소셜 업로드 API 라우터 소셜 미디어 영상 업로드 관련 엔드포인트를 제공합니다. 비즈니스 로직은 SocialUploadService에 위임합니다. """ import logging from typing import Optional from fastapi import APIRouter, BackgroundTasks, Depends, Query from sqlalchemy.ext.asyncio import AsyncSession from app.database.session import get_session from app.social.constants import SocialPlatform from app.social.schemas import ( MessageResponse, SocialUploadHistoryResponse, SocialUploadRequest, SocialUploadResponse, SocialUploadStatusResponse, ) from app.social.services import SocialUploadService, social_account_service from app.user.dependencies import get_current_user from app.user.models import User logger = logging.getLogger(__name__) router = APIRouter(prefix="/upload", tags=["Social Upload"]) upload_service = SocialUploadService(account_service=social_account_service) @router.post( "", response_model=SocialUploadResponse, summary="소셜 플랫폼에 영상 업로드 요청", description=""" 영상을 소셜 미디어 플랫폼에 업로드합니다. ## 사전 조건 - 해당 플랫폼에 계정이 연동되어 있어야 합니다 - 영상이 completed 상태여야 합니다 (result_movie_url 필요) ## 요청 필드 - **video_id**: 업로드할 영상 ID - **social_account_id**: 업로드할 소셜 계정 ID (연동 계정 목록 조회 API에서 확인) - **title**: 영상 제목 (최대 100자) - **description**: 영상 설명 (최대 5000자) - **tags**: 태그 목록 - **privacy_status**: 공개 상태 (public, unlisted, private) - **scheduled_at**: 예약 게시 시간 (선택사항) ## 업로드 상태 업로드는 백그라운드에서 처리되며, 상태를 폴링하여 확인할 수 있습니다: - `pending`: 업로드 대기 중 - `uploading`: 업로드 진행 중 - `processing`: 플랫폼에서 처리 중 - `completed`: 업로드 완료 - `failed`: 업로드 실패 """, ) async def upload_to_social( body: SocialUploadRequest, background_tasks: BackgroundTasks, current_user: User = Depends(get_current_user), session: AsyncSession = Depends(get_session), ) -> SocialUploadResponse: return await upload_service.request_upload(body, current_user, session, background_tasks) @router.get( "/{upload_id}/status", response_model=SocialUploadStatusResponse, summary="업로드 상태 조회", description="특정 업로드 작업의 상태를 조회합니다.", ) async def get_upload_status( upload_id: int, current_user: User = Depends(get_current_user), session: AsyncSession = Depends(get_session), ) -> SocialUploadStatusResponse: return await upload_service.get_upload_status(upload_id, current_user, session) @router.get( "/history", response_model=SocialUploadHistoryResponse, summary="업로드 이력 조회", description=""" 사용자의 소셜 미디어 업로드 이력을 조회합니다. ## tab 파라미터 - `all`: 전체 (기본값) - `completed`: 완료된 업로드 - `scheduled`: 예약 업로드 (pending + scheduled_at 있음) - `failed`: 실패한 업로드 """, ) async def get_upload_history( current_user: User = Depends(get_current_user), session: AsyncSession = Depends(get_session), tab: str = Query("all", description="탭 필터 (all/completed/scheduled/failed)"), platform: Optional[SocialPlatform] = Query(None, description="플랫폼 필터"), year: Optional[int] = Query(None, description="조회 연도 (없으면 현재 연도)"), month: Optional[int] = Query(None, ge=1, le=12, description="조회 월 (없으면 현재 월)"), page: int = Query(1, ge=1, description="페이지 번호"), size: int = Query(20, ge=1, le=100, description="페이지 크기"), ) -> SocialUploadHistoryResponse: return await upload_service.get_upload_history( current_user, session, tab, platform, year, month, page, size ) @router.post( "/{upload_id}/retry", response_model=SocialUploadResponse, summary="업로드 재시도", description="실패한 업로드를 재시도합니다.", ) async def retry_upload( upload_id: int, background_tasks: BackgroundTasks, current_user: User = Depends(get_current_user), session: AsyncSession = Depends(get_session), ) -> SocialUploadResponse: return await upload_service.retry_upload(upload_id, current_user, session, background_tasks) @router.delete( "/{upload_id}", response_model=MessageResponse, summary="업로드 취소", description="대기 중인 업로드를 취소합니다.", ) async def cancel_upload( upload_id: int, current_user: User = Depends(get_current_user), session: AsyncSession = Depends(get_session), ) -> MessageResponse: return await upload_service.cancel_upload(upload_id, current_user, session)