Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions apps/web/lib/api/pagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ export function buildPaginationQuery(filters: Filters): PaginationQuery {
}

return {
// Order by id only for better query performance on large datasets (single-column PK index).
// Trade-off: ordering is by id rather than createdAt, so order may not strictly match creation time.
orderBy: {
[sortBy]: sortOrder,
},
Expand Down
4 changes: 1 addition & 3 deletions apps/web/lib/api/partners/get-partners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,7 @@ export async function getPartners(filters: PartnerFilters) {
},
take: pageSize,
skip: (page - 1) * pageSize,
orderBy: {
[sortBy]: sortOrder,
},
orderBy: [{ [sortBy]: sortOrder }, { id: sortOrder }],
});

return partners.map(
Expand Down
65 changes: 65 additions & 0 deletions apps/web/tests/partners/pagination.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { EnrolledPartnerProps } from "@/lib/types";
import { beforeAll, describe, expect, test } from "vitest";
import { expectNoOverlap } from "../utils/helpers";
import { IntegrationHarness } from "../utils/integration";

describe.concurrent("/partners/** - pagination", async () => {
const h = new IntegrationHarness();
let http: IntegrationHarness["http"];
let baseline: EnrolledPartnerProps[];
let baselineIds: string[];

const commonQuery = {
pageSize: "5",
sortBy: "totalSaleAmount",
sortOrder: "desc",
};

beforeAll(async () => {
({ http } = await h.init());

const { status, data } = await http.get<EnrolledPartnerProps[]>({
path: "/partners",
query: { ...commonQuery, pageSize: "100" },
});

expect(status).toEqual(200);

baseline = data;
baselineIds = baseline.map((p) => p.id);
expect(baselineIds.length).toBeGreaterThanOrEqual(15);
});

test("Offset pagination has no duplicate partners across pages", async () => {
const page1 = await http.get<EnrolledPartnerProps[]>({
path: "/partners",
query: { ...commonQuery, page: "1" },
});
const page2 = await http.get<EnrolledPartnerProps[]>({
path: "/partners",
query: { ...commonQuery, page: "2" },
});
const page3 = await http.get<EnrolledPartnerProps[]>({
path: "/partners",
query: { ...commonQuery, page: "3" },
});

expect(page1.status).toEqual(200);
expect(page2.status).toEqual(200);
expect(page3.status).toEqual(200);
expect(page1.data).toHaveLength(5);
expect(page2.data).toHaveLength(5);
expect(page3.data).toHaveLength(5);

expectNoOverlap(page1.data, page2.data);
expectNoOverlap(page2.data, page3.data);
expectNoOverlap(page1.data, page3.data);

const paginatedIds = [...page1.data, ...page2.data, ...page3.data].map(
(p) => p.id,
);

expect(new Set(paginatedIds).size).toBe(paginatedIds.length);
expect(paginatedIds).toEqual(baselineIds.slice(0, paginatedIds.length));
});
});
Loading