MCPcopy Create free account
hub / github.com/Openpanel-dev/openpanel / getTopPages

Method getTopPages

packages/db/src/services/pages.service.ts:36–123  ·  view source on GitHub ↗
({
    projectId,
    startDate,
    endDate,
    timezone,
    search,
    limit,
  }: IGetPagesInput)

Source from the content-addressed store, hash-verified

34 constructor(private client: typeof ch) {}
35
36 async getTopPages({
37 projectId,
38 startDate,
39 endDate,
40 timezone,
41 search,
42 limit,
43 }: IGetPagesInput): Promise<ITopPage[]> {
44 // CTE: Get titles from the last 30 days for faster retrieval
45 const titlesCte = clix(this.client, timezone)
46 .select([
47 'concat(origin, path) as page_key',
48 "anyLast(properties['__title']) as title",
49 ])
50 .from(TABLE_NAMES.events, false)
51 .where('project_id', '=', projectId)
52 .where('name', '=', 'screen_view')
53 .where('created_at', '>=', clix.exp('now() - INTERVAL 30 DAY'))
54 .groupBy(['origin', 'path']);
55
56 // CTE: compute screen_view durations via window function (leadInFrame gives next event's timestamp)
57 const screenViewDurationsCte = clix(this.client, timezone)
58 .select([
59 'project_id',
60 'session_id',
61 'path',
62 'origin',
63 `dateDiff('millisecond', created_at, lead(created_at, 1, created_at) OVER (PARTITION BY session_id ORDER BY created_at)) AS duration`,
64 ])
65 .from(TABLE_NAMES.events, false)
66 .where('project_id', '=', projectId)
67 .where('name', '=', 'screen_view')
68 .where('path', '!=', '')
69 .where('created_at', 'BETWEEN', [
70 clix.datetime(startDate, 'toDateTime'),
71 clix.datetime(endDate, 'toDateTime'),
72 ]);
73
74 // Pre-filtered sessions subquery for better performance
75 const sessionsSubquery = clix(this.client, timezone)
76 .select(['id', 'project_id', 'is_bounce'])
77 .from(TABLE_NAMES.sessions, true) // FINAL
78 .where('project_id', '=', projectId)
79 .where('created_at', 'BETWEEN', [
80 clix.datetime(startDate, 'toDateTime'),
81 clix.datetime(endDate, 'toDateTime'),
82 ])
83 .where('sign', '=', 1);
84
85 // Main query: aggregate events and calculate bounce rate from pre-filtered sessions
86 const query = clix(this.client, timezone)
87 .with('page_titles', titlesCte)
88 .with('screen_view_durations', screenViewDurationsCte)
89 .select<ITopPage>([
90 'e.origin as origin',
91 'e.path as path',
92 "coalesce(pt.title, '') as title",
93 'uniq(e.session_id) as sessions',

Callers 6

getTopPagesCoreFunction · 0.45
getPagePerformanceCoreFunction · 0.45
overview.tsFile · 0.45
event.tsFile · 0.45
getPagesFunction · 0.45

Calls 14

clixFunction · 0.90
groupByMethod · 0.80
selectMethod · 0.80
orderByMethod · 0.80
whenMethod · 0.80
leftJoinMethod · 0.80
withMethod · 0.80
whereGroupMethod · 0.80
limitMethod · 0.80
executeMethod · 0.80
whereMethod · 0.45
fromMethod · 0.45

Tested by

no test coverage detected