"""Schémas Pydantic communs. Définit les schémas réutilisables (pagination, erreurs, etc.). """ from typing import Generic, TypeVar from pydantic import BaseModel, Field T = TypeVar("T") class PaginationParams(BaseModel): """Paramètres de pagination.""" page: int = Field(default=1, ge=1, description="Numéro de page (commence à 1)") page_size: int = Field(default=20, ge=1, le=100, description="Nombre d'éléments par page") @property def offset(self) -> int: """Calcule l'offset pour la requête SQL.""" return (self.page - 1) * self.page_size class PaginatedResponse(BaseModel, Generic[T]): """Réponse paginée générique.""" items: list[T] total: int = Field(..., description="Nombre total d'éléments") page: int = Field(..., description="Page actuelle") page_size: int = Field(..., description="Taille de la page") pages: int = Field(..., description="Nombre total de pages") @classmethod def create( cls, items: list[T], total: int, page: int, page_size: int ) -> "PaginatedResponse[T]": """Crée une réponse paginée.""" pages = (total + page_size - 1) // page_size if page_size > 0 else 0 return cls( items=items, total=total, page=page, page_size=page_size, pages=pages, ) class ErrorResponse(BaseModel): """Schéma de réponse d'erreur.""" detail: str = Field(..., description="Message d'erreur") type: str = Field(..., description="Type d'erreur") class SuccessResponse(BaseModel): """Schéma de réponse de succès.""" message: str = Field(..., description="Message de succès") id: int | None = Field(None, description="ID de l'élément concerné")