feat: endless deck — bigger pool, varied sorting & on-demand top-up - #33
Merged
Merged
Conversation
The deck was a finite, generate-once pool of popular titles: users could swipe through it in one sitting and hit "that's the whole deck" with no way to get more. Three changes, all bounded to stay on the Cloudflare free tier: - Bigger initial pool: common-ground slice 1→2 pages; each no-seed genre slice uses a different sort (popularity / rating / recency) for variety. - discoverTitles gains startPage + sortBy so we can read deeper pages and diversify without new endpoints. - On-demand top-up: GET /api/rooms/:id/deck/more extends the SAME shared pool (both users converge → matches still work), capped at MAX_DECK=120. Frontend prefetches more once ≤5 cards remain, so the deck feels endless. Free-tier safety: MAX_DECK caps TMDb calls, KV writes and the D1 deck row; top-up reads 2 cached pages; the page cursor is derived from pool size so we never re-fetch. topupCursor is pure + unit-tested.
valeboth
force-pushed
the
feat/deck-topup
branch
from
August 28, 2026 09:01
22b1da7 to
a6391fd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The deck was a generate-once, finite pool of popular titles. A user could swipe through it in a single sitting and hit "That's the whole deck 🎉" with no way to get more — and because both taste slices returned the same popular films, the unique pool was small.
What changed
Three things, all bounded to stay on the Cloudflare free tier:
1→2pages; each no-seed genre slice now uses a different sort so the pool spans popular / acclaimed / recent instead of all-popular.discoverTitlesgainsstartPageandsortByoptions (no behaviour change at defaults).GET /api/rooms/:id/deck/moreextends the same shared pool (both users converge → matches still work), deduped and capped atMAX_DECK = 300. The frontend prefetches more once ≤5 cards remain, so swiping feels endless; when the cap is hit it falls back to the existing empty-deck message.Free-tier safety
MAX_DECK = 300caps TMDb calls, KV writes and the size of the D1rooms.deckrow. A full room ≈ 15 TMDb pages (cached), ~7 KV writes, a ~90KB deck-cards value — the tightest free-tier limit (KV writes, 1k/day) stays far off.topupCursor) so we never re-fetch pages we already have.Tests
topupCursoris pure and unit-tested (page advance + sort rotation).typecheck,lint,vitest(6/6) andwrangler deploy --dry-runall pass.