This commit is contained in:
Carl-Gerhard Lindesvärd
2026-03-06 10:13:57 +01:00
parent 289ffb7d6d
commit 0cfccd549b
9 changed files with 372 additions and 84 deletions

View File

@@ -7,6 +7,7 @@ import {
getGroupListCount,
getGroupMemberProfiles,
getGroupPropertyKeys,
getGroupStats,
getGroupsByIds,
getGroupTypes,
TABLE_NAMES,
@@ -32,7 +33,18 @@ export const groupRouter = createTRPCRouter({
getGroupList(input),
getGroupListCount(input),
]);
return { data, meta: { count, take: input.take } };
const stats = await getGroupStats(
input.projectId,
data.map((g) => g.id)
);
return {
data: data.map((g) => ({
...g,
memberCount: stats.get(g.id)?.memberCount ?? 0,
lastActiveAt: stats.get(g.id)?.lastActiveAt ?? null,
})),
meta: { count, take: input.take },
};
}),
byId: protectedProcedure
@@ -160,6 +172,60 @@ export const groupRouter = createTRPCRouter({
};
}),
mostEvents: protectedProcedure
.input(z.object({ id: z.string(), projectId: z.string() }))
.query(async ({ input: { id, projectId } }) => {
return chQuery<{ count: number; name: string }>(`
SELECT count() as count, name
FROM ${TABLE_NAMES.events}
WHERE project_id = ${sqlstring.escape(projectId)}
AND has(groups, ${sqlstring.escape(id)})
AND name NOT IN ('screen_view', 'session_start', 'session_end')
GROUP BY name
ORDER BY count DESC
LIMIT 10
`);
}),
popularRoutes: protectedProcedure
.input(z.object({ id: z.string(), projectId: z.string() }))
.query(async ({ input: { id, projectId } }) => {
return chQuery<{ count: number; path: string }>(`
SELECT count() as count, path
FROM ${TABLE_NAMES.events}
WHERE project_id = ${sqlstring.escape(projectId)}
AND has(groups, ${sqlstring.escape(id)})
AND name = 'screen_view'
GROUP BY path
ORDER BY count DESC
LIMIT 10
`);
}),
memberGrowth: protectedProcedure
.input(z.object({ id: z.string(), projectId: z.string() }))
.query(async ({ input: { id, projectId } }) => {
return chQuery<{ date: string; count: number }>(`
SELECT
toDate(toStartOfDay(min_date)) AS date,
count() AS count
FROM (
SELECT profile_id, min(created_at) AS min_date
FROM ${TABLE_NAMES.events}
WHERE project_id = ${sqlstring.escape(projectId)}
AND has(groups, ${sqlstring.escape(id)})
AND profile_id != device_id
AND created_at >= now() - INTERVAL 30 DAY
GROUP BY profile_id
)
GROUP BY date
ORDER BY date ASC WITH FILL
FROM toDate(now() - INTERVAL 29 DAY)
TO toDate(now() + INTERVAL 1 DAY)
STEP 1
`);
}),
properties: protectedProcedure
.input(z.object({ projectId: z.string() }))
.query(async ({ input: { projectId } }) => {