feat(web): expand Runs automation asset focus ledger
All checks were successful
Code Review / ai-code-review (push) Successful in 14s
CD Pipeline / tests (push) Successful in 1m36s
CD Pipeline / build-and-deploy (push) Successful in 4m31s
CD Pipeline / post-deploy-checks (push) Successful in 1m37s

This commit is contained in:
Your Name
2026-06-25 23:37:53 +08:00
parent 6e6c8609de
commit 8514d936cb
4 changed files with 45 additions and 0 deletions

View File

@@ -10507,6 +10507,14 @@
"title": "資產沉澱",
"summary": "完成 {ready} / 卡點 {blocked}",
"boundary": "只讀推導;不代表已寫入 KM、更新 PlayBook trust、套用腳本 / 排程或執行 verifier。",
"detailsTitle": "焦點資產 ID",
"details": {
"workItem": "Work Item",
"dryRun": "乾跑",
"apply": "套用候選",
"verifier": "Verifier",
"nextStep": "下一步"
},
"items": {
"km": "KM",
"playbook": "PlayBook",

View File

@@ -10507,6 +10507,14 @@
"title": "資產沉澱",
"summary": "完成 {ready} / 卡點 {blocked}",
"boundary": "只讀推導;不代表已寫入 KM、更新 PlayBook trust、套用腳本 / 排程或執行 verifier。",
"detailsTitle": "焦點資產 ID",
"details": {
"workItem": "Work Item",
"dryRun": "乾跑",
"apply": "套用候選",
"verifier": "Verifier",
"nextStep": "下一步"
},
"items": {
"km": "KM",
"playbook": "PlayBook",

View File

@@ -4743,6 +4743,7 @@ export default function RunsPage() {
<AwoooPAutomationAssetLedger
chain={incidentFocusChain}
remediationSummary={null}
showDetails
/>
</div>
</div>

View File

@@ -29,13 +29,17 @@ function valueLabel(value: number, fallback: string) {
export function AwoooPAutomationAssetLedger({
chain,
remediationSummary,
showDetails = false,
className,
}: {
chain?: AwoooPStatusChain | null;
remediationSummary?: AutomationAssetRemediationSummary | null;
showDetails?: boolean;
className?: string;
}) {
const t = useTranslations("awooop.automationAssetLedger");
const handoff = chain?.automation_handoff;
const handoffAssets = handoff?.asset_ids;
const kmCount = chain?.evidence?.knowledge_entries ?? 0;
const playbookCount = (chain?.execution?.playbook_ids?.length ?? 0)
+ (chain?.execution?.playbook_paths?.length ?? 0);
@@ -107,6 +111,13 @@ export function AwoooPAutomationAssetLedger({
] satisfies Array<{ key: string; tone: AutomationAssetTone; value: string }>;
const readyCount = items.filter((item) => item.tone === "ready").length;
const blockedCount = items.filter((item) => item.tone === "blocked").length;
const detailItems = [
{ key: "workItem", value: handoff?.work_item_id },
{ key: "dryRun", value: handoffAssets?.dry_run },
{ key: "apply", value: handoffAssets?.apply_candidate },
{ key: "verifier", value: handoffAssets?.verifier },
{ key: "nextStep", value: handoff?.next_action ?? chain?.next_step },
].filter((item) => Boolean(item.value));
return (
<div className={cn("min-w-[260px] border border-[#e0ddd4] bg-white p-2", className)}>
@@ -134,6 +145,23 @@ export function AwoooPAutomationAssetLedger({
<p className="mt-2 text-[11px] leading-5 text-[#77736a]">
{t("boundary")}
</p>
{showDetails && detailItems.length > 0 && (
<div className="mt-2 border-t border-[#eee9dd] pt-2">
<p className="text-[11px] font-semibold text-[#141413]">{t("detailsTitle")}</p>
<dl className="mt-2 space-y-1.5">
{detailItems.map((item) => (
<div key={item.key} className="min-w-0">
<dt className="text-[10px] font-semibold uppercase tracking-[0.08em] text-[#9a968c]">
{t(`details.${item.key}` as never)}
</dt>
<dd className="mt-0.5 break-all font-mono text-[11px] leading-4 text-[#141413]">
{String(item.value)}
</dd>
</div>
))}
</dl>
</div>
)}
</div>
);
}