Thanks to visit codestin.com
Credit goes to Github.com

Skip to content

Conversation

@devkiran
Copy link
Collaborator

@devkiran devkiran commented Dec 2, 2025

Summary by CodeRabbit

  • New Features

    • Added cursor-based pagination (startingAfter/endingBefore) alongside existing offset pagination and request validation.
  • Refactor

    • Centralized pagination logic into a shared helper and layered cursor pagination into query schemas while marking legacy pagination as deprecated.
  • Performance

    • Updated composite database indexes to improve pagination and time-range queries.
  • Tests

    • Added comprehensive pagination tests covering offset, cursor, mixed methods, error cases, and sort orders.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link
Contributor

vercel bot commented Dec 2, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
dub Ready Ready Preview Jan 8, 2026 6:45am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 2, 2025

Warning

Rate limit exceeded

@devkiran has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 24 minutes and 38 seconds before requesting another review.

βŒ› How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between fa98048 and 689b3ff.

πŸ“’ Files selected for processing (1)
  • apps/web/lib/api/pagination.ts
πŸ“ Walkthrough

Walkthrough

This PR centralizes pagination by adding a reusable getPaginationOptions helper (cursor + offset), updates Zod pagination schemas to expose cursor-based queries (marking offset deprecated), refactors API callsites to use the helper, updates Prisma composite indexes to include id as a tiebreaker, and adds comprehensive pagination tests.

Changes

Cohort / File(s) Summary
Pagination utility & types
apps/web/lib/api/pagination.ts
New getPaginationOptions(filters) plus Filters/PaginationOptions types implementing cursor and offset pagination, validation, and errors.
Zod pagination primitives
apps/web/lib/zod/schemas/misc.ts
getPaginationQuerySchema signature changed (optional pageSize, deprecated flag); new getCursorPaginationQuerySchema exported.
Zod schema integrations
apps/web/lib/zod/schemas/commissions.ts, apps/web/lib/zod/schemas/customers.ts, apps/web/lib/zod/schemas/links.ts
Schemas now merge getCursorPaginationQuerySchema before existing pagination merge; offset pagination preserved but marked deprecated.
API callsites / endpoints
apps/web/app/(ee)/api/customers/route.ts, apps/web/lib/api/commissions/get-commissions.ts, apps/web/lib/api/links/get-links-for-workspace.ts
Replaced manual page/pageSize/sort handling with getPaginationOptions(filters); getLinksForWorkspace signature changed to accept a single filters object.
Database schema / indexes
packages/prisma/schema/commission.prisma, packages/prisma/schema/customer.prisma, packages/prisma/schema/link.prisma
Composite indexes updated to include id as a tiebreaker (added/changed to include id).
Tests (pagination)
apps/web/tests/commissions/pagination.test.ts, apps/web/tests/customers/pagination.test.ts, apps/web/tests/links/list-links.test.ts
New comprehensive tests covering offset & cursor pagination, invalid combos/limits, mixed-method precedence, deterministic ordering, and cursor behavior.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant API as Web API
  participant Pager as getPaginationOptions
  participant DB as Prisma/Database

  Client->>API: GET /endpoint?{page,pageSize,startingAfter,endingBefore,sortBy,...}
  API->>Pager: getPaginationOptions(filters)
  Pager-->>API: { take, skip } or { cursor, cursorId }, orderBy
  API->>DB: Prisma.findMany({ where: ..., include: ..., ...paginationOptions })
  DB-->>API: results
  API-->>Client: 200 + items
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PR #3172 β€” Implements the same cursor+offset pagination refactor and adds getPaginationOptions, cursor pagination schemas, and tests across the same endpoints.
  • PR #3182 β€” Reverts the cursor-based pagination changes introduced by this work (direct conflict candidate).
  • PR #3121 β€” Applies pagination changes to payouts and relies on the updated pagination utilities/schema; touches similar pagination surface.

Suggested reviewers

  • steven-tey

