""" 소셜 OAuth 관련 Pydantic 스키마 """ from datetime import datetime from typing import Any, Optional from pydantic import BaseModel, ConfigDict, Field class SocialConnectResponse(BaseModel): """소셜 계정 연동 시작 응답""" auth_url: str = Field(..., description="OAuth 인증 URL") state: str = Field(..., description="CSRF 방지용 state 토큰") platform: str = Field(..., description="플랫폼명") model_config = ConfigDict( json_schema_extra={ "example": { "auth_url": "https://accounts.google.com/o/oauth2/v2/auth?...", "state": "abc123xyz", "platform": "youtube", } } ) class SocialAccountResponse(BaseModel): """연동된 소셜 계정 정보""" id: int = Field(..., description="소셜 계정 ID") platform: str = Field(..., description="플랫폼명") platform_user_id: str = Field(..., description="플랫폼 내 사용자 ID") platform_username: Optional[str] = Field(None, description="플랫폼 내 사용자명") display_name: Optional[str] = Field(None, description="표시 이름") profile_image_url: Optional[str] = Field(None, description="프로필 이미지 URL") is_active: bool = Field(..., description="활성화 상태") connected_at: datetime = Field(..., description="연동 일시") platform_data: Optional[dict[str, Any]] = Field( None, description="플랫폼별 추가 정보 (채널ID, 구독자 수 등)" ) model_config = ConfigDict( from_attributes=True, json_schema_extra={ "example": { "id": 1, "platform": "youtube", "platform_user_id": "UC1234567890", "platform_username": "my_channel", "display_name": "My Channel", "profile_image_url": "https://...", "is_active": True, "connected_at": "2024-01-15T12:00:00", "platform_data": { "channel_id": "UC1234567890", "channel_title": "My Channel", "subscriber_count": 1000, }, } } ) class SocialAccountListResponse(BaseModel): """연동된 소셜 계정 목록 응답""" accounts: list[SocialAccountResponse] = Field(..., description="연동 계정 목록") total: int = Field(..., description="총 연동 계정 수") model_config = ConfigDict( json_schema_extra={ "example": { "accounts": [ { "id": 1, "platform": "youtube", "platform_user_id": "UC1234567890", "platform_username": "my_channel", "display_name": "My Channel", "is_active": True, "connected_at": "2024-01-15T12:00:00", } ], "total": 1, } } ) class OAuthTokenResponse(BaseModel): """OAuth 토큰 응답 (내부 사용)""" access_token: str refresh_token: Optional[str] = None expires_in: int token_type: str = "Bearer" scope: Optional[str] = None class PlatformUserInfo(BaseModel): """플랫폼 사용자 정보 (내부 사용)""" platform_user_id: str username: Optional[str] = None display_name: Optional[str] = None profile_image_url: Optional[str] = None platform_data: dict[str, Any] = Field(default_factory=dict) class MessageResponse(BaseModel): """단순 메시지 응답""" success: bool = Field(..., description="성공 여부") message: str = Field(..., description="응답 메시지") model_config = ConfigDict( json_schema_extra={ "example": { "success": True, "message": "작업이 완료되었습니다.", } } )