Skip to content

Conversation

@calvin-codecov
Copy link
Contributor

@calvin-codecov calvin-codecov commented Dec 12, 2025

Removing option to start a new yearly plan

Closes https://linear.app/getsentry/project/block-annual-plan-subscriptions-4e0b8ca9a437/overview

Screenshot 2025-12-16 at 9 51 36 AM

Note

Remove annual plan selection across plan pages, default everything to monthly pricing, update links/utilities accordingly, and align tests.

  • Upgrade flows (UI/controllers):
    • Remove annual billing option from BillingOptions for Pro/Sentry/Team; show only monthly radio and pricing in ProPlanController, SentryPlanController, TeamPlanController.
    • Update PriceCallout components to compute/show monthly totals only and next billing date.
    • UpdateBlurb: stop treating monthly→annual as upgrade; only note Annual→Monthly changes.
  • Plan detail cards:
    • ProPlanDetails, TeamPlanDetails, SentryPlanDetails: display monthly unit prices and “billed monthly”; include monthly plan benefits.
    • Cancel page TeamPlanCard and current plan PlanUpgradeTeam: show monthly price/aux text and upgrade links.
  • Navigation/links:
    • Add query params to upgrade links (e.g., ?plan=pro|team); ActionsBilling accepts optional buttonOptions to pass params through.
  • Defaults/logic:
    • Add determineDefaultPlan to choose default monthly plan (respects selected/current plan and Sentry eligibility); used in UpgradePlanPage and getDefaultValuesUpgradeForm.
    • Mark BillingRate.ANNUALLY as deprecated in billing.ts.
  • Tests:
    • Update snapshots/expectations to monthly pricing (e.g., $12, $6, Sentry “billed monthly”) and removal of annual radio/options; add coverage for link query params and new default plan logic.

Written by Cursor Bugbot for commit e8a0632. This will update automatically on new commits. Configure here.

Comment on lines 224 to 234
})

const isMonthlyPlan = plan?.billingRate === BillingRate.MONTHLY

const isPaidPlan = !!plan?.billingRate // If the plan has a billing rate, it's a paid plan

