ワンクリックで
feature-flag-domain
Use when changing feature flag or segment types, values, revisions, or SDK-visible targeting data.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Use when changing feature flag or segment types, values, revisions, or SDK-visible targeting data.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
Use when adding, changing, extracting, or reusing client components, including Storybook stories and controls.
Use when adding or changing forms in apps/client.
Use when changing GitHub OAuth, session cookies, SessionGuard, logout, or authenticated API request identity.
Use when adding or changing routes in apps/client.
Use when adding or changing client state, React Query data flow, immutable context values, or Zustand stores.
Use when styling apps/client with Tailwind CSS v4.
SOC 職業分類に基づく
| name | feature-flag-domain |
| description | Use when changing feature flag or segment types, values, revisions, or SDK-visible targeting data. |
Generated from ai/registry.json. Do not edit manually.
Canonical skill: ../../../ai/skills/feature-flag-domain.md.
Referenced context:
../../../ai/glossary/config-sdk-terms.md../../../ai/rules/feature-flag-domain-rules.md../../../ai/rules/client-form-rules.md../../../ai/architecture/feature-flag-lifecycle.md../../../ai/examples/good-feature-flag-service.mdThis file is compiled from canonical AI knowledge files. Edit canonical files under ai, then run npm run ai:sync.
ai/skills/feature-flag-domain.mdUse this skill when changing feature flag or segment behavior in API services, client forms, public config serialization, evaluator logic, or SDK-visible targeting data.
Change feature flag, segment, or advanced targeting behavior while preserving type normalization, environment values, prerequisite semantics, revision semantics, public config mapping, and evaluator compatibility.
ai/glossary/config-sdk-terms.mdai/rules/feature-flag-domain-rules.mdai/rules/client-form-rules.mdai/architecture/feature-flag-lifecycle.mdai/examples/good-feature-flag-service.mdclient-form-validation for client feature flag form changes.api-public-config-contract for public config output changes.sdk-evaluator-contract for evaluator or SDK-visible semantics changes.segments in Config JSON tied to revision and ETag bumps.npm --workspace @capture-flag/api run test after API feature flag changes.npm --workspace @capture-flag/client run build after client feature flag form changes.ai/glossary/config-sdk-terms.mdTerms shared by API, public config, evaluator, SDK, and client UI.
SDK-visible setting controlled by Capture Flag. Supported types are boolean, string, integer, double, json_object, and json_array.
Configured flag value stored in the database and emitted in Config JSON. This is not the same as SDK fallback value.
Value supplied by application code when calling getValue. The SDK returns fallback when config is unavailable, invalid, missing, or type-mismatched.
Ordered targeting rules emitted as rules in public Config JSON. The evaluator checks rules before percentage rollout.
Reusable group of attribute conditions scoped to one config and emitted as segments in public Config JSON.
A rule condition shaped as { "segment": "segment-key" }. It is evaluated locally by checking the referenced segment conditions against the Evaluation Context.
A rule condition shaped as { "prerequisiteFlag": "flag-key", "operator": "equals", "value": true }. It evaluates another flag from the same Config JSON locally before deciding whether the current rule matches.
Targeting features beyond simple attribute equality: prerequisite flags, arrayContains, date comparisons, and SemVer comparisons.
Deterministic distribution of values based on a rollout attribute such as identifier.
Context attribute used for rollout bucketing. Defaults to identifier.
Read-only credential scoped to one config and one environment. Stored as a hash in the API database.
The full SDK credential shown only immediately after creation. It must never be stored, logged, audited, or re-displayed.
Display-safe prefix derived from the raw SDK key and stored for UI identification and audit metadata.
Versioned public JSON downloaded by SDKs. It contains local-evaluation data, not evaluated flag results.
React provider and hook package that receives a JavaScript SDK client and evaluates flags through that client.
Per config + environment state that stores revision, ETag, and generated timestamp for public config caching.
HTTP cache validator used by SDK clients through If-None-Match.
Default SDK mode. The client fetches config only when no cache exists or when the cached entry is older than cacheTtlMs.
SDK mode where the JavaScript client refreshes config in the background on pollIntervalMs.
SDK mode where getValue uses the current cache and the application calls refresh() to fetch new config.
SDK mode where the client uses only existing cache and never performs network requests.
Default in-process SDK cache used by every client instance.
Browser persistent cache enabled explicitly through SDK options. It stores config, ETag, timestamp, cache schema version, and scope fingerprints, never raw SDK keys or raw base URLs.
Duration used by lazy loading to decide whether a cached config should be refreshed.
ETag stored with the cached config and sent on refresh through If-None-Match.
client.close() stops SDK-owned background polling timers.
ai/rules/feature-flag-domain-rules.mdRules for feature flag types, values, revisions, and SDK-visible data.
boolean, string, integer, double, json_object, and json_array flag types.rulesJson and percentageOptionsJson as JSON arrays.{ "segment": "segment-key" } conditions.{ "prerequisiteFlag": "flag-key", "operator": "equals", "value": true } conditions.equals and notEquals until a product requirement expands them.json_object and json_array are not valid prerequisites.arrayContains, dateBefore, dateAfter, semverEquals, semverGreaterThan, semverGreaterThanOrEquals, semverLessThan, and semverLessThanOrEquals.YYYY-MM-DD/date-time strings with timezone.MAJOR.MINOR.PATCH; ignore build metadata and apply prerelease precedence.conditionsJson as attribute conditions only; segment nesting remains unsupported.conditionsJson free of prerequisite flag references.percentage and value, match the flag type, and total 100.percentageAttribute to identifier.enabled field.FeatureFlagEnvironmentValue.defaultValue maps to public defaultValue.rulesJson maps to public rules.percentageOptionsJson maps to public percentageOptions.Segment.conditionsJson maps to public segments[segment.key].conditions.rules unchanged and are evaluated by the SDK/evaluator.ai/rules/client-form-rules.mdRules for forms in apps/client.
react-hook-form for mutation forms and forms with meaningful client validation.zod for form schemas when a form submits data to API mutations or has reusable validation rules.zodResolver from @hookform/resolvers/zod when using React Hook Form with Zod.defaultValues for every registered React Hook Form field.noValidate on forms so Zod owns validation messages."".aria-invalid on invalid fields.FormField in complex forms when they reduce repeated label/control/error markup.FormData manually in React components when React Hook Form or controlled state owns the form.required validation for app-level messages.ai/architecture/feature-flag-lifecycle.mdFeature flags are edited through private API services and consumed through public config JSON.
configId.project_admin, developer, or organization owner/admin shortcut).project_admin, developer, or organization owner/admin shortcut).project_admin, developer, or organization owner/admin shortcut).Feature flag deletion is soft delete through deletedAt. Deletion bumps affected config environment states and public config excludes the flag.
Segments are created, updated, and soft-deleted through private API routes scoped by config. Segment mutations require project administrative access (project_admin or organization owner/admin shortcut), not the developer role. Creating or deleting a segment changes the public Config JSON for every environment of that config. Updating key or conditionsJson also bumps every config environment state for the config; updating only UI metadata such as name or description does not bump public revisions. Segment rename and deletion are rejected while active flag rules still reference the segment key.
Advanced targeting lives inside rulesJson on feature flag environment values. Updating rules normalizes attribute conditions, segment references, and prerequisite flag references before the environment value is saved. Date comparisons accept numeric timestamps or ISO date strings, and SemVer comparisons use strict SemVer 2.0.0 strings. Prerequisite references must point to active flags in the same config, may use only equals or notEquals, must use a value matching the referenced flag type, and cannot reference the current flag. The API rejects prerequisite cycles for the target environment. Flag rename and deletion are rejected while active rules still reference that flag key as a prerequisite.
ai/examples/good-feature-flag-service.mdSource: apps/api/src/feature-flags/use-cases/create-feature-flag.service.ts (sha256: e3447019ab7377c435f4f4a6c46e5c29813e27e73520f9044656a9b4a5436f67)
Source: apps/api/src/feature-flags/use-cases/update-feature-flag-environment-value.service.ts (sha256: 1f13a84f9a7190b566b4eb5dd0829f49c488cf9a6284b7c2f98c7e5c23ae4b2f)
Why this is canonical:
Canonical feature flag service patterns from the feature flag use-case services.
const config = await this.featureFlagAccess.findConfigForCreate(userId, configId);
const normalizedInput = await this.featureFlagCreateInput.normalize({
input,
organizationId: config.project.organizationId,
});
return this.prisma.$transaction(async (tx) => {
const flag = await tx.featureFlag.create({
data: {
projectId: config.projectId,
configId,
key: normalizedInput.key,
name: normalizedInput.name,
description: normalizedInput.description,
type: normalizedInput.type,
initialDefaultValue: normalizedInput.defaultValue,
tags: normalizedInput.tags,
hint: normalizedInput.hint,
ownerUserId: normalizedInput.ownerUserId,
},
});
const environmentIds = await this.featureFlagEnvironmentValueInitializer.initialize(tx, {
projectId: config.projectId,
configId,
featureFlagId: flag.id,
defaultValue: normalizedInput.defaultValue,
updatedByUserId: userId,
});
await this.featureFlagConfigState.bumpForFlagCreate(tx, {
actorUserId: userId,
configId,
environmentIds,
featureFlagId: flag.id,
organizationId: config.project.organizationId,
projectId: config.projectId,
});
await this.featureFlagAudit.writeFlagCreated(tx, {
actorUserId: userId,
environmentIds,
flag,
organizationId: config.project.organizationId,
});
});
Creation initializes every existing environment with SDK-visible values.
const writeResult = await this.featureFlagEnvironmentValueWriter.write(tx, {
createData: normalizedInput.createData,
environmentId,
featureFlagId,
publicUpdate: normalizedInput.publicUpdate,
updateData: normalizedInput.updateData,
});
if (!writeResult.didChange) {
return writeResult.value;
}
No-op public value updates must not bump revision, ETag, or audit.