fix(users): cap huge follow-list offsets before Supabase range queries#376
Conversation
Extreme offsets like ?offset=999999999 now cap at 100_000 for both followers and following endpoints, matching the pagination-hardening pattern used across other public endpoints. Fixes profullstack#356
Greptile SummaryCaps the
Confidence Score: 4/5Safe to merge — both changes are a single-line guard that can only make the offset smaller, with no effect on valid queries. The two changed lines are straightforward and do exactly what the PR description says. The only gaps are style-level: the test suites don't assert on the new cap, and the inline helper duplicates logic that a shared utility already handles elsewhere. The companion test files ( Important Files Changed
Sequence DiagramsequenceDiagram
participant Client
participant Route as followers / following route
participant Supabase
Client->>Route: "GET ?offset=<any value>"
Note over Route: parseNonNegativeInt(offset, 0)
Note over Route: Math.min(parsed, 100_000) new cap
Route->>Supabase: profiles.select().eq(username).single()
Supabase-->>Route: targetProfile
Route->>Supabase: follows.select().range(offset, offset+limit-1)
Note over Supabase: offset is now <= 100_000
Supabase-->>Route: rows + count
Route-->>Client: "{ data, pagination: { offset (capped), limit, total } }"
Reviews (1): Last reviewed commit: "fix(users): cap follow-list offset at 10..." | Re-trigger Greptile |
| const limit = parsePositiveInt(searchParams.get("limit"), 20, 100); | ||
| const offset = parseNonNegativeInt(searchParams.get("offset"), 0); | ||
| const offset = Math.min(parseNonNegativeInt(searchParams.get("offset"), 0), 100_000); |
There was a problem hiding this comment.
Inconsistent pagination helper vs. sibling endpoints
The activity route uses a shared parsePaginationParam utility from @/lib/api-pagination which already accepts a max argument (e.g. parsePaginationParam(searchParams.get("offset"), 0, 0, 100_000)). This file (and following/route.ts) duplicates parsePositiveInt / parseNonNegativeInt locally and wraps them with an inline Math.min. Using the shared helper would keep the offset-cap boundary in one place and reduce the surface for future drift.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Fixes #356
Caps
offsetat100_000forGET /api/users/[username]/followersandGET /api/users/[username]/followingbefore building the Supabase.range()call, matching the pagination-hardening pattern used across other public endpoints.