From f23d5694ec206eb144fc1958b10e8784a5abf236 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Wed, 15 Oct 2025 16:44:14 -0700 Subject: [PATCH] clean up events/event-data endpoints --- .../[websiteId]/event-data/events/route.ts | 2 -- .../[websiteId]/event-data/fields/route.ts | 2 ++ .../event-data/properties/route.ts | 13 +++++----- .../[websiteId]/event-data/stats/route.ts | 3 ++- .../[websiteId]/event-data/values/route.ts | 12 ++++----- .../hooks/queries/useEventDataValuesQuery.ts | 6 ++--- src/queries/sql/events/getEventDataEvents.ts | 26 ++++++++++++++----- src/queries/sql/events/getEventDataFields.ts | 11 +++++--- src/queries/sql/events/getEventDataStats.ts | 11 +++++--- src/queries/sql/events/getEventDataValues.ts | 11 +++----- 10 files changed, 59 insertions(+), 38 deletions(-) diff --git a/src/app/api/websites/[websiteId]/event-data/events/route.ts b/src/app/api/websites/[websiteId]/event-data/events/route.ts index 4a490c03..2420f0fa 100644 --- a/src/app/api/websites/[websiteId]/event-data/events/route.ts +++ b/src/app/api/websites/[websiteId]/event-data/events/route.ts @@ -27,12 +27,10 @@ export async function GET( return unauthorized(); } - const { event } = query; const filters = await getQueryFilters(query, websiteId); const data = await getEventDataEvents(websiteId, { ...filters, - event, }); return json(data); diff --git a/src/app/api/websites/[websiteId]/event-data/fields/route.ts b/src/app/api/websites/[websiteId]/event-data/fields/route.ts index 49ea9628..cfee4967 100644 --- a/src/app/api/websites/[websiteId]/event-data/fields/route.ts +++ b/src/app/api/websites/[websiteId]/event-data/fields/route.ts @@ -3,6 +3,7 @@ import { getQueryFilters, parseRequest } from '@/lib/request'; import { unauthorized, json } from '@/lib/response'; import { canViewWebsite } from '@/permissions'; import { getEventDataFields } from '@/queries/sql'; +import { filterParams } from '@/lib/schema'; export async function GET( request: Request, @@ -11,6 +12,7 @@ export async function GET( const schema = z.object({ startAt: z.coerce.number().int(), endAt: z.coerce.number().int(), + ...filterParams, }); const { auth, query, error } = await parseRequest(request, schema); diff --git a/src/app/api/websites/[websiteId]/event-data/properties/route.ts b/src/app/api/websites/[websiteId]/event-data/properties/route.ts index c3b884ae..df513e5a 100644 --- a/src/app/api/websites/[websiteId]/event-data/properties/route.ts +++ b/src/app/api/websites/[websiteId]/event-data/properties/route.ts @@ -1,17 +1,17 @@ -import { z } from 'zod'; import { getQueryFilters, parseRequest } from '@/lib/request'; -import { unauthorized, json } from '@/lib/response'; +import { json, unauthorized } from '@/lib/response'; +import { filterParams } from '@/lib/schema'; import { canViewWebsite } from '@/permissions'; import { getEventDataProperties } from '@/queries/sql'; -import { dateRangeParams, filterParams } from '@/lib/schema'; +import { z } from 'zod'; export async function GET( request: Request, { params }: { params: Promise<{ websiteId: string }> }, ) { const schema = z.object({ - propertyName: z.string().optional(), - ...dateRangeParams, + startAt: z.coerce.number().int(), + endAt: z.coerce.number().int(), ...filterParams, }); @@ -27,10 +27,9 @@ export async function GET( return unauthorized(); } - const { propertyName } = query; const filters = await getQueryFilters(query, websiteId); - const data = await getEventDataProperties(websiteId, { ...filters, propertyName }); + const data = await getEventDataProperties(websiteId, filters); return json(data); } diff --git a/src/app/api/websites/[websiteId]/event-data/stats/route.ts b/src/app/api/websites/[websiteId]/event-data/stats/route.ts index b10ffbbc..bb482e2c 100644 --- a/src/app/api/websites/[websiteId]/event-data/stats/route.ts +++ b/src/app/api/websites/[websiteId]/event-data/stats/route.ts @@ -3,6 +3,7 @@ import { getQueryFilters, parseRequest } from '@/lib/request'; import { unauthorized, json } from '@/lib/response'; import { canViewWebsite } from '@/permissions'; import { getEventDataStats } from '@/queries/sql'; +import { filterParams } from '@/lib/schema'; export async function GET( request: Request, @@ -11,7 +12,7 @@ export async function GET( const schema = z.object({ startAt: z.coerce.number().int(), endAt: z.coerce.number().int(), - propertyName: z.string().optional(), + ...filterParams, }); const { auth, query, error } = await parseRequest(request, schema); diff --git a/src/app/api/websites/[websiteId]/event-data/values/route.ts b/src/app/api/websites/[websiteId]/event-data/values/route.ts index 5cf40665..2921af9f 100644 --- a/src/app/api/websites/[websiteId]/event-data/values/route.ts +++ b/src/app/api/websites/[websiteId]/event-data/values/route.ts @@ -3,16 +3,17 @@ import { getQueryFilters, parseRequest } from '@/lib/request'; import { unauthorized, json } from '@/lib/response'; import { canViewWebsite } from '@/permissions'; import { getEventDataValues } from '@/queries/sql'; -import { dateRangeParams, filterParams } from '@/lib/schema'; +import { filterParams } from '@/lib/schema'; export async function GET( request: Request, { params }: { params: Promise<{ websiteId: string }> }, ) { const schema = z.object({ - eventName: z.string().optional(), - propertyName: z.string().optional(), - ...dateRangeParams, + startAt: z.coerce.number().int(), + endAt: z.coerce.number().int(), + event: z.string(), + propertyName: z.string(), ...filterParams, }); @@ -28,12 +29,11 @@ export async function GET( return unauthorized(); } - const { eventName, propertyName } = query; + const { propertyName } = query; const filters = await getQueryFilters(query, websiteId); const data = await getEventDataValues(websiteId, { ...filters, - eventName, propertyName, }); diff --git a/src/components/hooks/queries/useEventDataValuesQuery.ts b/src/components/hooks/queries/useEventDataValuesQuery.ts index 6394a1bb..18bb6b2e 100644 --- a/src/components/hooks/queries/useEventDataValuesQuery.ts +++ b/src/components/hooks/queries/useEventDataValuesQuery.ts @@ -5,7 +5,7 @@ import { useFilterParameters } from '../useFilterParameters'; export function useEventDataValuesQuery( websiteId: string, - eventName: string, + event: string, propertyName: string, options?: ReactQueryOptions, ) { @@ -16,7 +16,7 @@ export function useEventDataValuesQuery( return useQuery({ queryKey: [ 'websites:event-data:values', - { websiteId, eventName, propertyName, startAt, endAt, unit, timezone, ...filters }, + { websiteId, event, propertyName, startAt, endAt, unit, timezone, ...filters }, ], queryFn: () => get(`/websites/${websiteId}/event-data/values`, { @@ -25,7 +25,7 @@ export function useEventDataValuesQuery( unit, timezone, ...filters, - eventName, + event, propertyName, }), enabled: !!(websiteId && propertyName), diff --git a/src/queries/sql/events/getEventDataEvents.ts b/src/queries/sql/events/getEventDataEvents.ts index c8c1e0a0..0d856371 100644 --- a/src/queries/sql/events/getEventDataEvents.ts +++ b/src/queries/sql/events/getEventDataEvents.ts @@ -78,7 +78,7 @@ async function clickhouseQuery( ): Promise<{ eventName: string; propertyName: string; dataType: number; total: number }[]> { const { rawQuery, parseFilters } = clickhouse; const { event } = filters; - const { queryParams } = parseFilters({ + const { filterQuery, cohortQuery, queryParams } = parseFilters({ ...filters, websiteId, }); @@ -93,9 +93,16 @@ async function clickhouseQuery( string_value as propertyValue, count(*) as total from event_data - where website_id = {websiteId:UUID} - and created_at between {startDate:DateTime64} and {endDate:DateTime64} - and event_name = {event:String} + join website_event + on website_event.event_id = event_data.event_id + and website_event.website_id = event_data.website_id + and website_event.website_id = {websiteId:UUID} + and website_event.created_at between {startDate:DateTime64} and {endDate:DateTime64} + ${cohortQuery} + where event_data.website_id = {websiteId:UUID} + and event_data.created_at between {startDate:DateTime64} and {endDate:DateTime64} + and event_data.event_name = {event:String} + ${filterQuery} group by data_key, data_type, string_value, event_name order by 1 asc, 2 asc, 3 asc, 5 desc limit 500 @@ -113,8 +120,15 @@ async function clickhouseQuery( data_type as dataType, count(*) as total from event_data - where website_id = {websiteId:UUID} - and created_at between {startDate:DateTime64} and {endDate:DateTime64} + join website_event + on website_event.event_id = event_data.event_id + and website_event.website_id = event_data.website_id + and website_event.website_id = {websiteId:UUID} + and website_event.created_at between {startDate:DateTime64} and {endDate:DateTime64} + ${cohortQuery} + where event_data.website_id = {websiteId:UUID} + and event_data.created_at between {startDate:DateTime64} and {endDate:DateTime64} + ${filterQuery} group by data_key, data_type, event_name order by 1 asc, 2 asc limit 500 diff --git a/src/queries/sql/events/getEventDataFields.ts b/src/queries/sql/events/getEventDataFields.ts index d62af2d4..42c46cd1 100644 --- a/src/queries/sql/events/getEventDataFields.ts +++ b/src/queries/sql/events/getEventDataFields.ts @@ -64,10 +64,15 @@ async function clickhouseQuery( data_type = 4, toString(date_trunc('hour', date_value)), string_value) as "value", count(*) as "total" - from event_data website_event + from event_data + join website_event + on website_event.event_id = event_data.event_id + and website_event.website_id = event_data.website_id + and website_event.website_id = {websiteId:UUID} + and website_event.created_at between {startDate:DateTime64} and {endDate:DateTime64} ${cohortQuery} - where website_id = {websiteId:UUID} - and created_at between {startDate:DateTime64} and {endDate:DateTime64} + where event_data.website_id = {websiteId:UUID} + and event_data.created_at between {startDate:DateTime64} and {endDate:DateTime64} ${filterQuery} group by data_key, data_type, value order by 2 desc diff --git a/src/queries/sql/events/getEventDataStats.ts b/src/queries/sql/events/getEventDataStats.ts index 606a49ea..28e2f4d0 100644 --- a/src/queries/sql/events/getEventDataStats.ts +++ b/src/queries/sql/events/getEventDataStats.ts @@ -71,10 +71,15 @@ async function clickhouseQuery( event_id, data_key, count(*) as "total" - from event_data website_event + from event_data + join website_event + on website_event.event_id = event_data.event_id + and website_event.website_id = event_data.website_id + and website_event.website_id = {websiteId:UUID} + and website_event.created_at between {startDate:DateTime64} and {endDate:DateTime64} ${cohortQuery} - where website_id = {websiteId:UUID} - and created_at between {startDate:DateTime64} and {endDate:DateTime64} + where event_data.website_id = {websiteId:UUID} + and event_data.created_at between {startDate:DateTime64} and {endDate:DateTime64} ${filterQuery} group by event_id, data_key ) as t diff --git a/src/queries/sql/events/getEventDataValues.ts b/src/queries/sql/events/getEventDataValues.ts index 0af93830..ad7dd1a3 100644 --- a/src/queries/sql/events/getEventDataValues.ts +++ b/src/queries/sql/events/getEventDataValues.ts @@ -11,10 +11,7 @@ interface WebsiteEventData { } export async function getEventDataValues( - ...args: [ - websiteId: string, - filters: QueryFilters & { eventName?: string; propertyName?: string }, - ] + ...args: [websiteId: string, filters: QueryFilters & { propertyName?: string }] ): Promise { return runQuery({ [PRISMA]: () => relationalQuery(...args), @@ -24,7 +21,7 @@ export async function getEventDataValues( async function relationalQuery( websiteId: string, - filters: QueryFilters & { eventName?: string; propertyName?: string }, + filters: QueryFilters & { propertyName?: string }, ) { const { rawQuery, parseFilters, getDateSQL } = prisma; const { filterQuery, joinSessionQuery, cohortQuery, queryParams } = parseFilters({ @@ -63,7 +60,7 @@ async function relationalQuery( async function clickhouseQuery( websiteId: string, - filters: QueryFilters & { eventName?: string; propertyName?: string }, + filters: QueryFilters & { propertyName?: string }, ): Promise<{ value: string; total: number }[]> { const { rawQuery, parseFilters } = clickhouse; const { filterQuery, cohortQuery, queryParams } = parseFilters({ ...filters, websiteId }); @@ -85,7 +82,7 @@ async function clickhouseQuery( where event_data.website_id = {websiteId:UUID} and event_data.created_at between {startDate:DateTime64} and {endDate:DateTime64} and event_data.data_key = {propertyName:String} - and event_data.event_name = {eventName:String} + and event_data.event_name = {event:String} ${filterQuery} group by value order by 2 desc