Skip to content

Commit 9b19c52

Browse files
committed
feat: Add Segment events for CheckoutIntent state transitions
Track state changes in CheckoutIntent lifecycle by emitting appropriate Segment analytics events on transitions
1 parent 5091aa0 commit 9b19c52

File tree

6 files changed

+698
-0
lines changed

6 files changed

+698
-0
lines changed

enterprise_access/apps/customer_billing/apps.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@
66
class CustomerBillingConfig(AppConfig):
77
default_auto_field = 'django.db.models.BigAutoField'
88
name = 'enterprise_access.apps.customer_billing'
9+
10+
def ready(self):
11+
import enterprise_access.apps.customer_billing.signals # noqa

enterprise_access/apps/customer_billing/constants.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@ class CheckoutIntentState(StrEnum):
7373
ERRORED_PROVISIONING = 'errored_provisioning'
7474
EXPIRED = 'expired'
7575

76+
class CheckoutIntentSegmentEvents:
77+
"""
78+
Segment events for CheckoutIntent lifecycle tracking.
79+
"""
80+
LIFECYCLE_EVENT = 'edx.server.enterprise-access.checkout-intent.lifecycle.event'
81+
7682

7783
ALLOWED_CHECKOUT_INTENT_STATE_TRANSITIONS = {
7884
CheckoutIntentState.CREATED: [
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""
2+
Segment event tracking for CheckoutIntent lifecycle events.
3+
"""
4+
5+
from enterprise_access.apps.api.serializers import CheckoutIntentReadOnlySerializer
6+
from enterprise_access.apps.customer_billing.constants import (
7+
CheckoutIntentSegmentEvents,
8+
)
9+
from enterprise_access.apps.track.segment import track_event
10+
11+
12+
def track_checkout_intent_event(checkout_intent, previous_state=None, new_state=None):
13+
"""Track CheckoutIntent lifecycle events (creation and state transitions)."""
14+
properties = CheckoutIntentReadOnlySerializer(checkout_intent).data
15+
properties["previous_state"] = previous_state
16+
properties["new_state"] = new_state or checkout_intent.state
17+
18+
track_event(
19+
lms_user_id=str(checkout_intent.user.id),
20+
event_name=CheckoutIntentSegmentEvents.LIFECYCLE_EVENT,
21+
properties=properties,
22+
)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from django.db.models.signals import post_save, pre_save
2+
from django.dispatch import receiver
3+
4+
from enterprise_access.apps.customer_billing.models import CheckoutIntent
5+
from enterprise_access.apps.customer_billing.segment_events import (
6+
track_checkout_intent_event,
7+
)
8+
9+
10+
@receiver(pre_save, sender=CheckoutIntent)
11+
def capture_previous_state(sender, instance, **kwargs):
12+
"""Capture the previous state before saving."""
13+
if instance.pk: # Only for updates, not creation
14+
try:
15+
instance._previous_state = CheckoutIntent.objects.get(pk=instance.pk).state
16+
except CheckoutIntent.DoesNotExist:
17+
instance._previous_state = None
18+
else:
19+
instance._previous_state = None
20+
21+
@receiver(post_save, sender=CheckoutIntent)
22+
def track_checkout_intent_changes(sender, instance, created, **kwargs):
23+
"""Automatically track events after save."""
24+
if created:
25+
# Creation event
26+
track_checkout_intent_event(instance, previous_state=None, new_state=instance.state)
27+
elif hasattr(instance, '_previous_state') and instance._previous_state != instance.state:
28+
# State transition event
29+
track_checkout_intent_event(instance, instance._previous_state, instance.state)

0 commit comments

Comments
 (0)