Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: record non-onboarding product intents for data warehouse #25859

Merged
merged 9 commits into from
Oct 29, 2024
7 changes: 7 additions & 0 deletions frontend/src/scenes/data-warehouse/new/sourceWizardLogic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import api from 'lib/api'
import posthog from 'posthog-js'
import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic'
import { Scene } from 'scenes/sceneTypes'
import { teamLogic } from 'scenes/teamLogic'
import { urls } from 'scenes/urls'

import {
Expand All @@ -16,6 +17,7 @@ import {
manualLinkSources,
ManualLinkSourceType,
PipelineTab,
ProductKey,
SourceConfig,
SourceFieldConfig,
} from '~/types'
Expand Down Expand Up @@ -731,6 +733,8 @@ export const sourceWizardLogic = kea<sourceWizardLogicType>([
['resetTable', 'createTableSuccess'],
dataWarehouseSettingsLogic,
['loadSources'],
teamLogic,
['addProductIntent'],
],
}),
reducers({
Expand Down Expand Up @@ -1129,6 +1133,9 @@ export const sourceWizardLogic = kea<sourceWizardLogicType>([
setManualLinkingProvider: () => {
actions.onNext()
},
selectConnector: () => {
actions.addProductIntent({ product_type: ProductKey.DATA_WAREHOUSE, intent_context: 'selected connector' })
},
})),
urlToAction(({ actions }) => ({
'/data-warehouse/:kind/redirect': ({ kind = '' }, searchParams) => {
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/scenes/teamLogic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,14 @@ export const teamLogic = kea<teamLogicType>([
resetToken: async () => await api.update(`api/environments/${values.currentTeamId}/reset_token`, {}),
addProductIntent: async ({
product_type,
intent_context,
}: {
product_type: ProductKey
intent_context?: string | null
}) =>
await api.update(`api/environments/${values.currentTeamId}/add_product_intent`, {
product_type,
intent_context: null,
intent_context: intent_context ?? undefined,
}),
recordProductIntentOnboardingComplete: async ({ product_type }: { product_type: ProductKey }) =>
await api.update(`api/environments/${values.currentTeamId}/complete_product_onboarding`, {
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,13 @@ export interface TeamType extends TeamBasicType {
extra_settings?: Record<string, string | number | boolean | undefined>
modifiers?: HogQLQueryModifiers
default_modifiers?: HogQLQueryModifiers
product_intents?: ProductIntentType[]
}

export interface ProductIntentType {
product_type: string
created_at: string
onboarding_completed_at?: string
}

// This type would be more correct without `Partial<TeamType>`, but it's only used in the shared dashboard/insight
Expand Down
19 changes: 15 additions & 4 deletions posthog/api/team.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@

from django.shortcuts import get_object_or_404
from loginas.utils import is_impersonated_session
from posthog.auth import PersonalAPIKeyAuthentication
from posthog.jwt import PosthogJwtAudience, encode_jwt
from rest_framework import exceptions, request, response, serializers, viewsets
from rest_framework.permissions import BasePermission, IsAuthenticated

from posthog.api.routing import TeamAndOrgViewSetMixin
from posthog.api.shared import TeamBasicSerializer
from posthog.api.utils import action
from posthog.auth import PersonalAPIKeyAuthentication
from posthog.constants import AvailableFeature
from posthog.event_usage import report_user_action
from posthog.geoip import get_geoip_properties
from posthog.jwt import PosthogJwtAudience, encode_jwt
from posthog.models import ProductIntent, Team, User
from posthog.models.activity_logging.activity_log import (
Detail,
Expand Down Expand Up @@ -209,7 +209,9 @@ def get_live_events_token(self, team: Team) -> Optional[str]:
)

def get_product_intents(self, obj):
return ProductIntent.objects.filter(team=obj).values("product_type", "created_at", "onboarding_completed_at")
return ProductIntent.objects.filter(team=obj).values(
"product_type", "created_at", "onboarding_completed_at", "updated_at"
)

@staticmethod
def validate_session_recording_linked_flag(value) -> dict | None:
Expand Down Expand Up @@ -580,7 +582,7 @@ def add_product_intent(self, request: request.Request, *args, **kwargs):
product_intent.updated_at = datetime.now(tz=UTC)
product_intent.save()

if created and isinstance(user, User):
if isinstance(user, User):
report_user_action(
user,
"user showed product intent",
Expand All @@ -590,6 +592,9 @@ def add_product_intent(self, request: request.Request, *args, **kwargs):
"$current_url": current_url,
"$session_id": session_id,
"intent_context": request.data.get("intent_context"),
"is_first_intent_for_product": created,
"intent_created_at": product_intent.created_at,
"intent_updated_at": product_intent.updated_at,
},
team=team,
)
Expand Down Expand Up @@ -619,6 +624,9 @@ def complete_product_onboarding(self, request: request.Request, *args, **kwargs)
"$current_url": current_url,
"$session_id": session_id,
"intent_context": request.data.get("intent_context"),
"is_first_intent_for_product": created,
"intent_created_at": product_intent.created_at,
"intent_updated_at": product_intent.updated_at,
},
team=team,
)
Expand All @@ -633,6 +641,9 @@ def complete_product_onboarding(self, request: request.Request, *args, **kwargs)
"product_key": product_type,
"$current_url": current_url,
"$session_id": session_id,
"intent_context": request.data.get("intent_context"),
"intent_created_at": product_intent.created_at,
"intent_updated_at": product_intent.updated_at,
},
team=team,
)
Expand Down
Loading