160 lines
5.2 KiB
Python
160 lines
5.2 KiB
Python
"""
|
|
User 모듈 SQLAlchemy 모델 정의
|
|
|
|
카카오 소셜 로그인 기반 사용자 관리 모델입니다.
|
|
|
|
주의: 이 모델은 현재 개발 중이므로 create_db_tables()에서 import하지 않습니다.
|
|
테이블 생성이 필요할 때 app/database/session.py의 create_db_tables()에
|
|
아래 import를 추가하세요:
|
|
|
|
from app.user.models import User # noqa: F401
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
from sqlalchemy import BigInteger, Boolean, DateTime, Index, String, func
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.database.session import Base
|
|
|
|
|
|
class User(Base):
|
|
"""
|
|
사용자 테이블 (카카오 소셜 로그인)
|
|
|
|
카카오 로그인을 통해 인증된 사용자 정보를 저장합니다.
|
|
|
|
Attributes:
|
|
id: 고유 식별자 (자동 증가)
|
|
kakao_id: 카카오 고유 ID (필수, 유니크)
|
|
email: 이메일 주소 (선택, 카카오에서 제공 시)
|
|
nickname: 카카오 닉네임 (선택)
|
|
profile_image_url: 카카오 프로필 이미지 URL (선택)
|
|
thumbnail_image_url: 카카오 썸네일 이미지 URL (선택)
|
|
is_active: 계정 활성화 상태 (기본 True)
|
|
is_admin: 관리자 여부 (기본 False)
|
|
last_login_at: 마지막 로그인 일시
|
|
created_at: 계정 생성 일시
|
|
updated_at: 계정 정보 수정 일시
|
|
|
|
카카오 API 응답 필드 매핑:
|
|
- kakao_id: id (카카오 회원번호)
|
|
- email: kakao_account.email
|
|
- nickname: kakao_account.profile.nickname 또는 properties.nickname
|
|
- profile_image_url: kakao_account.profile.profile_image_url
|
|
- thumbnail_image_url: kakao_account.profile.thumbnail_image_url
|
|
"""
|
|
|
|
__tablename__ = "user"
|
|
__table_args__ = (
|
|
Index("idx_user_kakao_id", "kakao_id", unique=True),
|
|
Index("idx_user_email", "email"),
|
|
Index("idx_user_is_active", "is_active"),
|
|
Index("idx_user_created_at", "created_at"),
|
|
{
|
|
"mysql_engine": "InnoDB",
|
|
"mysql_charset": "utf8mb4",
|
|
"mysql_collate": "utf8mb4_unicode_ci",
|
|
},
|
|
)
|
|
|
|
# ==========================================================================
|
|
# 기본 식별자
|
|
# ==========================================================================
|
|
id: Mapped[int] = mapped_column(
|
|
BigInteger,
|
|
primary_key=True,
|
|
nullable=False,
|
|
autoincrement=True,
|
|
comment="고유 식별자",
|
|
)
|
|
|
|
# ==========================================================================
|
|
# 카카오 소셜 로그인 필수 정보
|
|
# ==========================================================================
|
|
kakao_id: Mapped[int] = mapped_column(
|
|
BigInteger,
|
|
nullable=False,
|
|
unique=True,
|
|
comment="카카오 고유 ID (회원번호)",
|
|
)
|
|
|
|
# ==========================================================================
|
|
# 카카오에서 제공하는 사용자 정보 (선택적)
|
|
# ==========================================================================
|
|
email: Mapped[Optional[str]] = mapped_column(
|
|
String(255),
|
|
nullable=True,
|
|
comment="이메일 주소 (카카오 계정 이메일, 동의 시 제공)",
|
|
)
|
|
|
|
nickname: Mapped[Optional[str]] = mapped_column(
|
|
String(100),
|
|
nullable=True,
|
|
comment="카카오 닉네임",
|
|
)
|
|
|
|
profile_image_url: Mapped[Optional[str]] = mapped_column(
|
|
String(2048),
|
|
nullable=True,
|
|
comment="카카오 프로필 이미지 URL",
|
|
)
|
|
|
|
thumbnail_image_url: Mapped[Optional[str]] = mapped_column(
|
|
String(2048),
|
|
nullable=True,
|
|
comment="카카오 썸네일 이미지 URL",
|
|
)
|
|
|
|
# ==========================================================================
|
|
# 계정 상태 관리
|
|
# ==========================================================================
|
|
is_active: Mapped[bool] = mapped_column(
|
|
Boolean,
|
|
nullable=False,
|
|
default=True,
|
|
comment="계정 활성화 상태 (비활성화 시 로그인 차단)",
|
|
)
|
|
|
|
is_admin: Mapped[bool] = mapped_column(
|
|
Boolean,
|
|
nullable=False,
|
|
default=False,
|
|
comment="관리자 권한 여부",
|
|
)
|
|
|
|
# ==========================================================================
|
|
# 시간 정보
|
|
# ==========================================================================
|
|
last_login_at: Mapped[Optional[datetime]] = mapped_column(
|
|
DateTime,
|
|
nullable=True,
|
|
comment="마지막 로그인 일시",
|
|
)
|
|
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime,
|
|
nullable=False,
|
|
server_default=func.now(),
|
|
comment="계정 생성 일시",
|
|
)
|
|
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime,
|
|
nullable=False,
|
|
server_default=func.now(),
|
|
onupdate=func.now(),
|
|
comment="계정 정보 수정 일시",
|
|
)
|
|
|
|
def __repr__(self) -> str:
|
|
return (
|
|
f"<User("
|
|
f"id={self.id}, "
|
|
f"kakao_id={self.kakao_id}, "
|
|
f"nickname='{self.nickname}', "
|
|
f"is_active={self.is_active}"
|
|
f")>"
|
|
)
|