systemprompt_users/sessions/
store.rs1use super::SessionRepository;
7use async_trait::async_trait;
8use chrono::{DateTime, Utc};
9use systemprompt_identifiers::{SessionId, UserId};
10use systemprompt_traits::session_store::{
11 ActiveSessionLookup, CreateSessionParams, SessionBehavioralData, SessionRecord, SessionSnapshot,
12};
13use systemprompt_traits::{AnalyticsProviderError, AnalyticsResult};
14#[async_trait]
15impl systemprompt_traits::SessionStore for SessionRepository {
16 async fn fingerprint_session_ids(
17 &self,
18 fingerprint: &str,
19 window_days: i64,
20 ) -> AnalyticsResult<Vec<SessionId>> {
21 Self::fingerprint_session_ids(self, fingerprint, window_days)
22 .await
23 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
24 }
25 async fn find_by_id(&self, session_id: &SessionId) -> AnalyticsResult<Option<SessionSnapshot>> {
26 Self::find_by_id(self, session_id)
27 .await
28 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
29 }
30 async fn find_active_by_id(
31 &self,
32 session_id: &SessionId,
33 ) -> AnalyticsResult<Option<ActiveSessionLookup>> {
34 Self::find_active_by_id(self, session_id)
35 .await
36 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
37 }
38 async fn revoke_all_for_user(&self, user_id: &UserId) -> AnalyticsResult<u64> {
39 Self::revoke_all_for_user(self, user_id)
40 .await
41 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
42 }
43 async fn find_by_fingerprint(
44 &self,
45 fingerprint_hash: &str,
46 user_id: &UserId,
47 ) -> AnalyticsResult<Option<SessionSnapshot>> {
48 Self::find_by_fingerprint(self, fingerprint_hash, user_id)
49 .await
50 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
51 }
52 async fn list_active_by_user(&self, user_id: &UserId) -> AnalyticsResult<Vec<SessionSnapshot>> {
53 Self::list_active_by_user(self, user_id)
54 .await
55 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
56 }
57 async fn update_activity(&self, session_id: &SessionId) -> AnalyticsResult<()> {
58 Self::update_activity(self, session_id)
59 .await
60 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
61 }
62 async fn increment_request_count(&self, session_id: &SessionId) -> AnalyticsResult<()> {
63 Self::increment_request_count(self, session_id)
64 .await
65 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
66 }
67 async fn end_session(&self, session_id: &SessionId) -> AnalyticsResult<()> {
68 Self::end_session(self, session_id)
69 .await
70 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
71 }
72 async fn mark_as_scanner(&self, session_id: &SessionId) -> AnalyticsResult<()> {
73 Self::mark_as_scanner(self, session_id)
74 .await
75 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
76 }
77 async fn mark_converted(&self, session_id: &SessionId) -> AnalyticsResult<()> {
78 Self::mark_converted(self, session_id)
79 .await
80 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
81 }
82 async fn mark_as_behavioral_bot(
83 &self,
84 session_id: &SessionId,
85 reason: &str,
86 ) -> AnalyticsResult<()> {
87 Self::mark_as_behavioral_bot(self, session_id, reason)
88 .await
89 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
90 }
91 async fn check_and_mark_behavioral_bot(
92 &self,
93 session_id: &SessionId,
94 request_count_threshold: i32,
95 ) -> AnalyticsResult<bool> {
96 Self::check_and_mark_behavioral_bot(self, session_id, request_count_threshold)
97 .await
98 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
99 }
100 async fn cleanup_inactive(&self, inactive_hours: i32) -> AnalyticsResult<u64> {
101 Self::cleanup_inactive(self, inactive_hours)
102 .await
103 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
104 }
105 async fn count_inactive(&self, inactive_hours: i32) -> AnalyticsResult<i64> {
106 Self::count_inactive(self, inactive_hours)
107 .await
108 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
109 }
110 async fn count_sessions_missing_geo(&self) -> AnalyticsResult<i64> {
111 Self::count_sessions_missing_geo(self)
112 .await
113 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
114 }
115 async fn insert_session(&self, params: &CreateSessionParams<'_>) -> AnalyticsResult<()> {
116 Self::create_session(self, params)
117 .await
118 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
119 }
120 async fn find_recent_by_fingerprint(
121 &self,
122 fingerprint_hash: &str,
123 max_age_seconds: i64,
124 ) -> AnalyticsResult<Option<SessionRecord>> {
125 Self::find_recent_by_fingerprint(self, fingerprint_hash, max_age_seconds)
126 .await
127 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
128 }
129 async fn increment_ai_usage(
130 &self,
131 session_id: &SessionId,
132 tokens: i32,
133 cost_microdollars: i64,
134 ) -> AnalyticsResult<()> {
135 Self::increment_ai_usage(self, session_id, tokens, cost_microdollars)
136 .await
137 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
138 }
139 async fn update_behavioral_detection(
140 &self,
141 session_id: &SessionId,
142 score: i32,
143 is_behavioral_bot: bool,
144 reason: Option<&str>,
145 ) -> AnalyticsResult<()> {
146 Self::update_behavioral_detection(self, session_id, score, is_behavioral_bot, reason)
147 .await
148 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
149 }
150 async fn count_sessions_by_fingerprint(
151 &self,
152 fingerprint_hash: &str,
153 window_hours: i64,
154 ) -> AnalyticsResult<i64> {
155 Self::count_sessions_by_fingerprint(self, fingerprint_hash, window_hours)
156 .await
157 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
158 }
159 async fn get_session_for_behavioral_analysis(
160 &self,
161 session_id: &SessionId,
162 ) -> AnalyticsResult<Option<SessionBehavioralData>> {
163 Self::get_session_for_behavioral_analysis(self, session_id)
164 .await
165 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
166 }
167 async fn count_unique_ips_by_fingerprint(
168 &self,
169 fingerprint_hash: &str,
170 window_days: i64,
171 ) -> AnalyticsResult<i64> {
172 Self::count_unique_ips_by_fingerprint(self, fingerprint_hash, window_days)
173 .await
174 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
175 }
176 async fn get_session_starts_by_fingerprint(
177 &self,
178 fingerprint_hash: &str,
179 window_days: i64,
180 ) -> AnalyticsResult<Vec<DateTime<Utc>>> {
181 Self::get_session_starts_by_fingerprint(self, fingerprint_hash, window_days)
182 .await
183 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
184 }
185 async fn get_session_velocity(
186 &self,
187 session_id: &SessionId,
188 ) -> AnalyticsResult<(Option<i64>, Option<i64>)> {
189 Self::get_session_velocity(self, session_id)
190 .await
191 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
192 }
193 async fn count_active_fingerprint_sessions(&self, fingerprint: &str) -> AnalyticsResult<i32> {
194 self.count_active_fingerprint(fingerprint)
195 .await
196 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
197 }
198 async fn find_reusable_fingerprint_session(
199 &self,
200 fingerprint: &str,
201 ) -> AnalyticsResult<Option<SessionId>> {
202 self.find_reusable_fingerprint(fingerprint)
203 .await
204 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
205 }
206 async fn sessions_missing_geo(
207 &self,
208 after: Option<&SessionId>,
209 limit: i64,
210 ) -> AnalyticsResult<Vec<(SessionId, String)>> {
211 self.missing_geo(after, limit)
212 .await
213 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
214 }
215 async fn set_session_geo(
216 &self,
217 session_id: &SessionId,
218 country: Option<&str>,
219 region: Option<&str>,
220 city: Option<&str>,
221 ) -> AnalyticsResult<u64> {
222 self.set_geo(session_id, country, region, city)
223 .await
224 .map_err(|e| AnalyticsProviderError::Internal(e.to_string()))
225 }
226}