Poem

🐰
I hopped through queries with a twitchy nose,
Cursor or pageβ€”now everyone knows.
I nudged indexes neat, made order supreme,
Pages hop steady like a carrot dream. πŸ₯•

πŸš₯ Pre-merge checks | βœ… 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
βœ… Passed checks (2 passed)
Check name Status Explanation
Description Check βœ… Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check βœ… Passed The PR title accurately captures the main change: introducing cursor-based pagination support across multiple API endpoints and schemas.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@devkiran devkiran requested a review from steven-tey December 8, 2025 10:03
@devkiran devkiran marked this pull request as ready for review December 8, 2025 16:52
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/web/tests/links/list-links.test.ts (1)

9-42: Fix temporal dead zone in GET /links test cleanup

onTestFinished closes over firstLink before it is declared:

  • Line 15–17 use firstLink.id in the cleanup.
  • const { data: firstLink } = ... is only defined starting at line 19.

Because const bindings are in the temporal dead zone until their declaration runs, this will throw a ReferenceError when the cleanup callback is registered or executed.

A simple fix is to register the cleanup after firstLink is created:

-  onTestFinished(async () => {
-    await h.deleteLink(firstLink.id);
-  });
-
-  const { data: firstLink } = await http.post<Link>({
+  const { data: firstLink } = await http.post<Link>({
     path: "/links",
     body: { url, domain },
   });
+
+  onTestFinished(async () => {
+    await h.deleteLink(firstLink.id);
+  });

This keeps the behavior identical while avoiding the TDZ issue.

🧹 Nitpick comments (11)
packages/prisma/schema/commission.prisma (1)

48-58: New (programId, createdAt, id) index aligns with cursor-pagination access pattern

This index matches the expected ordering for cursor-based pagination by createdAt with id as a tiebreaker under a given programId, which should improve query performance and stability. You still retain the more complex [programId, createdAt, status, amount, earnings] index for other queries; you can revisit index overlap later if needed.

apps/web/lib/zod/schemas/links.ts (1)

7-18: Cursor + deprecated page-based pagination composition in getLinksQuerySchemaBase looks sound

Merging getCursorPaginationQuerySchema ahead of the deprecated getPaginationQuerySchema cleanly exposes both cursor params (startingAfter, endingBefore) and legacy page/pageSize, which matches how getPaginationOptions expects filters.

One minor follow-up to consider: linksExportQuerySchema omits page and pageSize but still inherits startingAfter/endingBefore from getLinksQuerySchemaBase. If the export endpoint never uses cursor pagination, you might want to omit those as well for clearer docs and validation, or explicitly document that they’re ignored for exports.

Also applies to: 160-179, 272-292

apps/web/lib/zod/schemas/customers.ts (1)

1-8: Customers query schema now cleanly supports cursor + deprecated page-based pagination

getCustomersQuerySchema correctly layers:

  • core filters and sort fields,
  • cursor pagination (startingAfter / endingBefore with a concrete example), and
  • deprecated page-based pagination with CUSTOMERS_MAX_PAGE_SIZE.

That matches the expectations of getPaginationOptions and clearly nudges clients towards cursor-based pagination.

For getCustomersCountQuerySchema, you omit page, pageSize, sortBy, and sortOrder, but cursor params still pass through. If the /customers/count endpoint never uses cursors, you might eventually tighten this by omitting startingAfter/endingBefore as well so the count contract is unambiguously β€œno pagination here”.

Also applies to: 13-73, 85-93

apps/web/lib/zod/schemas/commissions.ts (1)

131-136: Consider omitting cursor fields from count/export query schemas (optional)

getCommissionsCountQuerySchema and commissionsExportQuerySchema still allow startingAfter / endingBefore via getCommissionsQuerySchema, but those values are typically irrelevant for a global count or full export. If these endpoints never use cursor pagination, consider omitting cursor fields here as well to make the API surface clearer and avoid confusing no-op parameters.

Also applies to: 301-325

apps/web/tests/customers/pagination.test.ts (2)

18-30: Tests assume at least 10 customers in the E2E workspace

Several tests access baseline[4], baseline[5], and compare slices up to index 10. This is fine with the current seeded data, but will start failing if the fixture workspace ever has fewer than 10 customers. If you want the suite to be more robust to fixture changes, you could either seed the required minimum inside the tests or explicitly assert baseline.length >= 10 with a clear failure message.

Also applies to: 32-78, 163-255


258-277: Deduplicate pagination helper assertions across test suites (optional)

expectSortedByCreatedAt, expectSortedByCreatedAtAsc, and expectNoOverlap are mirrored in the commissions pagination tests. Consider moving these helpers into a shared test utility (for example under tests/utils/pagination.ts) to avoid duplication and keep future changes to pagination assertions in one place.

apps/web/lib/api/links/get-links-for-workspace.ts (1)

17-39: Relying on parsed filters for pagination fields (optional clarification)

getPaginationOptions assumes page, pageSize, sortBy, and sortOrder are present and valid on filters. As long as all callers pass in objects produced by getLinksQuerySchemaExtended.parse, that’s guaranteed via Zod defaults and enums. If this function is ever reused with unvalidated inputs, you may want to either export and reuse the Filters type from pagination.ts or document that pre-validation is required.

Also applies to: 156-157

apps/web/lib/api/pagination.ts (1)

4-20: Document or generalize the id-based cursor assumption (optional)

PaginationOptions.cursor and the secondary orderBy key are hard-coded to id, which matches your current models but is an implicit requirement. If you ever paginate on a model whose cursor column is not id, you’ll need to extend this helper. Consider either documenting this assumption in a comment or parameterizing the cursor field name in the future.

Also applies to: 24-55

apps/web/lib/zod/schemas/misc.ts (1)

31-66: Optional: push mutual-exclusion check into Zod as well

You currently enforce startingAfter / endingBefore mutual exclusivity in getPaginationOptions, which is sufficient for runtime behavior. If you want clients of the Zod schema alone (e.g. non-HTTP callers) to see validation errors earlier, you could add a .refine on getCursorPaginationQuerySchema to reject payloads that specify both fields.

Also applies to: 68-93

apps/web/tests/commissions/pagination.test.ts (2)

18-29: Tests rely on having at least 10 commissions in the E2E workspace

As with the customers suite, several expectations depend on baseline[4], baseline[5], and slices up to index 10. That’s fine with current fixtures but will break if the seeded workspace ever has fewer commissions. If you’d like these tests to be more resilient, you could either seed the necessary minimum inside the suite or assert baseline.length >= 10 with a clear failure reason.

Also applies to: 31-77, 180-280


283-302: Extract shared pagination assertion helpers (optional)

expectSortedByCreatedAt, expectSortedByCreatedAtAsc, and expectNoOverlap are duplicated from the customers pagination tests. Pulling them into a shared test helper module would reduce duplication and keep pagination-specific assertions consistent across suites.

πŸ“œ Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 23ae40e and 9aceb2d.

πŸ“’ Files selected for processing (14)
  • apps/web/app/(ee)/api/customers/route.ts (3 hunks)
  • apps/web/lib/api/commissions/get-commissions.ts (2 hunks)
  • apps/web/lib/api/links/get-links-for-workspace.ts (3 hunks)
  • apps/web/lib/api/pagination.ts (1 hunks)
  • apps/web/lib/zod/schemas/commissions.ts (2 hunks)
  • apps/web/lib/zod/schemas/customers.ts (2 hunks)
  • apps/web/lib/zod/schemas/links.ts (2 hunks)
  • apps/web/lib/zod/schemas/misc.ts (2 hunks)
  • apps/web/tests/commissions/pagination.test.ts (1 hunks)
  • apps/web/tests/customers/pagination.test.ts (1 hunks)
  • apps/web/tests/links/list-links.test.ts (2 hunks)
  • packages/prisma/schema/commission.prisma (1 hunks)
  • packages/prisma/schema/customer.prisma (1 hunks)
  • packages/prisma/schema/link.prisma (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
πŸ“š Learning: 2025-09-24T16:13:00.387Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2872
File: packages/prisma/schema/partner.prisma:151-153
Timestamp: 2025-09-24T16:13:00.387Z
Learning: In the Dub codebase, Prisma schemas use single-column indexes without brackets (e.g., `@index(partnerId)`) and multi-column indexes with brackets (e.g., `@index([programId, partnerId])`). This syntax pattern is consistently used throughout their schema files and works correctly with their Prisma version.

Applied to files:

  • packages/prisma/schema/commission.prisma
  • packages/prisma/schema/link.prisma
  • packages/prisma/schema/customer.prisma
πŸ“š Learning: 2025-06-06T07:59:03.120Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2177
File: apps/web/lib/api/links/bulk-create-links.ts:66-84
Timestamp: 2025-06-06T07:59:03.120Z
Learning: In apps/web/lib/api/links/bulk-create-links.ts, the team accepts the risk of potential undefined results from links.find() operations when building invalidLinks arrays, because existing links are fetched from the database based on the input links, so matches are expected to always exist.

Applied to files:

  • packages/prisma/schema/link.prisma
  • apps/web/lib/zod/schemas/links.ts
  • apps/web/lib/api/links/get-links-for-workspace.ts
  • apps/web/tests/links/list-links.test.ts
πŸ“š Learning: 2025-10-06T15:48:45.956Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2935
File: packages/prisma/schema/workspace.prisma:21-36
Timestamp: 2025-10-06T15:48:45.956Z
Learning: In the Dub repository (dubinc/dub), Prisma schema changes are not managed with separate migration files. Do not flag missing Prisma migration files when schema changes are made to files like `packages/prisma/schema/workspace.prisma` or other schema files.

Applied to files:

  • packages/prisma/schema/customer.prisma
πŸ“š Learning: 2025-10-17T08:18:19.278Z
Learnt from: devkiran
Repo: dubinc/dub PR: 0
File: :0-0
Timestamp: 2025-10-17T08:18:19.278Z
Learning: In the apps/web codebase, `@/lib/zod` should only be used for places that need OpenAPI extended zod schema. All other places should import from the standard `zod` package directly using `import { z } from "zod"`.

Applied to files:

  • apps/web/lib/api/links/get-links-for-workspace.ts
  • apps/web/lib/zod/schemas/customers.ts
🧬 Code graph analysis (9)
apps/web/app/(ee)/api/customers/route.ts (2)
apps/web/lib/zod/schemas/customers.ts (1)
  • getCustomersQuerySchemaExtended (75-83)
apps/web/lib/api/pagination.ts (1)
  • getPaginationOptions (24-84)
apps/web/tests/customers/pagination.test.ts (2)
apps/web/tests/utils/integration.ts (1)
  • IntegrationHarness (14-118)
apps/web/lib/types.ts (1)
  • Customer (426-426)
apps/web/lib/api/pagination.ts (2)
packages/prisma/client.ts (1)
  • Prisma (30-30)
apps/web/lib/api/errors.ts (1)
  • DubApiError (58-75)
apps/web/lib/api/commissions/get-commissions.ts (1)
apps/web/lib/api/pagination.ts (1)
  • getPaginationOptions (24-84)
apps/web/lib/zod/schemas/links.ts (1)
apps/web/lib/zod/schemas/misc.ts (2)
  • getCursorPaginationQuerySchema (69-93)
  • getPaginationQuerySchema (32-66)
apps/web/lib/zod/schemas/commissions.ts (1)
apps/web/lib/zod/schemas/misc.ts (2)
  • getCursorPaginationQuerySchema (69-93)
  • getPaginationQuerySchema (32-66)
apps/web/lib/api/links/get-links-for-workspace.ts (1)
apps/web/lib/api/pagination.ts (1)
  • getPaginationOptions (24-84)
apps/web/tests/links/list-links.test.ts (1)
apps/web/tests/utils/integration.ts (1)
  • IntegrationHarness (14-118)
apps/web/tests/commissions/pagination.test.ts (2)
apps/web/tests/utils/integration.ts (1)
  • IntegrationHarness (14-118)
apps/web/lib/types.ts (1)
  • CommissionResponse (443-443)
πŸ”‡ Additional comments (10)
packages/prisma/schema/link.prisma (1)

94-103: Adding id as tiebreaker in composite index for cursor pagination looks correct

Including id after createdAt(sort: Desc) makes ordering deterministic and aligns with the new cursor-based pagination that sorts by createdAt then id. Syntax and column order are consistent with existing Prisma index patterns.

packages/prisma/schema/customer.prisma (1)

27-35: Extending customer index with id is consistent with cursor pagination requirements

Updating the index to [projectId, createdAt, id] gives deterministic ordering and supports keyset pagination on createdAt with id as a tiebreaker, without affecting existing filters.

apps/web/lib/api/commissions/get-commissions.ts (1)

6-10: Switch to getPaginationOptions cleanly centralizes commissions pagination

Delegating skip/take and orderBy to getPaginationOptions(filters) keeps this query focused on filtering and inclusion logic, and aligns it with the new cursor-based pagination behavior (deterministic sort by sortBy + id). Just ensure getCommissionsQuerySchema continues to define sensible defaults for page, pageSize, sortBy, and sortOrder so filters always satisfy the helper’s expectations.

Also applies to: 35-73

apps/web/app/(ee)/api/customers/route.ts (1)

4-15: Unified pagination via getPaginationOptions in customers route looks correct

Parsing filters once with getCustomersQuerySchemaExtended and then spreading ...getPaginationOptions(filters) into prisma.customer.findMany is a clean refactor:

  • Keeps filtering logic focused on business fields (email, externalId, search, country, linkId, customerIds).
  • Delegates page vs cursor behavior and deterministic ordering (sortBy + id) to a shared helper.
  • Lines up with the new customer index on [projectId, createdAt, id] for the default sort.

Just ensure that any future changes to the customers pagination schema (e.g., new sort fields) are mirrored in the Prisma indexes where needed to preserve performance characteristics.

Also applies to: 40-83

apps/web/lib/zod/schemas/commissions.ts (1)

5-8: Cursor + offset pagination schema layering looks consistent

Merging the cursor schema first and the paginated (deprecated) page/pageSize schema afterwards cleanly exposes both pagination styles, and the dedicated COMMISSIONS_MAX_PAGE_SIZE keeps the per-endpoint limit explicit. No functional issues spotted.

Also applies to: 56-129

apps/web/tests/customers/pagination.test.ts (1)

5-207: Strong end-to-end coverage of new pagination behavior

This suite does a good job validating offset vs cursor pagination, mixed-parameter precedence, sort order in both directions, and error handling for invalid combinations and large page values. The use of a common baseline plus ID-slice comparisons makes regressions around ordering and overlap easy to catch.

apps/web/lib/api/links/get-links-for-workspace.ts (1)

17-39: Centralizing link pagination via getPaginationOptions looks good

Switching to a single filters parameter and spreading getPaginationOptions(filters) into the Prisma query cleanly delegates all pagination and ordering concerns to the shared helper while preserving the existing filtering logic (tags, folders, search, dates, etc.). This keeps the endpoint aligned with the new pagination behavior used by other routes.

Also applies to: 41-42, 60-157

apps/web/lib/api/pagination.ts (1)

4-12: Shared pagination helper correctly models offset + cursor semantics

The getPaginationOptions implementation cleanly handles:

  • Mutual exclusion of startingAfter / endingBefore with a clear DubApiError.
  • Enforcing a maximum page value.
  • Determining take and skip for both offset and cursor modes.
  • Using a stable two-field orderBy (primary sortBy, secondary id) for deterministic pagination.

This should be a solid foundation for reusing across different Prisma models that have an id primary key.

Also applies to: 22-84

apps/web/lib/zod/schemas/misc.ts (1)

31-66: Pagination + cursor Zod schemas are well-structured and composable

The extended getPaginationQuerySchema options (custom pageSize, deprecated flag) and the new getCursorPaginationQuerySchema give you a nice building block for endpoints that need both legacy page-based pagination and the new cursor style, with clear OpenAPI docs and examples. No issues spotted with the Zod setup.

Also applies to: 68-93

apps/web/tests/commissions/pagination.test.ts (1)

5-280: Commissions pagination behavior is thoroughly covered

This suite mirrors the customers pagination tests and gives solid coverage for offset vs cursor flows, mixed-parameter precedence, invalid cursor combinations, large page values, and both sort directions. Using a shared baseline and ID-slice checks should make any future regressions in ordering or pagination logic very visible.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/web/tests/customers/pagination.test.ts (1)

52-65: Consider adding explicit sort parameters for deterministic results.

The cursor-based pagination tests (lines 52-65, 67-79, 138-149, 152-162) omit sortBy and sortOrder parameters while comparing results against a baseline fetched with explicit sortBy: "createdAt" and sortOrder: "desc". If the API's default sort order differs or changes, these tests could become flaky.

For example, update the startingAfter test:

 test("Cursor forward (startingAfter)", async () => {
   const firstPage = baseline.slice(0, 5);
   const lastId = firstPage[4].id;

   const { status, data } = await http.get<Customer[]>({
     path: "/customers",
-    query: { pageSize: "5", startingAfter: lastId },
+    query: { 
+      pageSize: "5", 
+      startingAfter: lastId,
+      sortBy: "createdAt",
+      sortOrder: "desc"
+    },
   });

   expect(status).toEqual(200);
   expectSortedByCreatedAt(data);

   expect(data.map((c) => c.id)).toEqual(baselineIds.slice(5, 10));
 });

Apply similar changes to the other cursor-based tests for consistency.

Also applies to: 67-79, 138-149, 152-162

πŸ“œ Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 9aceb2d and 4127762.

πŸ“’ Files selected for processing (3)
  • apps/web/tests/commissions/pagination.test.ts (1 hunks)
  • apps/web/tests/customers/pagination.test.ts (1 hunks)
  • apps/web/tests/links/list-links.test.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/web/tests/links/list-links.test.ts
  • apps/web/tests/commissions/pagination.test.ts
🧰 Additional context used
🧬 Code graph analysis (1)
apps/web/tests/customers/pagination.test.ts (2)
apps/web/tests/utils/integration.ts (1)
  • IntegrationHarness (14-118)
apps/web/lib/types.ts (1)
  • Customer (426-426)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
πŸ”‡ Additional comments (3)
apps/web/tests/customers/pagination.test.ts (3)

1-31: LGTM! Well-structured test setup.

The test setup correctly establishes a baseline dataset with explicit sort parameters and validates the ordering before running tests. This ensures deterministic test behavior.


81-256: Excellent error handling and sort order coverage!

The tests comprehensively cover:

  • Validation of mutually exclusive cursor parameters
  • Page size limits with helpful error messages
  • Invalid cursor ID handling (returning empty arrays)
  • Both ascending and descending sort orders with explicit parameters

The explicit inclusion of sortBy and sortOrder in the ascending order tests (lines 164-256) ensures deterministic behavior.


259-278: LGTM! Helper functions are correctly implemented.

The helper functions properly validate:

  • Monotonically decreasing timestamps for descending order (using >=)
  • Monotonically increasing timestamps for ascending order (using <=)
  • No overlapping customer IDs between pages

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants