fix(web): stream homepage evidence sources independently
All checks were successful
CD Pipeline / tests (push) Successful in 1m30s
Code Review / ai-code-review (push) Successful in 11s
CD Pipeline / build-and-deploy (push) Successful in 3m38s
CD Pipeline / post-deploy-checks (push) Successful in 1m51s

This commit is contained in:
Your Name
2026-05-26 11:45:48 +08:00
parent 5cfee5cf1b
commit 01c6cb2941

View File

@@ -769,62 +769,94 @@ export default function Home({ params }: { params: { locale: string } }) {
useEffect(() => {
const controller = new AbortController()
const encodedProjectId = encodeURIComponent('awoooi')
Promise.all([
let isCancelled = false
let pendingRequests = 8
const finishRequest = () => {
pendingRequests -= 1
if (pendingRequests <= 0 && !isCancelled) {
setAutomationBriefLoaded(true)
}
}
const loadBriefPart = <K extends keyof HomepageAutomationBriefSnapshot>(
key: K,
request: Promise<HomepageAutomationBriefSnapshot[K]>
) => {
request
.then(value => {
if (!isCancelled) {
setAutomationBrief(previous => ({ ...previous, [key]: value }))
}
})
.catch(() => {
if (!isCancelled) {
setAutomationBrief(previous => ({ ...previous, [key]: null }))
}
})
.finally(finishRequest)
}
setAutomationBrief({})
setAutomationBriefLoaded(false)
loadBriefPart(
'callbackReplies',
fetchHomepageJson<HomepageCallbackRepliesResponse>(
`${API_BASE}/api/v1/platform/runs/callback-replies?project_id=${encodedProjectId}&per_page=20`,
controller.signal
),
)
)
loadBriefPart(
'aiRouteStatus',
fetchHomepageJson<HomepageAiRouteStatusResponse>(
`${API_BASE}/api/v1/platform/ai-route-status?workload_type=deep_rca`,
controller.signal
),
)
)
loadBriefPart(
'kmStaleCandidates',
fetchHomepageJson<HomepageKmStaleCandidatesResponse>(
`${API_BASE}/api/v1/ai/governance/km-stale-candidates?project_id=${encodedProjectId}&limit=5`,
controller.signal
),
)
)
loadBriefPart(
'dossierCoverage',
fetchHomepageJson<HomepageDossierCoverageResponse>(
`${API_BASE}/api/v1/platform/events/dossier/coverage?project_id=${encodedProjectId}&limit=100`,
controller.signal
),
)
)
loadBriefPart(
'eventRecurrence',
fetchHomepageJson<HomepageEventRecurrenceResponse>(
`${API_BASE}/api/v1/platform/events/dossier/recurrence?project_id=${encodedProjectId}&limit=100`,
controller.signal
),
)
)
loadBriefPart(
'runsList',
fetchHomepageJson<HomepageRunsListResponse>(
`${API_BASE}/api/v1/platform/runs/list?project_id=${encodedProjectId}&per_page=25`,
controller.signal
),
)
)
loadBriefPart(
'cicdEvents',
fetchHomepageJson<HomepageCicdEventsResponse>(
`${API_BASE}/api/v1/platform/cicd/events?project_id=${encodedProjectId}&limit=12`,
controller.signal
),
)
)
loadBriefPart(
'kmOwnerReviewBurndown',
fetchHomepageJson<HomepageKmOwnerReviewBurndownResponse>(
`${API_BASE}/api/v1/ai/governance/km-stale-owner-review-burndown?project_id=${encodedProjectId}&limit=5`,
controller.signal
),
]).then(([
callbackReplies,
aiRouteStatus,
kmStaleCandidates,
dossierCoverage,
eventRecurrence,
runsList,
cicdEvents,
kmOwnerReviewBurndown,
]) => {
setAutomationBrief({
callbackReplies,
aiRouteStatus,
kmStaleCandidates,
dossierCoverage,
eventRecurrence,
runsList,
cicdEvents,
kmOwnerReviewBurndown,
})
}).catch(() => {})
.finally(() => setAutomationBriefLoaded(true))
return () => controller.abort()
)
)
return () => {
isCancelled = true
controller.abort()
}
}, [])
// 自動處置率 — 首頁 KPI 使用 24h truth-chain 驗證率,避免把歷史 disposition 總表誤讀成今日閉環。