""" Schemas Pydantic para Usuario. """ from datetime import datetime from typing import Optional from pydantic import BaseModel, EmailStr, Field, field_validator from app.schemas.base import BaseSchema, TimestampSchema class UsuarioBase(BaseSchema): """Schema base de usuario.""" email: EmailStr nombre: str = Field(..., min_length=2, max_length=100) apellido: Optional[str] = Field(None, max_length=100) telefono: Optional[str] = Field(None, max_length=20) class UsuarioCreate(UsuarioBase): """Schema para crear usuario.""" password: str = Field(..., min_length=8, max_length=100) es_admin: bool = False @field_validator("password") @classmethod def validate_password(cls, v: str) -> str: if len(v) < 8: raise ValueError("La contraseña debe tener al menos 8 caracteres") if not any(c.isupper() for c in v): raise ValueError("La contraseña debe tener al menos una mayúscula") if not any(c.islower() for c in v): raise ValueError("La contraseña debe tener al menos una minúscula") if not any(c.isdigit() for c in v): raise ValueError("La contraseña debe tener al menos un número") return v class UsuarioUpdate(BaseSchema): """Schema para actualizar usuario.""" nombre: Optional[str] = Field(None, min_length=2, max_length=100) apellido: Optional[str] = Field(None, max_length=100) telefono: Optional[str] = Field(None, max_length=20) avatar_url: Optional[str] = None preferencias: Optional[str] = None class UsuarioUpdatePassword(BaseModel): """Schema para cambiar contraseña.""" password_actual: str password_nuevo: str = Field(..., min_length=8, max_length=100) @field_validator("password_nuevo") @classmethod def validate_password(cls, v: str) -> str: if len(v) < 8: raise ValueError("La contraseña debe tener al menos 8 caracteres") return v class UsuarioResponse(UsuarioBase, TimestampSchema): """Schema de respuesta de usuario.""" id: int es_admin: bool activo: bool ultimo_acceso: Optional[datetime] = None avatar_url: Optional[str] = None class UsuarioInDB(UsuarioResponse): """Schema interno con hash de password.""" password_hash: str # ============================================================================ # Schemas de Autenticación # ============================================================================ class LoginRequest(BaseModel): """Schema para solicitud de login.""" email: EmailStr password: str class LoginResponse(BaseModel): """Schema de respuesta de login.""" access_token: str refresh_token: str token_type: str = "bearer" expires_in: int user: UsuarioResponse class RefreshTokenRequest(BaseModel): """Schema para refresh token.""" refresh_token: str class TokenResponse(BaseModel): """Schema de respuesta de tokens.""" access_token: str refresh_token: str token_type: str = "bearer" expires_in: int