diff --git a/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionActivity.tsx b/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionActivity.tsx
index 3b0ad008..66393493 100644
--- a/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionActivity.tsx
+++ b/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionActivity.tsx
@@ -7,12 +7,16 @@ import styles from './SessionActivity.module.css';
export function SessionActivity({
websiteId,
sessionId,
+ startDate,
+ endDate,
}: {
websiteId: string;
sessionId: string;
+ startDate: Date;
+ endDate: Date;
}) {
const { formatDate } = useTimezone();
- const { data, isLoading } = useSessionActivity(websiteId, sessionId);
+ const { data, isLoading } = useSessionActivity(websiteId, sessionId, startDate, endDate);
if (isLoading) {
return ;
diff --git a/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionDetailsPage.tsx b/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionDetailsPage.tsx
index 212f8533..d6a07edc 100644
--- a/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionDetailsPage.tsx
+++ b/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionDetailsPage.tsx
@@ -28,7 +28,12 @@ export default function SessionDetailsPage({
diff --git a/src/components/hooks/queries/useSessionActivity.ts b/src/components/hooks/queries/useSessionActivity.ts
index e6d7ffa0..16c139ab 100644
--- a/src/components/hooks/queries/useSessionActivity.ts
+++ b/src/components/hooks/queries/useSessionActivity.ts
@@ -1,12 +1,21 @@
import { useApi } from './useApi';
-export function useSessionActivity(websiteId: string, sessionId: string) {
+export function useSessionActivity(
+ websiteId: string,
+ sessionId: string,
+ startDate: Date,
+ endDate: Date,
+) {
const { get, useQuery } = useApi();
return useQuery({
- queryKey: ['session:activity', { websiteId, sessionId }],
+ queryKey: ['session:activity', { websiteId, sessionId, startDate, endDate }],
queryFn: () => {
- return get(`/websites/${websiteId}/sessions/${sessionId}/activity`);
+ return get(`/websites/${websiteId}/sessions/${sessionId}/activity`, {
+ startAt: +new Date(startDate),
+ endAt: +new Date(endDate),
+ });
},
+ enabled: Boolean(websiteId && sessionId && startDate && endDate),
});
}
diff --git a/src/declaration.d.ts b/src/declaration.d.ts
index d968c14d..986adf27 100644
--- a/src/declaration.d.ts
+++ b/src/declaration.d.ts
@@ -1,5 +1,4 @@
declare module 'cors';
-declare module 'dateformat';
declare module 'debug';
declare module 'chartjs-adapter-date-fns';
declare module 'md5';
diff --git a/src/lib/clickhouse.ts b/src/lib/clickhouse.ts
index 63027d75..474417b9 100644
--- a/src/lib/clickhouse.ts
+++ b/src/lib/clickhouse.ts
@@ -1,4 +1,5 @@
import { ClickHouseClient, createClient } from '@clickhouse/client';
+import { formatInTimeZone } from 'date-fns-tz';
import debug from 'debug';
import { CLICKHOUSE } from 'lib/db';
import { DEFAULT_PAGE_SIZE, OPERATORS } from './constants';
@@ -48,6 +49,10 @@ function getClient() {
return client;
}
+function getUTCString(date?: Date) {
+ return formatInTimeZone(date || new Date(), 'UTC', 'yyyy-MM-dd HH:mm:ss');
+}
+
function getDateStringSQL(data: any, unit: string = 'utc', timezone?: string) {
if (timezone) {
return `formatDateTime(${data}, '${CLICKHOUSE_DATE_FORMATS[unit]}', '${timezone}')`;
@@ -221,6 +226,7 @@ export default {
getDateStringSQL,
getDateSQL,
getFilterQuery,
+ getUTCString,
parseFilters,
pagedQuery,
findUnique,
diff --git a/src/pages/api/websites/[websiteId]/session-data/properties.ts b/src/pages/api/websites/[websiteId]/session-data/properties.ts
index 4cd2e1e6..92e182d2 100644
--- a/src/pages/api/websites/[websiteId]/session-data/properties.ts
+++ b/src/pages/api/websites/[websiteId]/session-data/properties.ts
@@ -6,7 +6,7 @@ import { methodNotAllowed, ok, unauthorized } from 'next-basics';
import { getSessionDataProperties } from 'queries';
import * as yup from 'yup';
-export interface EventDataFieldsRequestQuery {
+export interface SessionDataFieldsRequestQuery {
websiteId: string;
startAt: string;
endAt: string;
@@ -23,7 +23,7 @@ const schema = {
};
export default async (
- req: NextApiRequestQueryBody
,
+ req: NextApiRequestQueryBody,
res: NextApiResponse,
) => {
await useCors(req, res);
diff --git a/src/pages/api/websites/[websiteId]/sessions/[sessionId]/activity.ts b/src/pages/api/websites/[websiteId]/sessions/[sessionId]/activity.ts
index 8d1b2346..2b0fc084 100644
--- a/src/pages/api/websites/[websiteId]/sessions/[sessionId]/activity.ts
+++ b/src/pages/api/websites/[websiteId]/sessions/[sessionId]/activity.ts
@@ -9,12 +9,16 @@ import { getSessionActivity } from 'queries';
export interface SessionActivityRequestQuery extends PageParams {
websiteId: string;
sessionId: string;
+ startAt: number;
+ endAt: number;
}
const schema = {
GET: yup.object().shape({
websiteId: yup.string().uuid().required(),
sessionId: yup.string().uuid().required(),
+ startAt: yup.number().integer(),
+ endAt: yup.number().integer(),
}),
};
@@ -26,14 +30,17 @@ export default async (
await useAuth(req, res);
await useValidate(schema, req, res);
- const { websiteId, sessionId } = req.query;
+ const { websiteId, sessionId, startAt, endAt } = req.query;
if (req.method === 'GET') {
if (!(await canViewWebsite(req.auth, websiteId))) {
return unauthorized(res);
}
- const data = await getSessionActivity(websiteId, sessionId);
+ const startDate = new Date(+startAt);
+ const endDate = new Date(+endAt);
+
+ const data = await getSessionActivity(websiteId, sessionId, startDate, endDate);
return ok(res, data);
}
diff --git a/src/queries/analytics/events/saveEvent.ts b/src/queries/analytics/events/saveEvent.ts
index 5e21e303..6c0f917b 100644
--- a/src/queries/analytics/events/saveEvent.ts
+++ b/src/queries/analytics/events/saveEvent.ts
@@ -135,10 +135,10 @@ async function clickhouseQuery(data: {
city,
...args
} = data;
- const { insert } = clickhouse;
+ const { insert, getUTCString } = clickhouse;
const { sendMessage } = kafka;
const eventId = uuid();
- const createdAt = new Date().toISOString();
+ const createdAt = getUTCString();
const message = {
...args,
diff --git a/src/queries/analytics/sessions/getSessionActivity.ts b/src/queries/analytics/sessions/getSessionActivity.ts
index 47c5f590..c50a82d9 100644
--- a/src/queries/analytics/sessions/getSessionActivity.ts
+++ b/src/queries/analytics/sessions/getSessionActivity.ts
@@ -2,32 +2,43 @@ import clickhouse from 'lib/clickhouse';
import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db';
import prisma from 'lib/prisma';
-export async function getSessionActivity(...args: [websiteId: string, sessionId: string]) {
+export async function getSessionActivity(
+ ...args: [websiteId: string, sessionId: string, startDate: Date, endDate: Date]
+) {
return runQuery({
[PRISMA]: () => relationalQuery(...args),
[CLICKHOUSE]: () => clickhouseQuery(...args),
});
}
-async function relationalQuery(websiteId: string, sessionId: string) {
+async function relationalQuery(
+ websiteId: string,
+ sessionId: string,
+ startDate: Date,
+ endDate: Date,
+) {
return prisma.client.websiteEvent.findMany({
where: {
id: sessionId,
websiteId,
+ createdAt: { gte: startDate, lte: endDate },
},
take: 500,
});
}
-async function clickhouseQuery(websiteId: string, sessionId: string) {
- const { rawQuery, getDateStringSQL } = clickhouse;
+async function clickhouseQuery(
+ websiteId: string,
+ sessionId: string,
+ startDate: Date,
+ endDate: Date,
+) {
+ const { rawQuery } = clickhouse;
return rawQuery(
`
select
- session_id as id,
- website_id as websiteId,
- ${getDateStringSQL('created_at')} as createdAt,
+ created_at as createdAt,
url_path as urlPath,
url_query as urlQuery,
referrer_domain as referrerDomain,
@@ -38,9 +49,10 @@ async function clickhouseQuery(websiteId: string, sessionId: string) {
from website_event
where website_id = {websiteId:UUID}
and session_id = {sessionId:UUID}
+ and created_at between {startDate:DateTime64} and {endDate:DateTime64}
order by created_at desc
limit 500
`,
- { websiteId, sessionId },
+ { websiteId, sessionId, startDate, endDate },
);
}
diff --git a/src/queries/analytics/sessions/saveSessionData.ts b/src/queries/analytics/sessions/saveSessionData.ts
index d932f7ed..5259239a 100644
--- a/src/queries/analytics/sessions/saveSessionData.ts
+++ b/src/queries/analytics/sessions/saveSessionData.ts
@@ -80,9 +80,9 @@ async function clickhouseQuery(data: {
}) {
const { websiteId, sessionId, sessionData } = data;
- const { insert } = clickhouse;
+ const { insert, getUTCString } = clickhouse;
const { sendMessages } = kafka;
- const createdAt = new Date().toISOString();
+ const createdAt = getUTCString();
const jsonKeys = flattenJSON(sessionData);