fix(site): use page count in usePaginatedQuery overshoot fallback (#30572)

Enables oxlint's `erasing-op` rule and fixes the one violation it found,
an operator precedence bug in `usePaginatedQuery`.

When the requested page reports a count of 0, the hook refetches page 1
to compute where to clamp. `Math.ceil(firstPageResult?.count ?? 0 /
limit)` parsed as `count ?? (0 / limit)`, so it used the record count as
the page count and left the user on the overshot page. The fix adds
parentheses, and a regression test covers it (the test fails without the
fix).

<details>
<summary>Context and findings</summary>

Part of evaluating oxlint's `correctness` category. Turning on the whole
category reported 1152 diagnostics across 24 rules, so rules are being
enabled one at a time instead, which keeps the explicit allowlist model
in `.oxlintrc.jsonc`. `erasing-op` had a single hit, and it was a real
bug.

Validation: `pnpm run lint` (Biome, oxlint, types, circular deps, React
Compiler, knip) and the full unit suite.

</details>

_Generated by Coder Agents on behalf of @jeremyruppel._
This commit is contained in:
Jeremy Ruppel
2026-10-12 10:31:06 -04:00
committed by GitHub
parent 5b060beeb1
commit 1c805b0931
3 changed files with 17 additions and 1 deletions
+1
View File
@@ -109,6 +109,7 @@
"require-yield": "error",
"rules-of-hooks": "error",
"refs": "error",
"erasing-op": "error",
// --- security ---
"jsx-no-target-blank": "error",
+15
View File
@@ -228,6 +228,21 @@ describe(usePaginatedQuery.name, () => {
await waitFor(() => expect(result.current.currentPage).toBe(1));
});
it("No custom callback: uses the first page's count when an overshot page reports a count of 0", async () => {
const mockQueryFn = vi.fn(({ pageNumber }: { pageNumber: number }) =>
Promise.resolve({ data: [], count: pageNumber === 1 ? 100 : 0 }),
);
const { result } = await render(
{
queryKey: ({ pageNumber }) => ["overshoot", pageNumber],
queryFn: mockQueryFn,
},
"/?page=35",
);
await waitFor(() => expect(result.current.currentPage).toBe(4));
});
it("With custom callback: Calls callback and does not update search params automatically", async () => {
const testControl = new URLSearchParams({
page: "1000",
+1 -1
View File
@@ -232,7 +232,7 @@ export function usePaginatedQuery<
const firstPageOptions = getQueryOptionsFromPage(1);
try {
const firstPageResult = await queryClient.fetchQuery(firstPageOptions);
const rounded = Math.ceil(firstPageResult?.count ?? 0 / limit);
const rounded = Math.ceil((firstPageResult?.count ?? 0) / limit);
fixedTotalPages = Math.max(rounded, 1);
} catch {
fixedTotalPages = 1;