diff --git a/src/sentry/preprod/eap/read.py b/src/sentry/preprod/eap/read.py index c90f118b7e4acb..2bd9cef6337ac1 100644 --- a/src/sentry/preprod/eap/read.py +++ b/src/sentry/preprod/eap/read.py @@ -33,7 +33,7 @@ ResolvedAttribute( public_alias="metrics_artifact_type", internal_name="metrics_artifact_type", - search_type="integer", + search_type="string", ), ResolvedAttribute( public_alias="max_install_size", diff --git a/src/sentry/preprod/eap/write.py b/src/sentry/preprod/eap/write.py index 37a149377a6bbe..65fee767b2d5c0 100644 --- a/src/sentry/preprod/eap/write.py +++ b/src/sentry/preprod/eap/write.py @@ -1,5 +1,6 @@ from __future__ import annotations +import logging import uuid from typing import Any @@ -27,6 +28,18 @@ from sentry.utils.eap import hex_to_item_id from sentry.utils.kafka_config import get_topic_definition +logger = logging.getLogger(__name__) + + +def _metrics_artifact_type_label(value: int | None) -> str | None: + if value is None: + return None + try: + return PreprodArtifactSizeMetrics.MetricsArtifactType(value).to_choice_label() + except (ValueError, KeyError): + logger.warning("preprod.eap.unknown_metrics_artifact_type", extra={"value": value}) + return None + def produce_preprod_size_metric_to_eap( size_metric: PreprodArtifactSizeMetrics, @@ -65,7 +78,7 @@ def produce_preprod_size_metric_to_eap( "preprod_artifact_id": size_metric.preprod_artifact_id, "size_metric_id": size_metric.id, "sub_item_type": "size_metric", - "metrics_artifact_type": size_metric.metrics_artifact_type, + "metrics_artifact_type": _metrics_artifact_type_label(size_metric.metrics_artifact_type), "identifier": size_metric.identifier, "min_install_size": size_metric.min_install_size, "max_install_size": size_metric.max_install_size, diff --git a/src/sentry/preprod/models.py b/src/sentry/preprod/models.py index a110f45b4334b4..9f172db9d9dd3a 100644 --- a/src/sentry/preprod/models.py +++ b/src/sentry/preprod/models.py @@ -578,6 +578,14 @@ def as_choices(cls) -> tuple[tuple[int, str], ...]: (cls.APP_CLIP_ARTIFACT, "app_clip_artifact"), ) + def to_choice_label(self) -> str: + """Return the human-readable choice label for this enum value. + + Used by the EAP write path to store artifact type as a string attribute. + """ + choices = dict(self.as_choices()) + return choices[self.value] + class SizeAnalysisState(IntEnum): PENDING = 0 """Size analysis has not started yet.""" diff --git a/src/sentry/search/eap/preprod_size/attributes.py b/src/sentry/search/eap/preprod_size/attributes.py index 2e7085c2555e96..6dc23a05ef85e5 100644 --- a/src/sentry/search/eap/preprod_size/attributes.py +++ b/src/sentry/search/eap/preprod_size/attributes.py @@ -9,9 +9,9 @@ for column in COMMON_COLUMNS + [ ResolvedAttribute( - public_alias="metrics_artifact_type", + public_alias="artifact_type", internal_name="metrics_artifact_type", - search_type="integer", + search_type="string", ), ResolvedAttribute( public_alias="install_size", diff --git a/tests/sentry/preprod/eap/test_write.py b/tests/sentry/preprod/eap/test_write.py index 78021a86763d37..de4c75db3dbcea 100644 --- a/tests/sentry/preprod/eap/test_write.py +++ b/tests/sentry/preprod/eap/test_write.py @@ -93,8 +93,8 @@ def test_write_preprod_size_metric_encodes_all_fields_correctly(self, mock_produ assert attrs["preprod_artifact_id"].int_value == artifact.id assert attrs["size_metric_id"].int_value == size_metric.id assert ( - attrs["metrics_artifact_type"].int_value - == PreprodArtifactSizeMetrics.MetricsArtifactType.MAIN_ARTIFACT + attrs["metrics_artifact_type"].string_value + == PreprodArtifactSizeMetrics.MetricsArtifactType.MAIN_ARTIFACT.to_choice_label() ) assert attrs["identifier"].string_value == "com.example.feature" assert attrs["min_install_size"].int_value == 1000 diff --git a/tests/snuba/preprod/eap/test_preprod_eap_integration.py b/tests/snuba/preprod/eap/test_preprod_eap_integration.py index e671188d866b47..9854acb52939c4 100644 --- a/tests/snuba/preprod/eap/test_preprod_eap_integration.py +++ b/tests/snuba/preprod/eap/test_preprod_eap_integration.py @@ -98,8 +98,8 @@ def test_write_and_read_size_metric_round_trip(self): response.column_values[columns["size_metric_id"]].results[0].val_int == size_metric.id ) assert ( - response.column_values[columns["metrics_artifact_type"]].results[0].val_int - == PreprodArtifactSizeMetrics.MetricsArtifactType.MAIN_ARTIFACT + response.column_values[columns["metrics_artifact_type"]].results[0].val_str + == PreprodArtifactSizeMetrics.MetricsArtifactType.MAIN_ARTIFACT.to_choice_label() ) assert response.column_values[columns["max_install_size"]].results[0].val_int == 5000 assert response.column_values[columns["max_download_size"]].results[0].val_int == 3000