diff --git a/src/sentry/grouping/grouptype.py b/src/sentry/grouping/grouptype.py index cfa4b9c1f70f21..d7458e5005eb32 100644 --- a/src/sentry/grouping/grouptype.py +++ b/src/sentry/grouping/grouptype.py @@ -26,6 +26,7 @@ class ErrorGroupType(GroupType): slug = "error" description = "Error" category = GroupCategory.ERROR.value + category_v2 = GroupCategory.ERROR.value default_priority = PriorityLevel.MEDIUM released = True detector_settings = DetectorSettings( diff --git a/src/sentry/incidents/grouptype.py b/src/sentry/incidents/grouptype.py index b0fe3a7ae41536..e58de57cb6a4a9 100644 --- a/src/sentry/incidents/grouptype.py +++ b/src/sentry/incidents/grouptype.py @@ -56,6 +56,7 @@ class MetricAlertFire(GroupType): slug = "metric_alert_fire" description = "Metric alert fired" category = GroupCategory.METRIC_ALERT.value + category_v2 = GroupCategory.PERFORMANCE_REGRESSION.value creation_quota = Quota(3600, 60, 100) default_priority = PriorityLevel.HIGH enable_auto_resolve = False diff --git a/src/sentry/issues/grouptype.py b/src/sentry/issues/grouptype.py index 1222bb06dbdf51..4a79917dbce743 100644 --- a/src/sentry/issues/grouptype.py +++ b/src/sentry/issues/grouptype.py @@ -29,14 +29,41 @@ class GroupCategory(IntEnum): ERROR = 1 + """ + Deprecated + Will be broken out into PERFORMANCE_REGRESSION, PERFORMANCE_BEST_PRACTICE, and RESPONSIVENESS + """ PERFORMANCE = 2 PROFILE = 3 # deprecated, merging with PERFORMANCE + """ + Deprecated + Cron types will move to the OUTAGE category + """ CRON = 4 + """ + Deprecated + Replay types will move to the USER_EXPERIENCE category + """ REPLAY = 5 FEEDBACK = 6 + """ + Deprecated + Uptime types will move to the OUTAGE category + """ UPTIME = 7 + """ + Deprecated + Metric alert types will move to the PERFORMANCE_REGRESSION category + """ METRIC_ALERT = 8 + # New issue categories (under the organizations:issue-taxonomy flag) + OUTAGE = 9 + PERFORMANCE_REGRESSION = 10 + USER_EXPERIENCE = 11 + RESPONSIVENESS = 12 + PERFORMANCE_BEST_PRACTICE = 13 + GROUP_CATEGORIES_CUSTOM_EMAIL = ( GroupCategory.ERROR, @@ -60,6 +87,7 @@ class GroupTypeRegistry: _registry: dict[int, type[GroupType]] = field(default_factory=dict) _slug_lookup: dict[str, type[GroupType]] = field(default_factory=dict) _category_lookup: dict[int, set[int]] = field(default_factory=lambda: defaultdict(set)) + _category_lookup_v2: dict[int, set[int]] = field(default_factory=lambda: defaultdict(set)) def add(self, group_type: type[GroupType]) -> None: if self._registry.get(group_type.type_id): @@ -69,6 +97,7 @@ def add(self, group_type: type[GroupType]) -> None: self._registry[group_type.type_id] = group_type self._slug_lookup[group_type.slug] = group_type self._category_lookup[group_type.category].add(group_type.type_id) + self._category_lookup_v2[group_type.category_v2].add(group_type.type_id) def all(self) -> list[type[GroupType]]: return list(self._registry.values()) @@ -105,6 +134,9 @@ def get_all_group_type_ids(self) -> set[int]: def get_by_category(self, category: int) -> set[int]: return self._category_lookup[category] + def get_by_category_v2(self, category: int) -> set[int]: + return self._category_lookup_v2[category] + def get_by_slug(self, slug: str) -> type[GroupType] | None: if slug not in self._slug_lookup: return None @@ -160,6 +192,9 @@ class GroupType: slug: str description: str category: int + # New issue category mapping (under the organizations:issue-taxonomy flag) + # When GA'd, the original `category` will be removed and this will be renamed to `category`. + category_v2: int noise_config: NoiseConfig | None = None default_priority: int = PriorityLevel.MEDIUM # If True this group type should be released everywhere. If False, fall back to features to @@ -271,6 +306,7 @@ class PerformanceSlowDBQueryGroupType(PerformanceGroupTypeDefaults, GroupType): slug = "performance_slow_db_query" description = "Slow DB Query" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value noise_config = NoiseConfig(ignore_limit=100) default_priority = PriorityLevel.LOW released = True @@ -282,6 +318,7 @@ class PerformanceRenderBlockingAssetSpanGroupType(PerformanceGroupTypeDefaults, slug = "performance_render_blocking_asset_span" description = "Large Render Blocking Asset" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.RESPONSIVENESS.value default_priority = PriorityLevel.LOW released = True use_flagpole_for_all_features = True @@ -293,6 +330,7 @@ class PerformanceNPlusOneGroupType(PerformanceGroupTypeDefaults, GroupType): slug = "performance_n_plus_one_db_queries" description = "N+1 Query" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value default_priority = PriorityLevel.LOW released = True @@ -303,6 +341,7 @@ class PerformanceConsecutiveDBQueriesGroupType(PerformanceGroupTypeDefaults, Gro slug = "performance_consecutive_db_queries" description = "Consecutive DB Queries" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value noise_config = NoiseConfig(ignore_limit=15) default_priority = PriorityLevel.LOW released = True @@ -314,6 +353,7 @@ class PerformanceFileIOMainThreadGroupType(PerformanceGroupTypeDefaults, GroupTy slug = "performance_file_io_main_thread" description = "File IO on Main Thread" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.RESPONSIVENESS.value default_priority = PriorityLevel.LOW released = True @@ -324,6 +364,7 @@ class PerformanceConsecutiveHTTPQueriesGroupType(PerformanceGroupTypeDefaults, G slug = "performance_consecutive_http" description = "Consecutive HTTP" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value noise_config = NoiseConfig(ignore_limit=5) default_priority = PriorityLevel.LOW released = True @@ -335,6 +376,7 @@ class PerformanceNPlusOneAPICallsGroupType(GroupType): slug = "performance_n_plus_one_api_calls" description = "N+1 API Call" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value default_priority = PriorityLevel.LOW released = True @@ -345,6 +387,7 @@ class PerformanceMNPlusOneDBQueriesGroupType(PerformanceGroupTypeDefaults, Group slug = "performance_m_n_plus_one_db_queries" description = "MN+1 Query" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value default_priority = PriorityLevel.LOW released = True @@ -355,6 +398,7 @@ class PerformanceUncompressedAssetsGroupType(PerformanceGroupTypeDefaults, Group slug = "performance_uncompressed_assets" description = "Uncompressed Asset" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value noise_config = NoiseConfig(ignore_limit=100) default_priority = PriorityLevel.LOW released = True @@ -366,6 +410,7 @@ class PerformanceDBMainThreadGroupType(PerformanceGroupTypeDefaults, GroupType): slug = "performance_db_main_thread" description = "DB on Main Thread" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.RESPONSIVENESS.value default_priority = PriorityLevel.LOW released = True @@ -376,6 +421,7 @@ class PerformanceLargeHTTPPayloadGroupType(PerformanceGroupTypeDefaults, GroupTy slug = "performance_large_http_payload" description = "Large HTTP payload" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value default_priority = PriorityLevel.LOW released = True @@ -387,6 +433,7 @@ class PerformanceHTTPOverheadGroupType(PerformanceGroupTypeDefaults, GroupType): description = "HTTP/1.1 Overhead" noise_config = NoiseConfig(ignore_limit=20) category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.RESPONSIVENESS.value default_priority = PriorityLevel.LOW released = True @@ -397,6 +444,7 @@ class PerformanceP95EndpointRegressionGroupType(GroupType): slug = "performance_p95_endpoint_regression" description = "Endpoint Regression" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_REGRESSION.value enable_auto_resolve = False enable_escalation_detection = False default_priority = PriorityLevel.MEDIUM @@ -411,6 +459,7 @@ class PerformanceStreamedSpansGroupTypeExperimental(GroupType): slug = "performance_streamed_spans_exp" description = "Streamed Spans (Experimental)" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value enable_auto_resolve = False enable_escalation_detection = False default_priority = PriorityLevel.LOW @@ -423,6 +472,7 @@ class ProfileFileIOGroupType(GroupType): slug = "profile_file_io_main_thread" description = "File I/O on Main Thread" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.RESPONSIVENESS.value default_priority = PriorityLevel.LOW released = True @@ -433,6 +483,7 @@ class ProfileImageDecodeGroupType(GroupType): slug = "profile_image_decode_main_thread" description = "Image Decoding on Main Thread" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.RESPONSIVENESS.value default_priority = PriorityLevel.LOW released = True @@ -443,6 +494,7 @@ class ProfileJSONDecodeType(GroupType): slug = "profile_json_decode_main_thread" description = "JSON Decoding on Main Thread" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.RESPONSIVENESS.value default_priority = PriorityLevel.LOW released = True @@ -453,6 +505,7 @@ class ProfileRegexType(GroupType): slug = "profile_regex_main_thread" description = "Regex on Main Thread" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.RESPONSIVENESS.value released = True default_priority = PriorityLevel.LOW @@ -463,6 +516,7 @@ class ProfileFrameDropType(GroupType): slug = "profile_frame_drop" description = "Frame Drop" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.RESPONSIVENESS.value noise_config = NoiseConfig(ignore_limit=2000) released = True default_priority = PriorityLevel.LOW @@ -474,6 +528,7 @@ class ProfileFunctionRegressionType(GroupType): slug = "profile_function_regression" description = "Function Regression" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value enable_auto_resolve = False released = True default_priority = PriorityLevel.MEDIUM @@ -486,6 +541,7 @@ class MonitorIncidentType(GroupType): slug = "monitor_check_in_failure" description = "Crons Monitor Failed" category = GroupCategory.CRON.value + category_v2 = GroupCategory.OUTAGE.value released = True creation_quota = Quota(3600, 60, 60_000) # 60,000 per hour, sliding window of 60 seconds default_priority = PriorityLevel.HIGH @@ -515,6 +571,7 @@ class ReplayRageClickType(ReplayGroupTypeDefaults, GroupType): slug = "replay_click_rage" description = "Rage Click Detected" category = GroupCategory.REPLAY.value + category_v2 = GroupCategory.USER_EXPERIENCE.value default_priority = PriorityLevel.MEDIUM notification_config = NotificationConfig() released = True @@ -526,6 +583,7 @@ class ReplayHydrationErrorType(ReplayGroupTypeDefaults, GroupType): slug = "replay_hydration_error" description = "Hydration Error Detected" category = GroupCategory.REPLAY.value + category_v2 = GroupCategory.USER_EXPERIENCE.value default_priority = PriorityLevel.MEDIUM notification_config = NotificationConfig() released = True @@ -537,6 +595,7 @@ class FeedbackGroup(GroupType): slug = "feedback" description = "Feedback" category = GroupCategory.FEEDBACK.value + category_v2 = GroupCategory.FEEDBACK.value creation_quota = Quota(3600, 60, 1000) # 1000 per hour, sliding window of 60 seconds default_priority = PriorityLevel.MEDIUM notification_config = NotificationConfig(context=[]) @@ -552,6 +611,7 @@ class MetricIssuePOC(GroupType): slug = "metric_issue_poc" description = "Metric Issue POC" category = GroupCategory.METRIC_ALERT.value + category_v2 = GroupCategory.PERFORMANCE_REGRESSION.value default_priority = PriorityLevel.HIGH enable_auto_resolve = False enable_escalation_detection = False diff --git a/src/sentry/uptime/grouptype.py b/src/sentry/uptime/grouptype.py index e4206a5304ad85..2d487547447ef4 100644 --- a/src/sentry/uptime/grouptype.py +++ b/src/sentry/uptime/grouptype.py @@ -15,6 +15,7 @@ class UptimeDomainCheckFailure(GroupType): slug = "uptime_domain_failure" description = "Uptime Domain Monitor Failure" category = GroupCategory.UPTIME.value + category_v2 = GroupCategory.OUTAGE.value creation_quota = Quota(3600, 60, 1000) # 1000 per hour, sliding window of 60 seconds default_priority = PriorityLevel.HIGH enable_auto_resolve = False diff --git a/tests/sentry/issues/test_grouptype.py b/tests/sentry/issues/test_grouptype.py index 45b74515e6091d..0c010f219cdb48 100644 --- a/tests/sentry/issues/test_grouptype.py +++ b/tests/sentry/issues/test_grouptype.py @@ -12,6 +12,8 @@ MetricIssuePOC, NoiseConfig, PerformanceGroupTypeDefaults, + PerformanceNPlusOneGroupType, + PerformanceSlowDBQueryGroupType, get_group_type_by_slug, get_group_types_by_category, ) @@ -38,6 +40,7 @@ class TestGroupType(GroupType): slug = "test" description = "Test" category = GroupCategory.ERROR.value + category_v2 = GroupCategory.ERROR.value ignore_limit = 0 @dataclass(frozen=True) @@ -46,6 +49,7 @@ class TestGroupType2(GroupType): slug = "hellboy" description = "Hellboy" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value @dataclass(frozen=True) class TestGroupType3(GroupType): @@ -53,6 +57,7 @@ class TestGroupType3(GroupType): slug = "angelgirl" description = "AngelGirl" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value assert get_group_types_by_category(GroupCategory.PERFORMANCE.value) == {2, 3} assert get_group_types_by_category(GroupCategory.ERROR.value) == {1} @@ -64,6 +69,7 @@ class TestGroupType(GroupType): slug = "test" description = "Test" category = GroupCategory.ERROR.value + category_v2 = GroupCategory.ERROR.value ignore_limit = 0 assert get_group_type_by_slug(TestGroupType.slug) == TestGroupType @@ -76,12 +82,13 @@ class TestGroupType(GroupType): slug = "error" description = "Error" category = 22 + category_v2 = 22 with self.assertRaisesMessage( ValueError, f"Category must be one of {[category.value for category in GroupCategory]} from GroupCategory", ): - TestGroupType(1, "error", "Error", 22) + TestGroupType(1, "error", "Error", 22, 22) def test_default_noise_config(self) -> None: @dataclass(frozen=True) @@ -90,6 +97,7 @@ class TestGroupType(GroupType): slug = "test" description = "Test" category = GroupCategory.ERROR.value + category_v2 = GroupCategory.ERROR.value @dataclass(frozen=True) class TestGroupType2(PerformanceGroupTypeDefaults, GroupType): @@ -97,6 +105,7 @@ class TestGroupType2(PerformanceGroupTypeDefaults, GroupType): slug = "hellboy" description = "Hellboy" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value assert TestGroupType.noise_config is None assert TestGroupType2.noise_config == NoiseConfig() @@ -110,6 +119,7 @@ class TestGroupType(PerformanceGroupTypeDefaults, GroupType): slug = "hellboy" description = "Hellboy" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value noise_config = NoiseConfig(ignore_limit=100, expiry_time=timedelta(hours=12)) assert TestGroupType.noise_config.ignore_limit == 100 @@ -124,6 +134,7 @@ class TestGroupType(PerformanceGroupTypeDefaults, GroupType): slug = "test" description = "Test" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value released = True assert TestGroupType.allow_post_process_group(self.organization) @@ -136,6 +147,7 @@ class TestGroupType(PerformanceGroupTypeDefaults, GroupType): slug = "test" description = "Test" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value released = False assert not TestGroupType.allow_post_process_group(self.organization) @@ -148,6 +160,7 @@ class TestGroupType(PerformanceGroupTypeDefaults, GroupType): slug = "test" description = "Test" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value released = False with self.feature(TestGroupType.build_post_process_group_feature_name()): @@ -170,3 +183,14 @@ def test_get_visible(self) -> None: UptimeDomainCheckFailure, ErrorGroupType, } + + def test_get_by_category_v2(self) -> None: + registry = GroupTypeRegistry() + registry.add(ErrorGroupType) + registry.add(PerformanceSlowDBQueryGroupType) + registry.add(PerformanceNPlusOneGroupType) + assert registry.get_by_category_v2(GroupCategory.ERROR.value) == {ErrorGroupType.type_id} + assert registry.get_by_category_v2(GroupCategory.PERFORMANCE_BEST_PRACTICE.value) == { + PerformanceSlowDBQueryGroupType.type_id, + PerformanceNPlusOneGroupType.type_id, + } diff --git a/tests/sentry/issues/test_ingest.py b/tests/sentry/issues/test_ingest.py index dc0a156c308bea..6559fd43e0cdcf 100644 --- a/tests/sentry/issues/test_ingest.py +++ b/tests/sentry/issues/test_ingest.py @@ -382,6 +382,7 @@ class TestGroupType(GroupType): slug = "test" description = "Test" category = GroupCategory.PROFILE.value + category_v2 = GroupCategory.RESPONSIVENESS.value noise_config = NoiseConfig(ignore_limit=2) event = self.store_event(data={}, project_id=self.project.id) diff --git a/tests/sentry/workflow_engine/endpoints/test_organization_detector_types.py b/tests/sentry/workflow_engine/endpoints/test_organization_detector_types.py index a703ea7f1626b7..c72a20e04d3bde 100644 --- a/tests/sentry/workflow_engine/endpoints/test_organization_detector_types.py +++ b/tests/sentry/workflow_engine/endpoints/test_organization_detector_types.py @@ -43,6 +43,7 @@ class TestMetricGroupType(GroupType): slug = MetricAlertFire.slug description = "Metric alert" category = GroupCategory.METRIC_ALERT.value + category_v2 = GroupCategory.PERFORMANCE_REGRESSION.value detector_settings = DetectorSettings(handler=MockDetectorHandler) released = True @@ -52,6 +53,7 @@ class TestCronsGroupType(GroupType): slug = MonitorIncidentType.slug description = "Crons" category = GroupCategory.CRON.value + category_v2 = GroupCategory.OUTAGE.value detector_settings = DetectorSettings(handler=MockDetectorHandler) released = True @@ -61,6 +63,7 @@ class TestUptimeGroupType(GroupType): slug = UptimeDomainCheckFailure.slug description = "Uptime" category = GroupCategory.UPTIME.value + category_v2 = GroupCategory.OUTAGE.value detector_settings = DetectorSettings(handler=MockDetectorHandler) released = True @@ -71,6 +74,7 @@ class TestPerformanceGroupType(GroupType): slug = PerformanceSlowDBQueryGroupType.slug description = "Performance" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value released = True def tearDown(self): diff --git a/tests/sentry/workflow_engine/endpoints/test_validators.py b/tests/sentry/workflow_engine/endpoints/test_validators.py index c7a623cb62398d..5e2051c22dd769 100644 --- a/tests/sentry/workflow_engine/endpoints/test_validators.py +++ b/tests/sentry/workflow_engine/endpoints/test_validators.py @@ -119,6 +119,7 @@ def test_validate_detector_type_valid(self): slug="test_type", description="no handler", category=GroupCategory.METRIC_ALERT.value, + category_v2=GroupCategory.PERFORMANCE_REGRESSION.value, detector_settings=DetectorSettings(validator=MetricAlertsDetectorValidator), ) validator = self.validator_class() @@ -141,6 +142,7 @@ def test_validate_detector_type_incompatible(self): slug="test_type", description="no handler", category=GroupCategory.METRIC_ALERT.value, + category_v2=GroupCategory.PERFORMANCE_REGRESSION.value, ) validator = self.validator_class() with pytest.raises( diff --git a/tests/sentry/workflow_engine/handlers/detector/test_base.py b/tests/sentry/workflow_engine/handlers/detector/test_base.py index 7005ffd4f1c1f3..d6d51931df927f 100644 --- a/tests/sentry/workflow_engine/handlers/detector/test_base.py +++ b/tests/sentry/workflow_engine/handlers/detector/test_base.py @@ -82,6 +82,7 @@ class NoHandlerGroupType(GroupType): slug = "no_handler" description = "no handler" category = GroupCategory.METRIC_ALERT.value + category_v2 = GroupCategory.METRIC_ALERT.value class MockDetectorHandler(DetectorHandler[dict]): def evaluate( @@ -111,6 +112,7 @@ class HandlerGroupType(GroupType): slug = "handler" description = "handler" category = GroupCategory.METRIC_ALERT.value + category_v2 = GroupCategory.PERFORMANCE_REGRESSION.value detector_settings = DetectorSettings(handler=MockDetectorHandler) class HandlerStateGroupType(GroupType): @@ -118,6 +120,7 @@ class HandlerStateGroupType(GroupType): slug = "handler_with_state" description = "handler with state" category = GroupCategory.METRIC_ALERT.value + category_v2 = GroupCategory.PERFORMANCE_REGRESSION.value detector_settings = DetectorSettings(handler=MockDetectorStateHandler) class HandlerUpdateGroupType(GroupType): @@ -125,6 +128,7 @@ class HandlerUpdateGroupType(GroupType): slug = "handler_update" description = "handler update" category = GroupCategory.METRIC_ALERT.value + category_v2 = GroupCategory.PERFORMANCE_REGRESSION.value detector_settings = DetectorSettings(handler=MockDetectorWithUpdateHandler) self.no_handler_type = NoHandlerGroupType diff --git a/tests/sentry/workflow_engine/models/test_json_config_base.py b/tests/sentry/workflow_engine/models/test_json_config_base.py index bccd77b9513ec3..2bcdecc05a2621 100644 --- a/tests/sentry/workflow_engine/models/test_json_config_base.py +++ b/tests/sentry/workflow_engine/models/test_json_config_base.py @@ -44,6 +44,7 @@ class TestGroupType(GroupType): slug = "test" description = "Test" category = GroupCategory.ERROR.value + category_v2 = GroupCategory.ERROR.value detector_settings = DetectorSettings(config_schema=self.example_schema) @dataclass(frozen=True) @@ -52,6 +53,7 @@ class ExampleGroupType(GroupType): slug = "example" description = "Example" category = GroupCategory.PERFORMANCE.value + category_v2 = GroupCategory.PERFORMANCE_BEST_PRACTICE.value detector_settings = DetectorSettings( config_schema={"type": "object", "additionalProperties": False}, ) @@ -103,6 +105,7 @@ class TestGroupType(GroupType): slug = "test_metric_alert_fire" description = "Metric alert fired" category = GroupCategory.METRIC_ALERT.value + category_v2 = GroupCategory.PERFORMANCE_REGRESSION.value detector_settings = DetectorSettings( config_schema=MetricAlertFire.detector_settings.config_schema, )