//! `POST /api/agents` and `POST /api/agents/{name}/forge-token`. use serde::{Deserialize, Serialize}; /// Where the queued job landed — a caller polls `/api/jobq/graph` (or /// `?states=`) with this id to watch it settle, same as every other job /// kind this daemon will ever queue. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "schema", derive(utoipa::ToSchema))] pub struct CreateAgentResponse { pub node_id: u64, /// Name collisions that were **allowed through**, phrased for the /// operator who just chose the name. /// /// The creation still happened — this is the "loud warning now, refuse /// after a grace period" step, so a caller that ignores this field gets /// exactly today's behaviour. It rides on the response rather than /// living only in the daemon's log because the person who can still fix /// the name in one keystroke is the one holding this response, and they /// are not reading the journal. /// /// Empty (and omitted from the JSON) in the normal case, so a client /// that never looks at it is not handed an empty array to reason about. #[serde(default, skip_serializing_if = "Vec::is_empty")] pub warnings: Vec, } /// Success body of `POST /api/agents/{name}/forge-token`. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "schema", derive(utoipa::ToSchema))] pub struct MintAgentForgeTokenResponse { /// The queued node, so a caller can follow it in the job view. pub node_id: u64, } #[cfg(test)] mod tests { use super::{CreateAgentResponse, MintAgentForgeTokenResponse}; /// No warnings means no `warnings` key, and a body without one still /// decodes: that is the normal response. #[test] fn a_create_response_round_trips() { for (resp, wire) in [ ( CreateAgentResponse { node_id: 7, warnings: vec![], }, r#"{"node_id":7}"#, ), ( CreateAgentResponse { node_id: 7, warnings: vec!["name is reserved".to_owned()], }, r#"{"node_id":7,"warnings":["name is reserved"]}"#, ), ] { assert_eq!(serde_json::to_string(&resp).unwrap(), wire); assert_eq!( serde_json::from_str::(wire).unwrap(), resp ); } } #[test] fn a_forge_token_response_round_trips() { let resp = MintAgentForgeTokenResponse { node_id: 7 }; let wire = r#"{"node_id":7}"#; assert_eq!(serde_json::to_string(&resp).unwrap(), wire); assert_eq!( serde_json::from_str::(wire).unwrap(), resp ); } }