diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 96018843d06..f1e49231d30 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -6897,6 +6897,14 @@ components: items: $ref: "#/components/schemas/AllocationExposureRolloutStep" type: array + scheduled_start_time: + description: |- + The resolved UTC start time computed from `scheduled_start`. This field is + read-only and cannot be set directly. + example: "2025-06-13T12:00:00Z" + format: date-time + nullable: true + type: string updated_at: description: The timestamp when the schedule was last updated. example: "2024-01-01T12:00:00Z" @@ -36788,6 +36796,10 @@ components: description: The name of the environment. example: "env-search-term" type: string + observe_full_evaluation_data: + description: Indicates whether full evaluation data is observed for this environment. + example: false + type: boolean queries: description: List of queries to define the environment scope. example: ["staging", "test"] @@ -39095,6 +39107,10 @@ components: items: $ref: "#/components/schemas/FeatureFlagEnvironment" type: array + is_favorite: + description: Indicates whether the feature flag is marked as a favorite by the current user. + example: false + type: boolean json_schema: description: JSON schema for validation when value_type is JSON. example: '{"type": "object", "properties": {"enabled": {"type": "boolean"}}}' @@ -39117,6 +39133,8 @@ components: description: Indicates whether this feature flag requires approval for changes. example: false type: boolean + staleness_details: + $ref: "#/components/schemas/FeatureFlagAttributesStalenessDetails" staleness_status: description: Indicates the whether a feature flag is stale or not. example: "ACTIVE" @@ -39147,6 +39165,48 @@ components: - value_type - variants type: object + FeatureFlagAttributesStalenessDetails: + description: Details about the feature flag's staleness status. + nullable: true + properties: + code_references: + description: Code references associated with the feature flag. + items: + additionalProperties: {} + type: object + nullable: true + type: array + dismissed_by: + description: The ID of the user who dismissed the staleness notification. + format: uuid + nullable: true + type: string + id: + description: The unique identifier of the staleness details record. + example: "550e8400-e29b-41d4-a716-446655440020" + format: uuid + type: string + recommended_actions: + description: Recommended actions to address the feature flag's staleness. + items: + additionalProperties: {} + type: object + nullable: true + type: array + skip_state_check_until: + description: The timestamp until which staleness checks are skipped. + format: date-time + nullable: true + type: string + stale_reason: + description: The reason the feature flag is considered stale. + nullable: true + type: string + staleness_status: + description: The staleness status of the feature flag. + example: "ACTIVE" + type: string + type: object FeatureFlagEnvironment: description: Environment-specific settings for a feature flag. properties: @@ -39186,6 +39246,10 @@ components: description: Indicates whether the environment is production. example: false type: boolean + observe_full_evaluation_data: + description: Indicates whether full evaluation data is observed for this environment. + example: false + type: boolean override_allocation_key: description: The allocation key used for the override variant. example: "allocation-override-123abc" @@ -91810,10 +91874,27 @@ components: description: Rollout options request payload. properties: autostart: - description: Whether the schedule should begin automatically. + deprecated: true + description: |- + Whether the schedule should begin automatically. Deprecated in favor of + `scheduled_start`, which takes precedence when both are set. example: false nullable: true type: boolean + scheduled_start: + description: |- + Controls when the schedule starts. Supersedes `autostart`. One of: + + - `none`: create the schedule without starting it. + - `now`: start the schedule immediately. + - `relative:`: start after a duration (for example `relative:2h`). + - `absolute:`: start at a specific time (for example `absolute:2025-06-13T12:00:00Z`). + + An `absolute` timestamp in the past or present is treated as `now`. A future start time + is not supported for allocations linked to a standard experiment. + example: "absolute:2025-06-13T12:00:00Z" + pattern: ^(none|now|relative:([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+|absolute:\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2}))$ + type: string selection_interval_ms: description: Interval in milliseconds for uniform interval strategies. example: 3600000 diff --git a/examples/v2/feature-flags/CreateAllocationsForFeatureFlagInEnvironment.java b/examples/v2/feature-flags/CreateAllocationsForFeatureFlagInEnvironment.java index 2e5ec9610b2..6a1da568dd5 100644 --- a/examples/v2/feature-flags/CreateAllocationsForFeatureFlagInEnvironment.java +++ b/examples/v2/feature-flags/CreateAllocationsForFeatureFlagInEnvironment.java @@ -45,6 +45,7 @@ public static void main(String[] args) { .rolloutOptions( new RolloutOptionsRequest() .autostart(false) + .scheduledStart("absolute:2025-06-13T12:00:00Z") .selectionIntervalMs(3600000L) .strategy(RolloutStrategy.UNIFORM_INTERVALS)) .rolloutSteps( diff --git a/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment.java b/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment.java index 4feb3f0660f..66497d5f583 100644 --- a/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment.java +++ b/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment.java @@ -47,6 +47,7 @@ public static void main(String[] args) { .rolloutOptions( new RolloutOptionsRequest() .autostart(false) + .scheduledStart("absolute:2025-06-13T12:00:00Z") .selectionIntervalMs(3600000L) .strategy(RolloutStrategy.UNIFORM_INTERVALS)) .rolloutSteps( diff --git a/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment_2978423597.java b/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment_2978423597.java new file mode 100644 index 00000000000..ab683b393c6 --- /dev/null +++ b/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment_2978423597.java @@ -0,0 +1,105 @@ +// Update targeting rules for a flag in an environment with a scheduled start returns "OK" response + +import com.datadog.api.client.ApiClient; +import com.datadog.api.client.ApiException; +import com.datadog.api.client.v2.api.FeatureFlagsApi; +import com.datadog.api.client.v2.model.AllocationDataRequest; +import com.datadog.api.client.v2.model.AllocationDataType; +import com.datadog.api.client.v2.model.AllocationType; +import com.datadog.api.client.v2.model.ExposureRolloutStepRequest; +import com.datadog.api.client.v2.model.ExposureScheduleRequest; +import com.datadog.api.client.v2.model.ListAllocationsResponse; +import com.datadog.api.client.v2.model.OverwriteAllocationsRequest; +import com.datadog.api.client.v2.model.RolloutOptionsRequest; +import com.datadog.api.client.v2.model.RolloutStrategy; +import com.datadog.api.client.v2.model.UpsertAllocationRequest; +import com.datadog.api.client.v2.model.VariantWeightRequest; +import java.util.Arrays; +import java.util.Collections; +import java.util.UUID; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = ApiClient.getDefaultApiClient(); + FeatureFlagsApi apiInstance = new FeatureFlagsApi(defaultClient); + + // there is a valid "feature_flag" in the system + UUID FEATURE_FLAG_DATA_ATTRIBUTES_VARIANTS_0_ID = null; + try { + FEATURE_FLAG_DATA_ATTRIBUTES_VARIANTS_0_ID = + UUID.fromString(System.getenv("FEATURE_FLAG_DATA_ATTRIBUTES_VARIANTS_0_ID")); + } catch (IllegalArgumentException e) { + System.err.println("Error parsing UUID: " + e.getMessage()); + } + UUID FEATURE_FLAG_DATA_ID = null; + try { + FEATURE_FLAG_DATA_ID = UUID.fromString(System.getenv("FEATURE_FLAG_DATA_ID")); + } catch (IllegalArgumentException e) { + System.err.println("Error parsing UUID: " + e.getMessage()); + } + + // there is a valid "environment" in the system + UUID ENVIRONMENT_DATA_ID = null; + try { + ENVIRONMENT_DATA_ID = UUID.fromString(System.getenv("ENVIRONMENT_DATA_ID")); + } catch (IllegalArgumentException e) { + System.err.println("Error parsing UUID: " + e.getMessage()); + } + + OverwriteAllocationsRequest body = + new OverwriteAllocationsRequest() + .data( + Collections.singletonList( + new AllocationDataRequest() + .type(AllocationDataType.ALLOCATIONS) + .attributes( + new UpsertAllocationRequest() + .key("scheduled-start-allocation-example-feature-flag") + .name("New targeting rule Example-Feature-Flag") + .variantWeights( + Collections.singletonList( + new VariantWeightRequest() + .variantId(FEATURE_FLAG_DATA_ATTRIBUTES_VARIANTS_0_ID) + .value(100.0))) + .exposureSchedule( + new ExposureScheduleRequest() + .rolloutOptions( + new RolloutOptionsRequest() + .strategy(RolloutStrategy.UNIFORM_INTERVALS) + .scheduledStart( + "absolute:2021-11-12T11:11:11+00:00") + .selectionIntervalMs(86400000L)) + .rolloutSteps( + Arrays.asList( + new ExposureRolloutStepRequest() + .exposureRatio(0.05) + .intervalMs(null) + .isPauseRecord(false) + .groupedStepIndex(0L), + new ExposureRolloutStepRequest() + .exposureRatio(0.25) + .intervalMs(null) + .isPauseRecord(false) + .groupedStepIndex(1L), + new ExposureRolloutStepRequest() + .exposureRatio(1.0) + .intervalMs(null) + .isPauseRecord(false) + .groupedStepIndex(2L)))) + .type(AllocationType.CANARY)))); + + try { + ListAllocationsResponse result = + apiInstance.updateAllocationsForFeatureFlagInEnvironment( + FEATURE_FLAG_DATA_ID, ENVIRONMENT_DATA_ID, body); + System.out.println(result); + } catch (ApiException e) { + System.err.println( + "Exception when calling FeatureFlagsApi#updateAllocationsForFeatureFlagInEnvironment"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/datadog/api/client/v2/model/AllocationExposureSchedule.java b/src/main/java/com/datadog/api/client/v2/model/AllocationExposureSchedule.java index 9317a5b5491..72b9929595e 100644 --- a/src/main/java/com/datadog/api/client/v2/model/AllocationExposureSchedule.java +++ b/src/main/java/com/datadog/api/client/v2/model/AllocationExposureSchedule.java @@ -33,6 +33,7 @@ AllocationExposureSchedule.JSON_PROPERTY_ID, AllocationExposureSchedule.JSON_PROPERTY_ROLLOUT_OPTIONS, AllocationExposureSchedule.JSON_PROPERTY_ROLLOUT_STEPS, + AllocationExposureSchedule.JSON_PROPERTY_SCHEDULED_START_TIME, AllocationExposureSchedule.JSON_PROPERTY_UPDATED_AT }) @jakarta.annotation.Generated( @@ -67,6 +68,10 @@ public class AllocationExposureSchedule { public static final String JSON_PROPERTY_ROLLOUT_STEPS = "rollout_steps"; private List rolloutSteps = new ArrayList<>(); + public static final String JSON_PROPERTY_SCHEDULED_START_TIME = "scheduled_start_time"; + private JsonNullable scheduledStartTime = + JsonNullable.undefined(); + public static final String JSON_PROPERTY_UPDATED_AT = "updated_at"; private OffsetDateTime updatedAt; @@ -348,6 +353,38 @@ public void setRolloutSteps(List rolloutSteps) { } } + public AllocationExposureSchedule scheduledStartTime(OffsetDateTime scheduledStartTime) { + this.scheduledStartTime = JsonNullable.of(scheduledStartTime); + return this; + } + + /** + * The resolved UTC start time computed from scheduled_start. This field is read-only + * and cannot be set directly. + * + * @return scheduledStartTime + */ + @jakarta.annotation.Nullable + @JsonIgnore + public OffsetDateTime getScheduledStartTime() { + return scheduledStartTime.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_SCHEDULED_START_TIME) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public JsonNullable getScheduledStartTime_JsonNullable() { + return scheduledStartTime; + } + + @JsonProperty(JSON_PROPERTY_SCHEDULED_START_TIME) + public void setScheduledStartTime_JsonNullable(JsonNullable scheduledStartTime) { + this.scheduledStartTime = scheduledStartTime; + } + + public void setScheduledStartTime(OffsetDateTime scheduledStartTime) { + this.scheduledStartTime = JsonNullable.of(scheduledStartTime); + } + public AllocationExposureSchedule updatedAt(OffsetDateTime updatedAt) { this.updatedAt = updatedAt; return this; @@ -434,6 +471,7 @@ public boolean equals(Object o) { && Objects.equals(this.id, allocationExposureSchedule.id) && Objects.equals(this.rolloutOptions, allocationExposureSchedule.rolloutOptions) && Objects.equals(this.rolloutSteps, allocationExposureSchedule.rolloutSteps) + && Objects.equals(this.scheduledStartTime, allocationExposureSchedule.scheduledStartTime) && Objects.equals(this.updatedAt, allocationExposureSchedule.updatedAt) && Objects.equals( this.additionalProperties, allocationExposureSchedule.additionalProperties); @@ -451,6 +489,7 @@ public int hashCode() { id, rolloutOptions, rolloutSteps, + scheduledStartTime, updatedAt, additionalProperties); } @@ -470,6 +509,7 @@ public String toString() { sb.append(" id: ").append(toIndentedString(id)).append("\n"); sb.append(" rolloutOptions: ").append(toIndentedString(rolloutOptions)).append("\n"); sb.append(" rolloutSteps: ").append(toIndentedString(rolloutSteps)).append("\n"); + sb.append(" scheduledStartTime: ").append(toIndentedString(scheduledStartTime)).append("\n"); sb.append(" updatedAt: ").append(toIndentedString(updatedAt)).append("\n"); sb.append(" additionalProperties: ") .append(toIndentedString(additionalProperties)) diff --git a/src/main/java/com/datadog/api/client/v2/model/EnvironmentAttributes.java b/src/main/java/com/datadog/api/client/v2/model/EnvironmentAttributes.java index 22134069ee1..e0233304332 100644 --- a/src/main/java/com/datadog/api/client/v2/model/EnvironmentAttributes.java +++ b/src/main/java/com/datadog/api/client/v2/model/EnvironmentAttributes.java @@ -28,6 +28,7 @@ EnvironmentAttributes.JSON_PROPERTY_IS_PRODUCTION, EnvironmentAttributes.JSON_PROPERTY_KEY, EnvironmentAttributes.JSON_PROPERTY_NAME, + EnvironmentAttributes.JSON_PROPERTY_OBSERVE_FULL_EVALUATION_DATA, EnvironmentAttributes.JSON_PROPERTY_QUERIES, EnvironmentAttributes.JSON_PROPERTY_REQUIRE_FEATURE_FLAG_APPROVAL, EnvironmentAttributes.JSON_PROPERTY_UPDATED_AT @@ -51,6 +52,10 @@ public class EnvironmentAttributes { public static final String JSON_PROPERTY_NAME = "name"; private String name; + public static final String JSON_PROPERTY_OBSERVE_FULL_EVALUATION_DATA = + "observe_full_evaluation_data"; + private Boolean observeFullEvaluationData; + public static final String JSON_PROPERTY_QUERIES = "queries"; private List queries = null; @@ -183,6 +188,27 @@ public void setName(String name) { this.name = name; } + public EnvironmentAttributes observeFullEvaluationData(Boolean observeFullEvaluationData) { + this.observeFullEvaluationData = observeFullEvaluationData; + return this; + } + + /** + * Indicates whether full evaluation data is observed for this environment. + * + * @return observeFullEvaluationData + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_OBSERVE_FULL_EVALUATION_DATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Boolean getObserveFullEvaluationData() { + return observeFullEvaluationData; + } + + public void setObserveFullEvaluationData(Boolean observeFullEvaluationData) { + this.observeFullEvaluationData = observeFullEvaluationData; + } + public EnvironmentAttributes queries(List queries) { this.queries = queries; return this; @@ -315,6 +341,8 @@ public boolean equals(Object o) { && Objects.equals(this.isProduction, environmentAttributes.isProduction) && Objects.equals(this.key, environmentAttributes.key) && Objects.equals(this.name, environmentAttributes.name) + && Objects.equals( + this.observeFullEvaluationData, environmentAttributes.observeFullEvaluationData) && Objects.equals(this.queries, environmentAttributes.queries) && Objects.equals( this.requireFeatureFlagApproval, environmentAttributes.requireFeatureFlagApproval) @@ -330,6 +358,7 @@ public int hashCode() { isProduction, key, name, + observeFullEvaluationData, queries, requireFeatureFlagApproval, updatedAt, @@ -345,6 +374,9 @@ public String toString() { sb.append(" isProduction: ").append(toIndentedString(isProduction)).append("\n"); sb.append(" key: ").append(toIndentedString(key)).append("\n"); sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" observeFullEvaluationData: ") + .append(toIndentedString(observeFullEvaluationData)) + .append("\n"); sb.append(" queries: ").append(toIndentedString(queries)).append("\n"); sb.append(" requireFeatureFlagApproval: ") .append(toIndentedString(requireFeatureFlagApproval)) diff --git a/src/main/java/com/datadog/api/client/v2/model/FeatureFlagAttributes.java b/src/main/java/com/datadog/api/client/v2/model/FeatureFlagAttributes.java index f4af48e2a1f..dfd44f41d11 100644 --- a/src/main/java/com/datadog/api/client/v2/model/FeatureFlagAttributes.java +++ b/src/main/java/com/datadog/api/client/v2/model/FeatureFlagAttributes.java @@ -30,11 +30,13 @@ FeatureFlagAttributes.JSON_PROPERTY_DESCRIPTION, FeatureFlagAttributes.JSON_PROPERTY_DISTRIBUTION_CHANNEL, FeatureFlagAttributes.JSON_PROPERTY_FEATURE_FLAG_ENVIRONMENTS, + FeatureFlagAttributes.JSON_PROPERTY_IS_FAVORITE, FeatureFlagAttributes.JSON_PROPERTY_JSON_SCHEMA, FeatureFlagAttributes.JSON_PROPERTY_KEY, FeatureFlagAttributes.JSON_PROPERTY_LAST_UPDATED_BY, FeatureFlagAttributes.JSON_PROPERTY_NAME, FeatureFlagAttributes.JSON_PROPERTY_REQUIRE_APPROVAL, + FeatureFlagAttributes.JSON_PROPERTY_STALENESS_DETAILS, FeatureFlagAttributes.JSON_PROPERTY_STALENESS_STATUS, FeatureFlagAttributes.JSON_PROPERTY_TAGS, FeatureFlagAttributes.JSON_PROPERTY_UPDATED_AT, @@ -63,6 +65,9 @@ public class FeatureFlagAttributes { public static final String JSON_PROPERTY_FEATURE_FLAG_ENVIRONMENTS = "feature_flag_environments"; private List featureFlagEnvironments = null; + public static final String JSON_PROPERTY_IS_FAVORITE = "is_favorite"; + private Boolean isFavorite; + public static final String JSON_PROPERTY_JSON_SCHEMA = "json_schema"; private JsonNullable jsonSchema = JsonNullable.undefined(); @@ -78,6 +83,10 @@ public class FeatureFlagAttributes { public static final String JSON_PROPERTY_REQUIRE_APPROVAL = "require_approval"; private Boolean requireApproval; + public static final String JSON_PROPERTY_STALENESS_DETAILS = "staleness_details"; + private JsonNullable stalenessDetails = + JsonNullable.undefined(); + public static final String JSON_PROPERTY_STALENESS_STATUS = "staleness_status"; private String stalenessStatus; @@ -269,6 +278,27 @@ public void setFeatureFlagEnvironments(List featureFlagE } } + public FeatureFlagAttributes isFavorite(Boolean isFavorite) { + this.isFavorite = isFavorite; + return this; + } + + /** + * Indicates whether the feature flag is marked as a favorite by the current user. + * + * @return isFavorite + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_IS_FAVORITE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Boolean getIsFavorite() { + return isFavorite; + } + + public void setIsFavorite(Boolean isFavorite) { + this.isFavorite = isFavorite; + } + public FeatureFlagAttributes jsonSchema(String jsonSchema) { this.jsonSchema = JsonNullable.of(jsonSchema); return this; @@ -382,6 +412,41 @@ public void setRequireApproval(Boolean requireApproval) { this.requireApproval = requireApproval; } + public FeatureFlagAttributes stalenessDetails( + FeatureFlagAttributesStalenessDetails stalenessDetails) { + this.stalenessDetails = + JsonNullable.of(stalenessDetails); + return this; + } + + /** + * Details about the feature flag's staleness status. + * + * @return stalenessDetails + */ + @jakarta.annotation.Nullable + @JsonIgnore + public FeatureFlagAttributesStalenessDetails getStalenessDetails() { + return stalenessDetails.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_STALENESS_DETAILS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public JsonNullable getStalenessDetails_JsonNullable() { + return stalenessDetails; + } + + @JsonProperty(JSON_PROPERTY_STALENESS_DETAILS) + public void setStalenessDetails_JsonNullable( + JsonNullable stalenessDetails) { + this.stalenessDetails = stalenessDetails; + } + + public void setStalenessDetails(FeatureFlagAttributesStalenessDetails stalenessDetails) { + this.stalenessDetails = + JsonNullable.of(stalenessDetails); + } + public FeatureFlagAttributes stalenessStatus(String stalenessStatus) { this.stalenessStatus = stalenessStatus; return this; @@ -574,11 +639,13 @@ public boolean equals(Object o) { && Objects.equals(this.distributionChannel, featureFlagAttributes.distributionChannel) && Objects.equals( this.featureFlagEnvironments, featureFlagAttributes.featureFlagEnvironments) + && Objects.equals(this.isFavorite, featureFlagAttributes.isFavorite) && Objects.equals(this.jsonSchema, featureFlagAttributes.jsonSchema) && Objects.equals(this.key, featureFlagAttributes.key) && Objects.equals(this.lastUpdatedBy, featureFlagAttributes.lastUpdatedBy) && Objects.equals(this.name, featureFlagAttributes.name) && Objects.equals(this.requireApproval, featureFlagAttributes.requireApproval) + && Objects.equals(this.stalenessDetails, featureFlagAttributes.stalenessDetails) && Objects.equals(this.stalenessStatus, featureFlagAttributes.stalenessStatus) && Objects.equals(this.tags, featureFlagAttributes.tags) && Objects.equals(this.updatedAt, featureFlagAttributes.updatedAt) @@ -596,11 +663,13 @@ public int hashCode() { description, distributionChannel, featureFlagEnvironments, + isFavorite, jsonSchema, key, lastUpdatedBy, name, requireApproval, + stalenessDetails, stalenessStatus, tags, updatedAt, @@ -623,11 +692,13 @@ public String toString() { sb.append(" featureFlagEnvironments: ") .append(toIndentedString(featureFlagEnvironments)) .append("\n"); + sb.append(" isFavorite: ").append(toIndentedString(isFavorite)).append("\n"); sb.append(" jsonSchema: ").append(toIndentedString(jsonSchema)).append("\n"); sb.append(" key: ").append(toIndentedString(key)).append("\n"); sb.append(" lastUpdatedBy: ").append(toIndentedString(lastUpdatedBy)).append("\n"); sb.append(" name: ").append(toIndentedString(name)).append("\n"); sb.append(" requireApproval: ").append(toIndentedString(requireApproval)).append("\n"); + sb.append(" stalenessDetails: ").append(toIndentedString(stalenessDetails)).append("\n"); sb.append(" stalenessStatus: ").append(toIndentedString(stalenessStatus)).append("\n"); sb.append(" tags: ").append(toIndentedString(tags)).append("\n"); sb.append(" updatedAt: ").append(toIndentedString(updatedAt)).append("\n"); diff --git a/src/main/java/com/datadog/api/client/v2/model/FeatureFlagAttributesStalenessDetails.java b/src/main/java/com/datadog/api/client/v2/model/FeatureFlagAttributesStalenessDetails.java new file mode 100644 index 00000000000..4cf544629a2 --- /dev/null +++ b/src/main/java/com/datadog/api/client/v2/model/FeatureFlagAttributesStalenessDetails.java @@ -0,0 +1,404 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2019-Present Datadog, Inc. + */ + +package com.datadog.api.client.v2.model; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; +import org.openapitools.jackson.nullable.JsonNullable; + +/** Details about the feature flag's staleness status. */ +@JsonPropertyOrder({ + FeatureFlagAttributesStalenessDetails.JSON_PROPERTY_CODE_REFERENCES, + FeatureFlagAttributesStalenessDetails.JSON_PROPERTY_DISMISSED_BY, + FeatureFlagAttributesStalenessDetails.JSON_PROPERTY_ID, + FeatureFlagAttributesStalenessDetails.JSON_PROPERTY_RECOMMENDED_ACTIONS, + FeatureFlagAttributesStalenessDetails.JSON_PROPERTY_SKIP_STATE_CHECK_UNTIL, + FeatureFlagAttributesStalenessDetails.JSON_PROPERTY_STALE_REASON, + FeatureFlagAttributesStalenessDetails.JSON_PROPERTY_STALENESS_STATUS +}) +@jakarta.annotation.Generated( + value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") +public class FeatureFlagAttributesStalenessDetails { + @JsonIgnore public boolean unparsed = false; + public static final String JSON_PROPERTY_CODE_REFERENCES = "code_references"; + private JsonNullable>> codeReferences = + JsonNullable.>>undefined(); + + public static final String JSON_PROPERTY_DISMISSED_BY = "dismissed_by"; + private JsonNullable dismissedBy = JsonNullable.undefined(); + + public static final String JSON_PROPERTY_ID = "id"; + private UUID id; + + public static final String JSON_PROPERTY_RECOMMENDED_ACTIONS = "recommended_actions"; + private JsonNullable>> recommendedActions = + JsonNullable.>>undefined(); + + public static final String JSON_PROPERTY_SKIP_STATE_CHECK_UNTIL = "skip_state_check_until"; + private JsonNullable skipStateCheckUntil = + JsonNullable.undefined(); + + public static final String JSON_PROPERTY_STALE_REASON = "stale_reason"; + private JsonNullable staleReason = JsonNullable.undefined(); + + public static final String JSON_PROPERTY_STALENESS_STATUS = "staleness_status"; + private String stalenessStatus; + + public FeatureFlagAttributesStalenessDetails codeReferences( + List> codeReferences) { + this.codeReferences = JsonNullable.>>of(codeReferences); + return this; + } + + public FeatureFlagAttributesStalenessDetails addCodeReferencesItem( + Map codeReferencesItem) { + if (this.codeReferences == null || !this.codeReferences.isPresent()) { + this.codeReferences = JsonNullable.>>of(new ArrayList<>()); + } + try { + this.codeReferences.get().add(codeReferencesItem); + } catch (java.util.NoSuchElementException e) { + // this can never happen, as we make sure above that the value is present + } + return this; + } + + /** + * Code references associated with the feature flag. + * + * @return codeReferences + */ + @jakarta.annotation.Nullable + @JsonIgnore + public List> getCodeReferences() { + return codeReferences.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_CODE_REFERENCES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public JsonNullable>> getCodeReferences_JsonNullable() { + return codeReferences; + } + + @JsonProperty(JSON_PROPERTY_CODE_REFERENCES) + public void setCodeReferences_JsonNullable( + JsonNullable>> codeReferences) { + this.codeReferences = codeReferences; + } + + public void setCodeReferences(List> codeReferences) { + this.codeReferences = JsonNullable.>>of(codeReferences); + } + + public FeatureFlagAttributesStalenessDetails dismissedBy(UUID dismissedBy) { + this.dismissedBy = JsonNullable.of(dismissedBy); + return this; + } + + /** + * The ID of the user who dismissed the staleness notification. + * + * @return dismissedBy + */ + @jakarta.annotation.Nullable + @JsonIgnore + public UUID getDismissedBy() { + return dismissedBy.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_DISMISSED_BY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public JsonNullable getDismissedBy_JsonNullable() { + return dismissedBy; + } + + @JsonProperty(JSON_PROPERTY_DISMISSED_BY) + public void setDismissedBy_JsonNullable(JsonNullable dismissedBy) { + this.dismissedBy = dismissedBy; + } + + public void setDismissedBy(UUID dismissedBy) { + this.dismissedBy = JsonNullable.of(dismissedBy); + } + + public FeatureFlagAttributesStalenessDetails id(UUID id) { + this.id = id; + return this; + } + + /** + * The unique identifier of the staleness details record. + * + * @return id + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_ID) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public FeatureFlagAttributesStalenessDetails recommendedActions( + List> recommendedActions) { + this.recommendedActions = JsonNullable.>>of(recommendedActions); + return this; + } + + public FeatureFlagAttributesStalenessDetails addRecommendedActionsItem( + Map recommendedActionsItem) { + if (this.recommendedActions == null || !this.recommendedActions.isPresent()) { + this.recommendedActions = JsonNullable.>>of(new ArrayList<>()); + } + try { + this.recommendedActions.get().add(recommendedActionsItem); + } catch (java.util.NoSuchElementException e) { + // this can never happen, as we make sure above that the value is present + } + return this; + } + + /** + * Recommended actions to address the feature flag's staleness. + * + * @return recommendedActions + */ + @jakarta.annotation.Nullable + @JsonIgnore + public List> getRecommendedActions() { + return recommendedActions.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_RECOMMENDED_ACTIONS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public JsonNullable>> getRecommendedActions_JsonNullable() { + return recommendedActions; + } + + @JsonProperty(JSON_PROPERTY_RECOMMENDED_ACTIONS) + public void setRecommendedActions_JsonNullable( + JsonNullable>> recommendedActions) { + this.recommendedActions = recommendedActions; + } + + public void setRecommendedActions(List> recommendedActions) { + this.recommendedActions = JsonNullable.>>of(recommendedActions); + } + + public FeatureFlagAttributesStalenessDetails skipStateCheckUntil( + OffsetDateTime skipStateCheckUntil) { + this.skipStateCheckUntil = JsonNullable.of(skipStateCheckUntil); + return this; + } + + /** + * The timestamp until which staleness checks are skipped. + * + * @return skipStateCheckUntil + */ + @jakarta.annotation.Nullable + @JsonIgnore + public OffsetDateTime getSkipStateCheckUntil() { + return skipStateCheckUntil.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_SKIP_STATE_CHECK_UNTIL) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public JsonNullable getSkipStateCheckUntil_JsonNullable() { + return skipStateCheckUntil; + } + + @JsonProperty(JSON_PROPERTY_SKIP_STATE_CHECK_UNTIL) + public void setSkipStateCheckUntil_JsonNullable( + JsonNullable skipStateCheckUntil) { + this.skipStateCheckUntil = skipStateCheckUntil; + } + + public void setSkipStateCheckUntil(OffsetDateTime skipStateCheckUntil) { + this.skipStateCheckUntil = JsonNullable.of(skipStateCheckUntil); + } + + public FeatureFlagAttributesStalenessDetails staleReason(String staleReason) { + this.staleReason = JsonNullable.of(staleReason); + return this; + } + + /** + * The reason the feature flag is considered stale. + * + * @return staleReason + */ + @jakarta.annotation.Nullable + @JsonIgnore + public String getStaleReason() { + return staleReason.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_STALE_REASON) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public JsonNullable getStaleReason_JsonNullable() { + return staleReason; + } + + @JsonProperty(JSON_PROPERTY_STALE_REASON) + public void setStaleReason_JsonNullable(JsonNullable staleReason) { + this.staleReason = staleReason; + } + + public void setStaleReason(String staleReason) { + this.staleReason = JsonNullable.of(staleReason); + } + + public FeatureFlagAttributesStalenessDetails stalenessStatus(String stalenessStatus) { + this.stalenessStatus = stalenessStatus; + return this; + } + + /** + * The staleness status of the feature flag. + * + * @return stalenessStatus + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_STALENESS_STATUS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getStalenessStatus() { + return stalenessStatus; + } + + public void setStalenessStatus(String stalenessStatus) { + this.stalenessStatus = stalenessStatus; + } + + /** + * A container for additional, undeclared properties. This is a holder for any undeclared + * properties as specified with the 'additionalProperties' keyword in the OAS document. + */ + private Map additionalProperties; + + /** + * Set the additional (undeclared) property with the specified name and value. If the property + * does not already exist, create it otherwise replace it. + * + * @param key The arbitrary key to set + * @param value The associated value + * @return FeatureFlagAttributesStalenessDetails + */ + @JsonAnySetter + public FeatureFlagAttributesStalenessDetails putAdditionalProperty(String key, Object value) { + if (this.additionalProperties == null) { + this.additionalProperties = new HashMap(); + } + this.additionalProperties.put(key, value); + return this; + } + + /** + * Return the additional (undeclared) property. + * + * @return The additional properties + */ + @JsonAnyGetter + public Map getAdditionalProperties() { + return additionalProperties; + } + + /** + * Return the additional (undeclared) property with the specified name. + * + * @param key The arbitrary key to get + * @return The specific additional property for the given key + */ + public Object getAdditionalProperty(String key) { + if (this.additionalProperties == null) { + return null; + } + return this.additionalProperties.get(key); + } + + /** Return true if this FeatureFlagAttributesStalenessDetails object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + FeatureFlagAttributesStalenessDetails featureFlagAttributesStalenessDetails = + (FeatureFlagAttributesStalenessDetails) o; + return Objects.equals(this.codeReferences, featureFlagAttributesStalenessDetails.codeReferences) + && Objects.equals(this.dismissedBy, featureFlagAttributesStalenessDetails.dismissedBy) + && Objects.equals(this.id, featureFlagAttributesStalenessDetails.id) + && Objects.equals( + this.recommendedActions, featureFlagAttributesStalenessDetails.recommendedActions) + && Objects.equals( + this.skipStateCheckUntil, featureFlagAttributesStalenessDetails.skipStateCheckUntil) + && Objects.equals(this.staleReason, featureFlagAttributesStalenessDetails.staleReason) + && Objects.equals( + this.stalenessStatus, featureFlagAttributesStalenessDetails.stalenessStatus) + && Objects.equals( + this.additionalProperties, featureFlagAttributesStalenessDetails.additionalProperties); + } + + @Override + public int hashCode() { + return Objects.hash( + codeReferences, + dismissedBy, + id, + recommendedActions, + skipStateCheckUntil, + staleReason, + stalenessStatus, + additionalProperties); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class FeatureFlagAttributesStalenessDetails {\n"); + sb.append(" codeReferences: ").append(toIndentedString(codeReferences)).append("\n"); + sb.append(" dismissedBy: ").append(toIndentedString(dismissedBy)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" recommendedActions: ").append(toIndentedString(recommendedActions)).append("\n"); + sb.append(" skipStateCheckUntil: ") + .append(toIndentedString(skipStateCheckUntil)) + .append("\n"); + sb.append(" staleReason: ").append(toIndentedString(staleReason)).append("\n"); + sb.append(" stalenessStatus: ").append(toIndentedString(stalenessStatus)).append("\n"); + sb.append(" additionalProperties: ") + .append(toIndentedString(additionalProperties)) + .append("\n"); + sb.append('}'); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/src/main/java/com/datadog/api/client/v2/model/FeatureFlagEnvironment.java b/src/main/java/com/datadog/api/client/v2/model/FeatureFlagEnvironment.java index 7afa898546a..a3fd245a8bc 100644 --- a/src/main/java/com/datadog/api/client/v2/model/FeatureFlagEnvironment.java +++ b/src/main/java/com/datadog/api/client/v2/model/FeatureFlagEnvironment.java @@ -30,6 +30,7 @@ FeatureFlagEnvironment.JSON_PROPERTY_ENVIRONMENT_NAME, FeatureFlagEnvironment.JSON_PROPERTY_ENVIRONMENT_QUERIES, FeatureFlagEnvironment.JSON_PROPERTY_IS_PRODUCTION, + FeatureFlagEnvironment.JSON_PROPERTY_OBSERVE_FULL_EVALUATION_DATA, FeatureFlagEnvironment.JSON_PROPERTY_OVERRIDE_ALLOCATION_KEY, FeatureFlagEnvironment.JSON_PROPERTY_OVERRIDE_VARIANT_ID, FeatureFlagEnvironment.JSON_PROPERTY_PENDING_SUGGESTION_ID, @@ -62,6 +63,10 @@ public class FeatureFlagEnvironment { public static final String JSON_PROPERTY_IS_PRODUCTION = "is_production"; private Boolean isProduction; + public static final String JSON_PROPERTY_OBSERVE_FULL_EVALUATION_DATA = + "observe_full_evaluation_data"; + private Boolean observeFullEvaluationData; + public static final String JSON_PROPERTY_OVERRIDE_ALLOCATION_KEY = "override_allocation_key"; private String overrideAllocationKey; @@ -275,6 +280,27 @@ public void setIsProduction(Boolean isProduction) { this.isProduction = isProduction; } + public FeatureFlagEnvironment observeFullEvaluationData(Boolean observeFullEvaluationData) { + this.observeFullEvaluationData = observeFullEvaluationData; + return this; + } + + /** + * Indicates whether full evaluation data is observed for this environment. + * + * @return observeFullEvaluationData + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_OBSERVE_FULL_EVALUATION_DATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Boolean getObserveFullEvaluationData() { + return observeFullEvaluationData; + } + + public void setObserveFullEvaluationData(Boolean observeFullEvaluationData) { + this.observeFullEvaluationData = observeFullEvaluationData; + } + public FeatureFlagEnvironment overrideAllocationKey(String overrideAllocationKey) { this.overrideAllocationKey = overrideAllocationKey; return this; @@ -466,6 +492,8 @@ public boolean equals(Object o) { && Objects.equals(this.environmentName, featureFlagEnvironment.environmentName) && Objects.equals(this.environmentQueries, featureFlagEnvironment.environmentQueries) && Objects.equals(this.isProduction, featureFlagEnvironment.isProduction) + && Objects.equals( + this.observeFullEvaluationData, featureFlagEnvironment.observeFullEvaluationData) && Objects.equals(this.overrideAllocationKey, featureFlagEnvironment.overrideAllocationKey) && Objects.equals(this.overrideVariantId, featureFlagEnvironment.overrideVariantId) && Objects.equals(this.pendingSuggestionId, featureFlagEnvironment.pendingSuggestionId) @@ -485,6 +513,7 @@ public int hashCode() { environmentName, environmentQueries, isProduction, + observeFullEvaluationData, overrideAllocationKey, overrideVariantId, pendingSuggestionId, @@ -506,6 +535,9 @@ public String toString() { sb.append(" environmentName: ").append(toIndentedString(environmentName)).append("\n"); sb.append(" environmentQueries: ").append(toIndentedString(environmentQueries)).append("\n"); sb.append(" isProduction: ").append(toIndentedString(isProduction)).append("\n"); + sb.append(" observeFullEvaluationData: ") + .append(toIndentedString(observeFullEvaluationData)) + .append("\n"); sb.append(" overrideAllocationKey: ") .append(toIndentedString(overrideAllocationKey)) .append("\n"); diff --git a/src/main/java/com/datadog/api/client/v2/model/RolloutOptionsRequest.java b/src/main/java/com/datadog/api/client/v2/model/RolloutOptionsRequest.java index b188ddd7ded..a0223fbf307 100644 --- a/src/main/java/com/datadog/api/client/v2/model/RolloutOptionsRequest.java +++ b/src/main/java/com/datadog/api/client/v2/model/RolloutOptionsRequest.java @@ -21,6 +21,7 @@ /** Rollout options request payload. */ @JsonPropertyOrder({ RolloutOptionsRequest.JSON_PROPERTY_AUTOSTART, + RolloutOptionsRequest.JSON_PROPERTY_SCHEDULED_START, RolloutOptionsRequest.JSON_PROPERTY_SELECTION_INTERVAL_MS, RolloutOptionsRequest.JSON_PROPERTY_STRATEGY }) @@ -31,6 +32,9 @@ public class RolloutOptionsRequest { public static final String JSON_PROPERTY_AUTOSTART = "autostart"; private JsonNullable autostart = JsonNullable.undefined(); + public static final String JSON_PROPERTY_SCHEDULED_START = "scheduled_start"; + private String scheduledStart; + public static final String JSON_PROPERTY_SELECTION_INTERVAL_MS = "selection_interval_ms"; private Long selectionIntervalMs; @@ -52,16 +56,20 @@ public RolloutOptionsRequest autostart(Boolean autostart) { } /** - * Whether the schedule should begin automatically. + * Whether the schedule should begin automatically. Deprecated in favor of scheduled_start + * , which takes precedence when both are set. * * @return autostart + * @deprecated */ + @Deprecated @jakarta.annotation.Nullable @JsonIgnore public Boolean getAutostart() { return autostart.orElse(null); } + @Deprecated @JsonProperty(JSON_PROPERTY_AUTOSTART) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) public JsonNullable getAutostart_JsonNullable() { @@ -77,6 +85,39 @@ public void setAutostart(Boolean autostart) { this.autostart = JsonNullable.of(autostart); } + public RolloutOptionsRequest scheduledStart(String scheduledStart) { + this.scheduledStart = scheduledStart; + return this; + } + + /** + * Controls when the schedule starts. Supersedes autostart. One of: + * + *
    + *
  • none: create the schedule without starting it. + *
  • now: start the schedule immediately. + *
  • relative:<duration>: start after a duration (for example + * relative:2h). + *
  • absolute:<RFC3339 timestamp>: start at a specific time (for example + * absolute:2025-06-13T12:00:00Z). + *
+ * + *

An absolute timestamp in the past or present is treated as now. A + * future start time is not supported for allocations linked to a standard experiment. + * + * @return scheduledStart + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_SCHEDULED_START) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getScheduledStart() { + return scheduledStart; + } + + public void setScheduledStart(String scheduledStart) { + this.scheduledStart = scheduledStart; + } + public RolloutOptionsRequest selectionIntervalMs(Long selectionIntervalMs) { this.selectionIntervalMs = selectionIntervalMs; return this; @@ -179,6 +220,7 @@ public boolean equals(Object o) { } RolloutOptionsRequest rolloutOptionsRequest = (RolloutOptionsRequest) o; return Objects.equals(this.autostart, rolloutOptionsRequest.autostart) + && Objects.equals(this.scheduledStart, rolloutOptionsRequest.scheduledStart) && Objects.equals(this.selectionIntervalMs, rolloutOptionsRequest.selectionIntervalMs) && Objects.equals(this.strategy, rolloutOptionsRequest.strategy) && Objects.equals(this.additionalProperties, rolloutOptionsRequest.additionalProperties); @@ -186,7 +228,8 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(autostart, selectionIntervalMs, strategy, additionalProperties); + return Objects.hash( + autostart, scheduledStart, selectionIntervalMs, strategy, additionalProperties); } @Override @@ -194,6 +237,7 @@ public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class RolloutOptionsRequest {\n"); sb.append(" autostart: ").append(toIndentedString(autostart)).append("\n"); + sb.append(" scheduledStart: ").append(toIndentedString(scheduledStart)).append("\n"); sb.append(" selectionIntervalMs: ") .append(toIndentedString(selectionIntervalMs)) .append("\n"); diff --git a/src/test/resources/com/datadog/api/client/v2/api/feature_flags.feature b/src/test/resources/com/datadog/api/client/v2/api/feature_flags.feature index f44699236d8..275ef515b33 100644 --- a/src/test/resources/com/datadog/api/client/v2/api/feature_flags.feature +++ b/src/test/resources/com/datadog/api/client/v2/api/feature_flags.feature @@ -122,7 +122,7 @@ Feature: Feature Flags Given new "CreateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} + And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "scheduled_start": "absolute:2025-06-13T12:00:00Z", "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} When the request is sent Then the response status is 202 Accepted - Approval required for this change @@ -131,7 +131,7 @@ Feature: Feature Flags Given new "CreateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} + And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "scheduled_start": "absolute:2025-06-13T12:00:00Z", "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} When the request is sent Then the response status is 400 Bad Request @@ -140,7 +140,7 @@ Feature: Feature Flags Given new "CreateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} + And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "scheduled_start": "absolute:2025-06-13T12:00:00Z", "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} When the request is sent Then the response status is 409 Conflict @@ -149,7 +149,7 @@ Feature: Feature Flags Given new "CreateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} + And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "scheduled_start": "absolute:2025-06-13T12:00:00Z", "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} When the request is sent Then the response status is 201 Created @@ -158,7 +158,7 @@ Feature: Feature Flags Given new "CreateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} + And body with value {"data": {"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "scheduled_start": "absolute:2025-06-13T12:00:00Z", "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}} When the request is sent Then the response status is 404 Not Found @@ -544,12 +544,24 @@ Feature: Feature Flags When the request is sent Then the response status is 200 OK + @team:DataDog/feature-flags + Scenario: Update targeting rules for a flag in an environment with a scheduled start returns "OK" response + Given there is a valid "feature_flag" in the system + And there is a valid "environment" in the system + And new "UpdateAllocationsForFeatureFlagInEnvironment" request + And request contains "feature_flag_id" parameter from "feature_flag.data.id" + And request contains "environment_id" parameter from "environment.data.id" + And body with value {"data":[{"type":"allocations","attributes":{"key":"scheduled-start-allocation-{{ unique_lower }}","name":"New targeting rule {{ unique }}","targeting_rules":[],"variant_weights":[{"variant_id":"{{ feature_flag.data.attributes.variants[0].id }}","value":100}],"exposure_schedule":{"rollout_options":{"strategy":"UNIFORM_INTERVALS","scheduled_start":"absolute:{{ timeISO('now + 1d') }}","selection_interval_ms":86400000},"rollout_steps":[{"exposure_ratio":0.05,"interval_ms":null,"is_pause_record":false,"grouped_step_index":0},{"exposure_ratio":0.25,"interval_ms":null,"is_pause_record":false,"grouped_step_index":1},{"exposure_ratio":1,"interval_ms":null,"is_pause_record":false,"grouped_step_index":2}]},"guardrail_metrics":[],"type":"CANARY"}}]} + When the request is sent + Then the response status is 200 OK + And the response "data[0].attributes.exposure_schedule.scheduled_start_time" is equal to "{{ timeISO('now + 1d') }}" + @generated @skip @team:DataDog/feature-flags Scenario: Update targeting rules for a flag returns "Accepted - Approval required for this change" response Given new "UpdateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} + And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "scheduled_start": "absolute:2025-06-13T12:00:00Z", "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} When the request is sent Then the response status is 202 Accepted - Approval required for this change @@ -558,7 +570,7 @@ Feature: Feature Flags Given new "UpdateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} + And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "scheduled_start": "absolute:2025-06-13T12:00:00Z", "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} When the request is sent Then the response status is 400 Bad Request @@ -567,7 +579,7 @@ Feature: Feature Flags Given new "UpdateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} + And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "scheduled_start": "absolute:2025-06-13T12:00:00Z", "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} When the request is sent Then the response status is 409 Conflict @@ -576,7 +588,7 @@ Feature: Feature Flags Given new "UpdateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} + And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "scheduled_start": "absolute:2025-06-13T12:00:00Z", "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} When the request is sent Then the response status is 404 Not Found @@ -585,6 +597,6 @@ Feature: Feature Flags Given new "UpdateAllocationsForFeatureFlagInEnvironment" request And request contains "feature_flag_id" parameter from "REPLACE.ME" And request contains "environment_id" parameter from "REPLACE.ME" - And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} + And body with value {"data": [{"attributes": {"experiment_id": "550e8400-e29b-41d4-a716-446655440030", "exposure_schedule": {"absolute_start_time": "2025-06-13T12:00:00Z", "control_variant_id": "550e8400-e29b-41d4-a716-446655440012", "control_variant_key": "control", "id": "550e8400-e29b-41d4-a716-446655440010", "rollout_options": {"autostart": false, "scheduled_start": "absolute:2025-06-13T12:00:00Z", "selection_interval_ms": 3600000, "strategy": "UNIFORM_INTERVALS"}, "rollout_steps": [{"exposure_ratio": 0.5, "grouped_step_index": 1, "id": "550e8400-e29b-41d4-a716-446655440040", "interval_ms": 3600000, "is_pause_record": false}]}, "guardrail_metrics": [{"metric_id": "metric-error-rate", "trigger_action": "PAUSE"}], "id": "550e8400-e29b-41d4-a716-446655440020", "key": "prod-rollout", "name": "Production Rollout", "targeting_rules": [{"conditions": [{"attribute": "user_tier", "operator": "ONE_OF", "saved_filter_id": "550e8400-e29b-41d4-a716-446655440090", "value": ["premium", "enterprise"]}]}], "type": "FEATURE_GATE", "variant_weights": [{"value": 50, "variant_id": "550e8400-e29b-41d4-a716-446655440001", "variant_key": "control"}]}, "type": "allocations"}]} When the request is sent Then the response status is 200 OK diff --git a/src/test/resources/generated-test/test-runner-data/manifest.json b/src/test/resources/generated-test/test-runner-data/manifest.json index 532fe647f8d..2dd5f883fbf 100644 --- a/src/test/resources/generated-test/test-runner-data/manifest.json +++ b/src/test/resources/generated-test/test-runner-data/manifest.json @@ -5523,6 +5523,13 @@ "scenario": "Update targeting rules for a flag in an environment returns \"OK\" response", "version": "v2" }, + { + "feature": "Feature Flags", + "feature_file": "../../com/datadog/api/client/v2/api/feature_flags.feature", + "file": "v2/feature-flags/update-targeting-rules-for-a-flag-in-an-environment-with-a-scheduled-start-returns-ok-response.json", + "scenario": "Update targeting rules for a flag in an environment with a scheduled start returns \"OK\" response", + "version": "v2" + }, { "feature": "Forms", "feature_file": "../../com/datadog/api/client/v2/api/forms.feature", diff --git a/src/test/resources/generated-test/test-runner-data/v2/feature-flags/update-targeting-rules-for-a-flag-in-an-environment-with-a-scheduled-start-returns-ok-response.json b/src/test/resources/generated-test/test-runner-data/v2/feature-flags/update-targeting-rules-for-a-flag-in-an-environment-with-a-scheduled-start-returns-ok-response.json new file mode 100644 index 00000000000..e5719d8c1db --- /dev/null +++ b/src/test/resources/generated-test/test-runner-data/v2/feature-flags/update-targeting-rules-for-a-flag-in-an-environment-with-a-scheduled-start-returns-ok-response.json @@ -0,0 +1,105 @@ +{ + "api": "FeatureFlags", + "expected_status": 200, + "feature": "Feature Flags", + "id": "v2/Feature Flags/Update targeting rules for a flag in an environment with a scheduled start returns \"OK\" response", + "operation_id": "UpdateAllocationsForFeatureFlagInEnvironment", + "request": { + "body": { + "schema": { + "format": null, + "ref": "OverwriteAllocationsRequest", + "type": "object" + }, + "source": "inline", + "value": { + "data": [ + { + "attributes": { + "exposure_schedule": { + "rollout_options": { + "scheduled_start": "absolute:{{ timeISO('now + 1d') }}", + "selection_interval_ms": 86400000, + "strategy": "UNIFORM_INTERVALS" + }, + "rollout_steps": [ + { + "exposure_ratio": 0.05, + "grouped_step_index": 0, + "interval_ms": null, + "is_pause_record": false + }, + { + "exposure_ratio": 0.25, + "grouped_step_index": 1, + "interval_ms": null, + "is_pause_record": false + }, + { + "exposure_ratio": 1, + "grouped_step_index": 2, + "interval_ms": null, + "is_pause_record": false + } + ] + }, + "guardrail_metrics": [], + "key": "scheduled-start-allocation-{{ unique_lower }}", + "name": "New targeting rule {{ unique }}", + "targeting_rules": [], + "type": "CANARY", + "variant_weights": [ + { + "value": 100, + "variant_id": "{{ feature_flag.data.attributes.variants[0].id }}" + } + ] + }, + "type": "allocations" + } + ] + } + }, + "content_type": "application/json", + "method": "PUT", + "pagination": false, + "parameters": [ + { + "explode": null, + "in": "path", + "name": "feature_flag_id", + "required": true, + "schema": { + "format": "uuid", + "ref": null, + "type": "string" + }, + "source": { + "path": "feature_flag.data.id", + "type": "fixture" + }, + "style": null + }, + { + "explode": null, + "in": "path", + "name": "environment_id", + "required": true, + "schema": { + "format": "uuid", + "ref": null, + "type": "string" + }, + "source": { + "path": "environment.data.id", + "type": "fixture" + }, + "style": null + } + ], + "path": "/api/v2/feature-flags/{feature_flag_id}/environments/{environment_id}/allocations" + }, + "scenario": "Update targeting rules for a flag in an environment with a scheduled start returns \"OK\" response", + "schema_version": 1, + "version": "v2" +} diff --git a/src/test/resources/generated-test/test-server b/src/test/resources/generated-test/test-server index 899230cbccd..417fcc086cf 100755 --- a/src/test/resources/generated-test/test-server +++ b/src/test/resources/generated-test/test-server @@ -435,7 +435,8 @@ def _json_contains(actual: Any, expected: Any) -> bool: return all(key in actual and _json_contains(actual[key], value) for key, value in expected.items()) if isinstance(expected, list) and isinstance(actual, list): return len(expected) == len(actual) and all( - _json_contains(actual_item, expected_item) for actual_item, expected_item in zip(actual, expected) + _json_contains(actual_item, expected_item) + for actual_item, expected_item in zip(actual, expected, strict=False) ) return actual == expected @@ -460,7 +461,8 @@ def _slug(value: str) -> str: def _now_iso() -> str: - return datetime.now(timezone.utc).isoformat().replace("+00:00", "Z") + # datetime.UTC is Python 3.11+; this standalone runtime supports Python 3.10. + return datetime.now(timezone.utc).isoformat().replace("+00:00", "Z") # noqa: UP017 def _read_json(path: Path) -> dict[str, Any]: diff --git a/src/test/resources/generated-test/test-server-data/v2/feature-flags.json b/src/test/resources/generated-test/test-server-data/v2/feature-flags.json index df736739e2c..5505716b00b 100644 --- a/src/test/resources/generated-test/test-server-data/v2/feature-flags.json +++ b/src/test/resources/generated-test/test-server-data/v2/feature-flags.json @@ -875,6 +875,206 @@ ], "scenario": "Update targeting rules for a flag in an environment returns \"OK\" response", "version": "v2" + }, + { + "feature": "Feature Flags", + "frozen_at": "2026-08-21T09:33:36.402Z", + "interactions": [ + { + "request": { + "body": { + "type": "json", + "value": { + "data": { + "attributes": { + "description": "Test feature flag for BDD scenarios", + "key": "test-feature-flag-Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816", + "name": "Test Feature Flag Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816", + "value_type": "BOOLEAN", + "variants": [ + { + "key": "variant-Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816-1", + "name": "Variant Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816 A", + "value": "true" + }, + { + "key": "variant-Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816-2", + "name": "Variant Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816 B", + "value": "false" + } + ] + }, + "type": "feature-flags" + } + } + }, + "content_type": "application/json", + "method": "POST", + "path": "/api/v2/feature-flags", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "{\"data\":{\"id\":\"34298df2-b296-4387-8b4c-a03f226d9fe3\",\"type\":\"feature-flags\",\"attributes\":{\"archived_at\":null,\"created_at\":\"2026-08-21T09:33:37.525519Z\",\"created_by\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"description\":\"Test feature flag for BDD scenarios\",\"distribution_channel\":\"ALL\",\"feature_flag_environments\":[{\"environment_id\":\"592600c2-8327-424d-960f-608c327ee96d\",\"environment_name\":\"Test Environment Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774470658\",\"environment_queries\":[\"env-Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774470658\",\"test-Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774470658\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-016f2e8164ed\",\"override_allocation_key\":\"allocation-override-016f2e8164ed\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"809cd83d-51ac-4f60-9ce5-cfad4d662114\",\"environment_name\":\"Test Environment Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774471346\",\"environment_queries\":[\"test-Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774471346\",\"env-Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774471346\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-3523797ecbc1\",\"override_allocation_key\":\"allocation-override-3523797ecbc1\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"21c84268-9fc7-4b6d-82ea-bb2090469aba\",\"environment_name\":\"Test Environment Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774472385\",\"environment_queries\":[\"test-Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774472385\",\"env-Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774472385\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-8e97590a41d4\",\"override_allocation_key\":\"allocation-override-8e97590a41d4\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"0b94dbaa-9efb-419d-8bd7-ef56f3828986\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1773321543\",\"environment_queries\":[\"staging\",\"test\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-5c514079e6df\",\"override_allocation_key\":\"allocation-override-5c514079e6df\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"afdaa512-6307-4965-bf92-62cc6bea5d00\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1773322166\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1773322166\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1773322166\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-f26a6d0cc316\",\"override_allocation_key\":\"allocation-override-f26a6d0cc316\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"04136d44-b58d-445b-b5c9-055f99575766\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1784893502\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1784893502\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1784893502\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-4d975ba6b03f\",\"override_allocation_key\":\"allocation-override-4d975ba6b03f\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"1203bcba-445f-4731-8842-a59d1073914f\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785154419\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785154419\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785154419\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-ad2b33a63f09\",\"override_allocation_key\":\"allocation-override-ad2b33a63f09\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"3e2bf225-677f-49c2-8cab-d16c0f1b0d5f\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785239524\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785239524\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785239524\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-09865f48d375\",\"override_allocation_key\":\"allocation-override-09865f48d375\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"5e00d2e3-2b06-4e60-a7ae-8c1a684a1fc5\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785326063\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785326063\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785326063\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-828e65213b6a\",\"override_allocation_key\":\"allocation-override-828e65213b6a\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"895d6669-f281-40ca-905f-95764b063997\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785412365\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785412365\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785412365\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-ecd7754fe698\",\"override_allocation_key\":\"allocation-override-ecd7754fe698\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"7477eea0-4499-452d-ad94-1e6188b8c5bc\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785498929\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785498929\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785498929\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-1a84abb376e1\",\"override_allocation_key\":\"allocation-override-1a84abb376e1\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"ecfbcdb4-306b-4adb-8438-03f3afaff0c9\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785759287\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785759287\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785759287\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-b023a58b6338\",\"override_allocation_key\":\"allocation-override-b023a58b6338\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"414342a5-9711-4cf2-b55e-9c573c669795\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785844421\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785844421\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785844421\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-9b6554dc1ebc\",\"override_allocation_key\":\"allocation-override-9b6554dc1ebc\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"1b7521fe-8131-46e2-b56c-e089d0b7270c\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785930926\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785930926\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785930926\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-627fd7ea6d04\",\"override_allocation_key\":\"allocation-override-627fd7ea6d04\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"230474f1-a11d-48b2-ba97-db27be150ae3\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1786017494\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1786017494\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1786017494\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-3b7f30ebbfa5\",\"override_allocation_key\":\"allocation-override-3b7f30ebbfa5\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"30dbdd46-0371-4d6f-9f0e-560900b80df9\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1786102241\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1786102241\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1786102241\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-b229e1b3d400\",\"override_allocation_key\":\"allocation-override-b229e1b3d400\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"838b7cae-0e39-4a49-a039-6192291e1180\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1786361780\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1786361780\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1786361780\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-3966d67a3ba1\",\"override_allocation_key\":\"allocation-override-3966d67a3ba1\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"4c533740-cb36-430b-8d53-afaefe2d3dc4\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1786447770\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1786447770\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1786447770\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-126709fceb62\",\"override_allocation_key\":\"allocation-override-126709fceb62\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"7aa8e8ee-921a-4f6c-aa22-81456ab65dcd\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1786534331\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1786534331\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1786534331\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-9ef8f7a24220\",\"override_allocation_key\":\"allocation-override-9ef8f7a24220\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"71abb17f-4f33-4fe7-9f78-5b8226fe3a50\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1786620629\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1786620629\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1786620629\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-9b58b33dded1\",\"override_allocation_key\":\"allocation-override-9b58b33dded1\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"bd2c54fd-df03-4601-bd6f-feb8ca885a68\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1786965433\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1786965433\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1786965433\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-b63fe2ca346f\",\"override_allocation_key\":\"allocation-override-b63fe2ca346f\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"16ad7487-026d-4296-8146-7732b292c39b\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1787051827\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1787051827\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1787051827\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-aa44d7066142\",\"override_allocation_key\":\"allocation-override-aa44d7066142\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"aac3bbe2-c293-459c-984f-b300c1ab6b9b\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1787138438\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1787138438\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1787138438\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-b4e5798a7f7d\",\"override_allocation_key\":\"allocation-override-b4e5798a7f7d\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"4e6acc4e-8d16-4370-88ae-6949e4504c76\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1787224738\",\"environment_queries\":[\"env-Test-Typescript-Create_an_environment_returns_Created_response-1787224738\",\"test-Test-Typescript-Create_an_environment_returns_Created_response-1787224738\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-1c09ebd79290\",\"override_allocation_key\":\"allocation-override-1c09ebd79290\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null}],\"is_favorite\":false,\"key\":\"test-feature-flag-Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816\",\"last_updated_by\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"Test Feature Flag Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816\",\"require_approval\":false,\"staleness_details\":{\"id\":\"34298df2-b296-4387-8b4c-a03f226d9fe3\",\"staleness_status\":\"ACTIVE\",\"stale_reason\":null,\"recommended_actions\":null,\"code_references\":null,\"skip_state_check_until\":null,\"dismissed_by\":null},\"staleness_status\":\"ACTIVE\",\"tags\":[],\"updated_at\":\"2026-08-21T09:33:37.525519Z\",\"value_type\":\"BOOLEAN\",\"variants\":[{\"id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"key\":\"variant-Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816-1\",\"name\":\"Variant Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816 A\",\"value\":\"true\",\"created_at\":\"2026-08-21T09:33:37.538822Z\",\"updated_at\":\"2026-08-21T09:33:37.538822Z\"},{\"id\":\"7f034548-5b18-490d-8253-5511355038cd\",\"key\":\"variant-Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816-2\",\"name\":\"Variant Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816 B\",\"value\":\"false\",\"created_at\":\"2026-08-21T09:33:37.542874Z\",\"updated_at\":\"2026-08-21T09:33:37.542874Z\"}]}}}" + }, + "headers": { + "content-type": "application/vnd.api+json" + }, + "reason": "Created", + "status": 201 + } + }, + { + "request": { + "body": { + "type": "json", + "value": { + "data": { + "attributes": { + "name": "Test Environment Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816", + "queries": [ + "test-Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816", + "env-Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816" + ] + }, + "type": "environments" + } + } + }, + "content_type": "application/json", + "method": "POST", + "path": "/api/v2/feature-flags/environments", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "{\"data\":{\"id\":\"9f093081-1ce1-4395-b77d-c49037862455\",\"type\":\"environments\",\"attributes\":{\"is_production\":false,\"name\":\"Test Environment Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816\",\"observe_full_evaluation_data\":false,\"queries\":[\"test-Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816\",\"env-Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816\"],\"require_feature_flag_approval\":false}}}" + }, + "headers": { + "content-type": "application/vnd.api+json" + }, + "reason": "Created", + "status": 201 + } + }, + { + "request": { + "body": { + "type": "json", + "value": { + "data": [ + { + "attributes": { + "exposure_schedule": { + "rollout_options": { + "scheduled_start": "absolute:2026-08-22T09:33:36.402Z", + "selection_interval_ms": 86400000, + "strategy": "UNIFORM_INTERVALS" + }, + "rollout_steps": [ + { + "exposure_ratio": 0.05, + "grouped_step_index": 0, + "interval_ms": null, + "is_pause_record": false + }, + { + "exposure_ratio": 0.25, + "grouped_step_index": 1, + "interval_ms": null, + "is_pause_record": false + }, + { + "exposure_ratio": 1, + "grouped_step_index": 2, + "interval_ms": null, + "is_pause_record": false + } + ] + }, + "guardrail_metrics": [], + "key": "scheduled-start-allocation-test-update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_ok_response-1787304816", + "name": "New targeting rule Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816", + "targeting_rules": [], + "type": "CANARY", + "variant_weights": [ + { + "value": 100, + "variant_id": "ecfaf2b6-879b-4411-ba22-78c69f509d5e" + } + ] + }, + "type": "allocations" + } + ] + } + }, + "content_type": "application/json", + "method": "PUT", + "path": "/api/v2/feature-flags/34298df2-b296-4387-8b4c-a03f226d9fe3/environments/9f093081-1ce1-4395-b77d-c49037862455/allocations", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "{\"data\":[{\"id\":\"12e25133-bc91-4942-8e16-44a7214c33de\",\"type\":\"allocations\",\"attributes\":{\"created_at\":\"2026-08-21T09:33:42.991860385Z\",\"environment_ids\":[\"9f093081-1ce1-4395-b77d-c49037862455\"],\"experiment_id\":null,\"exposure_schedule\":{\"id\":\"2d88e9df-e3bc-4407-826a-e24397b46be9\",\"allocation_id\":\"12e25133-bc91-4942-8e16-44a7214c33de\",\"control_variant_id\":null,\"absolute_start_time\":null,\"scheduled_start_time\":\"2026-08-22T09:33:36.402Z\",\"rollout_options\":{\"strategy\":\"UNIFORM_INTERVALS\",\"autostart\":false,\"selection_interval_ms\":86400000},\"rollout_steps\":[{\"id\":\"9cbdc775-d5be-4c63-93d0-679ae5556772\",\"allocation_exposure_schedule_id\":\"2d88e9df-e3bc-4407-826a-e24397b46be9\",\"order_position\":0,\"exposure_ratio\":0.05,\"interval_ms\":86400000,\"is_pause_record\":false,\"grouped_step_index\":0,\"created_at\":\"2026-08-21T09:33:43.001603Z\",\"updated_at\":\"2026-08-21T09:33:43.001603Z\"},{\"id\":\"b307f8ad-47fd-479a-aaba-a1551235a4e5\",\"allocation_exposure_schedule_id\":\"2d88e9df-e3bc-4407-826a-e24397b46be9\",\"order_position\":1,\"exposure_ratio\":0.25,\"interval_ms\":86400000,\"is_pause_record\":false,\"grouped_step_index\":1,\"created_at\":\"2026-08-21T09:33:43.001603Z\",\"updated_at\":\"2026-08-21T09:33:43.001603Z\"},{\"id\":\"2c511c93-5a7e-49be-a652-82e3d0cf45d5\",\"allocation_exposure_schedule_id\":\"2d88e9df-e3bc-4407-826a-e24397b46be9\",\"order_position\":2,\"exposure_ratio\":1,\"interval_ms\":null,\"is_pause_record\":false,\"grouped_step_index\":2,\"created_at\":\"2026-08-21T09:33:43.001603Z\",\"updated_at\":\"2026-08-21T09:33:43.001603Z\"}],\"guardrail_triggers\":[],\"guardrail_triggered_action\":null,\"created_at\":\"2026-08-21T09:33:42.998105Z\",\"updated_at\":\"2026-08-21T09:33:42.998105Z\"},\"guardrail_metrics\":[],\"key\":\"scheduled-start-allocation-test-update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_ok_response-1787304816\",\"name\":\"New targeting rule Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816\",\"order_position\":0,\"targeting_rules\":[],\"type\":\"CANARY\",\"updated_at\":\"2026-08-21T09:33:42.991860385Z\",\"variant_weights\":[{\"id\":\"3e78a93e-d901-4882-9f94-1682170c4769\",\"created_at\":\"2026-08-21T09:33:43.03525Z\",\"updated_at\":\"2026-08-21T09:33:43.03525Z\",\"value\":100,\"variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"variant\":{\"id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"key\":\"variant-Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816-1\",\"name\":\"Variant Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816 A\",\"value\":\"true\",\"created_at\":\"2026-08-21T09:33:37.538822Z\",\"updated_at\":\"2026-08-21T09:33:37.538822Z\"}}]}}]}" + }, + "headers": { + "content-type": "application/vnd.api+json" + }, + "reason": "OK", + "status": 200 + } + }, + { + "request": { + "body": { + "type": "empty", + "value": null + }, + "content_type": "", + "method": "DELETE", + "path": "/api/v2/feature-flags/environments/9f093081-1ce1-4395-b77d-c49037862455", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "" + }, + "headers": {}, + "reason": "No Content", + "status": 204 + } + }, + { + "request": { + "body": { + "type": "empty", + "value": null + }, + "content_type": "", + "method": "POST", + "path": "/api/v2/feature-flags/34298df2-b296-4387-8b4c-a03f226d9fe3/archive", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "{\"data\":{\"id\":\"34298df2-b296-4387-8b4c-a03f226d9fe3\",\"type\":\"feature-flags\",\"attributes\":{\"archived_at\":\"2026-08-21T09:33:43.534426Z\",\"created_at\":\"2026-08-21T09:33:37.525519Z\",\"created_by\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"description\":\"Test feature flag for BDD scenarios\",\"distribution_channel\":\"ALL\",\"feature_flag_environments\":[{\"environment_id\":\"592600c2-8327-424d-960f-608c327ee96d\",\"environment_name\":\"Test Environment Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774470658\",\"environment_queries\":[\"env-Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774470658\",\"test-Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774470658\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-016f2e8164ed\",\"override_allocation_key\":\"allocation-override-016f2e8164ed\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"809cd83d-51ac-4f60-9ce5-cfad4d662114\",\"environment_name\":\"Test Environment Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774471346\",\"environment_queries\":[\"test-Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774471346\",\"env-Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774471346\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-3523797ecbc1\",\"override_allocation_key\":\"allocation-override-3523797ecbc1\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"21c84268-9fc7-4b6d-82ea-bb2090469aba\",\"environment_name\":\"Test Environment Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774472385\",\"environment_queries\":[\"test-Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774472385\",\"env-Test-Typescript-Create_allocation_for_a_flag_in_an_environment_returns_Created_response-1774472385\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-8e97590a41d4\",\"override_allocation_key\":\"allocation-override-8e97590a41d4\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"0b94dbaa-9efb-419d-8bd7-ef56f3828986\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1773321543\",\"environment_queries\":[\"staging\",\"test\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-5c514079e6df\",\"override_allocation_key\":\"allocation-override-5c514079e6df\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"afdaa512-6307-4965-bf92-62cc6bea5d00\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1773322166\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1773322166\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1773322166\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-f26a6d0cc316\",\"override_allocation_key\":\"allocation-override-f26a6d0cc316\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"04136d44-b58d-445b-b5c9-055f99575766\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1784893502\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1784893502\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1784893502\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-4d975ba6b03f\",\"override_allocation_key\":\"allocation-override-4d975ba6b03f\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"1203bcba-445f-4731-8842-a59d1073914f\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785154419\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785154419\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785154419\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-ad2b33a63f09\",\"override_allocation_key\":\"allocation-override-ad2b33a63f09\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"3e2bf225-677f-49c2-8cab-d16c0f1b0d5f\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785239524\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785239524\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785239524\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-09865f48d375\",\"override_allocation_key\":\"allocation-override-09865f48d375\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"5e00d2e3-2b06-4e60-a7ae-8c1a684a1fc5\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785326063\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785326063\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785326063\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-828e65213b6a\",\"override_allocation_key\":\"allocation-override-828e65213b6a\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"895d6669-f281-40ca-905f-95764b063997\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785412365\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785412365\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785412365\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-ecd7754fe698\",\"override_allocation_key\":\"allocation-override-ecd7754fe698\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"7477eea0-4499-452d-ad94-1e6188b8c5bc\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785498929\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785498929\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785498929\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-1a84abb376e1\",\"override_allocation_key\":\"allocation-override-1a84abb376e1\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"ecfbcdb4-306b-4adb-8438-03f3afaff0c9\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785759287\",\"environment_queries\":[\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785759287\",\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785759287\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-b023a58b6338\",\"override_allocation_key\":\"allocation-override-b023a58b6338\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"414342a5-9711-4cf2-b55e-9c573c669795\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785844421\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785844421\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785844421\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-9b6554dc1ebc\",\"override_allocation_key\":\"allocation-override-9b6554dc1ebc\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"1b7521fe-8131-46e2-b56c-e089d0b7270c\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1785930926\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1785930926\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1785930926\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-627fd7ea6d04\",\"override_allocation_key\":\"allocation-override-627fd7ea6d04\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"230474f1-a11d-48b2-ba97-db27be150ae3\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1786017494\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1786017494\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1786017494\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-3b7f30ebbfa5\",\"override_allocation_key\":\"allocation-override-3b7f30ebbfa5\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"30dbdd46-0371-4d6f-9f0e-560900b80df9\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1786102241\",\"environment_queries\":[\"env-Test-Typescript-Create_an_environment_returns_Created_response-1786102241\",\"test-Test-Typescript-Create_an_environment_returns_Created_response-1786102241\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-b229e1b3d400\",\"override_allocation_key\":\"allocation-override-b229e1b3d400\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"838b7cae-0e39-4a49-a039-6192291e1180\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1786361780\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1786361780\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1786361780\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-3966d67a3ba1\",\"override_allocation_key\":\"allocation-override-3966d67a3ba1\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"4c533740-cb36-430b-8d53-afaefe2d3dc4\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1786447770\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1786447770\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1786447770\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-126709fceb62\",\"override_allocation_key\":\"allocation-override-126709fceb62\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"7aa8e8ee-921a-4f6c-aa22-81456ab65dcd\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1786534331\",\"environment_queries\":[\"env-Test-Typescript-Create_an_environment_returns_Created_response-1786534331\",\"test-Test-Typescript-Create_an_environment_returns_Created_response-1786534331\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-9ef8f7a24220\",\"override_allocation_key\":\"allocation-override-9ef8f7a24220\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"71abb17f-4f33-4fe7-9f78-5b8226fe3a50\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1786620629\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1786620629\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1786620629\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-9b58b33dded1\",\"override_allocation_key\":\"allocation-override-9b58b33dded1\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"bd2c54fd-df03-4601-bd6f-feb8ca885a68\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1786965433\",\"environment_queries\":[\"env-Test-Typescript-Create_an_environment_returns_Created_response-1786965433\",\"test-Test-Typescript-Create_an_environment_returns_Created_response-1786965433\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-b63fe2ca346f\",\"override_allocation_key\":\"allocation-override-b63fe2ca346f\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"16ad7487-026d-4296-8146-7732b292c39b\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1787051827\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1787051827\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1787051827\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-aa44d7066142\",\"override_allocation_key\":\"allocation-override-aa44d7066142\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"aac3bbe2-c293-459c-984f-b300c1ab6b9b\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1787138438\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1787138438\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1787138438\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-b4e5798a7f7d\",\"override_allocation_key\":\"allocation-override-b4e5798a7f7d\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null},{\"environment_id\":\"4e6acc4e-8d16-4370-88ae-6949e4504c76\",\"environment_name\":\"Test Environment Test-Typescript-Create_an_environment_returns_Created_response-1787224738\",\"environment_queries\":[\"test-Test-Typescript-Create_an_environment_returns_Created_response-1787224738\",\"env-Test-Typescript-Create_an_environment_returns_Created_response-1787224738\"],\"status\":\"DISABLED\",\"default_variant_id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"override_variant_id\":null,\"default_allocation_key\":\"allocation-default-1c09ebd79290\",\"override_allocation_key\":\"allocation-override-1c09ebd79290\",\"allocations\":null,\"is_production\":false,\"require_feature_flag_approval\":false,\"observe_full_evaluation_data\":false,\"pending_suggestion_id\":null}],\"is_favorite\":false,\"key\":\"test-feature-flag-Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816\",\"last_updated_by\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"Test Feature Flag Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816\",\"require_approval\":false,\"staleness_details\":{\"id\":\"34298df2-b296-4387-8b4c-a03f226d9fe3\",\"staleness_status\":\"ACTIVE\",\"stale_reason\":null,\"recommended_actions\":null,\"code_references\":[],\"skip_state_check_until\":null,\"dismissed_by\":null},\"staleness_status\":\"ACTIVE\",\"tags\":[],\"updated_at\":\"2026-08-21T09:33:43.534426Z\",\"value_type\":\"BOOLEAN\",\"variants\":[{\"id\":\"ecfaf2b6-879b-4411-ba22-78c69f509d5e\",\"key\":\"variant-Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816-1\",\"name\":\"Variant Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816 A\",\"value\":\"true\",\"created_at\":\"2026-08-21T09:33:37.538822Z\",\"updated_at\":\"2026-08-21T09:33:37.538822Z\"},{\"id\":\"7f034548-5b18-490d-8253-5511355038cd\",\"key\":\"variant-Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816-2\",\"name\":\"Variant Test-Update_targeting_rules_for_a_flag_in_an_environment_with_a_scheduled_start_returns_OK_response-1787304816 B\",\"value\":\"false\",\"created_at\":\"2026-08-21T09:33:37.542874Z\",\"updated_at\":\"2026-08-21T09:33:37.542874Z\"}]}}}" + }, + "headers": { + "content-type": "application/vnd.api+json" + }, + "reason": "OK", + "status": 200 + } + } + ], + "scenario": "Update targeting rules for a flag in an environment with a scheduled start returns \"OK\" response", + "version": "v2" } ], "schema_version": 1,