Skip to content

Conversation

cvxluo
Copy link
Contributor

@cvxluo cvxluo commented Aug 5, 2025

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 https://github.com/getsentry/getsentry/pull/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 can be rolled out via the automator.

@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Aug 5, 2025
@cvxluo cvxluo changed the title feat(billing): hack global views flag into PlanFeatures feat(billing): force global-views flag into PlanFeatures Aug 5, 2025
@cvxluo cvxluo requested a review from a team August 5, 2025 19:44
@cvxluo cvxluo marked this pull request as ready for review August 5, 2025 19:44
cursor[bot]

This comment was marked as outdated.

Comment on lines 93 to 97
for (const plan of plans) {
if (isBizPlanFamily(plan) || plan.id.includes('mm2')) {
plan.features.push('global-views');
}
}
Copy link
Contributor

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 to staleTime: Infinity. On each render of the PlanFeature component, the code iterates through plans and unconditionally pushes 'global-views' into the plan.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.

cursor[bot]

This comment was marked as outdated.

@cvxluo cvxluo requested a review from a team August 5, 2025 23:25
Copy link
Member

@isabellaenriquez isabellaenriquez left a 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)) {
Copy link
Member

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

@cvxluo
Copy link
Contributor Author

cvxluo commented Aug 8, 2025

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

👍 made a ticket for myself here

@cvxluo cvxluo merged commit a904373 into master Aug 12, 2025
45 checks passed
@cvxluo cvxluo deleted the cvxluo/hack-global-views-flag branch August 12, 2025 17:24
andrewshie-sentry pushed a commit that referenced this pull request Aug 12, 2025
`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.
narsaynorath added a commit that referenced this pull request Aug 15, 2025
…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.
priscilawebdev pushed a commit that referenced this pull request Aug 25, 2025
`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.
priscilawebdev pushed a commit that referenced this pull request Aug 25, 2025
…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.
andrewshie-sentry pushed a commit that referenced this pull request Aug 26, 2025
…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.
@github-actions github-actions bot locked and limited conversation to collaborators Aug 28, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Scope: Frontend Automatically applied to PRs that change frontend components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants