refactor(#2416): remove the non-pr config-change flow (request_apply_commit / applycommit)

This commit is contained in:
damocles 2026-07-15 20:45:29 +02:00 committed by mara
commit c2bd7db998
34 changed files with 293 additions and 1635 deletions

View file

@ -23,7 +23,7 @@ use crate::container_view::ContainerView;
use super::meta_inputs::{MetaInputView, read_meta_inputs};
use super::tombstones::{TombstoneView, build_tombstone_views};
use super::{AppState, approval_diff, approvals, error_response, scan_validated_paths};
use super::{AppState, approvals, error_response, scan_validated_paths};
#[allow(clippy::struct_excessive_bools)]
#[derive(Serialize)]
@ -233,31 +233,16 @@ struct ApprovalView {
id: i64,
agent: String,
kind: &'static str,
/// First 12 chars of the `commit_ref`, for `ApplyCommit` only.
/// Display-only (the short chip on the card).
/// First 12 chars of the reviewed PR head sha, for `MergeConfigPr`
/// only. Display-only (the short chip on the card).
sha_short: Option<String>,
/// Full commit sha, for `ApplyCommit` only. The frontend builds the
/// "commit on forge" link from this rather than `sha_short`: forgejo
/// 404s an abbreviated sha for the proposal commit (it lives on a
/// `proposal/<id>` tag ref, which forgejo won't disambiguate a short
/// hash against), but resolves the full 40-char sha by direct lookup.
#[serde(skip_serializing_if = "Option::is_none")]
sha_full: Option<String>,
/// Raw unified diff text, for `ApplyCommit` only. The client splits
/// on `\n` and per-line classifies (`+` / `-` / `@@` / `--- ` / `+++ `
/// → diff-add / diff-del / diff-hunk / diff-file). Shipping raw
/// instead of pre-rendered HTML saves bytes on the wire (no
/// per-line `<span>` markup) and removes the only HTML-escape
/// surface from the snapshot.
diff: Option<String>,
/// Manager-supplied description shown on the approval card.
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>,
/// Forge PR number, for `MergeConfigPr` only. Lets the frontend
/// build a "review PR on forge" link
/// (`{forgeBase}/agent-configs/{agent}/pulls/{pr_number}`) the same
/// way it builds the `apply_commit` "commit on forge" link from the
/// sha. `None` for every other kind.
/// (`{forgeBase}/agent-configs/{agent}/pulls/{pr_number}`). `None`
/// for every other kind.
#[serde(skip_serializing_if = "Option::is_none")]
pr_number: Option<u64>,
/// Raw `commit_ref` payload for `UpdateMetaInputs` (JSON-encoded
@ -352,7 +337,7 @@ pub(super) async fn api_state(
log_default("approvals.pending", state.coord.approvals.pending()),
);
let transients = build_transient_views(&containers, &transient_snapshot);
let approvals = build_approval_views(pending_approvals).await;
let approvals = build_approval_views(pending_approvals);
let approval_history = log_default(
"approvals.recent_resolved",
state.coord.approvals.recent_resolved(30),
@ -544,8 +529,8 @@ fn transient_label(k: crate::coordinator::TransientKind) -> &'static str {
}
}
/// Render each pending approval into its dashboard view (short sha +
/// unified diff for `ApplyCommit`, just the name for `Spawn`).
/// Render each pending approval into its dashboard view (short sha for
/// `MergeConfigPr`, just the name for `Spawn`).
/// Project a resolved sqlite row into the lean shape the dashboard
/// history tab consumes — no `diff_html` (rendering 30 of them
/// per /api/state poll would mean 30 git diffs per refresh).
@ -576,37 +561,15 @@ fn history_view(a: Approval) -> ApprovalHistoryView {
}
}
async fn build_approval_views(approvals: Vec<Approval>) -> Vec<ApprovalView> {
fn build_approval_views(approvals: Vec<Approval>) -> Vec<ApprovalView> {
let mut out = Vec::with_capacity(approvals.len());
for a in approvals {
out.push(match a.kind {
hive_sh4re::ApprovalKind::ApplyCommit => {
// Prefer the canonical fetched sha from applied;
// commit_ref is only the manager's claim and may be
// amended out from under us.
let displayed = a.fetched_sha.as_deref().unwrap_or(&a.commit_ref);
let sha = displayed[..displayed.len().min(12)].to_owned();
let diff = approval_diff(&a.agent, a.id).await;
ApprovalView {
id: a.id,
agent: a.agent.clone(),
kind: "apply_commit",
sha_short: Some(sha),
sha_full: Some(displayed.to_owned()),
diff: Some(diff),
description: a.description,
pr_number: None,
commit_ref: None,
requested_at: a.requested_at,
}
}
hive_sh4re::ApprovalKind::Spawn => ApprovalView {
id: a.id,
agent: a.agent,
kind: "spawn",
sha_short: None,
sha_full: None,
diff: None,
description: a.description,
pr_number: None,
commit_ref: None,
@ -617,8 +580,6 @@ async fn build_approval_views(approvals: Vec<Approval>) -> Vec<ApprovalView> {
agent: a.agent,
kind: "init_config",
sha_short: None,
sha_full: None,
diff: None,
description: a.description,
pr_number: None,
commit_ref: None,
@ -629,8 +590,6 @@ async fn build_approval_views(approvals: Vec<Approval>) -> Vec<ApprovalView> {
agent: a.agent,
kind: "update_meta_inputs",
sha_short: None,
sha_full: None,
diff: None,
description: a.description,
pr_number: None,
commit_ref: Some(a.commit_ref),
@ -641,8 +600,6 @@ async fn build_approval_views(approvals: Vec<Approval>) -> Vec<ApprovalView> {
agent: a.agent,
kind: "schedule_prompt",
sha_short: None,
sha_full: None,
diff: None,
description: a.description,
pr_number: None,
commit_ref: Some(a.commit_ref),
@ -650,8 +607,8 @@ async fn build_approval_views(approvals: Vec<Approval>) -> Vec<ApprovalView> {
},
hive_sh4re::ApprovalKind::MergeConfigPr => {
// commit_ref = PR number; fetched_sha = the reviewed PR
// head. Show the head sha; the forge PR diff surface is
// a later phase of the PR-based config flow — None for now.
// head. Show the head sha; the config diff surface lives
// on the forge PR itself.
let sha = a
.fetched_sha
.as_deref()
@ -664,8 +621,6 @@ async fn build_approval_views(approvals: Vec<Approval>) -> Vec<ApprovalView> {
agent: a.agent,
kind: "merge_config_pr",
sha_short: sha,
sha_full: None,
diff: None,
description: a.description,
pr_number,
commit_ref: None,