Repository navigation
fix(web): batch offers read availability; radar and best offer skip sold-out listings - #1176
Conversation
…old-out listings - getMasterProductOffersBatch reads rate.products.availability per chunk and attaches it, like the single-product read (#1170). - The deal radar drops out_of_stock and discontinued offers before the market floor, spread, deals and traps, for every caller (#1170). - selectBestOfferFromListings decides on availability, not stock: crawlers report stock 0 when they read no count (#1171). - The availability read no longer falls back to unknown on a failed read or a missing column; it throws RateDataUnavailableError like the offer reads (#1174). 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 48 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 |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follow-up to #1141 / #1164: sold-out and discontinued listings no longer show up as deals or best offers anywhere. One PR for all three issues, since the diff is small and they touch the same read.
Changes
getMasterProductOffersBatchreadsid, availabilityfromrate.productsper chunk of up to 150 masters, in parallel with the trust-view read, and attaches it withwithOfferAvailability. This covers both the trust view and the fallback path. Watchlist, compare, leaderboard, products and versus pick it up through the batch read.computeCrossPlatformDealRadarFromDatadropsout_of_stock/discontinuedoffers beforeplausibleOffers. That keeps them out of the market floor, spread, deals and traps for every caller (category radar,computeProductRadarSignal). Unknown availability still counts as in stock.selectBestOfferFromListingsno longer readsstock, because crawlers report0when they read no count. It drops unavailable offers byavailabilityinstead. No otherstock > 0filter exists underapps/web/src/server/rate.getListingAvailability(masterIds), built onfetchAllRows. A failed read or a missing column now throwsRateDataUnavailableErrorlike the offer reads it completes, instead of logging a warning and leaving availability unknown.Tests
core-rate-architecture.test.tscovers:stock: 0+in_stockstays buyable, andout_of_stock/discontinuedare skipped.cluster_id=in.asid=in.. It is narrowed so the new.in('cluster_id', …)read gets an empty page.pnpm --filter @repo/web test,tsc --noEmitand eslint on the changed files are green.Runtime check after deploy
Buds3 Pro's watchlist entry should get a best offer of 3,140,000 from an in-stock seller (#1171 acceptance), and the earbuds category radar should not cite FPT Shop's 2,694,000.
Closes #1170
Closes #1171
Closes #1174
🤖 Generated with Claude Code
📌 TL;DR
Refactors the listing availability lookup to support batch processing and strict error handling, while updating the deal radar and best-offer selection logic to exclude sold-out or discontinued listings based on the
availabilityfield rather than the unreliablestockcount.🎯 Type of Change
🔍 Changes Walkthrough
apps/web/src/lib/rate-api.tsgetListingAvailabilityForMasterintogetListingAvailabilityto accept an array of master IDs. Replaced manual pagination and silent error swallowing with the sharedfetchAllRowsutility, ensuring that availability read failures now throwRateDataUnavailableErrorinstead of returning an empty map. UpdatedgetMasterProductOffersBatchto fetch availability in parallel with offer data and apply it to results.apps/web/src/server/rate/api-handler.tsselectBestOfferFromListingsto filter out unavailable offers usingisOfferUnavailablebefore price validation. Removed thestock > 0check, asstock: 0is now treated as "unknown" rather than "out of stock," relying solely on theavailabilitystatus. Addedavailabilityto theWatchlistCandidateOfferinterface.apps/web/src/server/rate/deals.tscomputeCrossPlatformDealRadarFromDatato exclude sold-out or discontinued listings from the valid offers pool. This prevents unavailable items from skewing price spreads, deal signals, or trap detection metrics.apps/web/src/server/rate/__tests__/core-rate-architecture.test.tsstock: 0with unknown availability as valid.📊 Architectural Flow
sequenceDiagram participant Client participant APIHandler as api-handler.ts participant RateAPI as rate-api.ts participant DB as Supabase (rate.products) participant Deals as deals.ts Client->>APIHandler: Request Offers (Batch) APIHandler->>RateAPI: getMasterProductOffersBatch(masterIds) par Fetch Offers RateAPI->>DB: Select from v_products_with_merchant_trust DB-->>RateAPI: Offer Rows and Fetch Availability RateAPI->>DB: Select id, availability from products (IN masterIds) DB-->>RateAPI: Availability Rows end Note over RateAPI: If Availability Read Fails, Throw RateDataUnavailableError RateAPI->>RateAPI: Map offers with availability status RateAPI-->>APIHandler: Offers with Availability APIHandler->>APIHandler: selectBestOfferFromListings Note right of APIHandler: Filters out isOfferUnavailable<br/>(ignores stock count) APIHandler->>Deals: computeCrossPlatformDealRadarFromData Note right of Deals: Filters out isOfferUnavailable<br/>before calculating spreads Deals-->>APIHandler: Radar Data APIHandler-->>Client: Response