systemprompt_users/sessions/
store.rs1use crate::repository::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.into()))
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.into()))
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.into()))
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.into()))
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.into()))
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.into()))
56 }
57 async fn increment_request_count(&self, session_id: &SessionId) -> AnalyticsResult<()> {
58 Self::increment_request_count(self, session_id)
59 .await
60 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
61 }
62 async fn end_session(&self, session_id: &SessionId) -> AnalyticsResult<()> {
63 Self::end_session(self, session_id)
64 .await
65 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
66 }
67 async fn mark_as_scanner(&self, session_id: &SessionId) -> AnalyticsResult<()> {
68 Self::mark_as_scanner(self, session_id)
69 .await
70 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
71 }
72 async fn mark_converted(&self, session_id: &SessionId) -> AnalyticsResult<()> {
73 Self::mark_converted(self, session_id)
74 .await
75 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
76 }
77 async fn mark_as_behavioral_bot(
78 &self,
79 session_id: &SessionId,
80 reason: &str,
81 ) -> AnalyticsResult<()> {
82 Self::mark_as_behavioral_bot(self, session_id, reason)
83 .await
84 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
85 }
86 async fn check_and_mark_behavioral_bot(
87 &self,
88 session_id: &SessionId,
89 request_count_threshold: i32,
90 ) -> AnalyticsResult<bool> {
91 Self::check_and_mark_behavioral_bot(self, session_id, request_count_threshold)
92 .await
93 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
94 }
95 async fn cleanup_inactive(&self, inactive_hours: i32) -> AnalyticsResult<u64> {
96 Self::cleanup_inactive(self, inactive_hours)
97 .await
98 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
99 }
100 async fn count_inactive(&self, inactive_hours: i32) -> AnalyticsResult<i64> {
101 Self::count_inactive(self, inactive_hours)
102 .await
103 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
104 }
105 async fn count_sessions_missing_geo(&self) -> AnalyticsResult<i64> {
106 Self::count_sessions_missing_geo(self)
107 .await
108 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
109 }
110 async fn insert_session(&self, params: &CreateSessionParams<'_>) -> AnalyticsResult<()> {
111 Self::create_session(self, params)
112 .await
113 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
114 }
115 async fn find_recent_by_fingerprint(
116 &self,
117 fingerprint_hash: &str,
118 max_age_seconds: i64,
119 ) -> AnalyticsResult<Option<SessionRecord>> {
120 Self::find_recent_anonymous_by_fingerprint(self, fingerprint_hash, max_age_seconds)
121 .await
122 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
123 }
124 async fn increment_ai_usage(
125 &self,
126 session_id: &SessionId,
127 tokens: i32,
128 cost_microdollars: i64,
129 ) -> AnalyticsResult<()> {
130 Self::increment_ai_usage(self, session_id, tokens, cost_microdollars)
131 .await
132 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
133 }
134 async fn update_behavioral_detection(
135 &self,
136 session_id: &SessionId,
137 score: i32,
138 is_behavioral_bot: bool,
139 reason: Option<&str>,
140 ) -> AnalyticsResult<()> {
141 Self::update_behavioral_detection(self, session_id, score, is_behavioral_bot, reason)
142 .await
143 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
144 }
145 async fn count_sessions_by_fingerprint(
146 &self,
147 fingerprint_hash: &str,
148 window_hours: i64,
149 ) -> AnalyticsResult<i64> {
150 Self::count_sessions_by_fingerprint(self, fingerprint_hash, window_hours)
151 .await
152 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
153 }
154 async fn get_session_for_behavioral_analysis(
155 &self,
156 session_id: &SessionId,
157 ) -> AnalyticsResult<Option<SessionBehavioralData>> {
158 Self::get_session_for_behavioral_analysis(self, session_id)
159 .await
160 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
161 }
162 async fn count_unique_ips_by_fingerprint(
163 &self,
164 fingerprint_hash: &str,
165 window_days: i64,
166 ) -> AnalyticsResult<i64> {
167 Self::count_unique_ips_by_fingerprint(self, fingerprint_hash, window_days)
168 .await
169 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
170 }
171 async fn get_session_starts_by_fingerprint(
172 &self,
173 fingerprint_hash: &str,
174 window_days: i64,
175 ) -> AnalyticsResult<Vec<DateTime<Utc>>> {
176 Self::get_session_starts_by_fingerprint(self, fingerprint_hash, window_days)
177 .await
178 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
179 }
180 async fn get_session_velocity(
181 &self,
182 session_id: &SessionId,
183 ) -> AnalyticsResult<(Option<i64>, Option<i64>)> {
184 Self::get_session_velocity(self, session_id)
185 .await
186 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
187 }
188 async fn count_active_fingerprint_sessions(&self, fingerprint: &str) -> AnalyticsResult<i32> {
189 self.count_active_fingerprint(fingerprint)
190 .await
191 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
192 }
193 async fn find_reusable_fingerprint_session(
194 &self,
195 fingerprint: &str,
196 ) -> AnalyticsResult<Option<SessionId>> {
197 self.find_reusable_fingerprint(fingerprint)
198 .await
199 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
200 }
201 async fn sessions_missing_geo(
202 &self,
203 after: Option<&SessionId>,
204 limit: i64,
205 ) -> AnalyticsResult<Vec<(SessionId, String)>> {
206 self.missing_geo(after, limit)
207 .await
208 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
209 }
210 async fn set_session_geo(
211 &self,
212 session_id: &SessionId,
213 country: Option<&str>,
214 region: Option<&str>,
215 city: Option<&str>,
216 ) -> AnalyticsResult<u64> {
217 self.set_geo(session_id, country, region, city)
218 .await
219 .map_err(|e| AnalyticsProviderError::Internal(e.into()))
220 }
221}