Repository navigation
fix(web): a vote flushes only its product's caches, and only when it changes - #1320
Conversation
…changes #1306 (web part). Every vote request revalidated the global products, stats and reviews tags, and the database limit counts rows per review, so repeated actions on one review could keep the catalogue caches cold. - the stored vote is read first: the same vote again is not written and flushes nothing; - a changed vote revalidates the review caches and its product's page tag, not the global products and stats tags; - flushes are throttled per voter (6 per minute per instance); votes past that still count and the caches catch up on their own interval. The database guard change is proposed on the issue for JOY. Refs #1306 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #1306 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex round 1 on #1306: - review readers and summaries are also tagged per master (masterReviewsCacheTag); a vote revalidates that tag and the product's page tag, no longer the global reviews tag; - a report over a stored up/down vote counts as a change (the report clears the vote), so it is written. Refs #1306 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
If your organization's extra usage balance is empty, an organization admin can add extra usage credits at claude.ai/admin-settings/usage. If its monthly spend limit was reached, an admin can raise it on the same page. If neither applies, contact Anthropic support.
Once extra usage is available, someone with write access to this repository can comment @claude review on this pull request to trigger a review.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 53 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Refs #1306 (web part; the DB guard change is proposed on the issue for JOY, so the issue stays open)
From the apps/web security review. Severity: medium (load amplification through cache flushes; no data exposure).
What (
app/api/reviews/[id]/vote/route.ts)masterReviewsCacheTag, added to the review reader and summary caches inserver/rate/index.ts) and the product page tag. It no longer flushes the global products, stats or reviews tags.Tests
write-paths.test.ts: an unchanged vote reads the stored vote and is not written; a report over an up-vote is written.core-rate-architecture.test.ts: the vote route revalidates the per-product tags, not the global ones.Review gate
Codex adversarial, 2 rounds (cap 2-3):
Checks
Web
pnpm test,tsc --noEmit, eslint, prettier: green locally.🤖 Generated with Claude Code
📌 TL;DR
This PR optimizes the review voting API to prevent cache stampedes by replacing broad global cache invalidations with targeted, rate-limited revalidation of specific product and review tags. It also introduces logic to skip database writes and cache flushes entirely when a user submits a duplicate vote.
🎯 Type of Change
🔍 Changes Walkthrough
apps/web/src/app/api/reviews/[id]/vote/route.tsBoundedSlidingWindowRateLimiterto throttle cache revalidations per voter. Implemented a "same vote" check to skip DB writes if the vote hasn't changed. Replaced globalRATE_CACHE_TAGSinvalidation with targetedreviewProductTagsresolution.apps/web/src/server/rate/cache-tags.tsmasterReviewsCacheTaghelper to generate specific cache tags for a product's reviews, enabling granular invalidation.apps/web/src/server/rate/index.tsgetCachedMasterProductReviewsByKeyandgetCachedMasterProductReviewSummaryto include the newmasterReviewsCacheTagin their cache tag arrays.apps/web/src/app/api/v1/rate/__tests__/write-paths.test.tsapps/web/src/server/rate/__tests__/core-rate-architecture.test.tsmasterReviewsCacheTag,productCacheTag) instead of global tags (RATE_CACHE_TAGS.REVIEWS,RATE_CACHE_TAGS.PRODUCTS).📊 Architectural Flow
sequenceDiagram participant Client participant VoteAPI as Vote API Route participant DB as Database participant Cache as Next.js Cache Client->>VoteAPI: POST /api/reviews/[id]/vote VoteAPI->>DB: Check existing vote (RLS) alt Vote is unchanged VoteAPI-->>Client: 200 OK (No write, no cache flush) else Vote is changed VoteAPI->>DB: Write/Update vote VoteAPI->>VoteAPI: Check Rate Limiter (per voter) alt Rate Limit Passed VoteAPI->>DB: Resolve Product & Master Product IDs VoteAPI->>Cache: Revalidate specific tags (Product, Master Reviews) else Rate Limit Exceeded VoteAPI->>VoteAPI: Skip revalidation (Cache catches up on interval) end VoteAPI-->>Client: 200 OK end