Repository navigation
fix(marketplace): fail loud instead of listing no-upfront RIs at $0 - #1493
Conversation
resolveMarketplacePriceSchedule's default-schedule branch silently clamped a negative computed list price to 0 instead of rejecting it. A no-upfront RI (upfrontCost <= 0) or one with an unknown/elapsed term (originalTerm <= 0) makes marketplaceResidualPerUnit return 0, so the RI would be listed on AWS Marketplace for free instead of erroring out like the supplied-schedule branch already does for a non-positive price. The backend now returns an explicit error asking the caller to supply a price_schedule. The sell-consent-modal preview in frontend/src/history.ts had a parallel bug: it computed the preview price with a different formula than the backend (including recurring monthly cost, which the backend deliberately excludes, and not dividing by instance count), so it could show a nonzero preview price for exactly the case the backend now rejects, and diverge from the real listing price for multi-count RIs. The preview now mirrors marketplaceResidualPerUnit and resolveMarketplacePriceSchedule's default branch exactly, and shows "Default list price: unavailable (no upfront cost or unknown term)" instead of a fabricated or zero price when no default can be computed. Adds TestResolveMarketplacePriceSchedule_ZeroDefaultPriceRejected (backend) and two regression tests in history-marketplace-sell-button.test.ts (frontend): one pinning the per-unit formula against the old recurring-inclusive row-total formula for a multi-count RI, one asserting the no-upfront case shows "unavailable" and never "$0". Follow-up to #808, found during an adversarial review sweep.
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 55 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
Summary
Follow-up to #808 (Sell-on-Marketplace feature), found during an adversarial review sweep.
resolveMarketplacePriceSchedule's default-schedule branch (used when the caller supplies no explicitprice_schedule) silently clamped a negative computed list price to0instead of rejecting it:A no-upfront RI (
upfrontCost <= 0) or one with an unknown/elapsed term (originalTerm <= 0) makesmarketplaceResidualPerUnitreturn0, so the RI would be listed on AWS Marketplace for free instead of erroring out the way the supplied-schedule branch already does for a non-positive price ("price must be positive").The sell-consent-modal preview in
frontend/src/history.tshad a parallel bug: it computed the preview price with a different formula than the backend (it included recurringmonthly_cost, which the backend deliberately excludes since the buyer assumes the recurring obligation post-transfer, and it didn't divide by instancecount). This meant the preview could show a nonzero price for exactly the case the backend now rejects, and diverge from the real listing price for multi-count RIs.Fix
internal/api/handler_marketplace.go: the default-schedule branch now returns an explicit error ("cannot compute a default listing price for this RI (no upfront cost or unknown term to prorate); supply an explicit price_schedule") instead of silently listing at $0.frontend/src/history.ts: the consent-modal preview now mirrorsmarketplaceResidualPerUnit+resolveMarketplacePriceSchedule's default branch exactly (upfront-only, per-unit, prorated by remaining/original term), and shows"Default list price: unavailable (no upfront cost or unknown term)"instead of a fabricated or zero price when no default can be computed.Tests
TestResolveMarketplacePriceSchedule_ZeroDefaultPriceRejected(backend): asserts an error for bothupfrontCost=0andoriginalTerm=0.history-marketplace-sell-button.test.ts(frontend):Verified both the Go and frontend regression tests fail on the pre-fix code and pass after the fix.
Test plan
go build ./...go vet ./...go test ./internal/api/...(full package, includes new test)golangci-lint run(v2.10.1, CI-pinned) - 0 issuesgocyclo -over 10on changed files - cleannpx jest src/__tests__/history-marketplace-sell-button.test.ts- 10/10 passnpx tsc --noEmit- cleannpx eslinton changed frontend files - clean