Skip to content

Conversation

@eunjae-lee
Copy link
Contributor

@eunjae-lee eunjae-lee commented Jan 28, 2026

What does this PR do?

Adds a displayLocations property to the OptInFeatureConfig interface to control where opt-in features are displayed (settings page, banner, or both), and applies this filtering at the callers' side.

How to test locally

update "Feature" set enabled = true where slug='bookings-v3';

Run it to globally enable the flag, and then go to the settings page to see the "Features" menu.


Changes:

  • Added OptInFeatureDisplayLocation type with values "settings" | "banner"
  • Added optional displayLocations property to OptInFeatureConfig interface
  • Added helper functions:
    • getFeatureDisplayLocations() - returns display locations with default of ['settings']
    • shouldDisplayFeatureAt() - checks if a feature should display at a specific location
    • getOptInFeaturesForLocation() - filters features by location
  • Updated getOptInFeaturesForScope() to accept an optional displayLocation parameter for filtering
  • Simplified HAS_*_OPT_IN_FEATURES constants to use getOptInFeaturesForScope(scope, "settings").length > 0
  • Updated FeatureOptInService.listFeaturesForUser() to filter by 'settings' location
  • Updated FeatureOptInService.listFeaturesForTeam() to filter by 'settings' location
  • Updated useFeatureOptInBanner hook to check for 'banner' location before showing

Default behavior: If displayLocations is omitted, features default to ['settings'] only.

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. N/A - internal config change only.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  1. Verify the helper functions work as expected:

    • getFeatureDisplayLocations({ slug: "test", ... }) should return ["settings"] (default)
    • getFeatureDisplayLocations({ slug: "test", displayLocations: ["banner"] }) should return ["banner"]
    • shouldDisplayFeatureAt(feature, "settings") should return true for features without displayLocations
    • getOptInFeaturesForScope("user", "banner") should only return user-scoped features with "banner" in their displayLocations
  2. Verify caller-side filtering:

    • listFeaturesForUser() and listFeaturesForTeam() should only return features with 'settings' in displayLocations
    • Banner hook should only show features with 'banner' in displayLocations
    • HAS_*_OPT_IN_FEATURES constants should only be true if there are features with 'settings' location

Checklist

  • My code follows the style guidelines of this project
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings

Human Review Checklist

  • Verify the default behavior (defaulting to ['settings']) matches requirements
  • Confirm the filtering logic is applied correctly in all callers (service methods, banner hook, constants)
  • Verify the banner hook correctly prevents showing features without 'banner' in displayLocations
  • Note: The test mock returns all features regardless of displayLocation parameter - the filtering logic in getOptInFeaturesForScope isn't directly tested. Consider if this is acceptable or if tests should be added.

Link to Devin run: https://app.devin.ai/sessions/a064ee43a56d458caf2892b55959f1ea
Requested by: @eunjae-lee

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

devin-ai-integration bot and others added 3 commits January 28, 2026 10:07
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
- Update HAS_*_OPT_IN_FEATURES constants to filter by 'settings' location
- Add getOptInFeaturesForScopeInSettings() helper function
- Update FeatureOptInService.listFeaturesForUser() to filter by 'settings'
- Update FeatureOptInService.listFeaturesForTeam() to filter by 'settings'
- Update useFeatureOptInBanner hook to check for 'banner' location

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
@pull-request-size pull-request-size bot added size/L and removed size/M labels Jan 28, 2026
@eunjae-lee eunjae-lee changed the title feat: add displayLocations property to OptInFeatureConfig feat: show bookings-v3 only in the settings but not in the banner Jan 28, 2026
@eunjae-lee eunjae-lee changed the title feat: show bookings-v3 only in the settings but not in the banner fix: show bookings-v3 only in the settings but not in the banner Jan 28, 2026
height: 348,
},
policy: "permissive",
displayLocations: ["settings"],
Copy link
Contributor Author

@eunjae-lee eunjae-lee Jan 28, 2026

Choose a reason for hiding this comment

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

all we will need to do make the banner appear on /bookings is ↓

displayLocations: ["banner", "settings"],

@eunjae-lee eunjae-lee marked this pull request as ready for review January 28, 2026 14:31
@graphite-app graphite-app bot added consumer core area: core, team members only labels Jan 28, 2026
@graphite-app graphite-app bot requested a review from a team January 28, 2026 14:31
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 5 files

@eunjae-lee eunjae-lee marked this pull request as draft January 28, 2026 15:35
@eunjae-lee eunjae-lee marked this pull request as ready for review January 29, 2026 09:06
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 5 files

Copy link
Member

@sean-brydon sean-brydon left a comment

Choose a reason for hiding this comment

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

LGTM - nice and clean

Copy link
Contributor Author

eunjae-lee commented Jan 29, 2026

Merge activity

  • Jan 29, 9:17 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jan 29, 9:17 AM UTC: @eunjae-lee merged this pull request with Graphite.

@eunjae-lee eunjae-lee merged commit ea15474 into main Jan 29, 2026
84 of 89 checks passed
@eunjae-lee eunjae-lee deleted the devin/1769594384-add-display-locations-to-feature-opt-in branch January 29, 2026 09:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

consumer core area: core, team members only ready-for-e2e size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants