hive-agent: replace json! with typed structs in web_ui handlers
This commit is contained in:
parent
127846ef1b
commit
786e4610f0
3 changed files with 34 additions and 15 deletions
|
|
@ -7,7 +7,7 @@ use axum::{
|
||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
response::{IntoResponse, Response},
|
response::{IntoResponse, Response},
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::{AppState, SigintOutcome, error_response};
|
use super::{AppState, SigintOutcome, error_response};
|
||||||
|
|
||||||
|
|
@ -202,5 +202,10 @@ pub(super) async fn post_mark_todos_done(Form(form): Form<MarkTodosDoneForm>) ->
|
||||||
acked += count;
|
acked += count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
axum::Json(serde_json::json!({ "acked": acked })).into_response()
|
axum::Json(MarkTodosDoneBody { acked }).into_response()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct MarkTodosDoneBody {
|
||||||
|
acked: u64,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use axum::response::{IntoResponse, Response};
|
use axum::response::{IntoResponse, Response};
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::AppState;
|
use super::AppState;
|
||||||
|
|
||||||
|
|
@ -40,6 +40,11 @@ async fn fetch_reminder_stats(window_secs: u64) -> Option<hive_sh4re::approvals:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct TodosBody {
|
||||||
|
todos: Vec<hive_sh4re::inbox::LooseEnd>,
|
||||||
|
}
|
||||||
|
|
||||||
/// `GET /api/todos` — snapshot of this agent's local todos (loose-ends v2).
|
/// `GET /api/todos` — snapshot of this agent's local todos (loose-ends v2).
|
||||||
///
|
///
|
||||||
/// Connects to the in-agent harness socket (`HIVE_AGENT_SOCKET`) and calls
|
/// Connects to the in-agent harness socket (`HIVE_AGENT_SOCKET`) and calls
|
||||||
|
|
@ -54,5 +59,5 @@ pub(super) async fn api_todos() -> Response {
|
||||||
Some(hive_agent_sock::Response::LooseEnds { loose_ends }) => loose_ends,
|
Some(hive_agent_sock::Response::LooseEnds { loose_ends }) => loose_ends,
|
||||||
_ => Vec::new(),
|
_ => Vec::new(),
|
||||||
};
|
};
|
||||||
axum::Json(serde_json::json!({ "todos": todos })).into_response()
|
axum::Json(TodosBody { todos }).into_response()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,23 @@ use std::convert::Infallible;
|
||||||
use axum::Json;
|
use axum::Json;
|
||||||
use axum::extract::{Query, State};
|
use axum::extract::{Query, State};
|
||||||
use axum::response::sse::{Event, KeepAlive, Sse};
|
use axum::response::sse::{Event, KeepAlive, Sse};
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio_stream::{Stream, StreamExt, wrappers::BroadcastStream};
|
use tokio_stream::{Stream, StreamExt, wrappers::BroadcastStream};
|
||||||
|
|
||||||
use super::AppState;
|
use super::AppState;
|
||||||
|
|
||||||
|
/// Response body for `GET /api/events/history`. `seq` is omitted from the
|
||||||
|
/// wire entirely on a paginated (non-initial) load — matches the old
|
||||||
|
/// `json!` shape, which only ever set the `"seq"` key when `Some`.
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub(super) struct EventsHistoryBody {
|
||||||
|
events: Vec<crate::events::StoredEvent>,
|
||||||
|
min_id: Option<i64>,
|
||||||
|
has_more: bool,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
seq: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Query params for the paginated history endpoint.
|
/// Query params for the paginated history endpoint.
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub(super) struct HistoryParams {
|
pub(super) struct HistoryParams {
|
||||||
|
|
@ -23,7 +35,7 @@ pub(super) struct HistoryParams {
|
||||||
pub(super) async fn events_history(
|
pub(super) async fn events_history(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
Query(params): Query<HistoryParams>,
|
Query(params): Query<HistoryParams>,
|
||||||
) -> Json<serde_json::Value> {
|
) -> Json<EventsHistoryBody> {
|
||||||
use crate::events::HISTORY_CAPACITY;
|
use crate::events::HISTORY_CAPACITY;
|
||||||
let limit = params.limit.unwrap_or(100).min(HISTORY_CAPACITY);
|
let limit = params.limit.unwrap_or(100).min(HISTORY_CAPACITY);
|
||||||
let before = params.before;
|
let before = params.before;
|
||||||
|
|
@ -51,15 +63,12 @@ pub(super) async fn events_history(
|
||||||
se
|
se
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let mut resp = serde_json::json!({
|
Json(EventsHistoryBody {
|
||||||
"events": events,
|
events,
|
||||||
"min_id": min_id,
|
min_id,
|
||||||
"has_more": has_more,
|
has_more,
|
||||||
});
|
seq,
|
||||||
if let Some(s) = seq {
|
})
|
||||||
resp["seq"] = serde_json::json!(s);
|
|
||||||
}
|
|
||||||
Json(resp)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) async fn events_stream(
|
pub(super) async fn events_stream(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue