Merge branch 'session-recording' into dev
This commit is contained in:
@@ -24,6 +24,10 @@ export * from './pageviews/getPageviewMetrics';
|
||||
export * from './pageviews/getPageviewStats';
|
||||
export * from './performance/getPerformanceStats';
|
||||
export * from './performance/savePerformance';
|
||||
export * from './replays/deleteReplaysByWebsite';
|
||||
export * from './replays/getReplayChunks';
|
||||
export * from './replays/getSessionReplays';
|
||||
export * from './replays/saveReplayChunk';
|
||||
export * from './reports/getBreakdown';
|
||||
export * from './reports/getFunnel';
|
||||
export * from './reports/getJourney';
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import prisma from '@/lib/prisma';
|
||||
|
||||
export async function deleteReplaysByWebsite(websiteId: string) {
|
||||
return relationalQuery(websiteId);
|
||||
}
|
||||
|
||||
async function relationalQuery(websiteId: string) {
|
||||
return prisma.client.sessionReplay.deleteMany({
|
||||
where: { websiteId },
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import prisma from '@/lib/prisma';
|
||||
|
||||
export async function getReplayChunks(websiteId: string, sessionId: string) {
|
||||
return relationalQuery(websiteId, sessionId);
|
||||
}
|
||||
|
||||
async function relationalQuery(websiteId: string, sessionId: string) {
|
||||
return prisma.client.sessionReplay.findMany({
|
||||
where: {
|
||||
websiteId,
|
||||
sessionId,
|
||||
},
|
||||
orderBy: {
|
||||
chunkIndex: 'asc',
|
||||
},
|
||||
select: {
|
||||
events: true,
|
||||
chunkIndex: true,
|
||||
eventCount: true,
|
||||
startedAt: true,
|
||||
endedAt: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import prisma from '@/lib/prisma';
|
||||
import type { QueryFilters } from '@/lib/types';
|
||||
|
||||
const FUNCTION_NAME = 'getSessionReplays';
|
||||
|
||||
export async function getSessionReplays(...args: [websiteId: string, filters: QueryFilters]) {
|
||||
return relationalQuery(...args);
|
||||
}
|
||||
|
||||
async function relationalQuery(websiteId: string, filters: QueryFilters) {
|
||||
const { pagedRawQuery, parseFilters } = prisma;
|
||||
const { search, startDate, endDate } = filters;
|
||||
const { queryParams } = parseFilters({
|
||||
...filters,
|
||||
websiteId,
|
||||
search: search ? `%${search}%` : undefined,
|
||||
});
|
||||
|
||||
let dateQuery = '';
|
||||
if (startDate && endDate) {
|
||||
dateQuery = `and sr.created_at between {{startDate}} and {{endDate}}`;
|
||||
} else if (startDate) {
|
||||
dateQuery = `and sr.created_at >= {{startDate}}`;
|
||||
}
|
||||
|
||||
const searchQuery = search
|
||||
? `and (session.distinct_id ilike {{search}}
|
||||
or session.city ilike {{search}}
|
||||
or session.browser ilike {{search}})`
|
||||
: '';
|
||||
|
||||
return pagedRawQuery(
|
||||
`
|
||||
select
|
||||
sr.session_id as "id",
|
||||
sr.website_id as "websiteId",
|
||||
session.browser,
|
||||
session.os,
|
||||
session.device,
|
||||
session.country,
|
||||
session.city,
|
||||
sum(sr.event_count) as "eventCount",
|
||||
count(sr.replay_id) as "chunkCount",
|
||||
min(sr.started_at) as "startedAt",
|
||||
max(sr.ended_at) as "endedAt",
|
||||
(extract(epoch from max(sr.ended_at) - min(sr.started_at)) * 1000)::bigint as "duration",
|
||||
max(sr.created_at) as "createdAt"
|
||||
from session_replay sr
|
||||
left join session on session.session_id = sr.session_id
|
||||
and session.website_id = sr.website_id
|
||||
where sr.website_id = {{websiteId::uuid}}
|
||||
${dateQuery}
|
||||
${searchQuery}
|
||||
group by sr.session_id,
|
||||
sr.website_id,
|
||||
session.browser,
|
||||
session.os,
|
||||
session.device,
|
||||
session.country,
|
||||
session.city
|
||||
order by max(sr.created_at) desc
|
||||
`,
|
||||
queryParams,
|
||||
filters,
|
||||
FUNCTION_NAME,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from './deleteReplaysByWebsite';
|
||||
export * from './getReplayChunks';
|
||||
export * from './getSessionReplays';
|
||||
export * from './saveReplayChunk';
|
||||
@@ -0,0 +1,39 @@
|
||||
import { uuid } from '@/lib/crypto';
|
||||
import prisma from '@/lib/prisma';
|
||||
|
||||
export interface SaveReplayChunkArgs {
|
||||
websiteId: string;
|
||||
sessionId: string;
|
||||
chunkIndex: number;
|
||||
events: Uint8Array;
|
||||
eventCount: number;
|
||||
startedAt: Date;
|
||||
endedAt: Date;
|
||||
}
|
||||
|
||||
export async function saveReplayChunk(args: SaveReplayChunkArgs) {
|
||||
return relationalQuery(args);
|
||||
}
|
||||
|
||||
async function relationalQuery({
|
||||
websiteId,
|
||||
sessionId,
|
||||
chunkIndex,
|
||||
events,
|
||||
eventCount,
|
||||
startedAt,
|
||||
endedAt,
|
||||
}: SaveReplayChunkArgs) {
|
||||
return prisma.client.sessionReplay.create({
|
||||
data: {
|
||||
id: uuid(),
|
||||
websiteId,
|
||||
sessionId,
|
||||
chunkIndex,
|
||||
events: new Uint8Array(events) as any,
|
||||
eventCount,
|
||||
startedAt,
|
||||
endedAt,
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user