Skip to content

Commit 7ffe3b6

Browse files
committed
revert to TextField for FeatureHealthEvent.reason, fix typing
1 parent 91f068b commit 7ffe3b6

10 files changed

+45
-97
lines changed

api/features/feature_health/mappers.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
import typing
23

34
from features.feature_health.models import FeatureHealthEvent
@@ -14,11 +15,15 @@ def map_feature_health_event_data_to_feature_health_event(
1415
feature: "Feature",
1516
environment: "Environment | None",
1617
) -> FeatureHealthEvent:
18+
if reason := feature_health_event_data.reason:
19+
instance_reason = json.dumps(reason)
20+
else:
21+
instance_reason = None
1722
instance = FeatureHealthEvent(
1823
feature=feature,
1924
environment=environment,
20-
type=feature_health_event_data.type,
21-
reason=feature_health_event_data.reason,
25+
type=feature_health_event_data.type.value,
26+
reason=instance_reason,
2227
external_id=feature_health_event_data.external_id,
2328
provider_name=feature_health_event_data.provider_name,
2429
)

api/features/feature_health/migrations/0002_alter_featurehealthevent_external_id_and_more_squashed_0003_alter_featurehealthevent_reason_and_more.py

-55
This file was deleted.

api/features/feature_health/migrations/0002_alter_featurehealthevent_external_id_and_more.py api/features/feature_health/migrations/0002_featurehealthevent_add_external_id_alter_created_at.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Generated by Django 4.2.18 on 2025-02-13 05:58
1+
# Generated by Django 4.2.18 on 2025-02-17 15:13
22

33
from django.db import migrations, models
44
import django.utils.timezone

api/features/feature_health/migrations/0003_alter_featurehealthevent_reason_and_more.py

-23
This file was deleted.

api/features/feature_health/models.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class FeatureHealthEvent(
148148
created_at = models.DateTimeField(default=timezone.now, editable=False, blank=True)
149149
type = models.CharField(max_length=50, choices=FeatureHealthEventType.choices)
150150
provider_name = models.CharField(max_length=255, null=True, blank=True)
151-
reason = models.JSONField(null=True, blank=True)
151+
reason = models.TextField(null=True, blank=True)
152152
external_id = models.CharField(max_length=255, null=True, blank=True)
153153

154154
def get_create_log_message(

api/features/feature_health/providers/sample/mappers.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@ def map_payload_to_provider_response(
3939
type=map_sample_event_status_to_feature_health_event_type(
4040
event_data["status"]
4141
),
42-
reason=(
43-
event_data.get("reason") or {"text_blocks": [], "url_blocks": []}
44-
),
42+
reason=event_data.get("reason"),
4543
provider_name=FeatureHealthProviderName.SAMPLE.value,
4644
),
4745
],

api/features/feature_health/serializers.py

+26-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import json
2+
import typing
3+
14
from rest_framework import serializers
25

36
from features.feature_health.models import (
@@ -8,29 +11,47 @@
811
from features.feature_health.providers.services import (
912
get_webhook_path_from_provider,
1013
)
14+
from features.feature_health.types import (
15+
FeatureHealthEventReasonTextBlock,
16+
FeatureHealthEventReasonUrlBlock,
17+
)
1118

19+
FeatureHealthEventReasonStr: typing.TypeAlias = str
1220

13-
class FeatureHealthEventReasonTextBlockSerializer(serializers.Serializer):
21+
22+
class FeatureHealthEventReasonTextBlockSerializer(
23+
serializers.Serializer[FeatureHealthEventReasonTextBlock]
24+
):
1425
text = serializers.CharField()
1526
title = serializers.CharField(required=False)
1627

1728

18-
class FeatureHealthEventReasonUrlBlockSerializer(serializers.Serializer):
29+
class FeatureHealthEventReasonUrlBlockSerializer(
30+
serializers.Serializer[FeatureHealthEventReasonUrlBlock]
31+
):
1932
url = serializers.CharField()
2033
title = serializers.CharField(required=False)
2134

2235

23-
class FeatureHealthEventReasonSerializer(serializers.Serializer):
36+
class FeatureHealthEventReasonSerializer(
37+
serializers.Serializer[FeatureHealthEventReasonStr]
38+
):
2439
text_blocks = serializers.ListField(
2540
child=FeatureHealthEventReasonTextBlockSerializer(),
2641
)
2742
url_blocks = serializers.ListField(
2843
child=FeatureHealthEventReasonUrlBlockSerializer(),
2944
)
3045

46+
def to_representation(
47+
self,
48+
instance: FeatureHealthEventReasonStr,
49+
) -> dict[str, typing.Any]:
50+
return super().to_representation(json.loads(instance))
51+
3152

32-
class FeatureHealthEventSerializer(serializers.ModelSerializer):
33-
reason = FeatureHealthEventReasonSerializer()
53+
class FeatureHealthEventSerializer(serializers.ModelSerializer[FeatureHealthEvent]):
54+
reason = FeatureHealthEventReasonSerializer(allow_null=True)
3455

3556
class Meta:
3657
model = FeatureHealthEvent

api/features/feature_health/types.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
from typing_extensions import TypedDict
66

7-
from features.feature_health.models import FeatureHealthEventType
7+
if typing.TYPE_CHECKING:
8+
from features.feature_health.models import FeatureHealthEventType
89

910

1011
class FeatureHealthEventReasonTextBlock(TypedDict):
@@ -25,9 +26,9 @@ class FeatureHealthEventReason(TypedDict):
2526
@dataclass
2627
class FeatureHealthEventData:
2728
feature_name: str
28-
type: FeatureHealthEventType
29-
reason: FeatureHealthEventReason
29+
type: "FeatureHealthEventType"
3030
provider_name: str
31+
reason: FeatureHealthEventReason | None = None
3132
environment_name: str | None = None
3233
external_id: str | None = None
3334
created_at: datetime | None = None

api/tests/integration/features/feature_health/conftest.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ def _get_feature_health_provider_webhook_url(
1111
feature_health_provider_data = {"name": name}
1212
url = reverse("api-v1:projects:feature-health-providers-list", args=[project])
1313
response = api_client.post(url, data=feature_health_provider_data)
14-
return response.json()["webhook_url"]
14+
webhook_url: str = response.json()["webhook_url"]
15+
return webhook_url
1516

1617

1718
@pytest.fixture

api/tests/integration/features/feature_health/test_views.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def test_webhook__sample_provider__post__expected_feature_health_event_created__
125125
"environment": None,
126126
"feature": feature,
127127
"provider_name": "Sample",
128-
"reason": {"text_blocks": [], "url_blocks": []},
128+
"reason": None,
129129
"type": "UNHEALTHY",
130130
}
131131
]
@@ -183,7 +183,7 @@ def test_webhook__sample_provider__post_with_environment_expected_feature_health
183183
"environment": environment,
184184
"feature": feature,
185185
"provider_name": "Sample",
186-
"reason": {"text_blocks": [], "url_blocks": []},
186+
"reason": None,
187187
"type": "UNHEALTHY",
188188
}
189189
]
@@ -226,7 +226,7 @@ def test_webhook__unhealthy_feature__post__expected_feature_health_event_created
226226
"environment": None,
227227
"feature": unhealthy_feature,
228228
"provider_name": "Sample",
229-
"reason": {"text_blocks": [], "url_blocks": []},
229+
"reason": None,
230230
"type": "HEALTHY",
231231
}
232232
]

0 commit comments

Comments
 (0)