89 lines
2.4 KiB
TypeScript
89 lines
2.4 KiB
TypeScript
import {
|
|
getSessionDistinctValues,
|
|
getSessionList,
|
|
getSessionReplayChunksFrom,
|
|
SESSION_DISTINCT_FIELDS,
|
|
sessionService,
|
|
} from '@openpanel/db';
|
|
import { zChartEventFilter } from '@openpanel/validation';
|
|
import { z } from 'zod';
|
|
import { createTRPCRouter, protectedProcedure } from '../trpc';
|
|
|
|
export function encodeCursor(cursor: {
|
|
createdAt: string;
|
|
id: string;
|
|
}): string {
|
|
const json = JSON.stringify(cursor);
|
|
return Buffer.from(json, 'utf8').toString('base64url'); // URL-safe
|
|
}
|
|
|
|
export function decodeCursor(
|
|
encoded: string
|
|
): { createdAt: string; id: string } | null {
|
|
try {
|
|
const json = Buffer.from(encoded, 'base64url').toString('utf8');
|
|
const obj = JSON.parse(json);
|
|
if (typeof obj.createdAt === 'string' && typeof obj.id === 'string') {
|
|
return obj;
|
|
}
|
|
return null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export const sessionRouter = createTRPCRouter({
|
|
list: protectedProcedure
|
|
.input(
|
|
z.object({
|
|
projectId: z.string(),
|
|
profileId: z.string().optional(),
|
|
cursor: z.string().nullish(),
|
|
filters: z.array(zChartEventFilter).default([]),
|
|
startDate: z.date().optional(),
|
|
endDate: z.date().optional(),
|
|
search: z.string().optional(),
|
|
take: z.number().default(50),
|
|
minPageViews: z.number().nullish(),
|
|
maxPageViews: z.number().nullish(),
|
|
minEvents: z.number().nullish(),
|
|
maxEvents: z.number().nullish(),
|
|
})
|
|
)
|
|
.query(({ input }) => {
|
|
return getSessionList({
|
|
...input,
|
|
cursor: input.cursor ? new Date(input.cursor) : undefined,
|
|
});
|
|
}),
|
|
|
|
distinctValues: protectedProcedure
|
|
.input(
|
|
z.object({
|
|
projectId: z.string(),
|
|
field: z.enum(SESSION_DISTINCT_FIELDS),
|
|
})
|
|
)
|
|
.query(({ input }) => {
|
|
return getSessionDistinctValues(input.projectId, input.field);
|
|
}),
|
|
|
|
byId: protectedProcedure
|
|
.input(z.object({ sessionId: z.string(), projectId: z.string() }))
|
|
.query(({ input: { sessionId, projectId } }) => {
|
|
return sessionService.byId(sessionId, projectId);
|
|
}),
|
|
|
|
replayChunksFrom: protectedProcedure
|
|
.input(
|
|
z.object({
|
|
sessionId: z.string(),
|
|
projectId: z.string(),
|
|
fromIndex: z.number().int().min(0).default(0),
|
|
})
|
|
)
|
|
.query(({ input: { sessionId, projectId, fromIndex } }) => {
|
|
return getSessionReplayChunksFrom(sessionId, projectId, fromIndex);
|
|
}),
|
|
});
|