Skip to content

feat(ACI): Make ProjectRuleDetailsEndpoint GET method backwards compatible#109387

Open
ceorourke wants to merge 6 commits intomasterfrom
ceorourke/ISWF-2031
Open

feat(ACI): Make ProjectRuleDetailsEndpoint GET method backwards compatible#109387
ceorourke wants to merge 6 commits intomasterfrom
ceorourke/ISWF-2031

Conversation

@ceorourke
Copy link
Member

Make ProjectRuleDetailsEndpoint GET method backwards compatible mostly via a new convert_args method that first attempts to looks up the AlertRuleWorkflow for dual written rules, and if that fails we assume it is a singly written workflow and look it up directly on the Workflow model.

@ceorourke ceorourke requested review from a team as code owners February 25, 2026 22:12
@linear
Copy link

linear bot commented Feb 25, 2026

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Feb 25, 2026
return args, kwargs


class WorkflowEngineRuleEndpoint(RuleEndpoint):
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to make a new class here because RuleEndpoint encompasses ProjectRuleGroupHistoryIndexEndpoint and ProjectRuleStatsIndexEndpoint as well which we don't want to affect.

except AlertRuleWorkflow.DoesNotExist:
# XXX: this means the workflow was single written and has no ARW or related Rule object
try:
workflow_id = get_object_id_from_fake_id(int(rule_id))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We assume we are being passed a "fake id" here because for singly written rules we will not have a rule id, so the rule index endpoint will generate a fake id for a workflow so it can be looked up here.

except Workflow.DoesNotExist:
raise ResourceDoesNotExist

return args, kwargs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Legacy rules return 404 when feature flag enabled

High Severity

When organizations:workflow-engine-rule-serializers is enabled, WorkflowEngineRuleEndpoint.convert_args returns 404 for legacy rules. If AlertRuleWorkflow lookup fails, it only tries Workflow via get_object_id_from_fake_id. When that also fails (e.g. for a legacy Rule id), it raises ResourceDoesNotExist instead of falling back to the legacy Rule lookup, breaking backwards compatibility.

Fix in Cursor Fix in Web

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's intentional

prepare_component_fields=True,
project_slug=project.slug,
)
serialized_rule = serialize(rule, request.user, rule_serializer)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GET uses wrong serializer when legacy Rule returned

High Severity

The GET handler selects the serializer using only the feature flag. If convert_args is fixed to fall back to legacy Rule when both AlertRuleWorkflow and Workflow lookups fail, the handler would pass a Rule to WorkflowEngineRuleSerializer, which expects Workflow objects. That would cause get_attrs and serialize to fail (e.g. KeyError on attrs["rule_id"]). Serializer selection should branch on isinstance(rule, Workflow) so legacy rules use RuleSerializer.

Fix in Cursor Fix in Web

Copy link
Member Author

@ceorourke ceorourke Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If convert_args is fixed to fall back to legacy Rule when both AlertRuleWorkflow and Workflow lookups fail

idk why you'd think that would happen

project_slug=project.slug,
)
serialized_rule = serialize(rule, request.user, rule_serializer)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PUT and DELETE crash when rule is a Workflow

High Severity

When the feature flag is on, convert_args can return a Workflow for dual-written or single-written rules. PUT and DELETE assume rule is a Rule and use rule.data, rule.label, rule.environment_id, rule.owner_team_id, rule.owner_user_id, rule.update(), RuleActivity.objects.create(rule=rule, ...), and rule.get_audit_log_data(). Workflow has .config and .name instead of .data and .label, and RuleActivity expects a Rule. These calls will raise AttributeError or type errors when rule is a Workflow.

Fix in Cursor Fix in Web

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's fine that's why it's behind a flag and we will get to it later.

Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

result[workflow]["rule_id"] = workflow_rule_ids[workflow.id]
result[workflow]["rule_id"] = workflow_rule_ids.get(
workflow.id, get_fake_id_from_object_id(workflow.id)
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IndexError when workflow has no WorkflowDataConditionGroup

Medium Severity

WorkflowEngineRuleSerializer.get_attrs assumes every workflow has at least one WorkflowDataConditionGroup and does workflow.prefetched_wdcgs[0] without checking. A workflow with no WorkflowDataConditionGroup raises IndexError during serialization.

Fix in Cursor Fix in Web

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'll always have one

@ceorourke ceorourke requested a review from a team February 25, 2026 23:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant