diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 96018843d0..f1e49231d3 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.py b/examples/v2/feature-flags/CreateAllocationsForFeatureFlagInEnvironment.py index 69dedef511..9ef57ba494 100644 --- a/examples/v2/feature-flags/CreateAllocationsForFeatureFlagInEnvironment.py +++ b/examples/v2/feature-flags/CreateAllocationsForFeatureFlagInEnvironment.py @@ -34,6 +34,7 @@ id=UUID("550e8400-e29b-41d4-a716-446655440010"), rollout_options=RolloutOptionsRequest( autostart=False, + scheduled_start="absolute:2025-06-13T12:00:00Z", selection_interval_ms=3600000, strategy=RolloutStrategy.UNIFORM_INTERVALS, ), diff --git a/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment.py b/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment.py index da2ef3b7f2..703e181f57 100644 --- a/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment.py +++ b/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment.py @@ -35,6 +35,7 @@ id=UUID("550e8400-e29b-41d4-a716-446655440010"), rollout_options=RolloutOptionsRequest( autostart=False, + scheduled_start="absolute:2025-06-13T12:00:00Z", selection_interval_ms=3600000, strategy=RolloutStrategy.UNIFORM_INTERVALS, ), diff --git a/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment_2978423597.py b/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment_2978423597.py new file mode 100644 index 0000000000..d85f2afc90 --- /dev/null +++ b/examples/v2/feature-flags/UpdateAllocationsForFeatureFlagInEnvironment_2978423597.py @@ -0,0 +1,81 @@ +""" +Update targeting rules for a flag in an environment with a scheduled start returns "OK" response +""" + +from os import environ +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.feature_flags_api import FeatureFlagsApi +from datadog_api_client.v2.model.allocation_data_request import AllocationDataRequest +from datadog_api_client.v2.model.allocation_data_type import AllocationDataType +from datadog_api_client.v2.model.allocation_type import AllocationType +from datadog_api_client.v2.model.exposure_rollout_step_request import ExposureRolloutStepRequest +from datadog_api_client.v2.model.exposure_schedule_request import ExposureScheduleRequest +from datadog_api_client.v2.model.overwrite_allocations_request import OverwriteAllocationsRequest +from datadog_api_client.v2.model.rollout_options_request import RolloutOptionsRequest +from datadog_api_client.v2.model.rollout_strategy import RolloutStrategy +from datadog_api_client.v2.model.upsert_allocation_request import UpsertAllocationRequest +from datadog_api_client.v2.model.variant_weight_request import VariantWeightRequest + +# there is a valid "feature_flag" in the system +FEATURE_FLAG_DATA_ATTRIBUTES_VARIANTS_0_ID = environ["FEATURE_FLAG_DATA_ATTRIBUTES_VARIANTS_0_ID"] +FEATURE_FLAG_DATA_ID = environ["FEATURE_FLAG_DATA_ID"] + +# there is a valid "environment" in the system +ENVIRONMENT_DATA_ID = environ["ENVIRONMENT_DATA_ID"] + +body = OverwriteAllocationsRequest( + data=[ + AllocationDataRequest( + type=AllocationDataType.ALLOCATIONS, + attributes=UpsertAllocationRequest( + key="scheduled-start-allocation-example-feature-flag", + name="New targeting rule Example-Feature-Flag", + targeting_rules=[], + variant_weights=[ + VariantWeightRequest( + variant_id=FEATURE_FLAG_DATA_ATTRIBUTES_VARIANTS_0_ID, + value=100.0, + ), + ], + exposure_schedule=ExposureScheduleRequest( + rollout_options=RolloutOptionsRequest( + strategy=RolloutStrategy.UNIFORM_INTERVALS, + scheduled_start="absolute:2021-11-12T11:11:11+00:00", + selection_interval_ms=86400000, + ), + rollout_steps=[ + ExposureRolloutStepRequest( + exposure_ratio=0.05, + interval_ms=None, + is_pause_record=False, + grouped_step_index=0, + ), + ExposureRolloutStepRequest( + exposure_ratio=0.25, + interval_ms=None, + is_pause_record=False, + grouped_step_index=1, + ), + ExposureRolloutStepRequest( + exposure_ratio=1.0, + interval_ms=None, + is_pause_record=False, + grouped_step_index=2, + ), + ], + ), + guardrail_metrics=[], + type=AllocationType.CANARY, + ), + ), + ], +) + +configuration = Configuration() +with ApiClient(configuration) as api_client: + api_instance = FeatureFlagsApi(api_client) + response = api_instance.update_allocations_for_feature_flag_in_environment( + feature_flag_id=FEATURE_FLAG_DATA_ID, environment_id=ENVIRONMENT_DATA_ID, body=body + ) + + print(response) diff --git a/src/datadog_api_client/v2/model/allocation_exposure_schedule.py b/src/datadog_api_client/v2/model/allocation_exposure_schedule.py index 6f63bc2bf3..c6c67855e8 100644 --- a/src/datadog_api_client/v2/model/allocation_exposure_schedule.py +++ b/src/datadog_api_client/v2/model/allocation_exposure_schedule.py @@ -39,6 +39,7 @@ def openapi_types(_): "id": (UUID,), "rollout_options": (RolloutOptions,), "rollout_steps": ([AllocationExposureRolloutStep],), + "scheduled_start_time": (datetime, none_type), "updated_at": (datetime,), } @@ -52,6 +53,7 @@ def openapi_types(_): "id": "id", "rollout_options": "rollout_options", "rollout_steps": "rollout_steps", + "scheduled_start_time": "scheduled_start_time", "updated_at": "updated_at", } @@ -67,6 +69,7 @@ def __init__( control_variant_id: Union[str, none_type, UnsetType] = unset, guardrail_triggered_action: Union[str, none_type, UnsetType] = unset, id: Union[UUID, UnsetType] = unset, + scheduled_start_time: Union[datetime, none_type, UnsetType] = unset, **kwargs, ): """ @@ -99,6 +102,10 @@ def __init__( :param rollout_steps: Ordered progression steps for exposure. :type rollout_steps: [AllocationExposureRolloutStep] + :param scheduled_start_time: The resolved UTC start time computed from ``scheduled_start``. This field is + read-only and cannot be set directly. + :type scheduled_start_time: datetime, none_type, optional + :param updated_at: The timestamp when the schedule was last updated. :type updated_at: datetime """ @@ -110,6 +117,8 @@ def __init__( kwargs["guardrail_triggered_action"] = guardrail_triggered_action if id is not unset: kwargs["id"] = id + if scheduled_start_time is not unset: + kwargs["scheduled_start_time"] = scheduled_start_time super().__init__(kwargs) self_.allocation_id = allocation_id diff --git a/src/datadog_api_client/v2/model/environment_attributes.py b/src/datadog_api_client/v2/model/environment_attributes.py index c4e858b10a..fabb470567 100644 --- a/src/datadog_api_client/v2/model/environment_attributes.py +++ b/src/datadog_api_client/v2/model/environment_attributes.py @@ -30,6 +30,7 @@ def openapi_types(_): "is_production": (bool,), "key": (str,), "name": (str,), + "observe_full_evaluation_data": (bool,), "queries": ([str],), "require_feature_flag_approval": (bool,), "updated_at": (datetime,), @@ -41,6 +42,7 @@ def openapi_types(_): "is_production": "is_production", "key": "key", "name": "name", + "observe_full_evaluation_data": "observe_full_evaluation_data", "queries": "queries", "require_feature_flag_approval": "require_feature_flag_approval", "updated_at": "updated_at", @@ -53,6 +55,7 @@ def __init__( description: Union[str, none_type, UnsetType] = unset, is_production: Union[bool, UnsetType] = unset, key: Union[str, UnsetType] = unset, + observe_full_evaluation_data: Union[bool, UnsetType] = unset, queries: Union[List[str], UnsetType] = unset, require_feature_flag_approval: Union[bool, UnsetType] = unset, updated_at: Union[datetime, UnsetType] = unset, @@ -76,6 +79,9 @@ def __init__( :param name: The name of the environment. :type name: str + :param observe_full_evaluation_data: Indicates whether full evaluation data is observed for this environment. + :type observe_full_evaluation_data: bool, optional + :param queries: List of queries to define the environment scope. :type queries: [str], optional @@ -93,6 +99,8 @@ def __init__( kwargs["is_production"] = is_production if key is not unset: kwargs["key"] = key + if observe_full_evaluation_data is not unset: + kwargs["observe_full_evaluation_data"] = observe_full_evaluation_data if queries is not unset: kwargs["queries"] = queries if require_feature_flag_approval is not unset: diff --git a/src/datadog_api_client/v2/model/feature_flag_attributes.py b/src/datadog_api_client/v2/model/feature_flag_attributes.py index 80596e1db4..4404dfe983 100644 --- a/src/datadog_api_client/v2/model/feature_flag_attributes.py +++ b/src/datadog_api_client/v2/model/feature_flag_attributes.py @@ -18,6 +18,9 @@ if TYPE_CHECKING: from datadog_api_client.v2.model.feature_flag_environment import FeatureFlagEnvironment + from datadog_api_client.v2.model.feature_flag_attributes_staleness_details import ( + FeatureFlagAttributesStalenessDetails, + ) from datadog_api_client.v2.model.value_type import ValueType from datadog_api_client.v2.model.variant import Variant @@ -26,6 +29,9 @@ class FeatureFlagAttributes(ModelNormal): @cached_property def openapi_types(_): from datadog_api_client.v2.model.feature_flag_environment import FeatureFlagEnvironment + from datadog_api_client.v2.model.feature_flag_attributes_staleness_details import ( + FeatureFlagAttributesStalenessDetails, + ) from datadog_api_client.v2.model.value_type import ValueType from datadog_api_client.v2.model.variant import Variant @@ -36,11 +42,13 @@ def openapi_types(_): "description": (str,), "distribution_channel": (str,), "feature_flag_environments": ([FeatureFlagEnvironment],), + "is_favorite": (bool,), "json_schema": (str, none_type), "key": (str,), "last_updated_by": (UUID,), "name": (str,), "require_approval": (bool,), + "staleness_details": (FeatureFlagAttributesStalenessDetails,), "staleness_status": (str,), "tags": ([str],), "updated_at": (datetime,), @@ -55,11 +63,13 @@ def openapi_types(_): "description": "description", "distribution_channel": "distribution_channel", "feature_flag_environments": "feature_flag_environments", + "is_favorite": "is_favorite", "json_schema": "json_schema", "key": "key", "last_updated_by": "last_updated_by", "name": "name", "require_approval": "require_approval", + "staleness_details": "staleness_details", "staleness_status": "staleness_status", "tags": "tags", "updated_at": "updated_at", @@ -79,9 +89,11 @@ def __init__( created_by: Union[UUID, UnsetType] = unset, distribution_channel: Union[str, UnsetType] = unset, feature_flag_environments: Union[List[FeatureFlagEnvironment], UnsetType] = unset, + is_favorite: Union[bool, UnsetType] = unset, json_schema: Union[str, none_type, UnsetType] = unset, last_updated_by: Union[UUID, UnsetType] = unset, require_approval: Union[bool, UnsetType] = unset, + staleness_details: Union[FeatureFlagAttributesStalenessDetails, none_type, UnsetType] = unset, staleness_status: Union[str, UnsetType] = unset, tags: Union[List[str], UnsetType] = unset, updated_at: Union[datetime, UnsetType] = unset, @@ -108,6 +120,9 @@ def __init__( :param feature_flag_environments: Environment-specific settings for the feature flag. :type feature_flag_environments: [FeatureFlagEnvironment], optional + :param is_favorite: Indicates whether the feature flag is marked as a favorite by the current user. + :type is_favorite: bool, optional + :param json_schema: JSON schema for validation when value_type is JSON. :type json_schema: str, none_type, optional @@ -123,6 +138,9 @@ def __init__( :param require_approval: Indicates whether this feature flag requires approval for changes. :type require_approval: bool, optional + :param staleness_details: Details about the feature flag's staleness status. + :type staleness_details: FeatureFlagAttributesStalenessDetails, none_type, optional + :param staleness_status: Indicates the whether a feature flag is stale or not. :type staleness_status: str, optional @@ -148,12 +166,16 @@ def __init__( kwargs["distribution_channel"] = distribution_channel if feature_flag_environments is not unset: kwargs["feature_flag_environments"] = feature_flag_environments + if is_favorite is not unset: + kwargs["is_favorite"] = is_favorite if json_schema is not unset: kwargs["json_schema"] = json_schema if last_updated_by is not unset: kwargs["last_updated_by"] = last_updated_by if require_approval is not unset: kwargs["require_approval"] = require_approval + if staleness_details is not unset: + kwargs["staleness_details"] = staleness_details if staleness_status is not unset: kwargs["staleness_status"] = staleness_status if tags is not unset: diff --git a/src/datadog_api_client/v2/model/feature_flag_attributes_staleness_details.py b/src/datadog_api_client/v2/model/feature_flag_attributes_staleness_details.py new file mode 100644 index 0000000000..3eb9ff614c --- /dev/null +++ b/src/datadog_api_client/v2/model/feature_flag_attributes_staleness_details.py @@ -0,0 +1,130 @@ +# 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. +from __future__ import annotations + +from typing import Any, Dict, List, Union + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, + date, + datetime, + none_type, + unset, + UnsetType, + UUID, +) + + +class FeatureFlagAttributesStalenessDetails(ModelNormal): + _nullable = True + + @cached_property + def openapi_types(_): + return { + "code_references": ( + [ + { + str: ( + bool, + date, + datetime, + dict, + float, + int, + list, + str, + UUID, + none_type, + ) + } + ], + none_type, + ), + "dismissed_by": (UUID, none_type), + "id": (UUID,), + "recommended_actions": ( + [ + { + str: ( + bool, + date, + datetime, + dict, + float, + int, + list, + str, + UUID, + none_type, + ) + } + ], + none_type, + ), + "skip_state_check_until": (datetime, none_type), + "stale_reason": (str, none_type), + "staleness_status": (str,), + } + + attribute_map = { + "code_references": "code_references", + "dismissed_by": "dismissed_by", + "id": "id", + "recommended_actions": "recommended_actions", + "skip_state_check_until": "skip_state_check_until", + "stale_reason": "stale_reason", + "staleness_status": "staleness_status", + } + + def __init__( + self_, + code_references: Union[List[Dict[str, Any]], none_type, UnsetType] = unset, + dismissed_by: Union[UUID, none_type, UnsetType] = unset, + id: Union[UUID, UnsetType] = unset, + recommended_actions: Union[List[Dict[str, Any]], none_type, UnsetType] = unset, + skip_state_check_until: Union[datetime, none_type, UnsetType] = unset, + stale_reason: Union[str, none_type, UnsetType] = unset, + staleness_status: Union[str, UnsetType] = unset, + **kwargs, + ): + """ + Details about the feature flag's staleness status. + + :param code_references: Code references associated with the feature flag. + :type code_references: [{str: (bool, date, datetime, dict, float, int, list, str, UUID, none_type,)}], none_type, optional + + :param dismissed_by: The ID of the user who dismissed the staleness notification. + :type dismissed_by: UUID, none_type, optional + + :param id: The unique identifier of the staleness details record. + :type id: UUID, optional + + :param recommended_actions: Recommended actions to address the feature flag's staleness. + :type recommended_actions: [{str: (bool, date, datetime, dict, float, int, list, str, UUID, none_type,)}], none_type, optional + + :param skip_state_check_until: The timestamp until which staleness checks are skipped. + :type skip_state_check_until: datetime, none_type, optional + + :param stale_reason: The reason the feature flag is considered stale. + :type stale_reason: str, none_type, optional + + :param staleness_status: The staleness status of the feature flag. + :type staleness_status: str, optional + """ + if code_references is not unset: + kwargs["code_references"] = code_references + if dismissed_by is not unset: + kwargs["dismissed_by"] = dismissed_by + if id is not unset: + kwargs["id"] = id + if recommended_actions is not unset: + kwargs["recommended_actions"] = recommended_actions + if skip_state_check_until is not unset: + kwargs["skip_state_check_until"] = skip_state_check_until + if stale_reason is not unset: + kwargs["stale_reason"] = stale_reason + if staleness_status is not unset: + kwargs["staleness_status"] = staleness_status + super().__init__(kwargs) diff --git a/src/datadog_api_client/v2/model/feature_flag_environment.py b/src/datadog_api_client/v2/model/feature_flag_environment.py index bf0dcc6e16..1a454977d8 100644 --- a/src/datadog_api_client/v2/model/feature_flag_environment.py +++ b/src/datadog_api_client/v2/model/feature_flag_environment.py @@ -50,6 +50,7 @@ def openapi_types(_): "environment_name": (str,), "environment_queries": ([str],), "is_production": (bool,), + "observe_full_evaluation_data": (bool,), "override_allocation_key": (str,), "override_variant_id": (str, none_type), "pending_suggestion_id": (str, none_type), @@ -65,6 +66,7 @@ def openapi_types(_): "environment_name": "environment_name", "environment_queries": "environment_queries", "is_production": "is_production", + "observe_full_evaluation_data": "observe_full_evaluation_data", "override_allocation_key": "override_allocation_key", "override_variant_id": "override_variant_id", "pending_suggestion_id": "pending_suggestion_id", @@ -82,6 +84,7 @@ def __init__( environment_name: Union[str, UnsetType] = unset, environment_queries: Union[List[str], UnsetType] = unset, is_production: Union[bool, UnsetType] = unset, + observe_full_evaluation_data: Union[bool, UnsetType] = unset, override_allocation_key: Union[str, UnsetType] = unset, override_variant_id: Union[str, none_type, UnsetType] = unset, pending_suggestion_id: Union[str, none_type, UnsetType] = unset, @@ -112,6 +115,9 @@ def __init__( :param is_production: Indicates whether the environment is production. :type is_production: bool, optional + :param observe_full_evaluation_data: Indicates whether full evaluation data is observed for this environment. + :type observe_full_evaluation_data: bool, optional + :param override_allocation_key: The allocation key used for the override variant. :type override_allocation_key: str, optional @@ -139,6 +145,8 @@ def __init__( kwargs["environment_queries"] = environment_queries if is_production is not unset: kwargs["is_production"] = is_production + if observe_full_evaluation_data is not unset: + kwargs["observe_full_evaluation_data"] = observe_full_evaluation_data if override_allocation_key is not unset: kwargs["override_allocation_key"] = override_allocation_key if override_variant_id is not unset: diff --git a/src/datadog_api_client/v2/model/rollout_options_request.py b/src/datadog_api_client/v2/model/rollout_options_request.py index 407695eb7a..fab6c1a421 100644 --- a/src/datadog_api_client/v2/model/rollout_options_request.py +++ b/src/datadog_api_client/v2/model/rollout_options_request.py @@ -19,18 +19,24 @@ class RolloutOptionsRequest(ModelNormal): + validations = { + "scheduled_start": {}, + } + @cached_property def openapi_types(_): from datadog_api_client.v2.model.rollout_strategy import RolloutStrategy return { "autostart": (bool, none_type), + "scheduled_start": (str,), "selection_interval_ms": (int,), "strategy": (RolloutStrategy,), } attribute_map = { "autostart": "autostart", + "scheduled_start": "scheduled_start", "selection_interval_ms": "selection_interval_ms", "strategy": "strategy", } @@ -39,15 +45,28 @@ def __init__( self_, strategy: RolloutStrategy, autostart: Union[bool, none_type, UnsetType] = unset, + scheduled_start: Union[str, UnsetType] = unset, selection_interval_ms: Union[int, UnsetType] = unset, **kwargs, ): """ Rollout options request payload. - :param autostart: Whether the schedule should begin automatically. + :param autostart: Whether the schedule should begin automatically. Deprecated in favor of + ``scheduled_start`` , which takes precedence when both are set. **Deprecated**. :type autostart: bool, none_type, optional + :param scheduled_start: 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. + :type scheduled_start: str, optional + :param selection_interval_ms: Interval in milliseconds for uniform interval strategies. :type selection_interval_ms: int, optional @@ -56,6 +75,8 @@ def __init__( """ if autostart is not unset: kwargs["autostart"] = autostart + if scheduled_start is not unset: + kwargs["scheduled_start"] = scheduled_start if selection_interval_ms is not unset: kwargs["selection_interval_ms"] = selection_interval_ms super().__init__(kwargs) diff --git a/src/datadog_api_client/v2/models/__init__.py b/src/datadog_api_client/v2/models/__init__.py index ba4fdd992c..338dfee811 100644 --- a/src/datadog_api_client/v2/models/__init__.py +++ b/src/datadog_api_client/v2/models/__init__.py @@ -3115,6 +3115,7 @@ from datadog_api_client.v2.model.fastly_services_response import FastlyServicesResponse from datadog_api_client.v2.model.feature_flag import FeatureFlag from datadog_api_client.v2.model.feature_flag_attributes import FeatureFlagAttributes +from datadog_api_client.v2.model.feature_flag_attributes_staleness_details import FeatureFlagAttributesStalenessDetails from datadog_api_client.v2.model.feature_flag_environment import FeatureFlagEnvironment from datadog_api_client.v2.model.feature_flag_environment_list_item import FeatureFlagEnvironmentListItem from datadog_api_client.v2.model.feature_flag_list_item import FeatureFlagListItem @@ -13571,6 +13572,7 @@ "FastlyServicesResponse", "FeatureFlag", "FeatureFlagAttributes", + "FeatureFlagAttributesStalenessDetails", "FeatureFlagEnvironment", "FeatureFlagEnvironmentListItem", "FeatureFlagListItem", diff --git a/tests/generated-test/test-runner-data/manifest.json b/tests/generated-test/test-runner-data/manifest.json index c71715538f..dc5b86e695 100644 --- a/tests/generated-test/test-runner-data/manifest.json +++ b/tests/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": "../../v2/features/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": "../../v2/features/forms.feature", diff --git a/tests/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/tests/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 0000000000..e5719d8c1d --- /dev/null +++ b/tests/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/tests/generated-test/test-server b/tests/generated-test/test-server index 899230cbcc..417fcc086c 100755 --- a/tests/generated-test/test-server +++ b/tests/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/tests/generated-test/test-server-data/v2/feature-flags.json b/tests/generated-test/test-server-data/v2/feature-flags.json index df736739e2..5505716b00 100644 --- a/tests/generated-test/test-server-data/v2/feature-flags.json +++ b/tests/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, diff --git a/tests/v2/features/feature_flags.feature b/tests/v2/features/feature_flags.feature index f44699236d..275ef515b3 100644 --- a/tests/v2/features/feature_flags.feature +++ b/tests/v2/features/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