Source: Deep code review — docs/code-review-2026-05.md (finding P2, P2).
Where: src/app/pages/categories-page.js:211-217
Issue: No limit() / cursor; the page loads the entire collection and filters client-side. Firestore read cost grows linearly with the corpus.
Fix: Server-side where('category','==',X) + orderBy('creationTime','desc') + limit(20) with startAfter cursor pagination. Add the matching composite index to firestore.indexes.json. Best built on the shared pagination utility (R4).
⚠️ Interacts with the unapproved-recipe read-rule fix (#320) — moving the approved filter server-side affects these queries.
Verification: Seed the emulator with 200 recipes; confirm category page loads in pages of 20.
Source: Deep code review —
docs/code-review-2026-05.md(finding P2, P2).Where:
src/app/pages/categories-page.js:211-217Issue: No
limit()/ cursor; the page loads the entire collection and filters client-side. Firestore read cost grows linearly with the corpus.Fix: Server-side
where('category','==',X)+orderBy('creationTime','desc')+limit(20)withstartAftercursor pagination. Add the matching composite index tofirestore.indexes.json. Best built on the shared pagination utility (R4).Verification: Seed the emulator with 200 recipes; confirm category page loads in pages of 20.