dashboard: approval_added / approval_resolved mutation events + client derived state

This commit is contained in:
müde 2026-05-17 13:30:25 +02:00
parent 291f1fce42
commit 56d615b51f
6 changed files with 244 additions and 11 deletions

View file

@ -157,6 +157,7 @@ async fn dispatch(req: &ManagerRequest, coord: &Arc<Coordinator>) -> ManagerResp
) {
Ok(id) => {
tracing::info!(%id, %name, "spawn approval queued");
coord.emit_approval_added(id, name, "spawn", None, None, description.clone());
ManagerResponse::Ok
}
Err(e) => ManagerResponse::Err {
@ -382,7 +383,17 @@ async fn submit_apply_commit(
// dashboard reflects it instead of leaving a phantom
// pending entry. The note doubles as the operator-visible
// explanation of why the approval can't be approved.
let _ = coord.approvals.mark_failed(id, &format!("{e:#}"));
let note = format!("{e:#}");
let _ = coord.approvals.mark_failed(id, &note);
coord.emit_approval_resolved(
id,
agent,
"apply_commit",
None,
"failed",
Some(note),
description.map(str::to_owned),
);
return Err(anyhow::anyhow!("git_fetch_to_tag: {e:#}"));
}
};
@ -390,6 +401,19 @@ async fn submit_apply_commit(
.approvals
.set_fetched_sha(id, &sha)
.map_err(|e| anyhow::anyhow!("persist fetched_sha: {e:#}"))?;
// Phase 5b: surface the new pending approval on the dashboard
// event channel. Compute the diff once here so live subscribers
// get a fully-formed row without a snapshot refetch.
let sha_short = sha[..sha.len().min(12)].to_owned();
let diff = crate::dashboard::approval_diff(agent, id).await;
coord.emit_approval_added(
id,
agent,
"apply_commit",
Some(sha_short),
Some(diff),
description.map(str::to_owned),
);
Ok((id, sha))
}