Fix revenue query filtering. Closes #4286

This commit is contained in:
Francis Cao committed 2026-07-23 09:41:59 -07:00
1 parent 934c028a53
commit 78346795eb
4 files changed
+405 -263

No files matched your search

+65 -51
View File
@@ -1,4 +1,5 @@
import clickhouse from '@/lib/clickhouse';
import { EVENT_TYPE } from '@/lib/constants';
import { CLICKHOUSE, PRISMA, runQuery } from '@/lib/db';
import prisma from '@/lib/prisma';
import type { QueryFilters } from '@/lib/types';
@@ -28,7 +29,7 @@ async function relationalQuery(
) {
const { startDate, endDate, unit = 'day', timezone = 'utc', currency } = parameters;
const { getDateSQL, rawQuery, parseFilters } = prisma;
const { queryParams, filterQuery, cohortQuery, joinSessionQuery } = parseFilters({
const { queryParams, filterQuery, cohortQuery, joinSessionQuery, dateQuery } = parseFilters({
...filters,
websiteId,
startDate,
@@ -36,34 +37,40 @@ async function relationalQuery(
currency,
});
const joinQuery =
filterQuery || cohortQuery
? `join (select *
from website_event
where website_id = {{websiteId::uuid}}
and created_at between {{startDate}} and {{endDate}}
and event_type = 2) website_event
on website_event.website_id = revenue.website_id
and website_event.session_id = revenue.session_id
and website_event.event_id = revenue.event_id`
: '';
const chart = await rawQuery(
`
with
filtered_sessions as (
select distinct website_event.website_id, website_event.session_id
from website_event
${cohortQuery}
${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}}
and website_event.event_type != ${EVENT_TYPE.performance}
${dateQuery}
${filterQuery}
),
filtered_revenue as (
select
revenue.event_id,
revenue.event_name,
revenue.created_at,
revenue.revenue
from revenue
join filtered_sessions
on filtered_sessions.website_id = revenue.website_id
and filtered_sessions.session_id = revenue.session_id
where revenue.website_id = {{websiteId::uuid}}
and revenue.created_at between {{startDate}} and {{endDate}}
and upper(revenue.currency) = {{currency}}
)
select
revenue.event_name x,
${getDateSQL('revenue.created_at', unit, timezone)} t,
sum(revenue.revenue) y,
count(revenue.event_id) count
from revenue
${joinQuery}
${cohortQuery}
${joinSessionQuery}
where revenue.website_id = {{websiteId::uuid}}
and revenue.created_at between {{startDate}} and {{endDate}}
and upper(revenue.currency) = {{currency}}
${filterQuery}
group by x, t
filtered_revenue.event_name x,
${getDateSQL('filtered_revenue.created_at', unit, timezone)} t,
sum(filtered_revenue.revenue) y,
count(filtered_revenue.event_id) count
from filtered_revenue
group by x, t
order by t
`,
queryParams,
@@ -79,7 +86,7 @@ async function clickhouseQuery(
) {
const { startDate, endDate, unit = 'day', timezone = 'utc', currency } = parameters;
const { getDateSQL, rawQuery, parseFilters } = clickhouse;
const { filterQuery, cohortQuery, queryParams } = parseFilters({
const { filterQuery, cohortQuery, dateQuery, queryParams } = parseFilters({
...filters,
websiteId,
startDate,
@@ -87,33 +94,40 @@ async function clickhouseQuery(
currency,
});
const joinQuery = filterQuery
? `any left join (
select *
from website_event
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type = 2) website_event
on website_event.website_id = website_revenue.website_id
and website_event.session_id = website_revenue.session_id
and website_event.event_id = website_revenue.event_id`
: '';
const chart = await rawQuery<{ x: string; t: string; y: number; count: number }[]>(
`
with
filtered_sessions as (
select website_id, session_id
from website_event
${cohortQuery}
where website_id = {websiteId:UUID}
and event_type != ${EVENT_TYPE.performance}
${dateQuery}
${filterQuery}
group by website_id, session_id
),
filtered_revenue as (
select
website_revenue.event_id,
website_revenue.event_name,
website_revenue.created_at,
website_revenue.revenue
from website_revenue
any inner join filtered_sessions
on filtered_sessions.website_id = website_revenue.website_id
and filtered_sessions.session_id = website_revenue.session_id
where website_revenue.website_id = {websiteId:UUID}
and website_revenue.created_at between {startDate:DateTime64} and {endDate:DateTime64}
and upper(website_revenue.currency) = {currency:String}
)
select
website_revenue.event_name x,
${getDateSQL('website_revenue.created_at', unit, timezone)} t,
sum(website_revenue.revenue) y,
count(website_revenue.event_id) count
from website_revenue
${joinQuery}
${cohortQuery}
where website_revenue.website_id = {websiteId:UUID}
and website_revenue.created_at between {startDate:DateTime64} and {endDate:DateTime64}
and upper(website_revenue.currency) = {currency:String}
${filterQuery}
group by x, t
filtered_revenue.event_name x,
${getDateSQL('filtered_revenue.created_at', unit, timezone)} t,
sum(filtered_revenue.revenue) y,
count(filtered_revenue.event_id) count
from filtered_revenue
group by x, t
order by t
`,
queryParams,
+181 -156
View File
@@ -1,6 +1,7 @@
import clickhouse from '@/lib/clickhouse';
import {
EMAIL_DOMAINS,
EVENT_TYPE,
LLM_DOMAINS,
PAID_AD_PARAMS,
SEARCH_DOMAINS,
@@ -44,42 +45,51 @@ async function relationalQuery(
): Promise<RevenueMetricsResult[RevenueMetricType]> {
const { startDate, endDate, currency } = parameters;
const { rawQuery, parseFilters } = prisma;
const { queryParams, filterQuery, cohortQuery, joinSessionQuery } = parseFilters({
const { queryParams, filterQuery, cohortQuery, joinSessionQuery, dateQuery } = parseFilters({
...filters,
websiteId,
startDate,
endDate,
currency,
});
const joinQuery =
filterQuery || cohortQuery
? `join (select *
from website_event
where website_id = {{websiteId::uuid}}
and created_at between {{startDate}} and {{endDate}}
and event_type = 2) website_event
on website_event.website_id = revenue.website_id
and website_event.session_id = revenue.session_id
and website_event.event_id = revenue.event_id`
: '';
const filteredSessionsQuery = `
filtered_sessions as (
select distinct website_event.website_id, website_event.session_id
from website_event
${cohortQuery}
${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}}
and website_event.event_type != ${EVENT_TYPE.performance}
${dateQuery}
${filterQuery}
)
`;
const filteredRevenueQuery = `
filtered_revenue as (
select revenue.website_id, revenue.session_id, revenue.created_at, revenue.revenue
from revenue
join filtered_sessions
on filtered_sessions.website_id = revenue.website_id
and filtered_sessions.session_id = revenue.session_id
where revenue.website_id = {{websiteId::uuid}}
and revenue.created_at between {{startDate}} and {{endDate}}
and upper(revenue.currency) = {{currency}}
)
`;
if (type === 'country') {
return rawQuery(
`
with
${filteredSessionsQuery},
${filteredRevenueQuery}
select
session.country as "name",
sum(revenue) as "value"
from revenue
${joinQuery}
sum(filtered_revenue.revenue) as "value"
from filtered_revenue
join session
on session.website_id = revenue.website_id
and session.session_id = revenue.session_id
${cohortQuery}
where revenue.website_id = {{websiteId::uuid}}
and revenue.created_at between {{startDate}} and {{endDate}}
and upper(revenue.currency) = {{currency}}
${filterQuery}
on session.website_id = filtered_revenue.website_id
and session.session_id = filtered_revenue.session_id
group by session.country
order by value desc
`,
@@ -90,20 +100,17 @@ async function relationalQuery(
if (type === 'region') {
return rawQuery(
`
with
${filteredSessionsQuery},
${filteredRevenueQuery}
select
session.country,
session.region as "name",
sum(revenue.revenue) as "value"
from revenue
${joinQuery}
sum(filtered_revenue.revenue) as "value"
from filtered_revenue
join session
on session.website_id = revenue.website_id
and session.session_id = revenue.session_id
${cohortQuery}
where revenue.website_id = {{websiteId::uuid}}
and revenue.created_at between {{startDate}} and {{endDate}}
and upper(revenue.currency) = {{currency}}
${filterQuery}
on session.website_id = filtered_revenue.website_id
and session.session_id = filtered_revenue.session_id
group by session.country, session.region
order by value desc
`,
@@ -114,22 +121,23 @@ async function relationalQuery(
if (type === 'referrer') {
return rawQuery(
`
WITH events AS (
with
${filteredSessionsQuery},
events as (
select
revenue.website_id,
revenue.session_id,
sum(revenue.revenue) as "value"
from revenue
${joinQuery}
${cohortQuery}
${joinSessionQuery}
join filtered_sessions
on filtered_sessions.website_id = revenue.website_id
and filtered_sessions.session_id = revenue.session_id
where revenue.website_id = {{websiteId::uuid}}
and revenue.created_at between {{startDate}} and {{endDate}}
and upper(revenue.currency) = {{currency}}
${filterQuery}
group by revenue.website_id, revenue.session_id),
revenue_data AS (
revenue_data as (
select
e.website_id,
e.session_id,
@@ -165,22 +173,23 @@ async function relationalQuery(
return rawQuery(
`
WITH events AS (
with
${filteredSessionsQuery},
events as (
select
revenue.website_id,
revenue.session_id,
sum(revenue.revenue) as "value"
from revenue
${joinQuery}
${cohortQuery}
${joinSessionQuery}
join filtered_sessions
on filtered_sessions.website_id = revenue.website_id
and filtered_sessions.session_id = revenue.session_id
where revenue.website_id = {{websiteId::uuid}}
and revenue.created_at between {{startDate}} and {{endDate}}
and upper(revenue.currency) = {{currency}}
${filterQuery}
group by revenue.website_id, revenue.session_id),
revenue_data AS (
revenue_data as (
select
e.website_id,
e.session_id,
@@ -195,7 +204,7 @@ async function relationalQuery(
group by session_id
) we on we.session_id = e.session_id),
revenue_prefix AS (
revenue_prefix as (
select
case when we.utm_medium ilike '%cp%' OR
we.utm_medium ilike '%ppc%' OR
@@ -253,48 +262,60 @@ async function clickhouseQuery(
): Promise<RevenueMetricsResult[RevenueMetricType]> {
const { startDate, endDate, currency } = parameters;
const { rawQuery, parseFilters } = clickhouse;
const { filterQuery, cohortQuery, queryParams } = parseFilters({
const { filterQuery, cohortQuery, dateQuery, queryParams } = parseFilters({
...filters,
websiteId,
startDate,
endDate,
currency,
});
const joinQuery = filterQuery
? `any left join (
select *
const filteredSessionsQuery = `
filtered_sessions as (
select
website_id,
session_id,
any(country) as country,
any(region) as region
from website_event
${cohortQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type = 2) website_event
on website_event.website_id = website_revenue.website_id
and website_event.session_id = website_revenue.session_id
and website_event.event_id = website_revenue.event_id`
: '';
and event_type != ${EVENT_TYPE.performance}
${dateQuery}
${filterQuery}
group by website_id, session_id
)
`;
const filteredRevenueQuery = `
filtered_revenue as (
select
website_revenue.website_id,
website_revenue.session_id,
website_revenue.created_at,
website_revenue.revenue
from website_revenue
any inner join filtered_sessions
on filtered_sessions.website_id = website_revenue.website_id
and filtered_sessions.session_id = website_revenue.session_id
where website_revenue.website_id = {websiteId:UUID}
and website_revenue.created_at between {startDate:DateTime64} and {endDate:DateTime64}
and upper(website_revenue.currency) = {currency:String}
)
`;
if (type === 'country') {
return rawQuery<{ name: string; value: number }[]>(
`
with
${filteredSessionsQuery},
${filteredRevenueQuery}
select
website_event.country as "name",
sum(website_revenue.revenue) as "value"
from website_revenue
any left join (
select *
from website_event
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type = 2) website_event
on website_event.website_id = website_revenue.website_id
and website_event.session_id = website_revenue.session_id
and website_event.event_id = website_revenue.event_id
${cohortQuery}
where website_revenue.website_id = {websiteId:UUID}
and website_revenue.created_at between {startDate:DateTime64} and {endDate:DateTime64}
and upper(website_revenue.currency) = {currency:String}
${filterQuery}
group by website_event.country
filtered_sessions.country as "name",
sum(filtered_revenue.revenue) as "value"
from filtered_revenue
any inner join filtered_sessions
on filtered_sessions.website_id = filtered_revenue.website_id
and filtered_sessions.session_id = filtered_revenue.session_id
group by filtered_sessions.country
order by value desc
`,
queryParams,
@@ -304,26 +325,18 @@ async function clickhouseQuery(
if (type === 'region') {
return rawQuery<{ name: string; value: number; country: string }[]>(
`
with
${filteredSessionsQuery},
${filteredRevenueQuery}
select
website_event.country,
website_event.region as "name",
sum(website_revenue.revenue) as "value"
from website_revenue
any left join (
select *
from website_event
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type = 2) website_event
on website_event.website_id = website_revenue.website_id
and website_event.session_id = website_revenue.session_id
and website_event.event_id = website_revenue.event_id
${cohortQuery}
where website_revenue.website_id = {websiteId:UUID}
and website_revenue.created_at between {startDate:DateTime64} and {endDate:DateTime64}
and upper(website_revenue.currency) = {currency:String}
${filterQuery}
group by 1,2
filtered_sessions.country,
filtered_sessions.region as "name",
sum(filtered_revenue.revenue) as "value"
from filtered_revenue
any inner join filtered_sessions
on filtered_sessions.website_id = filtered_revenue.website_id
and filtered_sessions.session_id = filtered_revenue.session_id
group by 1, 2
order by value desc
`,
queryParams,
@@ -333,34 +346,39 @@ async function clickhouseQuery(
if (type === 'referrer') {
return rawQuery<{ name: string; value: number }[]>(
`
WITH events AS (
select distinct
website_id,
session_id,
sum(revenue) as "value"
from website_revenue
${joinQuery}
${cohortQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and upper(currency) = {currency:String}
${filterQuery}
group by 1,2),
with
${filteredSessionsQuery},
events as (
select
website_revenue.website_id,
website_revenue.session_id,
sum(website_revenue.revenue) as "value"
from website_revenue
any inner join filtered_sessions
on filtered_sessions.website_id = website_revenue.website_id
and filtered_sessions.session_id = website_revenue.session_id
where website_revenue.website_id = {websiteId:UUID}
and website_revenue.created_at between {startDate:DateTime64} and {endDate:DateTime64}
and upper(website_revenue.currency) = {currency:String}
group by 1, 2
),
revenue AS (
select
revenue as (
select
e.website_id,
e.session_id,
e.value,
we.min_date as created_at
from events e
join (select session_id, min(created_at) min_date
from website_event
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
group by 1
) we
on we.session_id = e.session_id)
from events e
join (
select session_id, min(created_at) min_date
from website_event
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
group by 1
) we
on we.session_id = e.session_id
)
select
website_event.referrer_domain as "name",
@@ -383,37 +401,42 @@ async function clickhouseQuery(
return rawQuery<{ name: string; value: number }[]>(
`
WITH events AS (
select distinct
website_id,
session_id,
sum(revenue) as "value"
from website_revenue
${joinQuery}
${cohortQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and upper(currency) = {currency:String}
${filterQuery}
group by 1,2),
with
${filteredSessionsQuery},
events as (
select
website_revenue.website_id,
website_revenue.session_id,
sum(website_revenue.revenue) as "value"
from website_revenue
any inner join filtered_sessions
on filtered_sessions.website_id = website_revenue.website_id
and filtered_sessions.session_id = website_revenue.session_id
where website_revenue.website_id = {websiteId:UUID}
and website_revenue.created_at between {startDate:DateTime64} and {endDate:DateTime64}
and upper(website_revenue.currency) = {currency:String}
group by 1, 2
),
revenue AS (
select
e.website_id,
e.session_id,
e.value,
we.min_date as created_at
from events e
join (select session_id, min(created_at) min_date
from website_event
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
group by 1
) we
on we.session_id = e.session_id),
revenue as (
select
e.website_id,
e.session_id,
e.value,
we.min_date as created_at
from events e
join (
select session_id, min(created_at) min_date
from website_event
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
group by 1
) we
on we.session_id = e.session_id
),
channels AS (
select
channels as (
select
case when multiSearchAny(lower(utm_medium), ['cp', 'ppc', 'retargeting', 'paid']) != 0 then 'paid' else 'organic' end prefix,
case
when referrer_domain = '' and url_query = '' then 'direct'
@@ -444,16 +467,18 @@ async function clickhouseQuery(
when referrer_domain != hostname and referrer_domain != '' then 'referral'
else 'Unknown' end AS "name",
sum(revenue.value) as "value"
from revenue
any left join (
select *
from website_event
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}) website_event
on website_event.website_id = revenue.website_id
and website_event.session_id = revenue.session_id
and website_event.created_at = revenue.created_at
group by 1, 2)
from revenue
any left join (
select *
from website_event
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
) website_event
on website_event.website_id = revenue.website_id
and website_event.session_id = revenue.session_id
and website_event.created_at = revenue.created_at
group by 1, 2
)
select name, sum(value) value
from channels
+56 -56
View File
@@ -1,4 +1,5 @@
import clickhouse from '@/lib/clickhouse';
import { EVENT_TYPE } from '@/lib/constants';
import { CLICKHOUSE, PRISMA, runQuery } from '@/lib/db';
import prisma from '@/lib/prisma';
import type { QueryFilters } from '@/lib/types';
@@ -28,7 +29,7 @@ async function relationalQuery(
): Promise<RevenueStatsResult> {
const { startDate, endDate, currency } = parameters;
const { rawQuery, parseFilters } = prisma;
const { queryParams, filterQuery, cohortQuery, joinSessionQuery } = parseFilters({
const { queryParams, filterQuery, cohortQuery, joinSessionQuery, dateQuery } = parseFilters({
...filters,
websiteId,
startDate,
@@ -36,37 +37,36 @@ async function relationalQuery(
currency,
});
const joinQuery =
filterQuery || cohortQuery
? `join (select *
from website_event
where website_id = {{websiteId::uuid}}
and created_at between {{startDate}} and {{endDate}}
and event_type = 2) website_event
on website_event.website_id = revenue.website_id
and website_event.session_id = revenue.session_id
and website_event.event_id = revenue.event_id`
: '';
const total = await rawQuery(
`
with
filtered_sessions as (
select distinct website_event.website_id, website_event.session_id
from website_event
${cohortQuery}
${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}}
and website_event.event_type != ${EVENT_TYPE.performance}
${dateQuery}
${filterQuery}
),
filtered_revenue as (
select revenue.website_id, revenue.session_id, revenue.event_id, revenue.revenue
from revenue
join filtered_sessions
on filtered_sessions.website_id = revenue.website_id
and filtered_sessions.session_id = revenue.session_id
where revenue.website_id = {{websiteId::uuid}}
and revenue.created_at between {{startDate}} and {{endDate}}
and upper(revenue.currency) = {{currency}}
)
select
sum(revenue.revenue) as sum,
count(distinct revenue.event_id) as count,
count(distinct revenue.session_id) as unique_count,
(select count(distinct session_id)
from website_event
where website_id = {{websiteId::uuid}}
and created_at between {{startDate}} and {{endDate}}) as total_sessions
from revenue
${joinQuery}
${cohortQuery}
${joinSessionQuery}
where revenue.website_id = {{websiteId::uuid}}
and revenue.created_at between {{startDate}} and {{endDate}}
and upper(revenue.currency) = {{currency}}
${filterQuery}
`,
sum(filtered_revenue.revenue) as sum,
count(distinct filtered_revenue.event_id) as count,
count(distinct filtered_revenue.session_id) as unique_count,
(select count(*) from filtered_sessions) as total_sessions
from filtered_revenue
`,
queryParams,
).then(result => result?.[0]);
@@ -83,7 +83,7 @@ async function clickhouseQuery(
): Promise<RevenueStatsResult> {
const { startDate, endDate, currency } = parameters;
const { rawQuery, parseFilters } = clickhouse;
const { filterQuery, cohortQuery, queryParams } = parseFilters({
const { filterQuery, cohortQuery, dateQuery, queryParams } = parseFilters({
...filters,
websiteId,
startDate,
@@ -91,18 +91,6 @@ async function clickhouseQuery(
currency,
});
const joinQuery = filterQuery
? `any left join (
select *
from website_event
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type = 2) website_event
on website_event.website_id = website_revenue.website_id
and website_event.session_id = website_revenue.session_id
and website_event.event_id = website_revenue.event_id`
: '';
const total = await rawQuery<{
sum: number;
count: number;
@@ -110,21 +98,33 @@ async function clickhouseQuery(
total_sessions: number;
}>(
`
with
filtered_sessions as (
select website_id, session_id
from website_event
${cohortQuery}
where website_id = {websiteId:UUID}
and event_type != ${EVENT_TYPE.performance}
${dateQuery}
${filterQuery}
group by website_id, session_id
),
filtered_revenue as (
select website_revenue.website_id, website_revenue.session_id, website_revenue.event_id, website_revenue.revenue
from website_revenue
any inner join filtered_sessions
on filtered_sessions.website_id = website_revenue.website_id
and filtered_sessions.session_id = website_revenue.session_id
where website_revenue.website_id = {websiteId:UUID}
and website_revenue.created_at between {startDate:DateTime64} and {endDate:DateTime64}
and upper(website_revenue.currency) = {currency:String}
)
select
sum(website_revenue.revenue) as sum,
uniqExact(website_revenue.event_id) as count,
uniqExact(website_revenue.session_id) as unique_count,
(select uniqExact(session_id)
from website_event
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}) as total_sessions
from website_revenue
${joinQuery}
${cohortQuery}
where website_revenue.website_id = {websiteId:UUID}
and website_revenue.created_at between {startDate:DateTime64} and {endDate:DateTime64}
and upper(website_revenue.currency) = {currency:String}
${filterQuery}
sum(filtered_revenue.revenue) as sum,
uniqExact(filtered_revenue.event_id) as count,
uniqExact(filtered_revenue.session_id) as unique_count,
(select count() from filtered_sessions) as total_sessions
from filtered_revenue
`,
queryParams,
).then(result => result?.[0]);
@@ -0,0 +1,103 @@
import { beforeEach, expect, test, vi } from 'vitest';
import { getRevenueChart } from './getRevenueChart';
import { getRevenueMetrics } from './getRevenueMetrics';
import { getRevenueStats } from './getRevenueStats';
const { rawQueryMock, parseFiltersMock, getDateSQLMock } = vi.hoisted(() => ({
rawQueryMock: vi.fn(),
parseFiltersMock: vi.fn(),
getDateSQLMock: vi.fn(),
}));
vi.mock('@/lib/db', () => ({
CLICKHOUSE: 'clickhouse',
PRISMA: 'prisma',
runQuery: vi.fn((queries: Record<string, () => unknown>) => queries.prisma()),
}));
vi.mock('@/lib/prisma', () => ({
default: {
rawQuery: rawQueryMock,
parseFilters: parseFiltersMock,
getDateSQL: getDateSQLMock,
},
}));
vi.mock('@/lib/clickhouse', () => ({
default: {
rawQuery: vi.fn(),
parseFilters: vi.fn(),
getDateSQL: vi.fn(),
},
}));
const parameters = {
startDate: new Date('2026-05-18T00:00:00.000Z'),
endDate: new Date('2026-05-19T00:00:00.000Z'),
currency: 'EUR',
unit: 'day',
timezone: 'utc',
};
beforeEach(() => {
rawQueryMock.mockReset();
parseFiltersMock.mockReset();
getDateSQLMock.mockReset();
parseFiltersMock.mockReturnValue({
queryParams: {},
filterQuery: 'and website_event.utm_source = {{utmSource}}',
cohortQuery: '',
joinSessionQuery: '',
dateQuery: 'and created_at between {{startDate}} and {{endDate}}',
});
getDateSQLMock.mockReturnValue('bucketed_date');
});
test('getRevenueStats aggregates revenue from filtered sessions', async () => {
rawQueryMock.mockResolvedValue([
{
sum: 0,
count: 0,
unique_count: 0,
total_sessions: 0,
},
]);
await getRevenueStats('website-1', parameters, {});
const [query] = rawQueryMock.mock.calls[0];
expect(query).toContain('filtered_sessions as');
expect(query).toContain('join filtered_sessions');
expect(query).toContain('(select count(*) from filtered_sessions) as total_sessions');
expect(query).not.toContain('and website_event.event_id = revenue.event_id');
});
test('getRevenueChart buckets filtered revenue instead of revenue rows joined by event id', async () => {
rawQueryMock.mockResolvedValue([]);
await getRevenueChart('website-1', parameters, {});
const [query] = rawQueryMock.mock.calls[0];
expect(query).toContain('filtered_sessions as');
expect(query).toContain('filtered_revenue as');
expect(query).toContain('from filtered_revenue');
expect(query).toContain('bucketed_date');
expect(query).not.toContain('and website_event.event_id = revenue.event_id');
});
test('getRevenueMetrics uses the filtered session set for screen-load breakdowns', async () => {
rawQueryMock.mockResolvedValue([]);
await getRevenueMetrics('website-1', parameters, {}, 'country');
const [query] = rawQueryMock.mock.calls[0];
expect(query).toContain('filtered_sessions as');
expect(query).toContain('filtered_revenue as');
expect(query).toContain('sum(filtered_revenue.revenue) as "value"');
expect(query).not.toContain('and website_event.event_id = revenue.event_id');
});