use axum::Json;
use axum::http::StatusCode;
use serde::Serialize;
use crate::server::AppState;
#[derive(Serialize)]
pub struct HealthResponse {
status: &'static str,
version: &'static str,
}
#[cfg_attr(feature = "openapi", utoipa::path(
get,
path = "/api/health",
tag = "system",
responses(
(status = 200, description = "Service is up and its own DID (if configured) resolves locally; returns status + version", content_type = "application/json"),
(status = 503, description = "Service is up but its own DID isn't being served locally, or it has not reconciled with its control plane within the staleness bound", content_type = "application/json"),
),
))]
pub async fn health(state: AppState) -> (StatusCode, Json<HealthResponse>) {
let ok = did_hosting_common::server::health::own_did_served_locally(
&state.dids_ks,
state.config.server_did.as_deref(),
)
.await
&& crate::replication::is_fresh(&state);
let status = if ok {
StatusCode::OK
} else {
StatusCode::SERVICE_UNAVAILABLE
};
(
status,
Json(HealthResponse {
status: if ok { "ok" } else { "degraded" },
version: env!("CARGO_PKG_VERSION"),
}),
)
}