(input: {
projectId: string;
startDate: string;
endDate: string;
search?: string;
sortBy?: 'sessions' | 'pageviews' | 'bounce_rate' | 'avg_duration';
sortOrder?: 'asc' | 'desc';
limit?: number;
})
| 218 | } |
| 219 | |
| 220 | export async function getPagePerformanceCore(input: { |
| 221 | projectId: string; |
| 222 | startDate: string; |
| 223 | endDate: string; |
| 224 | search?: string; |
| 225 | sortBy?: 'sessions' | 'pageviews' | 'bounce_rate' | 'avg_duration'; |
| 226 | sortOrder?: 'asc' | 'desc'; |
| 227 | limit?: number; |
| 228 | }) { |
| 229 | const { timezone } = await getSettingsForProject(input.projectId); |
| 230 | const pages = await pagesService.getTopPages({ |
| 231 | projectId: input.projectId, |
| 232 | startDate: input.startDate, |
| 233 | endDate: input.endDate, |
| 234 | timezone, |
| 235 | search: input.search, |
| 236 | limit: 1000, |
| 237 | }); |
| 238 | |
| 239 | const col = input.sortBy ?? 'sessions'; |
| 240 | const dir = input.sortOrder === 'asc' ? 1 : -1; |
| 241 | const sorted = [...pages].sort( |
| 242 | (a, b) => dir * ((a[col] ?? 0) < (b[col] ?? 0) ? -1 : 1), |
| 243 | ); |
| 244 | const results = sorted.slice(0, input.limit ?? 50); |
| 245 | |
| 246 | const annotated = results.map((p) => ({ |
| 247 | ...p, |
| 248 | seo_signals: { |
| 249 | high_bounce: p.bounce_rate > 70, |
| 250 | low_engagement: p.avg_duration < 1, |
| 251 | good_landing_page: p.bounce_rate < 40 && p.avg_duration > 2, |
| 252 | }, |
| 253 | })); |
| 254 | |
| 255 | return { |
| 256 | total_pages: pages.length, |
| 257 | shown: annotated.length, |
| 258 | pages: annotated, |
| 259 | }; |
| 260 | } |
| 261 | |
| 262 | export interface IPageConversionRow { |
| 263 | path: string; |
no test coverage detected