// 타겟 페르소나 export interface TargetPersona { persona: string; age: { min_age: number; max_age: number; }; favor_target: string[]; decision_trigger: string; } // 셀링 포인트 export interface SellingPoint { english_category: string; korean_category: string; description: string; score: number; } // 마케팅 분석 결과 export interface MarketingAnalysis { brand_identity: { location_feature_analysis: string; concept_scalability: string; }; market_positioning: { category_definition: string; core_value: string; }; target_persona: TargetPersona[]; selling_points: SellingPoint[]; target_keywords: string[]; } export interface CrawlingResponse { image_list: string[]; image_count: number; m_id: number; processed_info: { customer_name: string; region: string; detail_region_info: string; }; marketing_analysis: MarketingAnalysis; } // URL 이미지 (서버에서 가져온 이미지) export interface UrlImage { type: 'url'; url: string; } // 업로드된 파일 이미지 export interface FileImage { type: 'file'; file: File; preview: string; // createObjectURL로 생성된 미리보기 URL } export type ImageItem = UrlImage | FileImage; // 가사 생성 요청 export interface LyricGenerateRequest { customer_name: string; detail_region_info: string; language: string; m_id: number; region: string; task_id: string; orientation?: 'vertical' | 'horizontal'; } // 가사 생성 응답 export interface LyricGenerateResponse { success: boolean; task_id: string; lyric?: string; language?: string; prompt_used?: string; error_message: string | null; } // 가사 상태 조회 응답 export interface LyricStatusResponse { message: string; status: 'processing' | 'completed' | 'failed'; task_id: string; lyric?: string; error_message?: string | null; } // 가사 상세 조회 응답 export interface LyricDetailResponse { id: number; task_id: string; project_id: number; status: string; lyric_prompt: string; lyric_result: string; created_at: string; } // 노래 생성 요청 export interface SongGenerateRequest { genre: string; language: string; lyrics: string; } // 노래 생성 응답 export interface SongGenerateResponse { success: boolean; task_id: string; song_id: string; message: string; error_message: string | null; } // 노래 상태 조회 응답 (Suno Polling) export interface SongStatusResponse { success: boolean; status: string; message: string; song_result_url: string | null; error_message: string | null; } // 노래 다운로드 상태 조회 응답 (DB Polling) export interface SongDownloadResponse { success: boolean; status: string; message: string; store_name: string; region: string; detail_region_info: string; task_id: string; language: string; song_result_url: string; created_at: string; error_message: string | null; } // 영상 생성 응답 export interface VideoGenerateResponse { success: boolean; task_id: string; creatomate_render_id: string message: string; error_message: string | null; } // 영상 상태 확인 응답 export interface VideoStatusResponse { success: boolean; status: string; message: string; render_data: { id: string; status: string; url: string | null; snapshot_url: string | null; video_id?: number; } | null; raw_response?: Record; error_message: string | null; } // 영상 다운로드(결과 조회) 응답 export interface VideoDownloadResponse { success: boolean; status: string; message: string; store_name: string; region: string; task_id: string; result_movie_url: string | null; created_at: string; error_message: string | null; } // 이미지 업로드 요청용 URL 이미지 정보 export interface ImageUrlItem { url: string; name?: string; } // 이미지 업로드 응답 export interface ImageUploadResponse { task_id: string; file_count: number; image_urls: string[]; images: Array<{ id: number; img_name: string; img_order: number; img_url: string; source: string; }>; } // 언어 매핑 export const LANGUAGE_MAP: Record = { '한국어': 'Korean', 'English': 'English', '中文': 'Chinese', '日本語': 'Japanese', 'ไทย': 'Thai', 'Tiếng Việt': 'Vietnamese', }; // 카카오 로그인 URL 응답 export interface KakaoLoginUrlResponse { auth_url: string; } // 카카오 콜백 사용자 정보 export interface KakaoCallbackUser { id: number; nickname: string; email: string | null; profile_image_url: string | null; is_new_user: boolean; } // 카카오 콜백 응답 (JWT 토큰) export interface KakaoCallbackResponse { access_token: string; refresh_token: string; token_type: string; expires_in: number; user: KakaoCallbackUser; redirect_url: string; } // 토큰 갱신 응답 export interface TokenRefreshResponse { access_token: string; refresh_token: string; token_type: string; expires_in: number; } // 사용자 정보 응답 export interface UserMeResponse { id: number; kakao_id: string; email?: string; nickname: string; profile_image_url: string | null; thumbnail_image_url?: string | null; is_active?: boolean; is_admin?: boolean; last_login_at?: string; created_at: string; } export interface UserCreditsResponse { credits: number; } // 비디오 목록 아이템 export interface VideoListItem { video_id: number; store_name: string; region: string; task_id: string; result_movie_url: string; created_at: string; } // 비디오 목록 응답 export interface VideosListResponse { items: VideoListItem[]; total: number; page: number; page_size: number; total_pages: number; has_next: boolean; has_prev: boolean; } // ============================================ // Social OAuth Types // ============================================ // YouTube OAuth 연결 응답 export interface YouTubeConnectResponse { auth_url: string; } // 연결된 소셜 계정 정보 (서버 응답 형식) export interface SocialAccount { id: number; platform: 'youtube' | 'instagram' | 'facebook'; platform_user_id: string; platform_username: string; display_name: string; is_active: boolean; connected_at: string; // OAuth 콜백에서 전달받는 추가 정보 (optional) profile_image?: string | null; } // 소셜 계정 목록 응답 export interface SocialAccountsResponse { accounts: SocialAccount[]; total: number; } // 소셜 계정 단일 조회 응답 export interface SocialAccountResponse { account: SocialAccount | null; connected: boolean; } // 소셜 계정 연결 해제 응답 export interface SocialDisconnectResponse { success: boolean; message: string; } // ============================================ // Social Upload Types (YouTube Upload) // ============================================ // 유튜브 SEO Description 자동완성 요청 export interface YTAutoSeoRequest { task_id: string; // 아카이브의 비디오 ID } // 유튜브 SEO Description 자동완성 응답 export interface YTAutoSeoResponse { title: string; description: string; keywords: string[]; } // 소셜 업로드 요청 export interface SocialUploadRequest { video_id: number; // 아카이브의 비디오 ID social_account_id: number; // 선택된 채널 ID title: string; // 최대 100자 description: string; // 최대 5000자 tags: string[]; // 태그 배열 privacy_status: 'public' | 'unlisted' | 'private'; // 공개 범위 scheduled_at: string | null; // ISO 형식 또는 null (즉시 게시) } // 소셜 업로드 응답 export interface SocialUploadResponse { success: boolean; upload_id: string; status: 'pending' | 'uploading' | 'completed' | 'failed'; message: string; } // 소셜 업로드 상태 조회 응답 export interface SocialUploadStatusResponse { success: boolean; upload_id: number; video_id: number; platform: string; status: 'pending' | 'uploading' | 'completed' | 'failed'; upload_progress: number; // 업로드 진행률 (0-100) title?: string; // 영상 제목 platform_video_id?: string; // 완료 시 플랫폼 비디오 ID platform_url?: string; // 완료 시 플랫폼 URL error_message?: string | null; // 실패 시 에러 메시지 retry_count?: number; created_at?: string; uploaded_at?: string; } // 업로드 히스토리 아이템 export interface UploadHistoryItem { upload_id: number; video_id: number; platform: string; status: 'pending' | 'uploading' | 'completed' | 'failed' | 'scheduled' | 'cancelled'; title: string; channel_name: string; scheduled_at: string | null; uploaded_at: string | null; created_at: string; platform_url: string | null; error_message: string | null; } // 업로드 히스토리 응답 export interface UploadHistoryResponse { success: boolean; items: UploadHistoryItem[]; total?: number; page?: number; size?: number; } // Social OAuth 토큰 만료 에러 응답 export interface TokenExpiredErrorResponse { detail: string; code: 'TOKEN_EXPIRED'; platform: string; reconnect_url: string; }