let newPlan = proPlanYear
if (isSentryUpgrade && !plan?.isSentryPlan) {
newPlan = isMonthlyPlan ? sentryPlanMonth : sentryPlanYear
// Ensure we default to monthly plan regardless of current billing cycle
let newPlan = proPlanMonth
if ((isSentryUpgrade && !plan?.isSentryPlan) || selectedPlan?.isSentryPlan) {
newPlan = sentryPlanMonth
} else if (plan?.isTeamPlan || selectedPlan?.isTeamPlan) {
newPlan = isMonthlyPlan ? teamPlanMonth : teamPlanYear
} else if (isPaidPlan) {
newPlan = plan
newPlan = teamPlanMonth
}

const seats = extractSeats({

This comment was marked as outdated.

@sentry
Copy link

sentry bot commented Dec 12, 2025

Codecov Report

❌ Patch coverage is 97.82609% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.73%. Comparing base (3c901d3) to head (e8a0632).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...Page/subRoutes/UpgradePlanPage/UpgradePlanPage.jsx 90.00% 0 Missing and 1 partial ⚠️
src/shared/utils/upgradeForm.ts 96.42% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3958      +/-   ##
==========================================
+ Coverage   98.61%   98.73%   +0.11%     
==========================================
  Files         828      826       -2     
  Lines       15126    14970     -156     
  Branches     4348     4285      -63     
==========================================
- Hits        14917    14780     -137     
+ Misses        201      182      -19     
  Partials        8        8              
Files with missing lines Coverage Δ
...TeamPlanSpecialOffer/TeamPlanCard/TeamPlanCard.tsx 100.00% <100.00%> (ø)
...ard/FreePlanCard/PlanUpgradePro/PlanUpgradePro.jsx 100.00% <100.00%> (ø)
...d/FreePlanCard/PlanUpgradeTeam/PlanUpgradeTeam.jsx 100.00% <100.00%> (ø)
...tPlanCard/shared/ActionsBilling/ActionsBilling.jsx 100.00% <100.00%> (ø)
...e/UpgradeDetails/ProPlanDetails/ProPlanDetails.jsx 100.00% <100.00%> (ø)
...adeDetails/SentryPlanDetails/SentryPlanDetails.jsx 100.00% <100.00%> (ø)
...UpgradeDetails/TeamPlanDetails/TeamPlanDetails.jsx 100.00% <100.00%> (ø)
...adePlanPage/UpgradeForm/Controllers/Controller.tsx 100.00% <100.00%> (ø)
...roPlanController/BillingOptions/BillingOptions.tsx 100.00% <100.00%> (ø)
...rs/ProPlanController/PriceCallout/PriceCallout.tsx 100.00% <100.00%> (ø)
... and 14 more

... and 5 files with indirect coverage changes

Components Coverage Δ
Assets 100.00% <ø> (ø)
Layouts 99.71% <ø> (ø)
Pages 98.34% <98.43%> (+0.20%) ⬆️
Services 99.32% <ø> (ø)
Shared 99.00% <96.42%> (-0.06%) ⬇️
UI 99.01% <ø> (ø)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3c901d3...e8a0632. Read the comment docs.

@codecov-public-qa
Copy link

codecov-public-qa bot commented Dec 12, 2025

Codecov Report

Attention: Patch coverage is 97.82609% with 2 lines in your changes missing coverage. Please review.

Project coverage is 98.73%. Comparing base (3c901d3) to head (e8a0632).
Report is 2 commits behind head on main.

✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...Page/subRoutes/UpgradePlanPage/UpgradePlanPage.jsx 90.00% 0 Missing and 1 partial ⚠️
src/shared/utils/upgradeForm.ts 96.42% 1 Missing ⚠️
@@            Coverage Diff             @@
##             main    #3958      +/-   ##
==========================================
+ Coverage   98.61%   98.73%   +0.11%     
==========================================
  Files         828      826       -2     
  Lines       15126    14970     -156     
  Branches     4348     4285      -63     
==========================================
- Hits        14917    14780     -137     
+ Misses        201      182      -19     
  Partials        8        8              
Files with missing lines Coverage Δ
...TeamPlanSpecialOffer/TeamPlanCard/TeamPlanCard.tsx 100.00% <100.00%> (ø)
...ard/FreePlanCard/PlanUpgradePro/PlanUpgradePro.jsx 100.00% <100.00%> (ø)
...d/FreePlanCard/PlanUpgradeTeam/PlanUpgradeTeam.jsx 100.00% <100.00%> (ø)
...tPlanCard/shared/ActionsBilling/ActionsBilling.jsx 100.00% <100.00%> (ø)
...e/UpgradeDetails/ProPlanDetails/ProPlanDetails.jsx 100.00% <100.00%> (ø)
...adeDetails/SentryPlanDetails/SentryPlanDetails.jsx 100.00% <100.00%> (ø)
...UpgradeDetails/TeamPlanDetails/TeamPlanDetails.jsx 100.00% <100.00%> (ø)
...adePlanPage/UpgradeForm/Controllers/Controller.tsx 100.00% <100.00%> (ø)
...roPlanController/BillingOptions/BillingOptions.tsx 100.00% <100.00%> (ø)
...rs/ProPlanController/PriceCallout/PriceCallout.tsx 100.00% <100.00%> (ø)
... and 14 more

... and 5 files with indirect coverage changes

Components Coverage Δ
Assets 100.00% <ø> (ø)
Layouts 99.71% <ø> (ø)
Pages 98.34% <98.43%> (+0.20%) ⬆️
Services 99.32% <ø> (ø)
Shared 99.00% <96.42%> (-0.06%) ⬇️
UI 99.01% <ø> (ø)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3c901d3...e8a0632. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sentry
Copy link

sentry bot commented Dec 12, 2025

Bundle Report

Changes will decrease total bundle size by 11.99kB (-0.1%) ⬇️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
gazebo-production-system 6.23MB -5.61kB (-0.09%) ⬇️
gazebo-production-esm 6.31MB -6.38kB (-0.1%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: gazebo-production-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/index.*.js 1 bytes 22.37kB 0.0%
assets/index.*.js 2 bytes 7.75kB 0.03%
assets/index.*.js 9 bytes 126.55kB 0.01%
assets/index.*.js 3.35kB 56.94kB 6.25% ⚠️
assets/index.*.js 2 bytes 26.27kB 0.01%
assets/index.*.js 2 bytes 14.24kB 0.01%
assets/index.*.js 1 bytes 17.22kB 0.01%
assets/index.*.js 1 bytes 12.29kB 0.01%
assets/index.*.js -3 bytes 5.86kB -0.05%
assets/index.*.js 4.45kB 53.59kB 9.04% ⚠️
assets/index.*.js -6.02kB 25.09kB -19.35%
assets/index.*.js 4 bytes 90.03kB 0.0%
assets/index.*.js 2 bytes 125.68kB 0.0%
assets/index.*.js -55 bytes 2.48kB -2.17%
assets/index.*.js 3 bytes 9.58kB 0.03%
assets/index.*.js -50 bytes 16.85kB -0.3%
assets/index.*.js 1 bytes 41.88kB 0.0%
assets/index.*.js 1 bytes 13.62kB 0.01%
assets/index.*.js 1 bytes 12.42kB 0.01%
assets/index.*.js -79 bytes 9.91kB -0.79%
assets/index.*.js 2 bytes 7.45kB 0.03%
assets/index.*.js 1 bytes 8.58kB 0.01%
assets/index.*.js 2 bytes 36.76kB 0.01%
assets/index.*.js 1 bytes 4.6kB 0.02%
assets/index.*.js 17.87kB 49.15kB 57.12% ⚠️
assets/index.*.js 1 bytes 12.43kB 0.01%
assets/RawFileViewer.*.js 1 bytes 127.15kB 0.0%
assets/ConfigureCachedBundleModal.*.js 5 bytes 8.31kB 0.06%
assets/useInvoices.*.js 711 bytes 3.21kB 28.5% ⚠️
assets/upgradeForm.*.js (New) 3.19kB 3.19kB 100.0% 🚀
assets/Alert.*.js -5 bytes 2.2kB -0.23%
assets/BenefitList.*.js 5 bytes 1.47kB 0.34%
assets/Checkbox.*.js -5 bytes 971 bytes -0.51%
assets/TotalsNumber.*.js -5 bytes 829 bytes -0.6%
assets/BillingDetails.*.js (Deleted) -29.04kB 0 bytes -100.0% 🗑️
assets/propTypes.*.js (Deleted) -731 bytes 0 bytes -100.0% 🗑️

Files in assets/index.*.js:

  • ./src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/PlanUpgradeTeam/PlanUpgradeTeam.jsx → Total Size: 3.12kB

  • ./src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/PlanUpgradePro/PlanUpgradePro.jsx → Total Size: 3.51kB

  • ./src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/shared/ActionsBilling/ActionsBilling.jsx → Total Size: 4.01kB

Files in assets/index.*.js:

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/SentryPlanDetails/SentryPlanDetails.jsx → Total Size: 2.53kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/BillingOptions/BillingOptions.tsx → Total Size: 1.3kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/SentryPlanController.tsx → Total Size: 1.58kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/BillingOptions/BillingOptions.tsx → Total Size: 1.31kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/BillingOptions/BillingOptions.tsx → Total Size: 1.3kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/ProPlanController.tsx → Total Size: 1.57kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/PriceCallout/PriceCallout.tsx → Total Size: 1.1kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/Controller.tsx → Total Size: 566 bytes

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/PriceCallout/PriceCallout.tsx → Total Size: 1.11kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/ProPlanDetails/ProPlanDetails.jsx → Total Size: 2.65kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/TeamPlanDetails/TeamPlanDetails.jsx → Total Size: 2.62kB

Files in assets/index.*.js:

  • ./src/pages/PlanPage/subRoutes/CancelPlanPage/subRoutes/TeamPlanSpecialOffer/TeamPlanCard/TeamPlanCard.tsx → Total Size: 2.44kB
view changes for bundle: gazebo-production-system

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/index-legacy.*.js 2 bytes 45.41kB 0.0%
assets/index-legacy.*.js 1 bytes 11.39kB 0.01%
assets/index-legacy.*.js -51 bytes 2.65kB -1.89%
assets/index-legacy.*.js 1 bytes 12.28kB 0.01%
assets/index-legacy.*.js 1 bytes 12.66kB 0.01%
assets/index-legacy.*.js -70 bytes 9.49kB -0.73%
assets/index-legacy.*.js 2 bytes 12.78kB 0.02%
assets/index-legacy.*.js 1 bytes 16.8kB 0.01%
assets/index-legacy.*.js 3 bytes 9.46kB 0.03%
assets/index-legacy.*.js 2 bytes 113.08kB 0.0%
assets/index-legacy.*.js 4 bytes 115.09kB 0.0%
assets/index-legacy.*.js 2 bytes 26.31kB 0.01%
assets/index-legacy.*.js 1 bytes 8.57kB 0.01%
assets/index-legacy.*.js 4 bytes 84.77kB 0.0%
assets/index-legacy.*.js 1 bytes 41.39kB 0.0%
assets/index-legacy.*.js 2 bytes 35.22kB 0.01%
assets/index-legacy.*.js 1 bytes 21.1kB 0.0%
assets/index-legacy.*.js -51 bytes 16.57kB -0.31%
assets/index-legacy.*.js 2 bytes 7.4kB 0.03%
assets/index-legacy.*.js 1 bytes 4.41kB 0.02%
assets/index-legacy.*.js -5.3kB 23.2kB -18.58%
assets/index-legacy.*.js 2 bytes 5.64kB 0.04%
assets/index-legacy.*.js 3.79kB 53.2kB 7.67% ⚠️
assets/index-legacy.*.js 2 bytes 7.81kB 0.03%
assets/index-legacy.*.js 1 bytes 11.79kB 0.01%
assets/index-legacy.*.js 19.89kB 49.41kB 67.37% ⚠️
assets/RawFileViewer-legacy.*.js 1 bytes 127.36kB 0.0%
assets/ConfigureCachedBundleModal-legacy.*.js 5 bytes 7.87kB 0.06%
assets/useInvoices-legacy.*.js 723 bytes 3.25kB 28.62% ⚠️
assets/upgradeForm-legacy.*.js (New) 2.94kB 2.94kB 100.0% 🚀
assets/BillingDetails-legacy.*.js (Deleted) -26.7kB 0 bytes -100.0% 🗑️
assets/propTypes-legacy.*.js (Deleted) -819 bytes 0 bytes -100.0% 🗑️

Files in assets/index-legacy.*.js:

  • ./src/pages/PlanPage/subRoutes/CancelPlanPage/subRoutes/TeamPlanSpecialOffer/TeamPlanCard/TeamPlanCard.tsx → Total Size: 2.44kB

Files in assets/index-legacy.*.js:

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/TeamPlanDetails/TeamPlanDetails.jsx → Total Size: 2.62kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/ProPlanDetails/ProPlanDetails.jsx → Total Size: 2.65kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/BillingOptions/BillingOptions.tsx → Total Size: 1.3kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/Controller.tsx → Total Size: 566 bytes

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/PriceCallout/PriceCallout.tsx → Total Size: 1.11kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/SentryPlanController.tsx → Total Size: 1.58kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/PriceCallout/PriceCallout.tsx → Total Size: 1.1kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/BillingOptions/BillingOptions.tsx → Total Size: 1.3kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/ProPlanController.tsx → Total Size: 1.57kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/BillingOptions/BillingOptions.tsx → Total Size: 1.31kB

  • ./src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/SentryPlanDetails/SentryPlanDetails.jsx → Total Size: 2.53kB

Files in assets/index-legacy.*.js:

  • ./src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/shared/ActionsBilling/ActionsBilling.jsx → Total Size: 4.01kB

  • ./src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/PlanUpgradeTeam/PlanUpgradeTeam.jsx → Total Size: 3.12kB

  • ./src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/PlanUpgradePro/PlanUpgradePro.jsx → Total Size: 3.51kB

@codecov-releaser
Copy link
Contributor

codecov-releaser commented Dec 12, 2025

✅ Deploy preview for gazebo ready!

Previews expire after 1 month automatically.

Storybook

Commit Created Cloud Enterprise
ada5ac8 Fri, 12 Dec 2025 23:40:02 GMT Expired Expired
627395d Sat, 13 Dec 2025 00:48:05 GMT Expired Expired
45dfba9 Mon, 15 Dec 2025 19:23:20 GMT Expired Expired
fc02b08 Mon, 15 Dec 2025 19:34:49 GMT Expired Expired
243077d Mon, 15 Dec 2025 23:16:03 GMT Expired Expired
f926684 Tue, 16 Dec 2025 10:05:39 GMT Expired Expired
89e5e6e Tue, 16 Dec 2025 18:04:16 GMT Expired Expired
4e8c031 Tue, 16 Dec 2025 22:31:44 GMT Expired Expired
ca8c2d4 Tue, 16 Dec 2025 23:26:42 GMT Expired Expired
e8a0632 Wed, 17 Dec 2025 00:05:04 GMT Cloud Enterprise

@codecov-notifications
Copy link

codecov-notifications bot commented Dec 13, 2025

Codecov Report

❌ Patch coverage is 97.82609% with 2 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...Page/subRoutes/UpgradePlanPage/UpgradePlanPage.jsx 90.00% 0 Missing and 1 partial ⚠️
src/shared/utils/upgradeForm.ts 96.42% 1 Missing ⚠️
@@            Coverage Diff             @@
##             main    #3958      +/-   ##
==========================================
+ Coverage   98.61%   98.73%   +0.11%     
==========================================
  Files         828      826       -2     
  Lines       15126    14970     -156     
  Branches     4348     4280      -68     
==========================================
- Hits        14917    14780     -137     
+ Misses        201      182      -19     
  Partials        8        8              
Files with missing lines Coverage Δ
...TeamPlanSpecialOffer/TeamPlanCard/TeamPlanCard.tsx 100.00% <100.00%> (ø)
...ard/FreePlanCard/PlanUpgradePro/PlanUpgradePro.jsx 100.00% <100.00%> (ø)
...d/FreePlanCard/PlanUpgradeTeam/PlanUpgradeTeam.jsx 100.00% <100.00%> (ø)
...tPlanCard/shared/ActionsBilling/ActionsBilling.jsx 100.00% <100.00%> (ø)
...e/UpgradeDetails/ProPlanDetails/ProPlanDetails.jsx 100.00% <100.00%> (ø)
...adeDetails/SentryPlanDetails/SentryPlanDetails.jsx 100.00% <100.00%> (ø)
...UpgradeDetails/TeamPlanDetails/TeamPlanDetails.jsx 100.00% <100.00%> (ø)
...adePlanPage/UpgradeForm/Controllers/Controller.tsx 100.00% <100.00%> (ø)
...roPlanController/BillingOptions/BillingOptions.tsx 100.00% <100.00%> (ø)
...rs/ProPlanController/PriceCallout/PriceCallout.tsx 100.00% <100.00%> (ø)
... and 14 more

... and 5 files with indirect coverage changes

Components Coverage Δ
Assets 100.00% <ø> (ø)
Layouts 99.71% <ø> (ø)
Pages 98.34% <98.43%> (+0.20%) ⬆️
Services 99.32% <ø> (ø)
Shared 99.00% <96.42%> (-0.06%) ⬇️
UI 99.01% <ø> (ø)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3c901d3...e8a0632. Read the comment docs.

@codecov-qa
Copy link

codecov-qa bot commented Dec 13, 2025

Codecov Report

❌ Patch coverage is 97.82609% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.73%. Comparing base (3c901d3) to head (e8a0632).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...Page/subRoutes/UpgradePlanPage/UpgradePlanPage.jsx 90.00% 0 Missing and 1 partial ⚠️
src/shared/utils/upgradeForm.ts 96.42% 1 Missing ⚠️
@@            Coverage Diff             @@
##             main    #3958      +/-   ##
==========================================
+ Coverage   96.54%   98.73%   +2.18%     
==========================================
  Files         828      826       -2     
  Lines       15126    14970     -156     
  Branches     4348     4285      -63     
==========================================
+ Hits        14604    14780     +176     
+ Misses        467      182     -285     
+ Partials       55        8      -47     
Files with missing lines Coverage Δ
...TeamPlanSpecialOffer/TeamPlanCard/TeamPlanCard.tsx 100.00% <100.00%> (ø)
...ard/FreePlanCard/PlanUpgradePro/PlanUpgradePro.jsx 100.00% <100.00%> (ø)
...d/FreePlanCard/PlanUpgradeTeam/PlanUpgradeTeam.jsx 100.00% <100.00%> (ø)
...tPlanCard/shared/ActionsBilling/ActionsBilling.jsx 100.00% <100.00%> (ø)
...e/UpgradeDetails/ProPlanDetails/ProPlanDetails.jsx 100.00% <100.00%> (ø)
...adeDetails/SentryPlanDetails/SentryPlanDetails.jsx 100.00% <100.00%> (ø)
...UpgradeDetails/TeamPlanDetails/TeamPlanDetails.jsx 100.00% <100.00%> (ø)
...adePlanPage/UpgradeForm/Controllers/Controller.tsx 100.00% <100.00%> (ø)
...roPlanController/BillingOptions/BillingOptions.tsx 100.00% <100.00%> (ø)
...rs/ProPlanController/PriceCallout/PriceCallout.tsx 100.00% <100.00%> (ø)
... and 14 more

... and 47 files with indirect coverage changes

Components Coverage Δ
Assets 100.00% <ø> (ø)
Layouts 99.71% <ø> (ø)
Pages 98.34% <98.43%> (+0.20%) ⬆️
Services 99.32% <ø> (ø)
Shared 99.00% <96.42%> (+1.75%) ⬆️
UI 99.01% <ø> (+20.18%) ⬆️

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3c901d3...e8a0632. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@calvin-codecov calvin-codecov changed the title feat: Remove option to change to yearly plan feat: Remove option to change to yearly/annual plan Dec 15, 2025
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Incomplete refactoring leaves yearly plan references inconsistent

The PR changed the pricing display from teamPlanYear?.baseUnitPrice to teamPlanMonth?.baseUnitPrice and updated the billing text to say "billed monthly", but left teamPlanYear?.marketingName (line 22) and teamPlanYear?.benefits (line 42) unchanged. This creates an inconsistent state where the component shows monthly pricing but displays the yearly plan's name and benefits. If yearly plans become unavailable from the API, teamPlanYear would be undefined, causing the card to render without a title and with an empty benefits list.

src/pages/PlanPage/subRoutes/CancelPlanPage/subRoutes/TeamPlanSpecialOffer/TeamPlanCard/TeamPlanCard.tsx#L21-L22

<div className="flex justify-between p-4">
<h2 className="font-semibold">{teamPlanYear?.marketingName} plan</h2>

src/pages/PlanPage/subRoutes/CancelPlanPage/subRoutes/TeamPlanSpecialOffer/TeamPlanCard/TeamPlanCard.tsx#L41-L42

Fix in Cursor Fix in Web


})
const monthlyProPlan = isSentryUpgrade ? sentryPlanMonth : proPlanMonth

let planOption = null
Copy link
Contributor Author

@calvin-codecov calvin-codecov Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was an existing bug where on default, the UI selected option didn't match up with what the form had as its value. planParams here on first load doesn't have anything set on default so it automatically has the UI show Pro is selected.

However, in the UpgradePlanPage component, we have this code

  if (
    (hasTeamPlans && planParam === TierNames.TEAM) ||
    planData?.plan?.isTeamPlan
  ) {
    defaultPaidYearlyPlan = teamPlanYear

(changed to use monthly instead of yearly in this PR) which sets the form default to Team if the current plan that the customer is on is a Team plan.

Consequently, the "Update" button at the bottom of the form will be correctly disabled even though it looks like it should be enabled. This line in UpdateButton.tsx const isSamePlan = newPlan?.value === currentPlanValue resolves to true. (newPlan comes from form values which start out with what getDefaultUpgradeForm resolves to.

With this change, the radio buttons will just look to selectedPlan just as getDefaultUpgradeForm does in UpgradeForm.tsx.

Comment on lines 42 to 52
/month
{nextBillingDate && (
<Fragment>
,<span className="font-semibold"> next billing date</span> is{' '}
{nextBillingDate}
</Fragment>
)}
</p>
<div className="flex flex-row gap-1">
<Icon size="sm" name="lightBulb" variant="solid" />
<p>
You{' '}
<span className="font-semibold">
save {formatNumberToUSD(nonBundledCost)}
</span>{' '}
with the Sentry bundle
{seats > 5 && (
<>
, save an{' '}
<span className="font-semibold">
additional{' '}
{formatNumberToUSD(
(perMonthPrice - perYearPrice) * MONTHS_PER_YEAR
)}
</span>{' '}
a year with annual billing
{nextBillingDate && (
<Fragment>
,<span className="font-semibold"> next billing date</span> is{' '}
{nextBillingDate}
</Fragment>
)}{' '}
<button
className="cursor-pointer font-semibold text-ds-blue-darker hover:underline"
onClick={() => setFormValue('newPlan', sentryPlanYear)}
>
switch to annual
</button>
</>
)}
</p>
</div>
</div>
)
}

This comment was marked as outdated.

Comment on lines +202 to +216
// figures out the default plan to use based on the selected plan, current plan, and isSentryUpgrade
export const determineDefaultPlan = ({
selectedPlan,
currentPlan,
plans,
isSentryUpgrade,
}: {
selectedPlan?: IndividualPlan | null
currentPlan?: Plan | null
plans?: IndividualPlan[] | null
isSentryUpgrade: boolean
}): IndividualPlan | undefined => {
const { proPlanMonth } = findProPlans({ plans })
const { sentryPlanMonth } = findSentryPlans({ plans })
const { teamPlanMonth } = findTeamPlans({ plans })
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to consolidate logic here for choosing default plan. Previously, we had some code here in the getDefaultValuesUpgradeForm() function and a slightly different logic in <UpgradePlanPage /> and its child <PlanTypeOptions /> which just showed Pro in the UI unless specified otherwise with the url param.

register={register}
errors={errors}
/>
<SentryPlanController seats={seats} register={register} errors={errors} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we got rid of the setformvalue and register in many components here. How does the logic work now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The <BillingOption /> components don't need setFormValue anymore since the only option available now is monthly. The <...Controller /> parent components also don't need it anymore to pass down. The other input components will still function as normal though.

Copy link
Contributor

@adrianviquez adrianviquez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went over this logic offline together and tested scenarios. Generally looked good, though Calvin wanted to revisit some specific behaviors. Will follow up after those are looked at

Comment on lines +239 to 249
(currentPlan?.billingRate === BillingRate.MONTHLY
? currentPlan
: undefined) ??
undefined

return plan
}

export const getDefaultValuesUpgradeForm = ({
accountDetails,
plans,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The shouldDisplayTeamCard function will incorrectly hide the Team plan if the backend stops providing a yearly plan option, as it requires both monthly and yearly plans to be present.
Severity: HIGH | Confidence: High

🔍 Detailed Analysis

The function shouldDisplayTeamCard requires both monthly and yearly team plans to be available to return true. However, this pull request is removing the option for users to start new yearly plans. If the backend API is updated to no longer provide a yearly team plan option for new customers, shouldDisplayTeamCard will incorrectly return false. This will cause the 'Team' plan card to be hidden on the upgrade page, preventing users from selecting it, even when a monthly team plan is available.

💡 Suggested Fix

Update the shouldDisplayTeamCard function to only check for the existence of a monthly team plan. Change the return condition from !isUndefined(teamPlanMonth) && !isUndefined(teamPlanYear) to !isUndefined(teamPlanMonth).

🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: src/shared/utils/upgradeForm.ts#L199-L249

Potential issue: The function `shouldDisplayTeamCard` requires both monthly and yearly
team plans to be available to return `true`. However, this pull request is removing the
option for users to start new yearly plans. If the backend API is updated to no longer
provide a yearly team plan option for new customers, `shouldDisplayTeamCard` will
incorrectly return `false`. This will cause the 'Team' plan card to be hidden on the
upgrade page, preventing users from selecting it, even when a monthly team plan is
available.

Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 7621343

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will address this in a separate PR as this isn't a problem at the moment.

@calvin-codecov calvin-codecov added this pull request to the merge queue Dec 17, 2025
Merged via the queue into main with commit acfda0a Dec 17, 2025
56 of 64 checks passed
@calvin-codecov calvin-codecov deleted the cy/remove_new_annual branch December 17, 2025 00:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants