Skip to main content

add-feature-flag

Add a new boolean feature flag (dynamic config key) to cadence-web. Use when asked to add, create, or set up a feature flag, config flag, or `*_ENABLED` toggle.

Zur Installation springen

Quellinformationen

Repository
cadence-workflow/cadence-web
Letzte Quellaktivität
3. September 2026 um 11:08
Erkannte Sprache von SKILL.md
Englisch
Sterne
435
Forks
129

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
add-feature-flag
description
Add a new boolean feature flag (dynamic config key) to cadence-web. Use when asked to add, create, or set up a feature flag, config flag, or `*_ENABLED` toggle.
# Add a feature flag Feature flags are dynamic config entries whose resolver returns `boolean`. Completeness is enforced by TypeScript — the fixture and the Zod schema map are typed against `dynamicConfigs`, so a missing entry fails `npm run typecheck`. Reference example: `WORKFLOW_DIAGNOSTICS_ENABLED` (added in the same 4 files below). ## Naming - Key: `UPPER_SNAKE_CASE`, ending in `_ENABLED` — e.g. `WORKFLOW_DIAGNOSTICS_ENABLED` - Env var: `CADENCE_` + key — e.g. `CADENCE_WORKFLOW_DIAGNOSTICS_ENABLED` - Resolver file: kebab-case of the key — e.g. `workflow-diagnostics-enabled.ts` - Resolver function: camelCase of the key — e.g. `workflowDiagnosticsEnabled` ## Files to touch Add the new entry directly after a related existing flag in each file (not alphabetically). ### 1. Resolver — `src/config/dynamic/resolvers/<flag-name>.ts` ```ts /** * Returns whether <feature> is enabled. * * To enable, set the CADENCE_<FLAG_NAME> env variable to `true`. * For further customization, override the implementation of this resolver. * * @returns {Promise<boolean>} Whether <feature> is enabled. */ export default async function <flagName>(): Promise<boolean> { return process.env.CADENCE_<FLAG_NAME> === 'true'; } ``` - Default export, `async`, returns `Promise<boolean>`. - Off by default; forks override the resolver. - If the flag depends on another flag, import and call that resolver rather than re-reading its env var (see `workflow-diagnostics-in-history-enabled.ts`). Check the cheap env var first. - If the flag needs args (e.g. `{ cluster, domain }`), add `<flag-name>.types.ts` with a `<FlagName>ResolverParams` type (see `cron-list-enabled.types.ts`). ### 2. Register — `src/config/dynamic/dynamic.config.ts` Three edits: ```ts // import (alphabetical by file path) import <flagName> from './resolvers/<flag-name>'; // type block <FLAG_NAME>: ConfigAsyncResolverDefinition<undefined, boolean, 'request', true>; // runtime block <FLAG_NAME>: { resolver: <flagName>, evaluateOn: 'request', isPublic: true, }, ``` Replace `undefined` with the args type if the resolver takes args. `isPublic: true` is what exposes the key to the client via `/api/config`. ### 3. Zod schema — `src/config/dynamic/resolvers/schemas/resolver-schemas.ts` ```ts <FLAG_NAME>: { args: z.undefined(), // or z.object({ cluster: z.string(), domain: z.string() }) returnType: z.boolean(), }, ``` ### 4. Test fixture — `src/utils/config/__fixtures__/resolved-config-values.ts` ```ts <FLAG_NAME>: false, ``` The `getConfigValue` auto-mock reads from this, so server-side tests see the new key automatically. ### 5. Resolver test (only if the resolver has logic) Skip for a plain env-var check. If the resolver combines conditions, calls another resolver, or takes args, add `src/config/dynamic/resolvers/__tests__/<flag-name>.node.ts`. Mirror `batch-actions-ui-enabled.node.ts`: `jest.mock` the imported resolvers, save/restore the env var in `beforeEach`/`afterEach`. ## Consuming the flag Client: ```ts const { data: isEnabled } = useSuspenseConfigValue('<FLAG_NAME>'); // or non-suspense: useConfigValue('<FLAG_NAME>', args?) ``` Server (route handlers): `await getConfigValue('<FLAG_NAME>')`. Client tests mock the endpoint: ```ts render(<Component />, { endpointsMocks: [ { path: '/api/config', httpMethod: 'GET', mockOnce: false, httpResolver: async () => HttpResponse.json(true), }, ], }); ``` ## When the feature ships Once the UI lands: - Add a row to the **Feature flags** table in `README.md` - Add a commented `# CADENCE_<FLAG_NAME>=true` under `### Feature flags` in `.env` ## Verify ```bash npm run typecheck # proves fixture + schema are complete npm run test:unit:node <flag-name>.node.ts # if you added a resolver test npm run test:unit:node -- src/route-handlers/get-config src/utils/config src/config/dynamic npm run lint ``` Optional live check: `npm run dev`, then `curl 'http://localhost:8088/api/config?configKey=<FLAG_NAME>'` → `false`; rerun with `CADENCE_<FLAG_NAME>=true npm run dev` → `true`.
Auf GitHub ansehen