fix(#1218): bulk topology move uses one git commit via new set-parent-bulk endpoint
This commit is contained in:
parent
644519f358
commit
7ec0a36d7a
4 changed files with 179 additions and 4 deletions
|
|
@ -78,6 +78,7 @@ pub async fn serve(port: u16, coord: Arc<Coordinator>) -> Result<()> {
|
|||
.route("/retry-reminder/{id}", post(post_retry_reminder))
|
||||
.route("/request-spawn", post(post_request_spawn))
|
||||
.route("/api/topology/set-parent", post(post_set_parent))
|
||||
.route("/api/topology/set-parent-bulk", post(post_set_parent_bulk))
|
||||
.route("/api/tool-groups", get(get_tool_groups))
|
||||
.route("/api/tool-groups/{agent}", post(post_tool_groups))
|
||||
.route("/api/capabilities", get(get_capabilities))
|
||||
|
|
@ -1054,6 +1055,15 @@ struct SetParentForm {
|
|||
new_parent: Option<String>,
|
||||
}
|
||||
|
||||
/// One entry in a `POST /api/topology/set-parent-bulk` JSON array.
|
||||
/// `new_parent`: absent/null/empty-string all mean "promote to root".
|
||||
#[derive(Deserialize)]
|
||||
struct SetParentBulkEntry {
|
||||
child: String,
|
||||
#[serde(default)]
|
||||
new_parent: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct AnswerForm {
|
||||
answer: String,
|
||||
|
|
@ -2476,6 +2486,36 @@ async fn post_set_parent(
|
|||
}
|
||||
}
|
||||
|
||||
/// `POST /api/topology/set-parent-bulk` — move multiple agents in a single
|
||||
/// request, producing **one** git commit. JSON body: `[{"child":"name",
|
||||
/// "new_parent":"target-or-null"}, ...]`. Empty array is a no-op (200 OK).
|
||||
/// First validation error aborts the whole batch.
|
||||
async fn post_set_parent_bulk(
|
||||
State(state): State<AppState>,
|
||||
axum::Json(body): axum::Json<Vec<SetParentBulkEntry>>,
|
||||
) -> Response {
|
||||
if body.is_empty() {
|
||||
return (StatusCode::OK, "ok").into_response();
|
||||
}
|
||||
// Collect borrows for the coordinator call.
|
||||
let moves: Vec<(&str, Option<&str>)> = body
|
||||
.iter()
|
||||
.map(|e| {
|
||||
let child: &str = &e.child;
|
||||
let parent: Option<&str> = e.new_parent.as_deref().filter(|s| !s.is_empty());
|
||||
(child, parent)
|
||||
})
|
||||
.collect();
|
||||
match state.coord.reparent_bulk_with_notify(&moves).await {
|
||||
Ok(()) => {
|
||||
let names: Vec<&str> = body.iter().map(|e| e.child.as_str()).collect();
|
||||
tracing::info!(agents = ?names, "operator: set-parent-bulk via dashboard");
|
||||
(StatusCode::OK, "ok").into_response()
|
||||
}
|
||||
Err(e) => error_response(&format!("set-parent-bulk failed: {e}")),
|
||||
}
|
||||
}
|
||||
|
||||
// ── tool-group endpoints ──────────────────────────────────
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
|
|
|||
Loading…
Reference in a new issue