1#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
4pub struct Status {
6 pub repository: String,
7 pub repository_id: String,
8 pub remote: Option<String>,
9 pub revision: String,
10 pub branch: Option<String>,
11 pub indexed_at: Option<String>,
12 pub stats: std::collections::HashMap<String, u64>,
13 pub freshness: String,
14 pub stale_files: Vec<String>,
15 pub stale_count: usize,
16 pub analysis_quality: Option<String>,
17 pub scan_stats: Option<serde_json::Value>,
18 pub indexed: bool,
19}
20
21pub fn status(store: &scc_store::Store) -> crate::Result<Status> {
23 let repo = store.repository();
24 let stale = crate::workspace::stale_paths(store)?;
25 Ok(match store.snapshot_status()? {
26 Some((snap, _)) => Status {
27 repository: repo.name,
28 repository_id: repo.id,
29 remote: repo.url,
30 revision: snap.revision,
31 branch: snap.branch,
32 indexed_at: Some(snap.indexed_at),
33 stats: store.stats()?,
34 freshness: if stale.is_empty() { "CURRENT".into() } else { "STALE".into() },
35 stale_files: stale.iter().take(10).cloned().collect(),
36 stale_count: stale.len(),
37 analysis_quality: store.meta_get("analysis_quality")?,
38 scan_stats: store
39 .meta_get("scan_stats")?
40 .and_then(|raw| serde_json::from_str(&raw).ok()),
41 indexed: true,
42 },
43 None => Status {
44 repository: repo.name,
45 repository_id: repo.id,
46 remote: repo.url,
47 revision: "not-indexed".into(),
48 branch: None,
49 indexed_at: None,
50 stats: Default::default(),
51 freshness: "NOT-INDEXED".into(),
52 stale_files: vec![],
53 stale_count: 0,
54 analysis_quality: None,
55 scan_stats: None,
56 indexed: false,
57 },
58 })
59}