Skip to main content

max / makenotwork

2.2 KB · 67 lines History Blame Raw
1 //! SyncKit field-version readout storage.
2 //!
3 //! Stores the latest result per target the same way `scan_pipeline_checks` does,
4 //! so `/status.json` renders the distribution from the ledger rather than
5 //! re-probing MNW's internal endpoint on every viewer poll. Keeping the history
6 //! rather than overwriting one row is deliberate: the interesting question about a
7 //! fleet is how fast an old version drains, and that needs yesterday's reading.
8
9 use super::{Result, SqlitePool, SyncKitFleetCheckResult};
10 use crate::types::SyncKitVersionSnapshot;
11 use tracing::instrument;
12
13 #[instrument(skip_all)]
14 pub async fn insert_synckit_fleet_check(
15 pool: &SqlitePool,
16 result: &SyncKitFleetCheckResult,
17 ) -> Result<i64> {
18 let versions = serde_json::to_string(&result.versions).unwrap_or_default();
19 let row = sqlx::query(
20 "INSERT INTO synckit_fleet_checks (target, window_days, devices, versions, checked_at, error)
21 VALUES (?, ?, ?, ?, ?, ?)",
22 )
23 .bind(&result.target)
24 .bind(result.window_days)
25 .bind(result.devices)
26 .bind(&versions)
27 .bind(&result.checked_at)
28 .bind(&result.error)
29 .execute(pool)
30 .await?;
31 Ok(row.last_insert_rowid())
32 }
33
34 /// The latest SyncKit fleet readout for a target, if one has been recorded.
35 #[instrument(skip_all)]
36 pub async fn get_latest_synckit_fleet_check(
37 pool: &SqlitePool,
38 target: &str,
39 ) -> Result<Option<SyncKitFleetCheckRow>> {
40 Ok(sqlx::query_as::<_, SyncKitFleetCheckRow>(
41 "SELECT id, target, window_days, devices, versions, checked_at, error
42 FROM synckit_fleet_checks WHERE target = ? ORDER BY id DESC LIMIT 1",
43 )
44 .bind(target)
45 .fetch_optional(pool)
46 .await?)
47 }
48
49 #[derive(Debug, Clone, sqlx::FromRow, serde::Serialize)]
50 pub struct SyncKitFleetCheckRow {
51 pub id: i64,
52 pub target: String,
53 pub window_days: i64,
54 pub devices: i64,
55 /// JSON array of version snapshots. Use [`Self::version_list`].
56 pub versions: String,
57 pub checked_at: String,
58 pub error: Option<String>,
59 }
60
61 impl SyncKitFleetCheckRow {
62 /// Decode the stored version snapshots, tolerating a malformed blob as empty.
63 pub fn version_list(&self) -> Vec<SyncKitVersionSnapshot> {
64 serde_json::from_str(&self.versions).unwrap_or_default()
65 }
66 }
67