1use std::sync::Arc;
2
3use parking_lot::Mutex;
4
5use crate::event::{EventSeverity, EventType};
6use crate::http::SharedState;
7
8pub async fn run_doc_monitor(
10 state: SharedState,
11 project: String,
12 _repo_path: String,
13 interval_secs: u64,
14) {
15 let last_checked = Arc::new(Mutex::new(chrono::Utc::now().timestamp()));
16
17 loop {
18 tokio::time::sleep(std::time::Duration::from_secs(interval_secs)).await;
19
20 let output = tokio::process::Command::new("git")
21 .args(["log", "-1", "--format=%ct"])
22 .output()
23 .await;
24
25 let stdout = match output {
26 Ok(o) if o.status.success() => String::from_utf8_lossy(&o.stdout).trim().to_string(),
27 _ => continue,
28 };
29
30 let last_commit_ts: i64 = stdout.parse().unwrap_or(0);
31 let now = chrono::Utc::now().timestamp();
32 let age_seconds = now - last_commit_ts;
33
34 let should_emit = {
36 let mut last = last_checked.lock();
37 if age_seconds > 86400 && *last < now - 86400 {
38 *last = now;
39 true
40 } else {
41 false
42 }
43 };
44 if should_emit {
47 let state_fb = state.clone();
48 let project_fb = project.clone();
49 let project_fb2 = project.clone();
50 let _ = tokio::task::spawn_blocking(move || {
51 let engine = state_fb.engine.lock();
52 let severity = if age_seconds > 604800 {
53 EventSeverity::Warning
54 } else {
55 EventSeverity::Info
56 };
57 if let Ok(event) = state_fb.event_bus.ingest(
58 engine.graph(),
59 project_fb,
60 EventType::DocSync,
61 severity,
62 "doc:wiki".into(),
63 format!("Documentation last touched {}s ago", age_seconds),
64 serde_json::json!({
65 "last_updated_seconds": age_seconds,
66 }),
67 ) {
68 let event_json = serde_json::to_value(&event).unwrap_or_default();
69 let subs = state_fb
70 .subscription_store
71 .subscribers(engine.graph(), &project_fb2)
72 .unwrap_or_default();
73 for agent_id in &subs {
74 let delivered =
75 state_fb
76 .ws_registry
77 .send_json(agent_id, "doc_event", &event_json);
78 if delivered {
79 let _ = state_fb.delivery_tracker.record_delivery(
80 engine.graph(),
81 agent_id,
82 &event.id,
83 );
84 }
85 }
86 }
87 })
88 .await;
89 }
90 }
91}