Trigger FLAG_UPDATED webhooks when a feature state change goes live. Triggered from AuditLog post_save. Fetches a fresh feature state from the database to ensure we get the latest data (including FeatureStateValue), since drf-writable-nested saves the parent before nested objects.
(
sender: FeatureState,
**kwargs: Any,
)
| 248 | |
| 249 | @receiver(feature_state_change_went_live) |
| 250 | def trigger_feature_state_change_webhooks( |
| 251 | sender: FeatureState, |
| 252 | **kwargs: Any, |
| 253 | ) -> None: |
| 254 | """ |
| 255 | Trigger FLAG_UPDATED webhooks when a feature state change goes live. |
| 256 | |
| 257 | Triggered from AuditLog post_save. Fetches a fresh feature state from the |
| 258 | database to ensure we get the latest data (including FeatureStateValue), |
| 259 | since drf-writable-nested saves the parent before nested objects. |
| 260 | """ |
| 261 | from features import tasks |
| 262 | |
| 263 | # Fetch fresh data from the database to ensure we have the latest state |
| 264 | # This is necessary because: |
| 265 | # 1. drf-writable-nested saves FeatureState before FeatureStateValue |
| 266 | # 2. The history record's instance may have stale cached values |
| 267 | try: |
| 268 | fresh_feature_state = FeatureState.objects.get(id=sender.id) |
| 269 | except FeatureState.DoesNotExist: |
| 270 | # Skip deleted feature states - handled in views |
| 271 | return |
| 272 | |
| 273 | # Skip versioned environments - handled by trigger_update_version_webhooks |
| 274 | if fresh_feature_state.environment_feature_version_id: |
| 275 | return |
| 276 | |
| 277 | tasks.trigger_feature_state_change_webhooks(fresh_feature_state) |
searching dependent graphs…