arbret/backend/pagination.py
counterweight 0dd84e90a5
refactor(backend): extract pagination utilities
Issue #4: Pagination logic was repeated across multiple routes.

Changes:
- Add pagination.py with reusable utilities:
  - calculate_total_pages: computes page count from total/per_page
  - calculate_offset: computes offset for given page
  - create_paginated_response: builds PaginatedResponse with metadata
- Update routes/audit.py to use pagination utilities
- Update routes/booking.py to use pagination utilities
- Update routes/invites.py to use pagination utilities

The utilities handle the common pagination math while routes
still manage their own query logic (filters, joins, ordering).
2025-12-22 00:00:24 +01:00

46 lines
1.2 KiB
Python

"""Pagination utilities for API responses."""
from typing import TypeVar
from pydantic import BaseModel
from schemas import PaginatedResponse
RecordT = TypeVar("RecordT", bound=BaseModel)
def calculate_total_pages(total: int, per_page: int) -> int:
"""Calculate total number of pages."""
return (total + per_page - 1) // per_page if total > 0 else 1
def calculate_offset(page: int, per_page: int) -> int:
"""Calculate the offset for a given page."""
return (page - 1) * per_page
def create_paginated_response(
records: list[RecordT],
total: int,
page: int,
per_page: int,
) -> PaginatedResponse[RecordT]:
"""
Create a paginated response with calculated metadata.
Args:
records: List of records for the current page
total: Total count of all records (before pagination)
page: Current page number (1-indexed)
per_page: Number of records per page
Returns:
A PaginatedResponse with all pagination metadata
"""
return PaginatedResponse[RecordT](
records=records,
total=total,
page=page,
per_page=per_page,
total_pages=calculate_total_pages(total, per_page),
)