Skip to content
7 changes: 7 additions & 0 deletions api/core/workflows_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class ChangeRequestCommitService:
def __init__(self, change_request: "ChangeRequest") -> None:
self.change_request = change_request

@transaction.atomic
Comment thread
srijantrpth marked this conversation as resolved.
def commit(self, committed_by: "FFAdminUser") -> None:
if not self.change_request.is_approved():
raise ChangeRequestNotApprovedError(
Expand Down Expand Up @@ -130,6 +131,12 @@ def _publish_segments(self) -> None:
logger.warning("missing-live-segment", draft_segment=draft_segment.uuid)
continue

# Prevent overwriting system segments
if getattr(live_segment, "is_system_segment", False):
raise ValueError(
"System segments cannot be overwritten via change request drafts."
)

# Make a revision of the live segment
revision = live_segment.clone(is_revision=True)
logger.info(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1283,3 +1283,44 @@ def test_change_request_commit__v1_segment_override_draft__inherits_mv_hashing_s
# Then the draft carries the superseded override's id as its bucketing salt
draft_feature_state.refresh_from_db()
assert draft_feature_state.mv_hashing_salt == live_override.id


def test_change_request_commit__system_segment_draft__raises_value_error(
segment: Segment,
change_request: ChangeRequest,
admin_user: FFAdminUser,
feature: Feature,
environment: Environment,
) -> None:
# Given
segment.is_system_segment = True
segment.save()

Segment.objects.create(
name="system-segment-draft",
change_request=change_request,
project=segment.project,
version_of=segment,
)

# Add a feature state to test transaction rollback behavior
feature_state = FeatureState.objects.create(
feature=feature,
environment=environment,
change_request=change_request,
version=None,
)
initial_version = feature_state.version

# When / Then
with pytest.raises(
ValueError,
match="System segments cannot be overwritten via change request drafts.",
):
change_request.commit(admin_user)
Comment thread
coderabbitai[bot] marked this conversation as resolved.

# Assert that the transaction rolled back successfully
feature_state.refresh_from_db()
change_request.refresh_from_db()
assert feature_state.version == initial_version
assert change_request.committed_at is None
Loading