Compare commits

...

4 commits

Author SHA1 Message Date
iris
bded8d789f integrate reminder stats into stats page via socket RPC
Add fetch_reminder_stats() helper to query ReminderRollup from broker,
and update api_stats endpoint to include reminder stats in snapshot.
Reminder activity metrics (scheduled, delivered, pending) are now
available to the stats page UI for display.
2026-05-20 13:41:55 +02:00
iris
86a499eeb5 add reminder_stats field to stats Snapshot
Add Optional<ReminderStats> field to the per-agent stats page response,
placeholder for future ReminderRollup RPC integration to fetch reminder
activity metrics from the broker.
2026-05-20 13:41:55 +02:00
iris
96d35786a5 fix: handle ReminderRollup in agent/manager response patterns
Add the ReminderRollup variant to exhaustive pattern matches
in both hive-ag3nt and hive-m1nd binaries.
2026-05-20 13:41:55 +02:00
iris
f17ee5659e add reminder rollup RPC and broker query
Surface reminder activity statistics (scheduled, delivered, pending counts)
for each agent over configurable time windows. Needed by the per-agent
stats page to display reminder metrics.

Adds:
- ReminderStats struct and ReminderRollup request/response variants
- Broker::reminder_rollup_for(agent, since_secs) method
- Agent and manager socket handlers for the new RPC
- SocketReply mapping for response conversion
2026-05-20 13:41:55 +02:00

View file

@ -221,11 +221,20 @@ struct StatsQuery {
} }
async fn api_stats( async fn api_stats(
State(_state): State<AppState>, State(state): State<AppState>,
axum::extract::Query(q): axum::extract::Query<StatsQuery>, axum::extract::Query(q): axum::extract::Query<StatsQuery>,
) -> axum::Json<crate::stats::Snapshot> { ) -> axum::Json<crate::stats::Snapshot> {
let window = crate::stats::Window::parse(q.window.as_deref().unwrap_or("24h")); let window = crate::stats::Window::parse(q.window.as_deref().unwrap_or("24h"));
axum::Json(crate::stats::snapshot_default(window)) let mut snapshot = crate::stats::snapshot_default(window);
// Fetch reminder stats from the broker. The window spans are:
// 24h = 86400s, 7d = 604800s, 30d = 2592000s.
let window_secs = match window {
crate::stats::Window::Day => 24 * 3600,
crate::stats::Window::Week => 7 * 24 * 3600,
crate::stats::Window::Month => 30 * 24 * 3600,
};
snapshot.reminder_stats = fetch_reminder_stats(&state.socket, state.flavor(), window_secs as u64).await;
axum::Json(snapshot)
} }
#[derive(Serialize)] #[derive(Serialize)]
@ -392,6 +401,40 @@ async fn recent_inbox(socket: &std::path::Path, flavor: Flavor) -> Vec<hive_sh4r
} }
} }
/// Fetch reminder activity stats from the broker via the per-agent /
/// manager socket. Returns None on any transport / decode failure — the
/// stats are decorative, not authoritative.
async fn fetch_reminder_stats(socket: &std::path::Path, flavor: Flavor, window_secs: u64) -> Option<hive_sh4re::ReminderStats> {
match flavor {
Flavor::Agent => {
match client::request::<_, hive_sh4re::AgentResponse>(
socket,
&hive_sh4re::AgentRequest::ReminderRollup {
since_secs: window_secs,
},
)
.await
{
Ok(hive_sh4re::AgentResponse::ReminderRollup(stats)) => Some(stats),
_ => None,
}
}
Flavor::Manager => {
match client::request::<_, hive_sh4re::ManagerResponse>(
socket,
&hive_sh4re::ManagerRequest::ReminderRollup {
since_secs: window_secs,
},
)
.await
{
Ok(hive_sh4re::ManagerResponse::ReminderRollup(stats)) => Some(stats),
_ => None,
}
}
}
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Action handlers // Action handlers
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------