-
-
Notifications
You must be signed in to change notification settings - Fork 255
feat: add override functionality to remote feature flags #7271
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
base: main
Are you sure you want to change the base?
feat: add override functionality to remote feature flags #7271
Conversation
packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts
Outdated
Show resolved
Hide resolved
packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts
Outdated
Show resolved
Hide resolved
packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts
Outdated
Show resolved
Hide resolved
packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts
Outdated
Show resolved
Hide resolved
packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts
Outdated
Show resolved
Hide resolved
packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts
Outdated
Show resolved
Hide resolved
packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts
Outdated
Show resolved
Hide resolved
packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts
Outdated
Show resolved
Hide resolved
packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts
Outdated
Show resolved
Hide resolved
packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts
Outdated
Show resolved
Hide resolved
packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts
Outdated
Show resolved
Hide resolved
packages/transaction-controller/src/TransactionControllerIntegration.test.ts
Show resolved
Hide resolved
f131cc8 to
11c0f59
Compare
11c0f59 to
7ae47a3
Compare
packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts
Outdated
Show resolved
Hide resolved
packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts
Outdated
Show resolved
Hide resolved
packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts
Outdated
Show resolved
Hide resolved
| if (Array.isArray(processedValue) && thresholdValue) { | ||
| // Store the raw A/B test array for later use | ||
| rawProcessedRemoteFeatureFlags[remoteFeatureFlagName] = | ||
| remoteFeatureFlagValue; |
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.
Bug: Raw A/B flags not stored when threshold equals zero
The new raw flag storage code on lines 297-299 is inside a conditional that checks Array.isArray(processedValue) && thresholdValue. Since thresholdValue is a number that can be exactly 0 (when a user's metaMetricsId produces the minimum UUID value), and 0 is falsy in JavaScript, the entire block is skipped. This means rawProcessedRemoteFeatureFlags won't capture A/B test arrays for users with threshold value 0, breaking the new A/B test visibility feature for this edge case. The raw flag storage logic likely needs to be independent of the thresholdValue check.
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.
this is existing functionality
Cal-L
left a comment
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.
Left a comment
| * @param value - The override value for the feature flag. | ||
| */ | ||
| setFlagOverride(flagName: string, value: Json): void { | ||
| this.update(() => { |
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.
Can spread ...this.state for unaffected states
| this.update(() => { | ||
| return { | ||
| remoteFeatureFlags: this.state.remoteFeatureFlags, | ||
| localOverrides: newOverrides, |
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.
spread ..this.state for unaffected states
| this.update(() => { | ||
| return { | ||
| remoteFeatureFlags: this.state.remoteFeatureFlags, | ||
| localOverrides: {}, |
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.
Spread state for unaffected states
packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts
Outdated
Show resolved
Hide resolved
| remoteFeatureFlags: processedRemoteFeatureFlags, | ||
| remoteFeatureFlags: processedFlags, | ||
| localOverrides: this.state.localOverrides, | ||
| rawRemoteFeatureFlags: remoteFeatureFlags, |
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.
Bug: rawRemoteFeatureFlags stores all flags instead of only A/B test flags
The #updateCache method stores the entire remoteFeatureFlags object as rawRemoteFeatureFlags, but the PR description, CHANGELOG, and tests clearly indicate that only A/B test flags (threshold arrays) should be stored for efficiency. The test 'only stores raw values for A/B test flags, not simple flags' expects rawRemoteFeatureFlags to contain only threshold-based flags like testFlagForThreshold, excluding simple boolean/string flags. The implementation stores everything, contradicting the documented "selective raw storage" behavior and causing the test to fail.
Remote Feature Flag Controller - Override Support & A/B Test Visibility
Explanation
Current State & Problem
The RemoteFeatureFlagController currently only supports remote feature flags with no ability to locally override them. This creates several pain points for developers and QA teams:
Solution Overview
This PR adds local override functionality with A/B test visibility through direct state access:
Core Features:
localOverridesstate field allows manual flag overrides that take precedence over remote flagsrawRemoteFeatureFlagsfield stores raw A/B test arrays (preserves original flag data before processing)setFlagOverride,clearFlagOverride,clearAllOverrides)How It Works:
#updateCachemethod now stores raw flag data inrawRemoteFeatureFlagsbefore processing A/B tests into single valuesstate.localOverrides[flagName] ?? state.remoteFeatureFlags[flagName]for override-aware access#updateCachemethodImplementation Details
State Management: Three state fields work together:
remoteFeatureFlags: Processed flags (A/B tests resolved to single values)localOverrides: Manual overrides that take precedencerawRemoteFeatureFlags: Original flag data before processing (preserves A/B test arrays)Override Persistence: Remote flag updates preserve existing local overrides through state preservation in
#updateCacheMessenger Integration: All override methods are exposed as controller actions for external access
Metadata Configuration: All new state fields are properly configured for logging, persistence, and UI exposure
Access Patterns
Getting Flag Values (with override support):
Accessing A/B Test Groups:
Managing Overrides:
Dependencies & Imports
Jsontype import from@metamask/utilsfor type safetyReferences
This enhancement addresses the need for local flag testing and A/B test visibility that has been requested by development and QA teams for improved testing workflows.
Checklist
Note: No breaking changes were introduced - this is purely additive functionality that maintains full backward compatibility.
Note
Adds local override support and raw A/B test flag visibility to RemoteFeatureFlagController, updates exports/metadata, and adjusts consumers/tests accordingly.
localOverridesandrawRemoteFeatureFlags; update metadata (persistence, logging, UI exposure).setFlagOverride,clearFlagOverride,clearAllOverrides; local overrides take precedence; preserved across remote updates via#updateCache.remoteFeatureFlagsand raw flags inrawRemoteFeatureFlags; exportcontrollerName.RemoteFeatureFlagControllerSetFlagOverrideAction,...ClearFlagOverrideAction,...ClearAllOverridesAction) and updated state type viaindex.ts.transaction-controllerandtransaction-pay-controllerto include new state fields and use updated flag state.CHANGELOG.mdwith new features and behavior changes.Written by Cursor Bugbot for commit c1af969. This will update automatically on new commits. Configure here.