use serde::Serialize;
use crate::catalog::{ApiMethodSpec, Platform};
use crate::node::session::NodeSessionState;
use crate::node::{NodeRole, registry::NodeAvailability};
use crate::server::runtime::PlatformServeMode;
#[derive(Debug, Serialize)]
pub struct PlatformSummary {
pub platform: Platform,
pub api_base_path: &'static str,
pub method_count: usize,
pub has_cookie: bool,
pub mode: PlatformServeMode,
pub published: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub route_node: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub route_source: Option<PlatformRouteSource>,
}
#[derive(Debug, Serialize)]
pub struct RootResponse {
pub name: &'static str,
pub version: &'static str,
pub mode: &'static str,
pub status: &'static str,
pub bind: String,
pub base_url: String,
pub endpoints: Vec<&'static str>,
pub platforms: Vec<PlatformSummary>,
#[serde(skip_serializing_if = "Option::is_none")]
pub node: Option<NodeSummary>,
pub runtime_routes: Vec<RuntimeRouteSummary>,
pub downstream_nodes: Vec<DownstreamNodeSummary>,
}
#[derive(Debug, Serialize)]
pub struct NodeSummary {
pub node_id: Option<String>,
pub role: Option<NodeRole>,
pub availability: NodeAvailability,
pub capabilities: Vec<String>,
pub max_concurrent_tasks: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub upstream: Option<UpstreamConnectionSummary>,
pub downstream_authenticating: usize,
pub downstream_ready: usize,
pub downstream_degraded: usize,
pub downstream_draining: usize,
pub downstream_isolated: usize,
}
#[derive(Debug, Serialize)]
pub struct DownstreamNodeSummary {
pub session_id: String,
pub node_id: String,
pub role: NodeRole,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
pub session_state: NodeSessionState,
pub availability: NodeAvailability,
pub capabilities: Vec<String>,
pub platforms: Vec<String>,
pub max_concurrent_tasks: Option<u32>,
pub active_tasks: u32,
pub connected_at_ms: u64,
pub last_seen_ms: u64,
}
#[derive(Debug, Serialize)]
pub struct RuntimeRouteSummary {
pub platform: Platform,
pub route_node: String,
}
#[derive(Debug, Clone, Copy, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum PlatformRouteSource {
Configured,
Runtime,
}
#[derive(Debug, Serialize)]
pub struct UpstreamConnectionSummary {
pub connected: bool,
pub state: NodeSessionState,
#[serde(skip_serializing_if = "Option::is_none")]
pub session_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub node_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub role: Option<NodeRole>,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub capabilities: Vec<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub platforms: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub connected_at_ms: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_seen_ms: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_disconnect_ms: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_error: Option<String>,
}
#[derive(Debug, Serialize)]
pub struct HealthResponse {
pub status: &'static str,
pub service: &'static str,
pub version: &'static str,
#[serde(skip_serializing_if = "Option::is_none")]
pub node: Option<NodeHealthSummary>,
}
#[derive(Debug, Serialize)]
pub struct NodeHealthSummary {
pub node_id: Option<String>,
pub role: Option<NodeRole>,
pub availability: NodeAvailability,
pub ready: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub upstream: Option<UpstreamConnectionSummary>,
pub downstream_total: usize,
pub downstream_authenticating: usize,
pub downstream_ready: usize,
pub downstream_degraded: usize,
pub downstream_draining: usize,
pub downstream_isolated: usize,
}
#[derive(Debug, Serialize)]
pub struct ApiCatalogResponse {
pub version: &'static str,
pub platforms: Vec<PlatformCatalogResponse>,
}
#[derive(Debug, Serialize)]
pub struct PlatformCatalogResponse {
pub platform: Platform,
pub api_base_path: &'static str,
pub method_count: usize,
pub methods: Vec<ApiMethodSpec>,
}
#[derive(Debug, Serialize)]
pub struct CatalogErrorResponse {
pub error: &'static str,
pub platform: String,
}
#[derive(Debug, Serialize)]
pub struct FetchErrorResponse {
pub error: &'static str,
pub detail: String,
}
#[derive(Debug, Serialize)]
pub struct ControlErrorResponse {
pub error: &'static str,
pub detail: String,
}
#[derive(Debug, Serialize)]
pub struct ControlActionResponse {
pub ok: bool,
pub action: &'static str,
#[serde(skip_serializing_if = "Option::is_none")]
pub target: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub detail: Option<String>,
}
#[derive(Debug, Serialize)]
pub struct RuntimeRouteMutationResponse {
pub ok: bool,
pub runtime_routes: Vec<RuntimeRouteSummary>,
pub cleared_platforms: Vec<Platform>,
}