Skip to content

Commit e223d81

Browse files
committed
feat(surveys): add linked_insight_id field
1 parent ce4ca53 commit e223d81

File tree

11 files changed

+113
-3
lines changed

11 files changed

+113
-3
lines changed

posthog/api/survey.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ class SurveyRates(TypedDict):
132132
class SurveySerializer(UserAccessControlSerializerMixin, serializers.ModelSerializer):
133133
linked_flag_id = serializers.IntegerField(required=False, allow_null=True, source="linked_flag.id")
134134
linked_flag = MinimalFeatureFlagSerializer(read_only=True)
135+
linked_insight_id = serializers.IntegerField(required=False, allow_null=True, source="linked_insight.id")
135136
targeting_flag = MinimalFeatureFlagSerializer(read_only=True)
136137
internal_targeting_flag = MinimalFeatureFlagSerializer(read_only=True)
137138
created_by = UserBasicSerializer(read_only=True)
@@ -168,6 +169,7 @@ class Meta:
168169
"schedule",
169170
"linked_flag",
170171
"linked_flag_id",
172+
"linked_insight_id",
171173
"targeting_flag",
172174
"internal_targeting_flag",
173175
"questions",
@@ -208,6 +210,7 @@ def get_conditions(self, survey: Survey):
208210
class SurveySerializerCreateUpdateOnly(serializers.ModelSerializer):
209211
linked_flag = MinimalFeatureFlagSerializer(read_only=True)
210212
linked_flag_id = serializers.IntegerField(required=False, write_only=True, allow_null=True)
213+
linked_insight_id = serializers.IntegerField(required=False, write_only=True, allow_null=True)
211214
targeting_flag_id = serializers.IntegerField(required=False, write_only=True)
212215
targeting_flag_filters = serializers.JSONField(required=False, write_only=True, allow_null=True)
213216
remove_targeting_flag = serializers.BooleanField(required=False, write_only=True, allow_null=True)
@@ -232,6 +235,7 @@ class Meta:
232235
"schedule",
233236
"linked_flag",
234237
"linked_flag_id",
238+
"linked_insight_id",
235239
"targeting_flag_id",
236240
"targeting_flag",
237241
"internal_targeting_flag",
@@ -829,7 +833,9 @@ def _create_or_update_targeting_flag(
829833

830834
class SurveyViewSet(TeamAndOrgViewSetMixin, AccessControlViewSetMixin, viewsets.ModelViewSet):
831835
scope_object = "survey"
832-
queryset = Survey.objects.select_related("linked_flag", "targeting_flag", "internal_targeting_flag").all()
836+
queryset = Survey.objects.select_related(
837+
"linked_flag", "linked_insight", "targeting_flag", "internal_targeting_flag"
838+
).all()
833839
filter_backends = [filters.SearchFilter]
834840
search_fields = ["name", "description"]
835841

posthog/api/test/__snapshots__/test_decide.ambr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3745,6 +3745,7 @@
37453745
"posthog_survey"."description",
37463746
"posthog_survey"."linked_flag_id",
37473747
"posthog_survey"."targeting_flag_id",
3748+
"posthog_survey"."linked_insight_id",
37483749
"posthog_survey"."internal_targeting_flag_id",
37493750
"posthog_survey"."internal_response_sampling_flag_id",
37503751
"posthog_survey"."type",
@@ -4127,6 +4128,7 @@
41274128
"posthog_survey"."description",
41284129
"posthog_survey"."linked_flag_id",
41294130
"posthog_survey"."targeting_flag_id",
4131+
"posthog_survey"."linked_insight_id",
41304132
"posthog_survey"."internal_targeting_flag_id",
41314133
"posthog_survey"."internal_response_sampling_flag_id",
41324134
"posthog_survey"."type",
@@ -4599,6 +4601,7 @@
45994601
"posthog_survey"."description",
46004602
"posthog_survey"."linked_flag_id",
46014603
"posthog_survey"."targeting_flag_id",
4604+
"posthog_survey"."linked_insight_id",
46024605
"posthog_survey"."internal_targeting_flag_id",
46034606
"posthog_survey"."internal_response_sampling_flag_id",
46044607
"posthog_survey"."type",
@@ -5016,6 +5019,7 @@
50165019
"posthog_survey"."description",
50175020
"posthog_survey"."linked_flag_id",
50185021
"posthog_survey"."targeting_flag_id",
5022+
"posthog_survey"."linked_insight_id",
50195023
"posthog_survey"."internal_targeting_flag_id",
50205024
"posthog_survey"."internal_response_sampling_flag_id",
50215025
"posthog_survey"."type",
@@ -5482,6 +5486,7 @@
54825486
"posthog_survey"."description",
54835487
"posthog_survey"."linked_flag_id",
54845488
"posthog_survey"."targeting_flag_id",
5489+
"posthog_survey"."linked_insight_id",
54855490
"posthog_survey"."internal_targeting_flag_id",
54865491
"posthog_survey"."internal_response_sampling_flag_id",
54875492
"posthog_survey"."type",
@@ -5856,6 +5861,7 @@
58565861
"posthog_survey"."description",
58575862
"posthog_survey"."linked_flag_id",
58585863
"posthog_survey"."targeting_flag_id",
5864+
"posthog_survey"."linked_insight_id",
58595865
"posthog_survey"."internal_targeting_flag_id",
58605866
"posthog_survey"."internal_response_sampling_flag_id",
58615867
"posthog_survey"."type",

posthog/api/test/__snapshots__/test_organization_feature_flag.ambr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,6 +1949,7 @@
19491949
"posthog_survey"."description",
19501950
"posthog_survey"."linked_flag_id",
19511951
"posthog_survey"."targeting_flag_id",
1952+
"posthog_survey"."linked_insight_id",
19521953
"posthog_survey"."internal_targeting_flag_id",
19531954
"posthog_survey"."internal_response_sampling_flag_id",
19541955
"posthog_survey"."type",
@@ -1986,6 +1987,7 @@
19861987
"posthog_survey"."description",
19871988
"posthog_survey"."linked_flag_id",
19881989
"posthog_survey"."targeting_flag_id",
1990+
"posthog_survey"."linked_insight_id",
19891991
"posthog_survey"."internal_targeting_flag_id",
19901992
"posthog_survey"."internal_response_sampling_flag_id",
19911993
"posthog_survey"."type",
@@ -2244,6 +2246,7 @@
22442246
"posthog_survey"."description",
22452247
"posthog_survey"."linked_flag_id",
22462248
"posthog_survey"."targeting_flag_id",
2249+
"posthog_survey"."linked_insight_id",
22472250
"posthog_survey"."internal_targeting_flag_id",
22482251
"posthog_survey"."internal_response_sampling_flag_id",
22492252
"posthog_survey"."type",

posthog/api/test/__snapshots__/test_survey.ambr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@
205205
"posthog_survey"."description",
206206
"posthog_survey"."linked_flag_id",
207207
"posthog_survey"."targeting_flag_id",
208+
"posthog_survey"."linked_insight_id",
208209
"posthog_survey"."internal_targeting_flag_id",
209210
"posthog_survey"."internal_response_sampling_flag_id",
210211
"posthog_survey"."type",

posthog/api/test/test_survey.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,7 @@ def test_can_list_surveys(self):
11431143
},
11441144
"linked_flag": None,
11451145
"linked_flag_id": None,
1146+
"linked_insight_id": None,
11461147
"conditions": None,
11471148
"archived": False,
11481149
"start_date": None,
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Generated by Django 4.2.26 on 2025-11-18 16:03
2+
3+
import django.db.models.deletion
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
dependencies = [
9+
("posthog", "0904_alter_dashboard_creation_mode"),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name="survey",
15+
name="linked_insight",
16+
field=models.ForeignKey(
17+
blank=True,
18+
null=True,
19+
on_delete=django.db.models.deletion.SET_NULL,
20+
related_name="surveys_linked_insight",
21+
related_query_name="survey_linked_insight",
22+
to="posthog.insight",
23+
),
24+
),
25+
]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0904_alter_dashboard_creation_mode
1+
0905_survey_add_linked_insight

