Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/hive-c0re/src/dashboard/misc_api.rs
iris fa131b46a6 dashboard: remove the flow page and the endpoints only it used
The flow page showed the raw broker message stream and had a compose box.
This removes the page and its bundle, its link in the pages menu, and the
styles only it used.

The history endpoint that backfilled it and the operator-send endpoint
behind the compose box had no other caller, so they go too, along with
the broker query behind the history endpoint. The stream endpoint stays:
the dashboard tabs still subscribe to it.

The docs lose the FL0W section and the references to the two endpoints.
2026-10-21 23:57:37 +02:00

84 lines
2.7 KiB
Rust

//! Remaining single-endpoint dashboard handlers: mark-all-read,
//! spawn-request and hive-wide turn stats.
use axum::{
extract::{Path as AxumPath, State},
http::StatusCode,
response::{IntoResponse, Response},
};
use serde::{Deserialize, Serialize};
use utoipa::{IntoParams, ToSchema};
use super::{AppState, Ident, error_response};
use crate::hive_stats::HiveStats;
#[derive(Deserialize, IntoParams)]
pub(super) struct StatsHiveQuery {
/// Stats window; defaults to `24h`.
window: Option<String>,
}
/// Hive-wide turn-stats rollup for the dashboard swarm-stats view.
///
/// Aggregates every agent's `hyperhive-turn-stats.sqlite` read-only
/// (skips missing/unreadable ones).
#[utoipa::path(
get,
path = "/api/stats-hive",
params(StatsHiveQuery),
responses((status = 200, description = "hive-wide turn-stats rollup", body = HiveStats)),
tag = "misc_api"
)]
pub(super) async fn api_stats_hive(
State(state): State<AppState>,
axum::extract::Query(q): axum::extract::Query<StatsHiveQuery>,
) -> Response {
let window = crate::hive_stats::Window::parse(q.window.as_deref().unwrap_or("24h"));
axum::Json(crate::hive_stats::hive_snapshot(
window,
&state.coord.model_prices,
))
.into_response()
}
#[derive(Serialize, ToSchema)]
pub(super) struct MarkAllReadBody {
marked: u64,
}
/// Operator-driven "clear this agent's inbox" — backs the side-panel
/// "mark all read" button.
///
/// Marks every message addressed to the agent as acked (backfilling
/// `delivered_at` for any still-pending rows so vacuum can collect
/// them). `marked` lets the frontend show "cleared N messages"
/// feedback without an extra fetch.
#[utoipa::path(
post,
path = "/api/agent/{name}/mark-all-read",
params(("name" = String, Path, description = "agent name")),
responses(
(status = 200, description = "count of messages marked read", body = MarkAllReadBody),
(status = 400, description = "bad agent name"),
(status = 500, description = "broker write failed"),
),
tag = "misc_api"
)]
pub(super) async fn post_mark_all_read(
State(state): State<AppState>,
AxumPath(name): AxumPath<String>,
) -> Response {
let name = match Ident::parse(&name) {
Ok(n) => n,
Err(reason) => {
return (StatusCode::BAD_REQUEST, format!("bad agent name: {reason}")).into_response();
}
};
match state.coord.broker.mark_all_read(name.as_str()) {
Ok(marked) => {
tracing::info!(%name, marked, "operator marked all messages read");
axum::Json(MarkAllReadBody { marked }).into_response()
}
Err(e) => error_response(&format!("mark-all-read {name} failed: {e:#}")),
}
}