131 lines
4.7 KiB
Python
131 lines
4.7 KiB
Python
"""
|
|
User 모듈 Pydantic 스키마 정의
|
|
|
|
API 요청/응답 검증을 위한 스키마들입니다.
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
# =============================================================================
|
|
# 카카오 OAuth 스키마
|
|
# =============================================================================
|
|
class KakaoLoginResponse(BaseModel):
|
|
"""카카오 로그인 URL 응답"""
|
|
|
|
auth_url: str = Field(..., description="카카오 인증 페이지 URL")
|
|
|
|
|
|
class KakaoCallbackRequest(BaseModel):
|
|
"""카카오 콜백 요청 (인가 코드)"""
|
|
|
|
code: str = Field(..., min_length=1, description="카카오 인가 코드")
|
|
|
|
|
|
# =============================================================================
|
|
# JWT 토큰 스키마
|
|
# =============================================================================
|
|
class TokenResponse(BaseModel):
|
|
"""토큰 발급 응답"""
|
|
|
|
access_token: str = Field(..., description="액세스 토큰")
|
|
refresh_token: str = Field(..., description="리프레시 토큰")
|
|
token_type: str = Field(default="Bearer", description="토큰 타입")
|
|
expires_in: int = Field(..., description="액세스 토큰 만료 시간 (초)")
|
|
|
|
|
|
class AccessTokenResponse(BaseModel):
|
|
"""액세스 토큰 갱신 응답"""
|
|
|
|
access_token: str = Field(..., description="액세스 토큰")
|
|
token_type: str = Field(default="Bearer", description="토큰 타입")
|
|
expires_in: int = Field(..., description="액세스 토큰 만료 시간 (초)")
|
|
|
|
|
|
class RefreshTokenRequest(BaseModel):
|
|
"""토큰 갱신 요청"""
|
|
|
|
refresh_token: str = Field(..., min_length=1, description="리프레시 토큰")
|
|
|
|
|
|
# =============================================================================
|
|
# 사용자 정보 스키마
|
|
# =============================================================================
|
|
class UserResponse(BaseModel):
|
|
"""사용자 정보 응답"""
|
|
|
|
id: int = Field(..., description="사용자 ID")
|
|
kakao_id: int = Field(..., description="카카오 회원번호")
|
|
email: Optional[str] = Field(None, description="이메일")
|
|
nickname: Optional[str] = Field(None, description="닉네임")
|
|
profile_image_url: Optional[str] = Field(None, description="프로필 이미지 URL")
|
|
thumbnail_image_url: Optional[str] = Field(None, description="썸네일 이미지 URL")
|
|
is_active: bool = Field(..., description="계정 활성화 상태")
|
|
is_admin: bool = Field(..., description="관리자 여부")
|
|
last_login_at: Optional[datetime] = Field(None, description="마지막 로그인 일시")
|
|
created_at: datetime = Field(..., description="가입 일시")
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class UserBriefResponse(BaseModel):
|
|
"""사용자 간략 정보 (토큰 응답에 포함)"""
|
|
|
|
id: int = Field(..., description="사용자 ID")
|
|
nickname: Optional[str] = Field(None, description="닉네임")
|
|
email: Optional[str] = Field(None, description="이메일")
|
|
profile_image_url: Optional[str] = Field(None, description="프로필 이미지 URL")
|
|
is_new_user: bool = Field(..., description="신규 가입 여부")
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class LoginResponse(BaseModel):
|
|
"""로그인 응답 (토큰 + 사용자 정보)"""
|
|
|
|
access_token: str = Field(..., description="액세스 토큰")
|
|
refresh_token: str = Field(..., description="리프레시 토큰")
|
|
token_type: str = Field(default="Bearer", description="토큰 타입")
|
|
expires_in: int = Field(..., description="액세스 토큰 만료 시간 (초)")
|
|
user: UserBriefResponse = Field(..., description="사용자 정보")
|
|
|
|
|
|
# =============================================================================
|
|
# 내부 사용 스키마 (카카오 API 응답 파싱)
|
|
# =============================================================================
|
|
class KakaoTokenResponse(BaseModel):
|
|
"""카카오 토큰 응답 (내부 사용)"""
|
|
|
|
access_token: str
|
|
token_type: str
|
|
refresh_token: Optional[str] = None
|
|
expires_in: int
|
|
scope: Optional[str] = None
|
|
refresh_token_expires_in: Optional[int] = None
|
|
|
|
|
|
class KakaoProfile(BaseModel):
|
|
"""카카오 프로필 정보 (내부 사용)"""
|
|
|
|
nickname: Optional[str] = None
|
|
profile_image_url: Optional[str] = None
|
|
thumbnail_image_url: Optional[str] = None
|
|
is_default_image: Optional[bool] = None
|
|
|
|
|
|
class KakaoAccount(BaseModel):
|
|
"""카카오 계정 정보 (내부 사용)"""
|
|
|
|
email: Optional[str] = None
|
|
profile: Optional[KakaoProfile] = None
|
|
|
|
|
|
class KakaoUserInfo(BaseModel):
|
|
"""카카오 사용자 정보 (내부 사용)"""
|
|
|
|
id: int
|
|
kakao_account: Optional[KakaoAccount] = None
|