Skip to content

Add pagination and stable ordering to expense and settlement lists #196

Description

@Cjay-Cyber-2

Description

Add bounded pagination and deterministic ordering to collection endpoints that return group expenses or settlement records. This prevents large groups from causing slow responses and gives clients a stable way to load older activity without missing or duplicating records between requests.

Context & Requirements

The API is a Fastify and TypeScript backend using Prisma, and every request must be validated with Zod. Collection responses are consumed by the web client through types in mergepay-web/src/lib/types.ts. Use a consistent cursor or page-based contract based on the repository's existing route conventions; do not introduce several incompatible pagination styles in one change. Sort by a unique, immutable tie-breaker such as creation time plus ID, and cap the requested page size server-side.

Pagination must remain scoped to the authenticated user's permitted groups. Do not let a cursor bypass membership or admin checks, and do not use an unbounded database query before slicing the result.

Acceptance Criteria

  • Relevant expense and settlement list endpoints accept validated pagination parameters and reject invalid limits or cursors.
  • Results have deterministic ordering across requests, including records with equal timestamps.
  • The server enforces a maximum page size and queries only the required records.
  • Pagination metadata clearly indicates whether another page exists and provides the next cursor or equivalent value.
  • Group membership and visibility rules are applied before returning every page.
  • Existing clients that omit pagination parameters retain a bounded, backward-compatible response shape.

Implementation Guidance

Locate the collection routes and Prisma queries under src, then compare their response types with mergepay-web/src/lib/types.ts. Follow current Zod schemas and Fastify error responses. Prefer database-level ordering and cursor filtering over in-memory slicing, and ensure the cursor encodes enough information to prevent ambiguous timestamp-only ordering.

Testing & Validation

Add route and query tests covering first, middle, and final pages; equal timestamps; invalid and oversized parameters; empty results; and unauthorized group access. Verify that the generated query does not fetch the full collection. Run npm run build, npm test, and npm run lint, and update API contract documentation or client types as required.

Submission Guidelines

Assignment is required before starting. Open one PR that includes Closes #<issue-number>, keeps one consistent pagination contract across the touched endpoints, and follows repository naming and response conventions.


Wave complexity: Medium

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions