Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
13a3fcf
feat(dashboards): Redesign dashboard generation initial prompt step (…
edwardgou-sentry Mar 24, 2026
2a8887f
ref(spans): add tests and small clean up (#111342)
lvthanh03 Mar 24, 2026
ba253c9
ref(workflow engine): Add assert_serializer_parity, use it for API de…
kcons Mar 24, 2026
c7e3b1a
chore(dashboards): clean up dashboard file from code owners baseline …
edwardgou-sentry Mar 24, 2026
5793969
chore(autofix): Rename some things in autofix (#111405)
Zylphrex Mar 24, 2026
e269fd1
chore(csp): allow to iframe `demo.arcade.software` (#111406)
oioki Mar 24, 2026
37e5d12
feat(onboarding): Implement SCM platform & features step (#111160)
jaydgoss Mar 24, 2026
37dd470
ref(nav) update page frame mobile navigation (#111387)
JonasBa Mar 24, 2026
15779fe
chore: Remove graduated feature flag performance-new-trends (#111146)
wedamija Mar 24, 2026
6134239
perf(dashboards): Measure re-render duration on edit dashboard click …
skaasten Mar 24, 2026
16739aa
fix(notifications): Update alert rule URLs to use /issues/alerts/ pre…
JonasBa Mar 24, 2026
1f81759
feat(insights): Navigate to prebuilt dashboards from trace view and s…
DominikB2014 Mar 24, 2026
5dd3be1
fix(dashboards): Use first-appearance order for chart axis assignment…
DominikB2014 Mar 24, 2026
857cfb1
ref: migrate remaining default exports of static constructs to named …
JoshuaKGoldberg Mar 24, 2026
de9846d
ref(cells): Add cell_name support to rpc dataclasses (#111169)
lynnagara Mar 24, 2026
1b5d3e4
ref(tasks): move seer-related tasks to their own folder (#111380)
cvxluo Mar 24, 2026
3974941
fix(insights): Show <0.0001 for very small numeric values instead of …
gggritso Mar 24, 2026
92ffbcf
feat(tracemetrics): Add trace metric bytes DataCategory to stats page…
k-fish Mar 24, 2026
50a660a
feat(dashboards): Adds more description context to artifact schema (#…
edwardgou-sentry Mar 24, 2026
eb889f9
feat(aci): Add issue preview to the metric monitor form (#111420)
malwilley Mar 24, 2026
895ba61
ref(dashboards): Widen GroupBy value type to include number and boole…
DominikB2014 Mar 24, 2026
7590847
feat(performance): Add search support to EAP txn summary sample event…
mjq Mar 24, 2026
578e998
fix(dashboards): Align backend overview queries widget filters with q…
DominikB2014 Mar 24, 2026
790a1da
ref(nav) promote search to primary nav (#111430)
JonasBa Mar 24, 2026
c7dca3e
fix(context engine): Remove the span in the loop (#111428)
Mihir-Mavalankar Mar 24, 2026
9b8fb4c
fix(insights): Link trace table on AI agent dashboard to trace view (…
DominikB2014 Mar 24, 2026
42c67b9
fix(explore): Confidence footer messages should pluralize zero (#111436)
narsaynorath Mar 24, 2026
a531203
feat(cells): locality configuration should specify cell for new orgs …
lynnagara Mar 24, 2026
75ba475
ref(issues): Remove old issue details routes (#111437)
malwilley Mar 24, 2026
aba248a
feat(eslint): expand no-default-exports rule to all static default ex…
JoshuaKGoldberg Mar 24, 2026
9ffc883
ref(nav) separate mobile context (#111416)
JonasBa Mar 24, 2026
9234eb3
fix(workflows): Add single-written workflow engine support to Project…
kcons Mar 24, 2026
b4db717
feat(issues): New stack trace component (#109428)
scttcper Mar 24, 2026
3c7a4e6
chore(tasks) Add taskworker-launchpad topics to Topic enum (#111338)
markstory Mar 24, 2026
fe83e76
feat(utils): Add ContextPropagatingThreadPoolExecutor and S016 lint r…
gricha Mar 24, 2026
4e55c5d
feat(gitlab): add task to upgrade project webhooks (#111388)
iamrajjoshi Mar 24, 2026
13624d0
ref(issues): Remove the remaining old issue details routes (#111447)
malwilley Mar 24, 2026
4045a02
ref(nav) promote seer to topbar (#111457)
JonasBa Mar 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
9 changes: 6 additions & 3 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ tests/sentry/api/endpoints/test_organization_attribute_mappings.py @get
/static/app/gettingStartedDocs/ @getsentry/value-discovery
/static/app/types/project.tsx @getsentry/value-discovery
/static/app/views/onboarding/ @getsentry/value-discovery
/tests/js/fixtures/detectedPlatform.ts @getsentry/value-discovery
/static/app/views/projectInstall/ @getsentry/value-discovery
/src/sentry/onboarding_tasks/ @getsentry/value-discovery
## End of Value Discovery
Expand All @@ -597,6 +598,8 @@ tests/sentry/api/endpoints/test_organization_attribute_mappings.py @get
/tests/sentry/seer/ @getsentry/machine-learning-ai
/src/sentry/seer/fetch_issues/ @getsentry/machine-learning-ai @getsentry/coding-workflows-sentry-backend
/tests/sentry/seer/fetch_issues/ @getsentry/machine-learning-ai @getsentry/coding-workflows-sentry-backend
/src/sentry/tasks/seer/ @getsentry/machine-learning-ai
/tests/sentry/tasks/seer/ @getsentry/machine-learning-ai
## End of ML & AI

## Issues
Expand Down Expand Up @@ -647,7 +650,7 @@ tests/sentry/api/endpoints/test_organization_attribute_mappings.py @get
/src/sentry/tasks/clear_expired_snoozes.py @getsentry/issue-detection-backend
/src/sentry/tasks/codeowners/ @getsentry/issue-detection-backend
/src/sentry/tasks/commit_context.py @getsentry/issue-detection-backend
/src/sentry/tasks/delete_seer_grouping_records.py @getsentry/issue-detection-backend
/src/sentry/tasks/seer/delete_seer_grouping_records.py @getsentry/issue-detection-backend
/src/sentry/tasks/embeddings_grouping/ @getsentry/issue-detection-backend
/src/sentry/tasks/groupowner.py @getsentry/issue-detection-backend
/src/sentry/tasks/merge.py @getsentry/issue-detection-backend
Expand All @@ -658,6 +661,7 @@ tests/sentry/api/endpoints/test_organization_attribute_mappings.py @get
/static/app/components/events/eventTags/ @getsentry/issue-workflow
/static/app/components/events/highlights/ @getsentry/issue-workflow
/static/app/components/issues/ @getsentry/issue-workflow
/static/app/components/stackTrace/ @getsentry/issue-workflow
/static/app/views/issueList/ @getsentry/issue-workflow
/static/app/views/issueList/pages/supergroups.tsx @getsentry/issue-detection-frontend
/static/app/views/issueList/supergroups/ @getsentry/issue-detection-frontend
Expand Down Expand Up @@ -685,14 +689,13 @@ tests/sentry/api/endpoints/test_organization_attribute_mappings.py @get
/tests/sentry/tasks/test_auto_ongoing_issues.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_auto_remove_inbox.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_auto_resolve_issues.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_backfill_seer_grouping_records.py @getsentry/issue-detection-backend
/tests/sentry/tasks/seer/test_delete_seer_grouping_records.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_check_new_issue_threshold_met.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_clear_expired_resolutions.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_clear_expired_rulesnoozes.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_clear_expired_snoozes.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_code_owners.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_commit_context.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_delete_seer_grouping_records.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_groupowner.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_merge.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_post_process.py @getsentry/issue-detection-backend
Expand Down
6 changes: 0 additions & 6 deletions .github/codeowners-coverage-baseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,6 @@ static/app/components/modals/explore/saveQueryModal.spec.tsx
static/app/components/modals/explore/saveQueryModal.tsx
static/app/components/modals/featureTourModal.spec.tsx
static/app/components/modals/featureTourModal.tsx
static/app/components/modals/generateDashboardFromSeerModal.tsx
static/app/components/modals/helpSearchModal.spec.tsx
static/app/components/modals/helpSearchModal.tsx
static/app/components/modals/importDashboardFromFileModal.tsx
Expand Down Expand Up @@ -1071,7 +1070,6 @@ static/app/components/repositories/scmIntegrationTree/useScmTreeFilters.tsx
static/app/components/repositories/scmRepoTreeModal.tsx
static/app/components/repositoryRow.spec.tsx
static/app/components/repositoryRow.tsx
static/app/components/reprocessedBox.tsx
static/app/components/resolutionBox.spec.tsx
static/app/components/resolutionBox.tsx
static/app/components/resourceCard.tsx
Expand Down Expand Up @@ -2524,14 +2522,12 @@ tests/sentry/tasks/test_activity.py
tests/sentry/tasks/test_assemble.py
tests/sentry/tasks/test_auth.py
tests/sentry/tasks/test_auto_enable_codecov.py
tests/sentry/tasks/test_autofix.py
tests/sentry/tasks/test_base.py
tests/sentry/tasks/test_beacon.py
tests/sentry/tasks/test_check_am2_compatibility.py
tests/sentry/tasks/test_check_auth.py
tests/sentry/tasks/test_collect_project_platforms.py
tests/sentry/tasks/test_commits.py
tests/sentry/tasks/test_context_engine_index.py
tests/sentry/tasks/test_delete_pending_groups.py
tests/sentry/tasks/test_digests.py
tests/sentry/tasks/test_email.py
Expand All @@ -2541,8 +2537,6 @@ tests/sentry/tasks/test_organization_contributors.py
tests/sentry/tasks/test_process_buffer.py
tests/sentry/tasks/test_relay.py
tests/sentry/tasks/test_reprocessing2.py
tests/sentry/tasks/test_seer.py
tests/sentry/tasks/test_seer_explorer_index.py
tests/sentry/tasks/test_store.py
tests/sentry/tasks/test_symbolication.py
tests/sentry/tasks/test_update_code_owners_schema.py
Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ dependencies = [
"sentry-arroyo>=2.38.1",
"sentry-conventions>=0.3.0",
"sentry-forked-email-reply-parser>=0.5.12.post1",
"sentry-kafka-schemas>=2.1.26",
"sentry-kafka-schemas>=2.1.27",
"sentry-ophio>=1.1.3",
"sentry-protos>=0.8.7",
"sentry-redis-tools>=0.5.0",
Expand Down Expand Up @@ -676,9 +676,9 @@ module = [
"sentry.tasks.beacon",
"sentry.tasks.codeowners.*",
"sentry.tasks.commit_context",
"sentry.tasks.delete_seer_grouping_records",
"sentry.tasks.on_demand_metrics",
"sentry.tasks.reprocessing2",
"sentry.tasks.seer.delete_seer_grouping_records",
"sentry.tasks.store",
"sentry.tasks.unmerge",
"sentry.taskworker.*",
Expand Down Expand Up @@ -888,8 +888,8 @@ module = [
"tests.sentry.snuba.test_tasks",
"tests.sentry.spans.grouping.*",
"tests.sentry.tasks.integrations.*",
"tests.sentry.tasks.seer.test_delete_seer_grouping_records",
"tests.sentry.tasks.test_code_owners",
"tests.sentry.tasks.test_delete_seer_grouping_records",
"tests.sentry.tasks.test_on_demand_metrics",
"tests.sentry.tempest.*",
"tests.sentry.templatetags.*",
Expand Down
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ sentry =
# All other linting (E, W, F, B, LOG, I) is handled by ruff.
# See [tool.ruff] in pyproject.toml for the main linting configuration.
select = S
# S016 is temporarily disabled until the ThreadPoolExecutor migration is complete.
extend-ignore = S016
per-file-ignores =
# these scripts must have minimal dependencies so opt out of the usual sentry rules
.github/*: S
Expand Down
9 changes: 0 additions & 9 deletions src/sentry/api/endpoints/organization_events_trends_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from rest_framework.response import Response
from snuba_sdk import Column

from sentry import features
from sentry.api.api_publish_status import ApiPublishStatus
from sentry.api.base import cell_silo_endpoint
from sentry.api.bases import NoProjects, OrganizationEventsEndpointBase
Expand Down Expand Up @@ -69,15 +68,7 @@ class OrganizationEventsNewTrendsStatsEndpoint(OrganizationEventsEndpointBase):
}
)

def has_feature(self, organization, request):
return features.has(
"organizations:performance-new-trends", organization, actor=request.user
)

def get(self, request: Request, organization: Organization) -> Response:
if not self.has_feature(organization, request):
return Response(status=404)

viewer_context = SeerViewerContext(organization_id=organization.id, user_id=request.user.id)

try:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def get_plugin_rules_urls(
and action.get("service") == plugin
):
matching_rule_urls.append(
f"{url_prefix}/alerts/rules/{rule.project.slug}/{rule.id}/details/"
f"{url_prefix}/issues/alerts/rules/{rule.project.slug}/{rule.id}/details/"
)
break
return matching_rule_urls
Expand Down
17 changes: 11 additions & 6 deletions src/sentry/conf/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,9 @@ def env(
CSP_FRAME_ANCESTORS = [
"'none'",
]
CSP_FRAME_SRC = [
"demo.arcade.software",
]
CSP_OBJECT_SRC = [
"'none'",
]
Expand Down Expand Up @@ -867,6 +870,7 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
"sentry.integrations.github.tasks.codecov_account_unlink",
"sentry.integrations.github.tasks.link_all_repos",
"sentry.integrations.github.tasks.pr_comment",
"sentry.integrations.gitlab.tasks",
"sentry.integrations.jira.tasks",
"sentry.integrations.opsgenie.tasks",
"sentry.integrations.slack.tasks.find_channel_id_for_alert_rule",
Expand Down Expand Up @@ -922,7 +926,7 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
"sentry.tasks.auto_remove_inbox",
"sentry.tasks.auto_resolve_issues",
"sentry.tasks.auto_source_code_config",
"sentry.tasks.autofix",
"sentry.tasks.seer.autofix",
"sentry.tasks.beacon",
"sentry.tasks.check_am2_compatibility",
"sentry.tasks.clear_expired_resolutions",
Expand All @@ -934,7 +938,7 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
"sentry.tasks.commit_context",
"sentry.tasks.commits",
"sentry.tasks.delete_pending_groups",
"sentry.tasks.delete_seer_grouping_records",
"sentry.tasks.seer.delete_seer_grouping_records",
"sentry.tasks.digests",
"sentry.tasks.email",
"sentry.tasks.files",
Expand All @@ -954,7 +958,7 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
"sentry.tasks.repository",
"sentry.tasks.reprocessing2",
"sentry.tasks.scim.privilege_sync",
"sentry.tasks.seer",
"sentry.tasks.seer.cleanup",
"sentry.tasks.statistical_detectors",
"sentry.tasks.store",
"sentry.tasks.summaries.weekly_reports",
Expand All @@ -972,8 +976,8 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
"sentry.workflow_engine.tasks.delayed_workflows",
"sentry.workflow_engine.tasks.workflows",
"sentry.workflow_engine.tasks.actions",
"sentry.tasks.seer_explorer_index",
"sentry.tasks.context_engine_index",
"sentry.tasks.seer.explorer_index",
"sentry.tasks.seer.context_engine_index",
# Used for tests
"sentry.taskworker.tasks.examples",
)
Expand Down Expand Up @@ -1412,7 +1416,6 @@ def custom_parameter_sort(parameter: dict) -> tuple[str, int]:
# Sentry and internal client configuration

SENTRY_EARLY_FEATURES = {
"organizations:performance-new-trends": "Enable new trends",
"organizations:performance-new-widget-designs": "Enable updated landing page widget designs",
"organizations:profiling-global-suspect-functions": "Enable global suspect functions in profiling",
}
Expand Down Expand Up @@ -2692,6 +2695,8 @@ def custom_parameter_sort(parameter: dict) -> tuple[str, int]:
"taskworker-internal-dlq": "default",
"taskworker-limited": "default",
"taskworker-limited-dlq": "default",
"taskworker-launchpad": "default",
"taskworker-launchpad-dlq": "default",
"taskworker-long": "default",
"taskworker-long-dlq": "default",
"taskworker-products": "default",
Expand Down
1 change: 1 addition & 0 deletions src/sentry/conf/types/cell_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ class LocalityConfig(TypedDict):
name: str
category: str
cells: list[str]
new_org_cell: str
visible: NotRequired[bool]
2 changes: 2 additions & 0 deletions src/sentry/conf/types/kafka_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ class Topic(Enum):
TASKWORKER_INGEST_PROFILING_DLQ = "taskworker-ingest-profiling-dlq"
TASKWORKER_INTERNAL = "taskworker-internal"
TASKWORKER_INTERNAL_DLQ = "taskworker-internal-dlq"
TASKWORKER_LAUNCHPAD = "taskworker-launchpad"
TASKWORKER_LAUNCHPAD_DLQ = "taskworker-launchpad-dlq"
TASKWORKER_LIMITED = "taskworker-limited"
TASKWORKER_LIMITED_DLQ = "taskworker-limited-dlq"
TASKWORKER_LONG = "taskworker-long"
Expand Down
2 changes: 1 addition & 1 deletion src/sentry/core/endpoints/project_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
from sentry.notifications.utils import has_alert_integration
from sentry.relay.datascrubbing import validate_pii_config_update, validate_pii_selectors
from sentry.seer.autofix.constants import AutofixAutomationTuningSettings
from sentry.tasks.delete_seer_grouping_records import call_seer_delete_project_grouping_records
from sentry.tasks.seer.delete_seer_grouping_records import call_seer_delete_project_grouping_records
from sentry.tempest.utils import has_tempest_access

logger = logging.getLogger(__name__)
Expand Down
11 changes: 10 additions & 1 deletion src/sentry/dashboards/models/generate_dashboard_artifact.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ def check_blocklist(cls, v: str) -> str:


class GeneratedWidgetLayout(BaseModel):
"""Layout position and size on a 6-column grid. Widget widths in each row should sum to 6 to fill the grid completely."""

x: int = Field(
default=0,
description=f"Column position (0-{GRID_WIDTH - 1}). x + w must not exceed {GRID_WIDTH}.",
Expand Down Expand Up @@ -115,18 +117,25 @@ def fit_within_grid(cls, w: int, values: dict[str, Any]) -> int:


class GeneratedWidget(BaseModel):
"""A single dashboard widget. Default sizes by display type: big_number 2w x 1h (3 per row), line/area/bar/stacked_area/top_n 3w x 2h (2 per row), table 6w x 2h (full row)."""

title: str = Field(..., max_length=255) # Matches serializer
description: str = Field(
..., max_length=255
) # Length matches serializer, required field for generation
display_type: DisplayType
widget_type: WidgetType
widget_type: WidgetType = Field(
...,
description="Dataset to query. Use 'spans' as the default — it covers most use cases. Use 'error-events' for error-specific data, 'issue' for issue tracking, 'logs' for log data, 'tracemetrics' for trace metrics.",
)
queries: list[GeneratedWidgetQuery]
layout: GeneratedWidgetLayout
limit: int | None = Field(default=None, le=10, ge=1)
interval: Intervals = Field(default="1h")


class GeneratedDashboard(BaseModel):
"""A complete dashboard definition on a 6-column grid. Widget widths per row must sum to 6. This is the sole output artifact."""

title: str = Field(..., max_length=255) # Matches serializer
widgets: list[GeneratedWidget] = Field(..., max_items=Dashboard.MAX_WIDGETS)
4 changes: 3 additions & 1 deletion src/sentry/deletions/defaults/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
from sentry.notifications.models.notificationmessage import NotificationMessage
from sentry.services.eventstore.models import Event
from sentry.snuba.dataset import Dataset
from sentry.tasks.delete_seer_grouping_records import may_schedule_task_to_delete_hashes_from_seer
from sentry.tasks.seer.delete_seer_grouping_records import (
may_schedule_task_to_delete_hashes_from_seer,
)
from sentry.utils import metrics

from ..base import BaseDeletionTask, BaseRelation, ModelDeletionTask, ModelRelation
Expand Down
2 changes: 0 additions & 2 deletions src/sentry/features/temporary.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,6 @@ def register_temporary_features(manager: FeatureManager) -> None:
manager.add("organizations:performance-mep-bannerless-ui", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
# Re-enable histograms for Metrics Enhanced Performance Views
manager.add("organizations:performance-mep-reintroduce-histograms", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
# Enable new trends
manager.add("organizations:performance-new-trends", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
# Enable updated landing page widget designs
manager.add("organizations:performance-new-widget-designs", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
# Enable MongoDB support for the Queries module
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
from typing import Any

from pydantic import root_validator

from sentry.hybridcloud.rpc import RpcModel


Expand All @@ -8,3 +12,14 @@ class RpcOrganizationSlugReservation(RpcModel):
slug: str
region_name: str
reservation_type: int

@root_validator(pre=True)
@classmethod
def _accept_cell_name(cls, values: dict[str, Any]) -> dict[str, Any]:
if "cell_name" in values and "region_name" not in values:
values["region_name"] = values.pop("cell_name")
return values

@property
def cell_name(self) -> str:
return self.region_name
47 changes: 47 additions & 0 deletions src/sentry/incidents/endpoints/bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,53 @@ def convert_args(
return args, kwargs


class WorkflowEngineProjectAlertRuleEndpoint(ProjectAlertRuleEndpoint):
def convert_args(
self, request: Request, alert_rule_id: int, *args: Any, **kwargs: Any
) -> tuple[tuple[Any, ...], dict[str, Any]]:
args, kwargs = super(ProjectAlertRuleEndpoint, self).convert_args(request, *args, **kwargs)
project = kwargs["project"]
validated_alert_rule_id = to_valid_int_id("alert_rule_id", alert_rule_id, raise_404=True)

# Allow orgs that have downgraded plans to delete metric alerts
if request.method != "DELETE" and not features.has(
"organizations:incidents", project.organization, actor=request.user
):
raise ResourceDoesNotExist

if not request.access.has_project_access(project):
raise PermissionDenied

if features.has("organizations:workflow-engine-rule-serializers", project.organization):
try:
ard = AlertRuleDetector.objects.get(
alert_rule_id=validated_alert_rule_id,
detector__project=project,
)
kwargs["alert_rule"] = ard.detector
except AlertRuleDetector.DoesNotExist:
# XXX: this means the detector was single written and has no ARD or related AlertRule object
try:
detector_id = get_object_id_from_fake_id(validated_alert_rule_id)
kwargs["alert_rule"] = Detector.objects.get(
id=detector_id,
project=project,
)
except Detector.DoesNotExist:
raise ResourceDoesNotExist

return args, kwargs

try:
kwargs["alert_rule"] = AlertRule.objects.get(
projects=project, id=validated_alert_rule_id
)
except AlertRule.DoesNotExist:
raise ResourceDoesNotExist

return args, kwargs


class WorkflowEngineOrganizationAlertRuleEndpoint(OrganizationAlertRuleEndpoint):
def convert_args(
self, request: Request, alert_rule_id: int, *args: Any, **kwargs: Any
Expand Down
Loading
Loading