hive-c0re: annotate the 3 SSE/stream dashboard routes with utoipa

This commit is contained in:
damocles 2026-08-01 00:01:07 +02:00 committed by mara
commit d10eebd455
3 changed files with 50 additions and 26 deletions

View file

@ -7,10 +7,8 @@ use std::sync::Arc;
use anyhow::{Context, Result};
use axum::{
Router,
http::StatusCode,
response::{IntoResponse, Response},
routing::get,
};
use utoipa::OpenApi;
use utoipa_axum::{router::OpenApiRouter, routes};
@ -120,27 +118,12 @@ pub async fn serve(
) -> Result<()> {
// API-only: the gateway static-serves the dashboard dist and proxies
// non-static requests here (see hive-gateway.nix). Unmatched paths 404.
// Every `#[utoipa::path]`-annotated route is registered further down
// via `OpenApiRouter` instead of a plain `.route(...)` call here — see
// the `router`/`api` split below. What's left in this plain chain is
// exactly the SSE/streaming endpoints utoipa can't model (see the
// `ApiDoc` doc comment) plus anything not yet annotated.
let app = Router::new()
.route(
"/api/build-logs/id/{id}/stream",
get(build_logs::get_build_log_stream),
)
.route(
"/api/dashboard/stream",
get(state_snapshot::dashboard_stream),
)
.route(
"/api/dashboard/history",
get(state_snapshot::dashboard_history),
)
// No static fallback — the gateway owns the dist; unmatched paths 404.
;
// No static fallback needed here either. Every route (SSE streams
// included — `utoipa::path` can document an SSE body as an opaque
// `text/event-stream` string, it just can't model individual frame
// shapes) is registered below via `OpenApiRouter`; see the `router`/
// `api` split.
//
// `routes!()` folds every handler it's given into ONE shared
// `MethodRouter` for the whole macro invocation — it does NOT group
// by path internally, so passing it handlers for more than one
@ -219,7 +202,9 @@ pub async fn serve(
.routes(routes!(questions::post_cancel_question))
.routes(routes!(tombstones::post_purge_tombstone))
.routes(routes!(meta_inputs::post_meta_update))
.merge(app.into())
.routes(routes!(build_logs::get_build_log_stream))
.routes(routes!(state_snapshot::dashboard_stream))
.routes(routes!(state_snapshot::dashboard_history))
.split_for_parts();
let app = router
.merge(SwaggerUi::new("/api/docs").url("/api/openapi.json", api))
@ -453,6 +438,9 @@ mod router_build_probe {
.routes(routes!(questions::post_answer_question))
.routes(routes!(questions::post_cancel_question))
.routes(routes!(tombstones::post_purge_tombstone))
.routes(routes!(meta_inputs::post_meta_update));
.routes(routes!(meta_inputs::post_meta_update))
.routes(routes!(build_logs::get_build_log_stream))
.routes(routes!(state_snapshot::dashboard_stream))
.routes(routes!(state_snapshot::dashboard_history));
}
}