from datetime import datetime from typing import Any, Optional from pydantic import BaseModel, EmailStr, Field from .roles import ALL_ROLES class LoginRequest(BaseModel): username: str password: str class RegisterRequest(BaseModel): username: str = Field(min_length=2, max_length=50) email: EmailStr password: str = Field(min_length=6, max_length=128) display_name: Optional[str] = None class VerifyEmailRequest(BaseModel): token: str = Field(min_length=8, max_length=128) class ResendVerificationRequest(BaseModel): email: Optional[EmailStr] = None username: Optional[str] = None class ForgotPasswordRequest(BaseModel): email: Optional[EmailStr] = None username: Optional[str] = None class ResetPasswordRequest(BaseModel): token: str = Field(min_length=8, max_length=128) password: str = Field(min_length=6, max_length=128) class ForgotPasswordResponse(BaseModel): message: str email: str reset_sent: bool dev_reset_url: Optional[str] = None class TokenResponse(BaseModel): access_token: str token_type: str = "bearer" class RegisterResponse(BaseModel): message: str email: str verification_sent: bool verification_required: bool = True dev_verify_url: Optional[str] = None class MessageResponse(BaseModel): message: str class UserResponse(BaseModel): id: int username: str email: Optional[str] = None display_name: Optional[str] = None role: str role_label: str = "" is_admin: bool = False permissions: list[str] = Field(default_factory=list) is_active: bool email_verified: bool = False max_accounts: int = 3 account_count: Optional[int] = None active_account_count: Optional[int] = None disabled_account_count: Optional[int] = None created_at: datetime class Config: from_attributes = True class UserCreate(BaseModel): username: str = Field(min_length=2, max_length=50) password: str = Field(min_length=6, max_length=128) display_name: Optional[str] = None role: str = "operator" email: Optional[EmailStr] = None email_verified: bool = True max_accounts: int = Field(default=3, ge=0, le=999) class UserUpdate(BaseModel): display_name: Optional[str] = None role: Optional[str] = None is_active: Optional[bool] = None password: Optional[str] = Field(default=None, min_length=6, max_length=128) email: Optional[EmailStr] = None email_verified: Optional[bool] = None max_accounts: Optional[int] = Field(default=None, ge=0, le=999) class RoleInfo(BaseModel): value: str label: str description: Optional[str] = None is_system: bool = False is_admin: bool = False permissions: list[str] = Field(default_factory=list) user_count: Optional[int] = None class RolesResponse(BaseModel): roles: list[RoleInfo] class RoleCreate(BaseModel): code: str = Field(min_length=2, max_length=50) label: str = Field(min_length=1, max_length=100) description: Optional[str] = Field(default=None, max_length=255) permissions: list[str] = Field(default_factory=list) class RoleUpdate(BaseModel): label: Optional[str] = Field(default=None, min_length=1, max_length=100) description: Optional[str] = Field(default=None, max_length=255) permissions: Optional[list[str]] = None class PermissionCatalogResponse(BaseModel): menus: list[dict[str, Any]] actions: list[dict[str, Any]] data: list[dict[str, Any]] = Field(default_factory=list) tree: list[dict[str, Any]] = Field(default_factory=list) pairs: list[dict[str, Any]] = Field(default_factory=list)