feat(awooop): pin manager situation board
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 1m0s
CD Pipeline / build-and-deploy (push) Successful in 7m9s
CD Pipeline / post-deploy-checks (push) Has been cancelled
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 1m0s
CD Pipeline / build-and-deploy (push) Successful in 7m9s
CD Pipeline / post-deploy-checks (push) Has been cancelled
This commit is contained in:
@@ -9180,6 +9180,51 @@
|
||||
"evidenceBoundary": "證據邊界"
|
||||
}
|
||||
},
|
||||
"managerSituation": {
|
||||
"eyebrow": "Manager overview",
|
||||
"title": "StockPlatform P0",
|
||||
"subtitle": "Blocker, impact, and next action are pinned to the first screen.",
|
||||
"loading": "Reading production readback.",
|
||||
"head": "Deployed source",
|
||||
"decision": "Decision",
|
||||
"decisionValue": "Fix P0, no side lane",
|
||||
"blockingSources": "Blocking sources",
|
||||
"noSourceNames": "Waiting for source contract readback",
|
||||
"states": {
|
||||
"sourceContract": "Source contract blocked",
|
||||
"preflight": "Recovery preflight blocked",
|
||||
"publicApi": "Public API blocked",
|
||||
"ready": "Ready to verify",
|
||||
"review": "Awaiting readback"
|
||||
},
|
||||
"cards": {
|
||||
"now": {
|
||||
"label": "Current blocker",
|
||||
"detail": "{id}"
|
||||
},
|
||||
"impact": {
|
||||
"label": "Impact",
|
||||
"value": "Public API not green",
|
||||
"detail": "Source trust is not sufficient."
|
||||
},
|
||||
"evidence": {
|
||||
"label": "Evidence",
|
||||
"value": "{count} sources failed",
|
||||
"receipted": "receipt provided",
|
||||
"missing": "receipt missing"
|
||||
},
|
||||
"next": {
|
||||
"label": "Next step",
|
||||
"value": "Repair source contract",
|
||||
"detail": "Run verifier immediately after repair."
|
||||
}
|
||||
},
|
||||
"chips": {
|
||||
"noDbWrite": "no DB write",
|
||||
"noSecret": "no secret",
|
||||
"publicVerifier": "public verifier"
|
||||
}
|
||||
},
|
||||
"stockplatformP0Receipt": {
|
||||
"eyebrow": "P0-006 Runtime receipt",
|
||||
"title": "StockPlatform data dependency readback",
|
||||
|
||||
@@ -9180,6 +9180,51 @@
|
||||
"evidenceBoundary": "證據邊界"
|
||||
}
|
||||
},
|
||||
"managerSituation": {
|
||||
"eyebrow": "管理者總覽",
|
||||
"title": "StockPlatform P0",
|
||||
"subtitle": "卡點、影響、下一步先放第一屏。",
|
||||
"loading": "正在讀取正式 readback。",
|
||||
"head": "正式部署",
|
||||
"decision": "決策",
|
||||
"decisionValue": "先修 P0,不開支線",
|
||||
"blockingSources": "阻塞來源",
|
||||
"noSourceNames": "等待 source contract readback",
|
||||
"states": {
|
||||
"sourceContract": "來源合約卡住",
|
||||
"preflight": "修復預檢卡住",
|
||||
"publicApi": "公開 API 卡住",
|
||||
"ready": "已可驗證",
|
||||
"review": "等待判讀"
|
||||
},
|
||||
"cards": {
|
||||
"now": {
|
||||
"label": "目前卡點",
|
||||
"detail": "{id}"
|
||||
},
|
||||
"impact": {
|
||||
"label": "影響",
|
||||
"value": "公開 API 未綠燈",
|
||||
"detail": "資料來源可信度不足"
|
||||
},
|
||||
"evidence": {
|
||||
"label": "證據",
|
||||
"value": "{count} 個來源未通過",
|
||||
"receipted": "receipt 已收件",
|
||||
"missing": "receipt 未到"
|
||||
},
|
||||
"next": {
|
||||
"label": "下一步",
|
||||
"value": "補來源合約",
|
||||
"detail": "修完直接跑 verifier"
|
||||
}
|
||||
},
|
||||
"chips": {
|
||||
"noDbWrite": "不寫 DB",
|
||||
"noSecret": "不讀 secret",
|
||||
"publicVerifier": "公開驗證器"
|
||||
}
|
||||
},
|
||||
"stockplatformP0Receipt": {
|
||||
"eyebrow": "P0-006 Runtime receipt",
|
||||
"title": "StockPlatform 資料依賴回讀",
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
GitPullRequest,
|
||||
ListChecks,
|
||||
Network,
|
||||
Radar,
|
||||
RefreshCw,
|
||||
SearchCheck,
|
||||
ShieldCheck,
|
||||
@@ -1065,7 +1066,16 @@ type CommanderInsertedRequirementWorkItem = {
|
||||
};
|
||||
|
||||
type PriorityWorkOrderResponse = {
|
||||
current_head?: {
|
||||
gitea_main_sha?: string | null;
|
||||
latest_successful_deployed_source_sha?: string | null;
|
||||
latest_successful_deploy_marker?: string | null;
|
||||
production_source_truth_available?: boolean | null;
|
||||
} | null;
|
||||
summary?: {
|
||||
active_p0_state?: string | null;
|
||||
next_executable_mainline_workplan_id?: string | null;
|
||||
next_executable_mainline_state?: string | null;
|
||||
commander_inserted_requirement_work_item_count?: number | null;
|
||||
commander_inserted_requirement_p0_count?: number | null;
|
||||
commander_inserted_requirement_p1_count?: number | null;
|
||||
@@ -1187,6 +1197,11 @@ type PriorityWorkOrderResponse = {
|
||||
stockplatform_source_contract_receipt_provided?: boolean | null;
|
||||
stockplatform_source_contract_ready?: boolean | null;
|
||||
stockplatform_source_contract_non_ok_source_count?: number | null;
|
||||
stockplatform_source_contract_blocking_sources?: Array<{
|
||||
source?: string | null;
|
||||
category?: string | null;
|
||||
status?: string | null;
|
||||
}> | null;
|
||||
} | null;
|
||||
}>;
|
||||
next_execution_order?: string[] | null;
|
||||
@@ -8732,6 +8747,187 @@ function stockplatformCompactTone(value: string | boolean | null | undefined) {
|
||||
return "border-[#c9d8ea] bg-[#eef5ff] text-[#1f5b9b]";
|
||||
}
|
||||
|
||||
function shortSha(value: string | null | undefined) {
|
||||
return value ? value.slice(0, 10) : "--";
|
||||
}
|
||||
|
||||
function stockplatformManagerStateKey(value: string | null | undefined) {
|
||||
const state = String(value ?? "");
|
||||
if (state.includes("source_contract")) return "sourceContract";
|
||||
if (state.includes("preflight")) return "preflight";
|
||||
if (state.includes("public_api")) return "publicApi";
|
||||
if (state.includes("ready")) return "ready";
|
||||
return "review";
|
||||
}
|
||||
|
||||
function ManagerSituationBoard({
|
||||
priority,
|
||||
loading,
|
||||
}: {
|
||||
priority: PriorityWorkOrderResponse | null;
|
||||
loading: boolean;
|
||||
}) {
|
||||
const t = useTranslations("awooop.workItems.managerSituation");
|
||||
const summary = priority?.summary;
|
||||
const evidence = priority?.in_progress_or_blocked_in_priority_order?.find(
|
||||
(item) =>
|
||||
item.evidence?.stockplatform_source_contract_readback_status ||
|
||||
item.evidence?.stockplatform_public_api_runtime_status
|
||||
)?.evidence;
|
||||
const activeWorkplan =
|
||||
summary?.next_executable_mainline_workplan_id ??
|
||||
"P0-006-STOCKPLATFORM-PUBLIC-API-CONTROLLED-RECOVERY-PREFLIGHT";
|
||||
const activeState =
|
||||
summary?.active_p0_state ??
|
||||
"blocked_stockplatform_public_api_controlled_recovery_preflight";
|
||||
const activeStateLabel = t(
|
||||
`states.${stockplatformManagerStateKey(activeState)}` as never
|
||||
);
|
||||
const sourceContractStatus =
|
||||
summary?.stockplatform_source_contract_readback_status ??
|
||||
evidence?.stockplatform_source_contract_readback_status ??
|
||||
"unknown";
|
||||
const nonOkSourceCount =
|
||||
summary?.stockplatform_source_contract_non_ok_source_count ??
|
||||
evidence?.stockplatform_source_contract_non_ok_source_count ??
|
||||
0;
|
||||
const receiptProvided =
|
||||
summary?.stockplatform_source_contract_receipt_provided ??
|
||||
evidence?.stockplatform_source_contract_receipt_provided ??
|
||||
false;
|
||||
const blockingSources =
|
||||
evidence?.stockplatform_source_contract_blocking_sources?.slice(0, 3) ?? [];
|
||||
const sourceNames = blockingSources
|
||||
.map((source) => source.source)
|
||||
.filter(Boolean)
|
||||
.join(" / ");
|
||||
const deployedSha =
|
||||
priority?.current_head?.latest_successful_deployed_source_sha ??
|
||||
priority?.current_head?.gitea_main_sha;
|
||||
const managerCards = [
|
||||
{
|
||||
key: "now",
|
||||
icon: TriangleAlert,
|
||||
label: t("cards.now.label"),
|
||||
value: activeStateLabel,
|
||||
detail: t("cards.now.detail", {
|
||||
id: activeWorkplan.startsWith("P0-006") ? "P0-006" : activeWorkplan,
|
||||
}),
|
||||
tone: "border-[#f0c6a8] bg-[#fff8f1] text-[#9a4d16]",
|
||||
},
|
||||
{
|
||||
key: "impact",
|
||||
icon: Database,
|
||||
label: t("cards.impact.label"),
|
||||
value: t("cards.impact.value"),
|
||||
detail: t("cards.impact.detail"),
|
||||
tone: "border-[#c9d8ea] bg-[#eef5ff] text-[#1f5b9b]",
|
||||
},
|
||||
{
|
||||
key: "evidence",
|
||||
icon: SearchCheck,
|
||||
label: t("cards.evidence.label"),
|
||||
value: t("cards.evidence.value", { count: nonOkSourceCount }),
|
||||
detail: receiptProvided ? t("cards.evidence.receipted") : t("cards.evidence.missing"),
|
||||
tone: stockplatformCompactTone(sourceContractStatus),
|
||||
},
|
||||
{
|
||||
key: "next",
|
||||
icon: ArrowRight,
|
||||
label: t("cards.next.label"),
|
||||
value: t("cards.next.value"),
|
||||
detail: t("cards.next.detail"),
|
||||
tone: "border-[#cbd7bf] bg-[#f4faef] text-[#3d6b24]",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<section
|
||||
className="border border-[#d8d3c7] bg-white"
|
||||
data-testid="awooop-manager-situation-board"
|
||||
>
|
||||
<div className="grid gap-px bg-[#e0ddd4] lg:grid-cols-[minmax(0,1.15fr)_minmax(0,1.85fr)]">
|
||||
<div className="bg-[#141413] p-4 text-white">
|
||||
<div className="flex items-center gap-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[#c9d8ea]">
|
||||
<Radar className="h-4 w-4" aria-hidden="true" />
|
||||
{t("eyebrow")}
|
||||
</div>
|
||||
<h3 className="mt-3 text-xl font-semibold tracking-normal">
|
||||
{t("title")}
|
||||
</h3>
|
||||
<p className="mt-2 text-sm leading-5 text-[#eee9dd]">
|
||||
{loading ? t("loading") : t("subtitle")}
|
||||
</p>
|
||||
<div className="mt-4 grid gap-2 sm:grid-cols-2">
|
||||
<div className="border border-[#4d4b44] bg-[#1d1c19] px-3 py-2">
|
||||
<div className="text-[11px] font-semibold text-[#b7b4a8]">
|
||||
{t("head")}
|
||||
</div>
|
||||
<div className="mt-1 font-mono text-sm font-semibold">
|
||||
{shortSha(deployedSha)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="border border-[#4d4b44] bg-[#1d1c19] px-3 py-2">
|
||||
<div className="text-[11px] font-semibold text-[#b7b4a8]">
|
||||
{t("decision")}
|
||||
</div>
|
||||
<div className="mt-1 text-sm font-semibold">
|
||||
{t("decisionValue")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white p-3">
|
||||
<div className="grid gap-2 md:grid-cols-2 xl:grid-cols-4">
|
||||
{managerCards.map((card) => {
|
||||
const Icon = card.icon;
|
||||
return (
|
||||
<div
|
||||
key={card.key}
|
||||
className={cn("min-w-0 border px-3 py-3", card.tone)}
|
||||
>
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<div className="text-[11px] font-semibold">{card.label}</div>
|
||||
<Icon className="h-4 w-4 shrink-0" aria-hidden="true" />
|
||||
</div>
|
||||
<div className="mt-2 break-words text-sm font-semibold leading-5 text-[#141413]">
|
||||
{loading ? "--" : card.value}
|
||||
</div>
|
||||
<div className="mt-1 break-words text-xs leading-4 text-[#5f5b52]">
|
||||
{loading ? "--" : card.detail}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="mt-2 grid gap-2 border border-[#d8d3c7] bg-[#faf9f3] p-2 lg:grid-cols-[minmax(0,1fr)_auto]">
|
||||
<div className="min-w-0">
|
||||
<div className="text-[11px] font-semibold text-[#77736a]">
|
||||
{t("blockingSources")}
|
||||
</div>
|
||||
<div className="mt-1 break-words font-mono text-xs font-semibold text-[#141413]">
|
||||
{loading ? "--" : sourceNames || t("noSourceNames")}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-1.5 text-[11px] font-semibold">
|
||||
<span className="border border-[#d8d3c7] bg-white px-2 py-1 text-[#5f5b52]">
|
||||
{t("chips.noDbWrite")}
|
||||
</span>
|
||||
<span className="border border-[#d8d3c7] bg-white px-2 py-1 text-[#5f5b52]">
|
||||
{t("chips.noSecret")}
|
||||
</span>
|
||||
<span className="border border-[#d8d3c7] bg-white px-2 py-1 text-[#5f5b52]">
|
||||
{t("chips.publicVerifier")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function StockPlatformP0ReceiptPanel({
|
||||
priority,
|
||||
loading,
|
||||
@@ -9607,11 +9803,7 @@ export default function AwoooPWorkItemsPage() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ProductionClaimBanner loading={loading} summary={telemetry.quality} />
|
||||
|
||||
<AutonomousRuntimeReceiptPanel mode="compact" />
|
||||
|
||||
<AiLoopLogSourceTagsPanel
|
||||
<ManagerSituationBoard
|
||||
priority={priorityWorkOrder}
|
||||
loading={priorityWorkOrderLoading && !priorityWorkOrder}
|
||||
/>
|
||||
@@ -9621,6 +9813,15 @@ export default function AwoooPWorkItemsPage() {
|
||||
loading={priorityWorkOrderLoading && !priorityWorkOrder}
|
||||
/>
|
||||
|
||||
<ProductionClaimBanner loading={loading} summary={telemetry.quality} />
|
||||
|
||||
<AutonomousRuntimeReceiptPanel mode="compact" />
|
||||
|
||||
<AiLoopLogSourceTagsPanel
|
||||
priority={priorityWorkOrder}
|
||||
loading={priorityWorkOrderLoading && !priorityWorkOrder}
|
||||
/>
|
||||
|
||||
<CommanderInsertedRequirementsPanel
|
||||
priority={commanderInsertedRequirementWorkOrder}
|
||||
loading={false}
|
||||
|
||||
Reference in New Issue
Block a user