""" SocialAccount 모듈 Pydantic 스키마 정의 소셜 계정 연동 API 요청/응답 검증을 위한 스키마들입니다. """ from datetime import datetime from typing import Any, Optional from pydantic import BaseModel, Field from app.user.models import Platform # ============================================================================= # 요청 스키마 # ============================================================================= class SocialAccountCreateRequest(BaseModel): """소셜 계정 연동 요청""" platform: Platform = Field(..., description="플랫폼 구분 (youtube, instagram, facebook, tiktok)") access_token: str = Field(..., min_length=1, description="OAuth 액세스 토큰") refresh_token: Optional[str] = Field(None, description="OAuth 리프레시 토큰") token_expires_at: Optional[datetime] = Field(None, description="토큰 만료 일시") scope: Optional[str] = Field(None, description="허용된 권한 범위") platform_user_id: str = Field(..., min_length=1, description="플랫폼 내 사용자 고유 ID") platform_username: Optional[str] = Field(None, description="플랫폼 내 사용자명/핸들") platform_data: Optional[dict[str, Any]] = Field(None, description="플랫폼별 추가 정보") model_config = { "json_schema_extra": { "example": { "platform": "instagram", "access_token": "IGQWRPcG...", "refresh_token": None, "token_expires_at": "2026-03-15T10:30:00", "scope": "instagram_basic,instagram_content_publish", "platform_user_id": "17841400000000000", "platform_username": "my_instagram_account", "platform_data": { "business_account_id": "17841400000000000", "facebook_page_id": "123456789" } } } } class SocialAccountUpdateRequest(BaseModel): """소셜 계정 정보 수정 요청""" access_token: Optional[str] = Field(None, min_length=1, description="OAuth 액세스 토큰") refresh_token: Optional[str] = Field(None, description="OAuth 리프레시 토큰") token_expires_at: Optional[datetime] = Field(None, description="토큰 만료 일시") scope: Optional[str] = Field(None, description="허용된 권한 범위") platform_username: Optional[str] = Field(None, description="플랫폼 내 사용자명/핸들") platform_data: Optional[dict[str, Any]] = Field(None, description="플랫폼별 추가 정보") is_active: Optional[bool] = Field(None, description="활성화 상태") model_config = { "json_schema_extra": { "example": { "access_token": "IGQWRPcG_NEW_TOKEN...", "token_expires_at": "2026-04-15T10:30:00", "is_active": True } } } # ============================================================================= # 응답 스키마 # ============================================================================= class SocialAccountResponse(BaseModel): """소셜 계정 정보 응답""" account_id: int = Field(..., validation_alias="id", description="소셜 계정 ID") platform: Platform = Field(..., description="플랫폼 구분") platform_user_id: str = Field(..., description="플랫폼 내 사용자 고유 ID") platform_username: Optional[str] = Field(None, description="플랫폼 내 사용자명/핸들") platform_data: Optional[dict[str, Any]] = Field(None, description="플랫폼별 추가 정보") scope: Optional[str] = Field(None, description="허용된 권한 범위") token_expires_at: Optional[datetime] = Field(None, description="토큰 만료 일시") is_active: bool = Field(..., description="활성화 상태") created_at: datetime = Field(..., description="연동 일시") updated_at: datetime = Field(..., description="수정 일시") model_config = { "from_attributes": True, "populate_by_name": True, "json_schema_extra": { "example": { "account_id": 1, "platform": "instagram", "platform_user_id": "17841400000000000", "platform_username": "my_instagram_account", "platform_data": { "business_account_id": "17841400000000000" }, "scope": "instagram_basic,instagram_content_publish", "token_expires_at": "2026-03-15T10:30:00", "is_active": True, "created_at": "2026-01-15T10:30:00", "updated_at": "2026-01-15T10:30:00" } } } class SocialAccountListResponse(BaseModel): """소셜 계정 목록 응답""" items: list[SocialAccountResponse] = Field(..., description="소셜 계정 목록") total: int = Field(..., description="총 계정 수") model_config = { "json_schema_extra": { "example": { "items": [ { "account_id": 1, "platform": "instagram", "platform_user_id": "17841400000000000", "platform_username": "my_instagram_account", "platform_data": None, "scope": "instagram_basic", "token_expires_at": "2026-03-15T10:30:00", "is_active": True, "created_at": "2026-01-15T10:30:00", "updated_at": "2026-01-15T10:30:00" } ], "total": 1 } } } class SocialAccountDeleteResponse(BaseModel): """소셜 계정 삭제 응답""" message: str = Field(..., description="결과 메시지") deleted_id: int = Field(..., description="삭제된 계정 ID") model_config = { "json_schema_extra": { "example": { "message": "소셜 계정이 삭제되었습니다.", "deleted_id": 1 } } }