feat(governance): bind km archive confirm to dry-run fingerprint
All checks were successful
Code Review / ai-code-review (push) Successful in 14s
Type Sync Check / check-type-sync (push) Successful in 31s
CD Pipeline / tests (push) Successful in 4m8s
CD Pipeline / build-and-deploy (push) Successful in 4m48s
CD Pipeline / post-deploy-checks (push) Successful in 2m13s

This commit is contained in:
Your Name
2026-05-20 09:19:32 +08:00
parent 83ca72e989
commit 584d2a77ff
8 changed files with 230 additions and 2 deletions

View File

@@ -303,6 +303,7 @@ type KnowledgeReviewDraftArchiveResponse = {
| "already_active"
| "not_requested";
stale_ratio_recheck_dispatch_id?: string | null;
dry_run_plan_fingerprint?: string | null;
next_action: string;
generated_at?: string | null;
};
@@ -1558,6 +1559,22 @@ function KnowledgeGovernancePanel({
}, [t]);
const confirmArchiveDuplicates = useCallback(async (group: KnowledgeReviewDraftDedupeGroup) => {
const dryRunPlanFingerprint =
archiveActions[group.governance_event_id]?.previewResult?.dry_run_plan_fingerprint;
if (!dryRunPlanFingerprint) {
setArchiveActions((current) => ({
...current,
[group.governance_event_id]: {
previewLoading: false,
confirmLoading: false,
previewResult: current[group.governance_event_id]?.previewResult ?? null,
result: null,
error: t("archiveActions.missingPreviewFingerprint"),
},
}));
return;
}
setArchiveActions((current) => ({
...current,
[group.governance_event_id]: {
@@ -1576,6 +1593,7 @@ function KnowledgeGovernancePanel({
owner: "operator_console",
owner_approved: true,
dry_run: false,
dry_run_plan_fingerprint: dryRunPlanFingerprint,
},
15000
);
@@ -1592,7 +1610,7 @@ function KnowledgeGovernancePanel({
if (result?.status === "archived" || result?.status === "noop_already_archived") {
onArchived();
}
}, [onArchived, t]);
}, [archiveActions, onArchived, t]);
return (
<section className="border border-[#e0ddd4] bg-white">
@@ -1723,7 +1741,10 @@ function KnowledgeGovernancePanel({
const archiveAction = archiveActions[group.governance_event_id];
const previewResult = archiveAction?.previewResult ?? null;
const finalResult = archiveAction?.result ?? null;
const previewReady = previewResult?.status === "dry_run";
const previewReady = (
previewResult?.status === "dry_run" &&
Boolean(previewResult.dry_run_plan_fingerprint)
);
const previewKey = groupArchiveStatusKey(previewResult?.status);
const finalResultKey = groupArchiveStatusKey(finalResult?.status);
return (
@@ -1824,6 +1845,11 @@ function KnowledgeGovernancePanel({
<p className="mt-1 text-[#5f5b52]">
{t("archiveActions.previewNext")}
</p>
<p className="mt-1 break-all font-mono text-[11px] text-[#5f5b52]">
{t("archiveActions.planFingerprint", {
fingerprint: previewResult.dry_run_plan_fingerprint ?? "--",
})}
</p>
{previewResult.stale_ratio_snapshot ? (
<p className="mt-1 text-[#5f5b52]">
{t("archiveActions.snapshot", {