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(web-analytics): Add session revenue to web overview query #27893

Merged
merged 12 commits into from
Jan 27, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@
e."$group_0" as aggregation_target,
if(notEmpty(pdi.distinct_id), pdi.person_id, e.person_id) as person_id,
person.person_props as person_props,
person.pmat_email as pmat_email,
if(event = 'step one', 1, 0) as step_0,
if(step_0 = 1, timestamp, null) as latest_0,
if(event = 'step two', 1, 0) as step_1,
Expand All @@ -80,7 +79,6 @@
HAVING argMax(is_deleted, version) = 0) AS pdi ON e.distinct_id = pdi.distinct_id
INNER JOIN
(SELECT id,
argMax(pmat_email, version) as pmat_email,
argMax(properties, version) as person_props
FROM person
WHERE team_id = 99999
Expand All @@ -97,7 +95,7 @@
AND event IN ['step one', 'step three', 'step two']
AND toTimeZone(timestamp, 'UTC') >= toDateTime('2021-05-01 00:00:00', 'UTC')
AND toTimeZone(timestamp, 'UTC') <= toDateTime('2021-05-10 23:59:59', 'UTC')
AND (("pmat_email" ILIKE '%g0%'
AND ((replaceRegexpAll(JSONExtractRaw(person_props, 'email'), '^"|"$', '') ILIKE '%g0%'
OR replaceRegexpAll(JSONExtractRaw(person_props, 'name'), '^"|"$', '') ILIKE '%g0%'
OR replaceRegexpAll(JSONExtractRaw(e.properties, 'distinct_id'), '^"|"$', '') ILIKE '%g0%'
OR replaceRegexpAll(JSONExtractRaw(group_properties_0, 'name'), '^"|"$', '') ILIKE '%g0%'
Expand Down
12 changes: 10 additions & 2 deletions frontend/src/queries/nodes/WebOverview/WebOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,21 @@ const formatUnit = (x: number, options?: { precise?: boolean }): string => {
return humanFriendlyLargeNumber(x)
}

const formatItem = (value: number | undefined, kind: WebOverviewItemKind, options?: { precise?: boolean }): string => {
const formatItem = (
value: number | undefined,
kind: WebOverviewItemKind,
options?: { precise?: boolean; currency?: string }
): string => {
if (value == null) {
return '-'
} else if (kind === 'percentage') {
return formatPercentage(value, options)
return formatPercentage(value, { precise: options?.precise })
} else if (kind === 'duration_s') {
return humanFriendlyDuration(value, { secondsPrecision: 3 })
} else if (kind === 'currency') {
return new Intl.NumberFormat(undefined, { style: 'currency', currency: options?.currency ?? 'USD' }).format(
value
)
}
return formatUnit(value, options)
}
Expand Down
46 changes: 45 additions & 1 deletion frontend/src/queries/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -12605,6 +12605,32 @@
"required": ["count"],
"type": "object"
},
"RevenueTrackingConfig": {
"additionalProperties": false,
"properties": {
"events": {
"items": {
"$ref": "#/definitions/RevenueTrackingEventItem"
},
"type": "array"
}
},
"required": ["events"],
"type": "object"
},
"RevenueTrackingEventItem": {
"additionalProperties": false,
"properties": {
"eventName": {
"type": "string"
},
"revenueProperty": {
"type": "string"
}
},
"required": ["eventName", "revenueProperty"],
"type": "object"
},
"RootAssistantMessage": {
"anyOf": [
{
Expand Down Expand Up @@ -14134,6 +14160,9 @@
"filterTestAccounts": {
"type": "boolean"
},
"includeRevenue": {
"type": "boolean"
},
"kind": {
"const": "WebExternalClicksTableQuery",
"type": "string"
Expand Down Expand Up @@ -14253,6 +14282,9 @@
"filterTestAccounts": {
"type": "boolean"
},
"includeRevenue": {
"type": "boolean"
},
"kind": {
"const": "WebGoalsQuery",
"type": "string"
Expand Down Expand Up @@ -14370,7 +14402,7 @@
"type": "object"
},
"WebOverviewItemKind": {
"enum": ["unit", "duration_s", "percentage"],
"enum": ["unit", "duration_s", "percentage", "currency"],
"type": "string"
},
"WebOverviewQuery": {
Expand Down Expand Up @@ -14398,6 +14430,9 @@
"filterTestAccounts": {
"type": "boolean"
},
"includeRevenue": {
"type": "boolean"
},
"kind": {
"const": "WebOverviewQuery",
"type": "string"
Expand Down Expand Up @@ -14535,6 +14570,9 @@
"includeBounceRate": {
"type": "boolean"
},
"includeRevenue": {
"type": "boolean"
},
"includeScrollDepth": {
"type": "boolean"
},
Expand Down Expand Up @@ -14697,6 +14735,9 @@
"filterTestAccounts": {
"type": "boolean"
},
"includeRevenue": {
"type": "boolean"
},
"kind": {
"const": "WebVitalsPathBreakdownQuery",
"type": "string"
Expand Down Expand Up @@ -14851,6 +14892,9 @@
"filterTestAccounts": {
"type": "boolean"
},
"includeRevenue": {
"type": "boolean"
},
"kind": {
"const": "WebVitalsQuery",
"type": "string"
Expand Down
12 changes: 11 additions & 1 deletion frontend/src/queries/schema/schema-general.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1450,6 +1450,7 @@ interface WebAnalyticsQueryBase<R extends Record<string, any>> extends DataNode<
forceSamplingRate?: SamplingRate
}
filterTestAccounts?: boolean
includeRevenue?: boolean
/** @deprecated ignored, always treated as enabled **/
useSessionsTable?: boolean
}
Expand All @@ -1458,7 +1459,7 @@ export interface WebOverviewQuery extends WebAnalyticsQueryBase<WebOverviewQuery
kind: NodeKind.WebOverviewQuery
}

export type WebOverviewItemKind = 'unit' | 'duration_s' | 'percentage'
export type WebOverviewItemKind = 'unit' | 'duration_s' | 'percentage' | 'currency'
export interface WebOverviewItem {
key: string
value?: number
Expand Down Expand Up @@ -2285,3 +2286,12 @@ export interface TracesQuery extends DataNode<TracesQueryResponse> {
}

export type CachedTracesQueryResponse = CachedQueryResponse<TracesQueryResponse>

export interface RevenueTrackingEventItem {
eventName: string
revenueProperty: string
}

export interface RevenueTrackingConfig {
events: RevenueTrackingEventItem[]
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { LemonTable } from 'lib/lemon-ui/LemonTable'
import { useCallback } from 'react'
import { revenueEventsSettingsLogic } from 'scenes/settings/environment/revenueEventsSettingsLogic'

import { RevenueTrackingEventItem } from '~/types'
import { RevenueTrackingEventItem } from '~/queries/schema'

export function RevenueEventsSettings(): JSX.Element {
const { saveDisabledReason, events } = useValues(revenueEventsSettingsLogic)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { loaders } from 'kea-loaders'
import { objectsEqual } from 'lib/utils'
import { teamLogic } from 'scenes/teamLogic'

import { RevenueTrackingConfig, RevenueTrackingEventItem } from '~/types'
import { RevenueTrackingConfig, RevenueTrackingEventItem } from '~/queries/schema'

import type { revenueEventsSettingsLogicType } from './revenueEventsSettingsLogicType'

Expand Down
3 changes: 2 additions & 1 deletion frontend/src/scenes/teamActivityDescriber.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import { Link } from 'lib/lemon-ui/Link'
import { isNotNil, isObject, pluralize } from 'lib/utils'
import { urls } from 'scenes/urls'

import { ActivityScope, RevenueTrackingEventItem, TeamSurveyConfigType, TeamType } from '~/types'
import { RevenueTrackingEventItem } from '~/queries/schema/schema-general'
import { ActivityScope, TeamSurveyConfigType, TeamType } from '~/types'

import { ThemeName } from './dataThemeLogic'

Expand Down
6 changes: 5 additions & 1 deletion frontend/src/scenes/web-analytics/webAnalyticsLogic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,10 @@ export const webAnalyticsLogic = kea<webAnalyticsLogicType>([
}
: undefined

const includeRevenue = !!featureFlags[FEATURE_FLAGS.WEB_REVENUE_TRACKING]
// the queries don't currently revenue when the conversion goal is an action
const includeRevenue =
!!featureFlags[FEATURE_FLAGS.WEB_REVENUE_TRACKING] &&
!(conversionGoal && 'actionId' in conversionGoal)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a confusing statement, I usually would apply De Morgan here, but I think this is fine, it'll look nicer once we remove the FF

Suggested change
!(conversionGoal && 'actionId' in conversionGoal)
(!conversionGoal || !('actionId' in conversionGoal))

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha I started with this and decided I preferred the other way. I also tried

(!conversionGoal || ('eventName' in conversionGoal))


const revenueEventsSeries: EventsNode[] =
includeRevenue && currentTeam?.revenue_tracking_config
Expand Down Expand Up @@ -921,6 +924,7 @@ export const webAnalyticsLogic = kea<webAnalyticsLogicType>([
compareFilter,
filterTestAccounts,
conversionGoal,
includeRevenue,
},
insightProps: createInsightProps(TileId.OVERVIEW),
},
Expand Down
11 changes: 1 addition & 10 deletions frontend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import type {
RecordingOrder,
RecordingsQuery,
} from './queries/schema'
import { NodeKind } from './queries/schema/schema-general'
import { NodeKind, RevenueTrackingConfig } from './queries/schema/schema-general'

// Type alias for number to be reflected as integer in json-schema.
/** @asType integer */
Expand Down Expand Up @@ -4848,15 +4848,6 @@ export enum CookielessServerHashMode {
Stateful = 2,
}

export interface RevenueTrackingEventItem {
eventName: string
revenueProperty: string
}

export interface RevenueTrackingConfig {
events: RevenueTrackingEventItem[]
}

/**
* Assistant Conversation
*/
Expand Down
Loading
Loading