Code Review
Fun PR and great writeup! The GraphQL optimization concept is solid (75+ calls → 1-2 is a real win). However, there are several issues that would break the site if merged in the current state.
Critical Issues
1. Merge will break all themes — missing exports from github.ts
The PR removes getOrganizedPRs(), OrganizedPRs type, and other exports. On main, src/lib/prData.ts imports these, and every theme-specific component (ascii/, newspaper/, web2/ PRList + HallOfChaos) depends on them. Merging = site-wide build failure.
2. PullRequest field mismatch — rank, hotScore, isTrending are undefined at runtime
The Rust struct produces 8 fields but the TypeScript PullRequest interface expects 11. Missing fields cause:
pr.rankrenders as#undefined.in every PRCardb.hotScore - a.hotScore→NaN, breaking "Trending" sort entirely[TRENDING]badge never appears
3. Server-to-client regression in PRList.tsx
Changed from a server component (ISR-cached, shared across visitors) to 'use client' with useEffect. Every visitor now makes a separate API call instead of sharing a server-rendered cache.
4. Relative URL in server component — HallOfChaos will crash
getMergedPRs() calls fetch('/api/github/merged') — a relative URL. HallOfChaos.tsx is an async server component where Node.js fetch can't resolve relative URLs. It will always render the error state.
5. N+1 queries negate GraphQL benefit
For each PR in the GraphQL response, fetch_commit_status() makes a separate REST call (github.rs:113). With 100 PRs that's 101 sequential HTTP requests, negating the GraphQL batching.
6. Cache poisons itself with error responses
prs/route.ts — If WASM returns an empty array due to a transient GitHub failure, it gets cached for 5 minutes. Every user sees empty data with X-Cache: HIT.
Important Issues
- 3 of 5 PR categories dropped —
newest,discussed,controversialare gone (onlytopByVotesandtrendingremain) - GraphQL reactions capped at 100 — no pagination for PRs with >100 reactions, silently wrong vote totals
- Silent vote suppression — REST fallback defaults to 0 votes on any reactions fetch failure, no logging
fetch_commit_statusreturnsOk(false)on HTTP errors — "can't reach GitHub" is treated as "CI failed"- Inconsistent wasm-pack targets —
wasm:builduses--target bundler,wasm:build:releaseuses--target web(incompatible outputs) - Committed
.wasmbinary — opaque artifact that can't be code-reviewed - No input validation on
limitquery param —NaN/negative/huge values passed directly to WASM
Suggestions
The core idea (GraphQL + Rust/WASM) has real merit. To make it mergeable:
- Restore backward-compatible exports from
github.tssoprData.tsand all theme components still work - Add missing fields (
rank,hotScore,isTrending,upvotes,downvotes,comments) — either in Rust or as a post-processing step in the API route - Keep
PRList.tsxas a server component with ISR caching - Use absolute URLs or direct API calls in server components
- Move commit status into the GraphQL query (
statusCheckRollup) to eliminate N+1 - Validate responses before caching