""" 用戶相關 Pydantic Schema """ from datetime import datetime from typing import Optional, Literal from pydantic import BaseModel, EmailStr, Field # ===== Pagination ===== class PaginationResponse(BaseModel): page: int limit: int total: int total_pages: int # ===== Role ===== class RoleBase(BaseModel): code: str name: str description: Optional[str] = None class RoleResponse(RoleBase): id: int class Config: from_attributes = True # ===== User ===== class UserBase(BaseModel): username: str = Field(..., min_length=2, max_length=50) display_name: str = Field(..., min_length=1, max_length=100) email: Optional[EmailStr] = None class UserCreate(UserBase): password: Optional[str] = Field(None, min_length=6, description="本地帳號必填") auth_type: Literal["ad", "local"] = "local" role_id: int class UserUpdate(BaseModel): display_name: Optional[str] = Field(None, max_length=100) email: Optional[EmailStr] = None role_id: Optional[int] = None is_active: Optional[bool] = None password: Optional[str] = Field(None, min_length=6, description="僅本地帳號可修改") class UserResponse(UserBase): id: int auth_type: str role: RoleResponse is_active: bool last_login_at: Optional[datetime] = None created_at: datetime class Config: from_attributes = True class UserListResponse(BaseModel): data: list[UserResponse] pagination: "PaginationResponse" # ===== Auth ===== class LoginRequest(BaseModel): username: str password: str auth_type: Literal["ad", "local"] = "ad" class LoginResponse(BaseModel): token: str user: UserResponse class TokenPayload(BaseModel): user_id: int username: str role: str exp: datetime