from datetime import datetime import enum from typing import Generic, Optional, TypeVar from pydantic import BaseModel, ConfigDict, EmailStr, Field T = TypeVar("T") class ResponseBase(BaseModel): success: Optional[bool] = Field(True) message: Optional[str] = None class BaseSingleResponse(ResponseBase, Generic[T]): result: Optional[T] = None class BaseListResponse(ResponseBase, Generic[T]): result: Optional[list[T]] = None count: Optional[int] = None class UserBase(BaseModel): email: EmailStr username: str = Field( ..., min_length=3, max_length=64, pattern=r"^[A-Za-z0-9_.-]+$", ) full_name: Optional[str] = Field(None, max_length=255, pattern=r"^[^<>]*$") role_id: int = 3 class UserCreate(UserBase): password: str | None = None class UserUpdate(BaseModel): email: Optional[EmailStr] = None username: Optional[str] = Field( None, min_length=3, max_length=64, pattern=r"^[A-Za-z0-9_.-]+$", ) full_name: Optional[str] = Field(None, max_length=255, pattern=r"^[^<>]*$") role_id: Optional[int] = None is_active: Optional[bool] = True class UserInDB(UserBase): model_config = ConfigDict(from_attributes=True) id: int created_at: datetime updated_at: Optional[datetime] = None is_active: bool class User(UserInDB): pass class UserResponse(ResponseBase): result: Optional[UserInDB] = None class UserListResponse(ResponseBase): result: Optional[list[User]] = None class SSPBase(BaseModel): title: str is_ssp: bool = True is_active: bool = True class SSPInDB(SSPBase): model_config = ConfigDict(from_attributes=True) id: int class SSPIDList(BaseModel): ssp_ids: list[int] class UserSSPLinkBase(BaseModel): user_id: int ssp: list[SSPInDB] class UserSSPLinkResponse(ResponseBase): result: Optional[UserSSPLinkBase] = None class Token(BaseModel): access_token: str token_type: str = "bearer" expires_in: Optional[int] = None refresh_token: Optional[str] = None class LoginRequest(BaseModel): username: str password: str class RefreshRequest(BaseModel): refresh_token: str class FormTypeSchemaEnum(str, enum.Enum): FORM_1 = "FORM_1" FORM_2 = "FORM_2" FORM_3 = "FORM_3" FORM_4 = "FORM_4" class BudgetFormResponse(BaseModel): id: int created_at: datetime created_by: int | None updated_at: datetime form_type_code: FormTypeSchemaEnum year: int org_unit_id: int class Config: from_attributes = True class SheetFormTypeResponse(BaseModel): form_type: FormTypeSchemaEnum sheets: list[str] class DirectionSchemaEnum(str, enum.Enum): SUPPORT = "Support" DEVELOPMENT = "Development" class SheetResponse(BaseModel): row_type: str depth: int data: dict sort_order: int | None = None