Skip to content

fix(pages): repair pagination follow-ups#341

Merged
ralyodio merged 2 commits into
profullstack:masterfrom
Jorel97:codex/fix-pagination-followups-340
May 30, 2026
Merged

fix(pages): repair pagination follow-ups#341
ralyodio merged 2 commits into
profullstack:masterfrom
Jorel97:codex/fix-pagination-followups-340

Conversation

@Jorel97
Copy link
Copy Markdown
Contributor

@Jorel97 Jorel97 commented May 29, 2026

Summary

  • restore corrupted Unicode characters on public listing pages after the pagination merge
  • tighten parsePageParam default max page from 100,000 to 1,000 and update coverage
  • compute username review averages from all ratings instead of the current page slice

Fixes #340.

Verification

  • Not run locally: this Codex workspace has Node available but no npm/package runner installed, so I could not execute the repo test suite here.
  • Checked the touched files for mojibake (?, ?, replacement char) and found no matches after the repair.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 30, 2026

Greptile Summary

This PR fixes three distinct regressions introduced by the previous pagination merge: mojibake (UTF-8 characters rendered as Latin-1 sequences) across eight listing pages, an inflated DEFAULT_MAX_PAGE of 100,000 now tightened to 1,000, and an average-rating computation that incorrectly used only the current page slice instead of all reviews.

  • Unicode repair — All occurrences of mangled , , , , and across affiliates, directory, for-hire, gigs, mcp, prompts, and skills pages are restored to their correct code points.
  • Pagination capDEFAULT_MAX_PAGE in pagination.ts reduced from 100,000 to 1,000 with the matching test expectation updated.
  • Reviews average fixroute.ts now issues a second Supabase query for all ratings (scoped by .range(0, totalReviews-1)) and computes the mean over the full set, replacing the per-page slice calculation.

Confidence Score: 5/5

Safe to merge; the Unicode repairs are mechanical and correct, the pagination cap is a sound tightening, and the reviews average calculation is a genuine improvement over the old page-slice approach.

All three goals are achieved cleanly. The reviews route now correctly aggregates across all rows rather than just the visible page. The only notable wrinkle is a theoretical race window where a concurrent review deletion between the two database queries triggers a 500 rather than a graceful partial compute, but review deletions are uncommon and the window is sub-millisecond, making this unlikely to surface in practice.

src/app/api/users/[username]/reviews/route.ts — the strict length guard on the ratings query could return 500 under concurrent deletions.

Important Files Changed

Filename Overview
src/app/api/users/[username]/reviews/route.ts Average-rating computation now fetches all ratings via a second query; introduces a race condition where a concurrent review deletion causes the guard check to hard-fail with 500.
src/lib/pagination.ts DEFAULT_MAX_PAGE tightened from 100,000 to 1,000; straightforward and safe.
src/lib/pagination.test.ts Test expectation updated to match the new 1,000 cap; consistent with the implementation change.
src/app/affiliates/page.tsx Mojibake repaired: mangled UTF-8 sequences for ≈ and — replaced with correct Unicode literals.
src/app/directory/page.tsx Mojibake repaired: —, ⚡, and ✕ characters restored in button labels and badge dismissal links.
src/app/mcp/page.tsx Mojibake repaired: — and ≈ and ✕ characters restored across metadata and listing UI.

Sequence Diagram

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

    Client->>ReviewsRoute: "GET ?limit=10&offset=0"
    ReviewsRoute->>Supabase: "SELECT profiles WHERE username=? (single)"
    Supabase-->>ReviewsRoute: profile.id

    ReviewsRoute->>Supabase: "SELECT reviews (paginated, count=exact)"
    Supabase-->>ReviewsRoute: reviews[], count

    alt "totalReviews > 0"
        ReviewsRoute->>Supabase: SELECT rating FROM reviews .range(0, totalReviews-1)
        Note over ReviewsRoute,Supabase: Race window: review could be deleted here
        Supabase-->>ReviewsRoute: allRatings[]
        alt "allRatings.length !== totalReviews"
            ReviewsRoute-->>Client: 500 Unable to calculate average rating
        else counts match
            ReviewsRoute-->>Client: "200 {data, summary, pagination}"
        end
    else "totalReviews == 0"
        ReviewsRoute-->>Client: "200 {data, summary:{average_rating:0}, pagination}"
    end
Loading

Reviews (2): Last reviewed commit: "fix(reviews): bound average rating query" | Re-trigger Greptile

Comment thread src/app/api/users/[username]/reviews/route.ts Outdated
@Jorel97
Copy link
Copy Markdown
Contributor Author

Jorel97 commented May 30, 2026

Addressed the Greptile note in 18d1d17: the all-ratings query now explicitly ranges from 0 to totalReviews - 1, and the route returns an error instead of a quietly incorrect average if the returned rating count does not match the exact count.

@ralyodio ralyodio merged commit 64b2844 into profullstack:master May 30, 2026
4 checks passed
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.

Follow up pagination fixes for Unicode and review averages

2 participants