posthog/models/surveys/survey.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ class Meta:
7171
related_name="surveys_targeting_flag",
7272
related_query_name="survey_targeting_flag",
7373
)
74+
linked_insight = models.ForeignKey(
75+
"posthog.Insight",
76+
null=True,
77+
blank=True,
78+
on_delete=models.SET_NULL,
79+
related_name="surveys_linked_insight",
80+
related_query_name="survey_linked_insight",
81+
)
7482
internal_targeting_flag = models.ForeignKey(
7583
"posthog.FeatureFlag",
7684
null=True,

posthog/schema.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11889,6 +11889,7 @@ class SurveyCreationSchema(BaseModel):
1188911889
iteration_count: Optional[float] = None
1189011890
iteration_frequency_days: Optional[float] = None
1189111891
linked_flag_id: Optional[float] = None
11892+
linked_insight_id: Optional[float] = None
1189211893
name: str
1189311894
questions: list[SurveyQuestionSchema]
1189411895
responses_limit: Optional[float] = None

products/surveys/backend/max_tools.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ async def _arun_impl(self, instructions: str) -> tuple[str, dict[str, Any]]:
100100
if result.should_launch:
101101
survey_data["start_date"] = django.utils.timezone.now()
102102

103+
# Link to insight if provided in context (e.g., from funnel cross-sell)
104+
if self.context.get("insight_id"):
105+
survey_data["linked_insight_id"] = self.context["insight_id"]
106+
103107
# Create the survey directly using Django ORM
104108
survey = await Survey.objects.acreate(team=team, created_by=user, **survey_data)
105109

0 commit comments

Comments
 (0)