feat: user based feature flag integration#173
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Integrates user-based feature flags into the Next.js app so flags are available to both Server Components (via a signed httpOnly cookie read in a server action) and Client Components (via a React provider kept in sync across tabs with BroadcastChannel).
custom
Changes:
- Add a new user feature flag model (
UserFeatureFlags+ defaults) and SSR hydration viagetServerFlags()passed into<Providers>. - On login / provider login / signup, fetch
GET /v1/userand persist/broadcast flags viaPOST /api/feature-flags; on logout clear flags across tabs and delete cookies. - Add API type/schema updates, documentation, and Cypress E2E coverage for the feature-flag cookie + provider state transitions.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/app/types.ts | Extends UserData to include features returned by the user service. |
| src/app/store/saga/profile-saga.ts | Adjusts token refresh saga typing (feature flags handled elsewhere). |
| src/app/store/saga/auth-saga.ts | Applies feature flags after login/signup/provider login and resets defaults on logout (cross-tab). |
| src/app/services/user-service-api-types.ts | Updates generated OpenAPI types to include features and new subscription endpoints/docs. |
| src/app/services/session-service.ts | Adds feature-flag refresh/apply helpers and returns renewal signal from session cookie establishment. |
| src/app/services/profile-service.ts | Maps features from the user profile API into UserData. |
| src/app/services/channel-service.ts | Adds typed channel support + a helper that also delivers to the sender tab. |
| src/app/providers.tsx | Wires UserFeatureFlagProvider into the provider tree with SSR initial flags. |
| src/app/interface/UserFeatureFlags.ts | Defines typed flag map, defaults, and conversion from API array form. |
| src/app/context/UserFeatureFlagProvider.tsx | New client provider + hook, sync via BroadcastChannel, and Cypress exposure hook. |
| src/app/components/AuthSessionProvider.tsx | Refreshes feature flags on session renewal cadence. |
| src/app/api/session/route.ts | Clears the feature-flag cookie along with the session cookie on logout. |
| src/app/api/feature-flags/route.ts | New route to HMAC-sign and set the md_features cookie. |
| src/app/actions/feature-flags.ts | New server action to read + verify the signed feature-flag cookie for SSR/server usage. |
| src/app/[locale]/layout.tsx | Hydrates user feature flags server-side and passes them into <Providers>. |
| package.json | Updates OpenAPI type generation scripts for user service + GBFS validator types. |
| external_types/UserServiceAPI.yaml | Updates the source OpenAPI spec to include user features + subscription endpoints. |
| docs/user-feature-flags.md | Adds architecture and usage documentation for user feature flags. |
| cypress/e2e/user-feature-flags.cy.ts | Adds E2E tests for cookie set/clear and provider state sync on login/logout/renewal. |
| const encoded = cookieValue.split('.')[0]; | ||
| // base64url → standard base64 before atob() | ||
| const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/'); | ||
| return JSON.parse(atob(base64)); |
|
*Lighthouse ran on https://mobilitydatabase-o63u5eo7c-mobility-data.vercel.app/ * (Desktop)
*Lighthouse ran on https://mobilitydatabase-o63u5eo7c-mobility-data.vercel.app/feeds * (Desktop)
*Lighthouse ran on https://mobilitydatabase-o63u5eo7c-mobility-data.vercel.app/feeds/gtfs/mdb-2126 * (Desktop)
*Lighthouse ran on https://mobilitydatabase-o63u5eo7c-mobility-data.vercel.app/feeds/gtfs_rt/mdb-2585 * (Desktop)
*Lighthouse ran on https://mobilitydatabase-o63u5eo7c-mobility-data.vercel.app/feeds/gbfs/gbfs-flamingo_porirua * (Desktop)
|
| displayName: userDisplayName, | ||
| } = useAuthSession(); | ||
| // TO REMOVE: for PR testing | ||
| const { isNotificationsEnabled } = useUserFeatureFlags(); // Ensure feature flags are loaded for SSR hydration |
There was a problem hiding this comment.
Please remove before merging
| TO REMOVE: is notification enabled:{' '} | ||
| {isNotificationsEnabled.toString()} |
There was a problem hiding this comment.
Please remove before merging
Summary:
closes #140
Enables user based feature flags for use in server and client components.
It was done in a way where its easy to add and consume feature flags. It's also done in a way where it should be easy to replace the firebase remote configs gradually
For a more detailed explanation on how it works, how to use it, and the options considered check the doc that was added in
docs/user-feature-flags.mdExpected behavior:
Scenarios
On login
On logout
On token renewal (~60 mins)
Testing tips:
For the review of this PR I added an element to the Header to display the value of a user based feature flag
Go to Retool and set
isNotificationsEnabledto true for the account you plan on using, then in the preview url check that the value changes based on your loginNOTE: If you are already logged, it's possible that the feature flags will be delayed up to 1 hour (tokenRenewal), for best testing, logout then login. Or you can wait 1 hour
Please make sure these boxes are checked before submitting your pull request - thanks!
yarn testto make sure you didn't break anything