feat(webapp): admin UI for global and org-level feature flag overrides#3291
feat(webapp): admin UI for global and org-level feature flag overrides#3291
Conversation
…lls, extract constants
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughThis PR adds full admin feature-flag management: a new client dialog component (FeatureFlagsDialog) and reusable FlagControls, a global admin route (/admin/feature-flags) with loader/action, and a new org-level API (admin.api.v2.orgs.$organizationId.feature-flags). It extracts FEATURE_FLAG and validation helpers into a new v3/featureFlags.ts module, updates many imports to the new module, replaces several Prisma Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
… FEATURE_FLAG constant, fix findUnique
0ski
left a comment
There was a problem hiding this comment.
Nice, that's going to be useful!
…letion on self-hosted
| export function getFlagControlType(schema: z.ZodTypeAny): FlagControlType { | ||
| const typeName = schema._def.typeName; | ||
|
|
||
| if (typeName === "ZodBoolean") { | ||
| return { type: "boolean" }; | ||
| } | ||
|
|
||
| if (typeName === "ZodEnum") { | ||
| return { type: "enum", options: schema._def.values as string[] }; | ||
| } | ||
|
|
||
| return { type: "string" }; | ||
| } |
There was a problem hiding this comment.
🚩 getFlagControlType relies on Zod internal _def.typeName for z.coerce.boolean()
The getFlagControlType function at apps/webapp/app/v3/featureFlags.ts:73-85 checks schema._def.typeName === "ZodBoolean" to detect boolean flags. All boolean flags in the catalog use z.coerce.boolean() rather than z.boolean(). In Zod 3.22+, z.coerce.boolean() creates a ZodBoolean with coerce: true, so _def.typeName should still be "ZodBoolean". However, this relies on Zod internals (_def.typeName) which are not part of the public API and could change between versions. The project pins Zod at 3.25.76. If the internal representation changed in this version (part of the Zod 3→4 transition), all boolean flags would incorrectly be classified as "string" type controls in the admin UI. Worth verifying with a quick runtime test.
Was this helpful? React with 👍 or 👎 to provide feedback.
Adds a dialog to the admin orgs page for viewing and editing per-org feature flag overrides. Flags are introspected from the catalog so the UI stays in sync with available flags automatically. Also adds a new tab for global flags.
Refactors featureFlags.server.ts to split catalog definition (shared) from server-only runtime (flags(), makeSetMultipleFlags). The shared module exports flag metadata and validation so both the UI and API routes can use it without pulling in server dependencies.
Org-level modal:
Global flags confirmation modal: