Skip to content

fix(reviews): clamp public user pagination params#286

Open
sevencat2004 wants to merge 3 commits into
profullstack:masterfrom
sevencat2004:fix/user-reviews-pagination-bounds
Open

fix(reviews): clamp public user pagination params#286
sevencat2004 wants to merge 3 commits into
profullstack:masterfrom
sevencat2004:fix/user-reviews-pagination-bounds

Conversation

@sevencat2004
Copy link
Copy Markdown

Summary

  • fixes invalid limit / offset handling in the public user reviews endpoint
  • defaults non-positive limits to 10, caps large limits at 50, and clamps negative offsets to 0
  • adds route tests for missing profiles, invalid pagination, large limit caps, and valid pagination

Closes #285

Validation

  • corepack pnpm test -- src/app/api/users/[username]/reviews/route.test.ts
  • node_modules.bin\tsc.CMD -p tsconfig.json --noEmit

Submitted for the ugig bounty: I will pay for every bug fix found and PR submitted that fixes it.

Solana wallet for bounty payout:
Dy4yMkjCfupxaURt6iTMUrxqSDEmAJPPkKF66QahxJZD

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 28, 2026

Greptile Summary

This PR fixes two related problems in the public user-reviews endpoint: invalid pagination params (limit=0, negative offset) are now clamped via dedicated helpers, and the average-rating calculation is corrected by fetching all ratings in a separate query instead of summing over the current page slice.

  • parsePositiveInt / parseNonNegativeInt helpers replace bare parseInt + ad-hoc Math.min, giving limit a safe default of 10 and capping it at 50, and clamping offset to ≥ 0.
  • A new pre-query fetches every rating for the reviewee so averageRating is always the true mean, not the mean of the current page — directly addressing the pre-existing bug flagged in the previous review.
  • Four new Vitest cases cover 404 on a missing profile, invalid-param clamping, large-limit cap, and happy-path pagination.

Confidence Score: 4/5

Safe to merge; the core logic change is correct and well-tested, with one minor design concern worth revisiting.

The param-clamping fix and the average-rating-over-all-reviews fix are both correct. The only notable concern is that the new allRatings query is unbounded — for a user with many reviews it fetches all rating rows on every page request, and a database-side aggregate would be more efficient. This is a design trade-off rather than a defect, and it does not affect correctness for typical workloads.

route.ts — the unbounded allRatings fetch warrants a second look if the platform expects users with large review counts.

Important Files Changed

Filename Overview
src/app/api/users/[username]/reviews/route.ts Adds param-clamping helpers and a separate ratings query to fix the average-rating-over-page-slice bug; introduces an unbounded fetch for all ratings rows.
src/app/api/users/[username]/reviews/route.test.ts New test file covering 404, invalid pagination clamping, large-limit cap, and valid pagination; no coverage for the new ratingsError path.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Route as GET /api/users/[username]/reviews
    participant DB as Supabase

    Client->>Route: "GET ?limit=X&offset=Y"
    Note over Route: clamp limit (1-50, default 10)<br/>clamp offset (>=0, default 0)
    Route->>DB: profiles.select("id").eq("username", username).single()
    DB-->>Route: "profile | null"
    alt profile not found
        Route-->>Client: 404 User not found
    else profile found
        Route->>DB: reviews.select("rating").eq("reviewee_id", id)
        DB-->>Route: allRatings[]
        Route->>DB: "reviews.select(*).eq(...).order(...).range(offset, offset+limit-1) {count: exact}"
        DB-->>Route: reviews[], count
        Note over Route: averageRating = sum(allRatings) / allRatings.length
        Route-->>Client: "200 { data, summary, pagination }"
    end
Loading

Reviews (2): Last reviewed commit: "test(reviews): cover summary rating sour..." | Re-trigger Greptile

@sevencat2004
Copy link
Copy Markdown
Author

Follow-up pushed in ed592f7: addressed Greptile's average-rating finding by computing the summary from an unpaginated rating query, while keeping the paginated review list unchanged. The test now verifies the summary uses all ratings, not only the current page.\n\nValidation run locally:\n- corepack pnpm test -- src/app/api/users/[username]/reviews/route.test.ts\n- node_modules\.bin\tsc.CMD -p tsconfig.json --noEmit

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.

Public user reviews accepts invalid pagination ranges

1 participant