-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
feat(billing): force global-views flag into PlanFeatures
#97148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
PlanFeatures
PlanFeatures
for (const plan of plans) { | ||
if (isBizPlanFamily(plan) || plan.id.includes('mm2')) { | ||
plan.features.push('global-views'); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential bug: The code mutates a cached `plan.features` array by pushing `'global-views'` on every render, leading to duplicate entries over time.
- Description: The
useBillingConfig
hook caches plan data indefinitely due tostaleTime: Infinity
. On each render of thePlanFeature
component, the code iterates through plans and unconditionally pushes'global-views'
into theplan.features
array. Because the plan objects are cached and shared across renders, this mutation occurs repeatedly on the same array reference. This leads to an accumulation of duplicate'global-views'
entries, which can cause memory bloat and potential functional issues in downstream code that expects unique feature identifiers. - Suggested fix: Before pushing to the array, add a check to ensure the feature does not already exist. For example:
if (!plan.features.includes('global-views')) { plan.features.push('global-views'); }
. This prevents duplicate entries from being added on subsequent renders.
severity: 0.45, confidence: 0.95
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's just make sure we have a TODO to remove this hack when global-views
is fully transitioned to flagpole 🙏🏽 lgtm, just one comment
// but since PlanFeature hooks into getsentry to determine which plan | ||
// `global-views` is in, we need to hardcode it into the plans here | ||
for (const plan of plans) { | ||
if (isBizPlanFamily(plan) || plan.id.includes('mm2') || isAmEnterprisePlan(plan.id)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i believe isBizPlanFamily
should already cover the mm2 plans that have global-views
, but plan.id.includes('mm2')
would also include plans that shouldn't have access
👍 made a ticket for myself here |
`PlanFeatures` takes a list of features and determines what plan has every one of those features. This is used in `powerFeatureHovercard`, which for a given feature, it shows a hovercard that says "Requires x plan", where x is the plan name from `PlanFeatures`. We wanted to move `global-views` to flagpole controlled, rather than getsentry (see getsentry/getsentry#17944), but since `PlanFeatures` reads from getsentry to determine what plan name to show, we ran into an issue where the plan name showed as 'unavailable' instead of 'business' (see #96947) To move `global-views` to flagpole controlled without having the hovercard break, we need `PlanFeatures` to know that `global-views` is a business feature. This _temporarily_ hard codes the feature into every business plan that `PlanFeatures` retrieves, so that we can safely remove the flag from getsentry. The motivation to have the flag in flagpole is so [this product change](https://sentry.slack.com/archives/C01N4L6SPT2/p1754414626890039) can be rolled out via the automator.
…7773) This forces the dashboards-edit and dashboards-basic feature flags to be associated to business and team plans even if they aren't returned by getsentry. This allows us to continue to indicate to the user what the next lowest plan the user needs to upgrade to for the feature. This is so we can migrate off of getsentry and move the flags into Flagpole to more easily switch the flags on when releasing logs. Builds off of #97148 which accomplishes the same thing but for `global-views` on different plans.
`PlanFeatures` takes a list of features and determines what plan has every one of those features. This is used in `powerFeatureHovercard`, which for a given feature, it shows a hovercard that says "Requires x plan", where x is the plan name from `PlanFeatures`. We wanted to move `global-views` to flagpole controlled, rather than getsentry (see getsentry/getsentry#17944), but since `PlanFeatures` reads from getsentry to determine what plan name to show, we ran into an issue where the plan name showed as 'unavailable' instead of 'business' (see #96947) To move `global-views` to flagpole controlled without having the hovercard break, we need `PlanFeatures` to know that `global-views` is a business feature. This _temporarily_ hard codes the feature into every business plan that `PlanFeatures` retrieves, so that we can safely remove the flag from getsentry. The motivation to have the flag in flagpole is so [this product change](https://sentry.slack.com/archives/C01N4L6SPT2/p1754414626890039) can be rolled out via the automator.
…7773) This forces the dashboards-edit and dashboards-basic feature flags to be associated to business and team plans even if they aren't returned by getsentry. This allows us to continue to indicate to the user what the next lowest plan the user needs to upgrade to for the feature. This is so we can migrate off of getsentry and move the flags into Flagpole to more easily switch the flags on when releasing logs. Builds off of #97148 which accomplishes the same thing but for `global-views` on different plans.
…7773) This forces the dashboards-edit and dashboards-basic feature flags to be associated to business and team plans even if they aren't returned by getsentry. This allows us to continue to indicate to the user what the next lowest plan the user needs to upgrade to for the feature. This is so we can migrate off of getsentry and move the flags into Flagpole to more easily switch the flags on when releasing logs. Builds off of #97148 which accomplishes the same thing but for `global-views` on different plans.
PlanFeatures
takes a list of features and determines what plan has every one of those features. This is used inpowerFeatureHovercard
, which for a given feature, it shows a hovercard that says "Requires x plan", where x is the plan name fromPlanFeatures
. We wanted to moveglobal-views
to flagpole controlled, rather than getsentry (see https://github.com/getsentry/getsentry/pull/17944), but sincePlanFeatures
reads from getsentry to determine what plan name to show, we ran into an issue where the plan name showed as 'unavailable' instead of 'business' (see #96947)To move
global-views
to flagpole controlled without having the hovercard break, we needPlanFeatures
to know thatglobal-views
is a business feature. This temporarily hard codes the feature into every business plan thatPlanFeatures
retrieves, so that we can safely remove the flag from getsentry. The motivation to have the flag in flagpole is so this product change can be rolled out via the automator.