Skip to main content

systemprompt_analytics/repository/session_signals/
geo.rs

1//! Session geolocation enrichment through the session owner.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use super::SessionSignalsRepository;
7use crate::{AnalyticsError, GeoIpReader, Result};
8use systemprompt_identifiers::SessionId;
9
10impl SessionSignalsRepository {
11    pub async fn backfill_session_geo(
12        &self,
13        reader: Option<&GeoIpReader>,
14        batch_size: i64,
15    ) -> Result<u64> {
16        if batch_size <= 0 {
17            return Err(AnalyticsError::invalid_argument(
18                "batch size must be positive",
19            ));
20        }
21        let mut updated = 0;
22        let mut after: Option<SessionId> = None;
23        loop {
24            let rows = self
25                .owner
26                .sessions_missing_geo(after.as_ref(), batch_size)
27                .await
28                .map_err(AnalyticsError::from)?;
29            let Some(last) = rows.last() else {
30                break;
31            };
32            after = Some(last.0.clone());
33            for (session_id, ip) in rows {
34                if let Some((country, region, city)) =
35                    crate::services::extractor::geoip::lookup_geoip(&ip, reader)
36                {
37                    updated += self
38                        .owner
39                        .set_session_geo(
40                            &session_id,
41                            country.as_deref(),
42                            region.as_deref(),
43                            city.as_deref(),
44                        )
45                        .await
46                        .map_err(AnalyticsError::from)?;
47                }
48            }
49        }
50        Ok(updated)
51    }
52}