systemprompt_analytics/repository/traffic/
pages.rs1use super::{NavigationQuery, PageQuery, TrafficAnalyticsRepository};
7use crate::Result;
8use crate::models::reporting::{TrafficNavigationRow, TrafficPageRow};
9
10impl TrafficAnalyticsRepository {
11 pub async fn get_pages(&self, query: PageQuery<'_>) -> Result<Vec<TrafficPageRow>> {
12 let PageQuery {
13 start,
14 end,
15 limit,
16 engaged_only,
17 referrer,
18 path_prefix,
19 } = query;
20 if engaged_only {
21 sqlx::query_as!(
22 TrafficPageRow,
23 r#"
24 SELECT
25 landing_page as "page",
26 COALESCE(referrer_source, 'direct') as "source",
27 COUNT(*)::bigint as "count!"
28 FROM v_engaged_traffic
29 WHERE started_at >= $1 AND started_at < $2
30 AND ($3::text IS NULL OR COALESCE(referrer_source, 'direct') = $3)
31 AND ($4::text IS NULL OR landing_page LIKE $4 || '%')
32 GROUP BY landing_page, referrer_source
33 ORDER BY COUNT(*) DESC
34 LIMIT $5
35 "#,
36 start,
37 end,
38 referrer,
39 path_prefix,
40 limit
41 )
42 .fetch_all(&*self.pool)
43 .await
44 .map_err(Into::into)
45 } else {
46 sqlx::query_as!(
47 TrafficPageRow,
48 r#"
49 SELECT
50 landing_page as "page",
51 COALESCE(referrer_source, 'direct') as "source",
52 COUNT(*)::bigint as "count!"
53 FROM v_clean_traffic
54 WHERE started_at >= $1 AND started_at < $2
55 AND landing_page IS NOT NULL
56 AND ($3::text IS NULL OR COALESCE(referrer_source, 'direct') = $3)
57 AND ($4::text IS NULL OR landing_page LIKE $4 || '%')
58 GROUP BY landing_page, referrer_source
59 ORDER BY COUNT(*) DESC
60 LIMIT $5
61 "#,
62 start,
63 end,
64 referrer,
65 path_prefix,
66 limit
67 )
68 .fetch_all(&*self.pool)
69 .await
70 .map_err(Into::into)
71 }
72 }
73
74 pub async fn get_navigation(
75 &self,
76 query: NavigationQuery<'_>,
77 ) -> Result<Vec<TrafficNavigationRow>> {
78 let NavigationQuery {
79 start,
80 end,
81 limit,
82 path_prefix,
83 internal_only,
84 } = query;
85 if internal_only {
86 sqlx::query_as!(
87 TrafficNavigationRow,
88 r#"
89 SELECT
90 endpoint as "from_path",
91 event_data->>'target_url' as "to_path",
92 COUNT(*)::bigint as "count!"
93 FROM analytics_events
94 WHERE event_type = 'link_click'
95 AND timestamp >= $1 AND timestamp < $2
96 AND ($3::text IS NULL OR event_data->>'target_url' LIKE $3 || '%')
97 AND COALESCE(event_data->>'is_external', 'false') <> 'true'
98 GROUP BY endpoint, event_data->>'target_url'
99 ORDER BY COUNT(*) DESC
100 LIMIT $4
101 "#,
102 start,
103 end,
104 path_prefix,
105 limit
106 )
107 .fetch_all(&*self.pool)
108 .await
109 .map_err(Into::into)
110 } else {
111 sqlx::query_as!(
112 TrafficNavigationRow,
113 r#"
114 SELECT
115 endpoint as "from_path",
116 event_data->>'target_url' as "to_path",
117 COUNT(*)::bigint as "count!"
118 FROM analytics_events
119 WHERE event_type = 'link_click'
120 AND timestamp >= $1 AND timestamp < $2
121 AND ($3::text IS NULL OR event_data->>'target_url' LIKE $3 || '%')
122 GROUP BY endpoint, event_data->>'target_url'
123 ORDER BY COUNT(*) DESC
124 LIMIT $4
125 "#,
126 start,
127 end,
128 path_prefix,
129 limit
130 )
131 .fetch_all(&*self.pool)
132 .await
133 .map_err(Into::into)
134 }
135 }
136}