72 lines
2.6 KiB
Python
72 lines
2.6 KiB
Python
"""
|
|
Pagination models for server-side pagination, sorting, and filtering.
|
|
|
|
All models use camelStyle naming convention for consistency with frontend.
|
|
"""
|
|
|
|
from typing import List, Dict, Any, Optional, Generic, TypeVar
|
|
from pydantic import BaseModel, Field
|
|
import math
|
|
|
|
T = TypeVar('T')
|
|
|
|
|
|
class SortField(BaseModel):
|
|
"""
|
|
Single sort field configuration.
|
|
"""
|
|
field: str = Field(..., description="Field name to sort by")
|
|
direction: str = Field(..., description="Sort direction: 'asc' or 'desc'")
|
|
|
|
|
|
class PaginationParams(BaseModel):
|
|
"""
|
|
Complete pagination state including page, sorting, and filters.
|
|
"""
|
|
page: int = Field(ge=1, description="Current page number (1-based)")
|
|
pageSize: int = Field(ge=1, le=1000, description="Number of items per page")
|
|
sort: List[SortField] = Field(default_factory=list, description="List of sort fields in priority order")
|
|
filters: Optional[Dict[str, Any]] = Field(default=None, description="Filter criteria (structure TBD for future implementation)")
|
|
|
|
|
|
class PaginationRequest(BaseModel):
|
|
"""
|
|
Pagination request parameters sent from frontend to backend.
|
|
All fields are optional. If pagination=None, no pagination is applied.
|
|
"""
|
|
pagination: Optional[PaginationParams] = None
|
|
|
|
|
|
class PaginatedResult(BaseModel):
|
|
"""
|
|
Internal result structure from interface layer.
|
|
Used when pagination is requested.
|
|
"""
|
|
items: List[Any]
|
|
totalItems: int
|
|
totalPages: int # Calculated as: math.ceil(totalItems / pageSize)
|
|
|
|
|
|
class PaginationMetadata(BaseModel):
|
|
"""
|
|
Pagination metadata returned to frontend for rendering controls.
|
|
Contains all information needed to render pagination UI and handle user interactions.
|
|
"""
|
|
currentPage: int = Field(..., description="Current page number (1-based)")
|
|
pageSize: int = Field(..., description="Number of items per page")
|
|
totalItems: int = Field(..., description="Total number of items across all pages (after filters)")
|
|
totalPages: int = Field(..., description="Total number of pages (calculated from totalItems / pageSize)")
|
|
sort: List[SortField] = Field(..., description="Current sort configuration applied")
|
|
filters: Optional[Dict[str, Any]] = Field(default=None, description="Current filters applied (for future use)")
|
|
|
|
|
|
class PaginatedResponse(BaseModel, Generic[T]):
|
|
"""
|
|
Response containing paginated data and metadata.
|
|
"""
|
|
items: List[T] = Field(..., description="Array of items for current page")
|
|
pagination: Optional[PaginationMetadata] = Field(..., description="Pagination metadata (None if pagination not applied)")
|
|
|
|
class Config:
|
|
arbitrary_types_allowed = True
|
|
|