systemprompt_models/events/
analytics_event.rs1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5#[serde(tag = "type", rename_all = "SCREAMING_SNAKE_CASE")]
6pub enum AnalyticsEvent {
7 SessionStarted {
8 timestamp: DateTime<Utc>,
9 #[serde(flatten)]
10 payload: SessionStartedPayload,
11 },
12 SessionEnded {
13 timestamp: DateTime<Utc>,
14 #[serde(flatten)]
15 payload: SessionEndedPayload,
16 },
17 PageView {
18 timestamp: DateTime<Utc>,
19 #[serde(flatten)]
20 payload: PageViewPayload,
21 },
22 EngagementUpdate {
23 timestamp: DateTime<Utc>,
24 #[serde(flatten)]
25 payload: EngagementUpdatePayload,
26 },
27 RealTimeStats {
28 timestamp: DateTime<Utc>,
29 #[serde(flatten)]
30 payload: RealTimeStatsPayload,
31 },
32 Heartbeat {
33 timestamp: DateTime<Utc>,
34 },
35}
36
37impl AnalyticsEvent {
38 pub const fn timestamp(&self) -> DateTime<Utc> {
39 match self {
40 Self::SessionStarted { timestamp, .. }
41 | Self::SessionEnded { timestamp, .. }
42 | Self::PageView { timestamp, .. }
43 | Self::EngagementUpdate { timestamp, .. }
44 | Self::RealTimeStats { timestamp, .. }
45 | Self::Heartbeat { timestamp } => *timestamp,
46 }
47 }
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct SessionStartedPayload {
52 pub session_id: String,
53 pub device_type: Option<String>,
54 pub browser: Option<String>,
55 pub os: Option<String>,
56 pub country: Option<String>,
57 pub referrer_source: Option<String>,
58 pub is_bot: bool,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct SessionEndedPayload {
63 pub session_id: String,
64 pub duration_ms: i64,
65 pub page_count: i64,
66 pub request_count: i64,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct PageViewPayload {
71 pub session_id: String,
72 pub user_id: Option<String>,
73 pub page_url: String,
74 pub content_id: Option<String>,
75 pub referrer: Option<String>,
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct EngagementUpdatePayload {
80 pub session_id: String,
81 pub page_url: String,
82 pub scroll_depth: i32,
83 pub time_on_page_ms: i64,
84 pub click_count: i32,
85}
86
87#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
88pub struct RealTimeStatsPayload {
89 pub active_sessions: i64,
90 pub active_users: i64,
91 pub requests_per_minute: i64,
92 pub page_views_last_5m: i64,
93 pub bot_requests_last_5m: i64,
94}
95
96#[derive(Debug, Clone, Copy)]
97pub struct AnalyticsEventBuilder;
98
99impl AnalyticsEventBuilder {
100 pub fn session_started(payload: SessionStartedPayload) -> AnalyticsEvent {
101 AnalyticsEvent::SessionStarted {
102 timestamp: Utc::now(),
103 payload,
104 }
105 }
106
107 pub fn session_ended(
108 session_id: String,
109 duration_ms: i64,
110 page_count: i64,
111 request_count: i64,
112 ) -> AnalyticsEvent {
113 AnalyticsEvent::SessionEnded {
114 timestamp: Utc::now(),
115 payload: SessionEndedPayload {
116 session_id,
117 duration_ms,
118 page_count,
119 request_count,
120 },
121 }
122 }
123
124 pub fn page_view(
125 session_id: String,
126 user_id: Option<String>,
127 page_url: String,
128 content_id: Option<String>,
129 referrer: Option<String>,
130 ) -> AnalyticsEvent {
131 AnalyticsEvent::PageView {
132 timestamp: Utc::now(),
133 payload: PageViewPayload {
134 session_id,
135 user_id,
136 page_url,
137 content_id,
138 referrer,
139 },
140 }
141 }
142
143 pub fn engagement_update(
144 session_id: String,
145 page_url: String,
146 scroll_depth: i32,
147 time_on_page_ms: i64,
148 click_count: i32,
149 ) -> AnalyticsEvent {
150 AnalyticsEvent::EngagementUpdate {
151 timestamp: Utc::now(),
152 payload: EngagementUpdatePayload {
153 session_id,
154 page_url,
155 scroll_depth,
156 time_on_page_ms,
157 click_count,
158 },
159 }
160 }
161
162 pub fn realtime_stats(
163 active_sessions: i64,
164 active_users: i64,
165 requests_per_minute: i64,
166 page_views_last_5m: i64,
167 bot_requests_last_5m: i64,
168 ) -> AnalyticsEvent {
169 AnalyticsEvent::RealTimeStats {
170 timestamp: Utc::now(),
171 payload: RealTimeStatsPayload {
172 active_sessions,
173 active_users,
174 requests_per_minute,
175 page_views_last_5m,
176 bot_requests_last_5m,
177 },
178 }
179 }
180
181 pub fn heartbeat() -> AnalyticsEvent {
182 AnalyticsEvent::Heartbeat {
183 timestamp: Utc::now(),
184 }
185 }
186}