Files
skills/docs/api-stack/api/api-schemas/src/common/pagination.md
2026-05-29 08:20:56 +01:00

3.9 KiB
Raw Blame History

pagination

Purpose

Defines Zod schemas for pagination input and output shapes used across all Suaveplan list endpoints. These schemas serve as the single source of truth that is consumed by server route handlers, React data-fetching hooks, and OpenAPI document generators alike, ensuring cursor-based and offset-based pagination are expressed identically across every layer of the stack.

Features

  • PaginationInput — accepts an optional 1-based page number, a limit (clamped 1–200), and an opaque cursor string; all fields optional so callers can omit what they don't need
  • PaginationOutput — carries total count (nullable when unknown), current page, limit, hasNextPage flag, and opaque startCursor/endCursor strings for cursor-based traversal
  • Full TypeScript inference via z.infer<> — no manual interface duplication
  • Both cursor-based and offset-based strategies represented in one schema set
  • Zod v4 compatible

Usage: Basic Example

import { PaginationInput } from "@suaveplan/api-schemas/common";

// Parse a query-string object coming from an HTTP request
const params = PaginationInput.parse({ limit: 20, cursor: "eyJpZCI6IjEifQ==" });
// → { limit: 20, cursor: "eyJpZCI6IjEifQ==" }

Usage: Advanced Example

import { PaginationInput, PaginationOutput } from "@suaveplan/api-schemas/common";

// Validate request query params with safe parse
const result = PaginationInput.safeParse({ page: 2, limit: 50 });
if (!result.success) {
  console.error(result.error.flatten());
} else {
  const { page, limit } = result.data;
  // Use page/limit to run a DB query, then build PaginationOutput:
  const meta = PaginationOutput.parse({
    total: 120,
    page: 2,
    limit: 50,
    hasNextPage: true,
    startCursor: "eyJpZCI6IjUxIn0=",
    endCursor: "eyJpZCI6IjEwMCJ9",
  });
}

API Reference

PaginationInput

Zod object schema. All fields optional.

Field Type Description
page number (int ≥ 1) 1-based page index; ignored when cursor is present
limit number (int 1–200) Maximum items per page
cursor string (min length 1) Opaque cursor from a prior response

Type export: type PaginationInput = z.infer<typeof PaginationInput>

PaginationOutput

Zod object schema. Returned as part of list responses.

Field Type Description
total number | null Total matching records; null when count is skipped
page number | null Current page (null for pure cursor pagination)
limit number (int ≥ 1) Items per page
hasNextPage boolean Whether more items follow this page
startCursor string | null Cursor pointing to first item in this page
endCursor string | null Cursor pointing to last item in this page

Type export: type PaginationOutput = z.infer<typeof PaginationOutput>

Implementation Notes

All fields in PaginationInput are optional to support partial query-string parsing in HTTP frameworks that pass unknown keys through. The limit field is hard-clamped to 200 to prevent accidental unbounded queries; services that require a different ceiling should create a refined schema via .superRefine(). The cursor is validated as a non-empty string but its internal encoding is opaque to this schema layer — encoding/decoding is the responsibility of the data adapter.