fix(web): show provider source evidence on homepage
This commit is contained in:
@@ -321,6 +321,10 @@
|
||||
"title": "CI/CD notifications enter AwoooP Timeline",
|
||||
"detail": "Gitea main deploys, deploy markers, and post-deploy notifications flow through the AWOOI API and AwoooP Run Timeline."
|
||||
},
|
||||
"sourceDossier": {
|
||||
"title": "Sentry / SigNoz source dossier evidence",
|
||||
"detail": "Latest sources {sources}; Sentry refs {sentry}, SigNoz refs {signoz}. Provider filters verify this, so the overall sample no longer hides source evidence."
|
||||
},
|
||||
"callbackEvidence": {
|
||||
"title": "Telegram detail / history DB truth chain",
|
||||
"detail": "{total} callback evidence rows are available for Run detail, history, and snapshot lookup."
|
||||
@@ -349,7 +353,7 @@
|
||||
},
|
||||
"kmGovernance": {
|
||||
"title": "Stale KM governance",
|
||||
"detail": "{stale} KM rows are older than {days} days; Hermes drafts, owner review, and writeback remain."
|
||||
"detail": "{stale}/{total} KM rows are older than {days} days ({ratio}); pending owner reviews {pending}, entries still needed for threshold {remaining}."
|
||||
},
|
||||
"callbackBacklogDecay": {
|
||||
"title": "Callback legacy backlog 24h decay",
|
||||
@@ -535,6 +539,7 @@
|
||||
},
|
||||
"sources": {
|
||||
"dossierCoverage": "/api/v1/platform/events/dossier/coverage",
|
||||
"dossierCoverageWithProviders": "/api/v1/platform/events/dossier/coverage + provider=sentry/signoz",
|
||||
"runsAndCicd": "/api/v1/platform/runs/list + /api/v1/platform/cicd/events",
|
||||
"aiRouteStatus": "/api/v1/platform/ai-route-status",
|
||||
"runsAndStatusChain": "/api/v1/platform/runs/list + /api/v1/platform/status-chain",
|
||||
@@ -545,7 +550,7 @@
|
||||
},
|
||||
"signal": {
|
||||
"metric": "sources {sources} / refs {refs}",
|
||||
"detail": "missing refs {missing}, duplicates {duplicates}; Alert {alert} / Sentry {sentry} / SigNoz {signoz}"
|
||||
"detail": "missing refs {missing}, duplicates {duplicates}; Alert {alert} / Sentry(provider) {sentry} / SigNoz(provider) {signoz}"
|
||||
},
|
||||
"intake": {
|
||||
"metric": "Runs {runs} / linked {linked}",
|
||||
|
||||
@@ -322,6 +322,10 @@
|
||||
"title": "CI/CD 通知進 AwoooP 時間線",
|
||||
"detail": "Gitea main 推版、deploy marker、post-deploy 通知已走 AWOOI API 與 AwoooP 執行時間線。"
|
||||
},
|
||||
"sourceDossier": {
|
||||
"title": "Sentry / SigNoz 來源卷宗證據",
|
||||
"detail": "最近來源 {sources} 筆;Sentry refs {sentry}、SigNoz refs {signoz},用 provider 篩選驗證,不再被整體樣本誤判。"
|
||||
},
|
||||
"callbackEvidence": {
|
||||
"title": "Telegram 詳情 / 歷史 DB 真相鏈",
|
||||
"detail": "callback evidence 目前 {total} 筆,可從 Runs 反查詳情、歷史與快照。"
|
||||
@@ -350,7 +354,7 @@
|
||||
},
|
||||
"kmGovernance": {
|
||||
"title": "KM 陳舊資料治理",
|
||||
"detail": "超過 {days} 天未更新 KM:{stale} 筆;需 Hermes 產草稿、owner 審核後回寫。"
|
||||
"detail": "超過 {days} 天未更新 KM:{stale}/{total}({ratio});待 owner 審核 {pending} 筆,距離門檻還需處理 {remaining} 筆。"
|
||||
},
|
||||
"callbackBacklogDecay": {
|
||||
"title": "Callback legacy backlog 24h decay",
|
||||
@@ -536,6 +540,7 @@
|
||||
},
|
||||
"sources": {
|
||||
"dossierCoverage": "/api/v1/platform/events/dossier/coverage",
|
||||
"dossierCoverageWithProviders": "/api/v1/platform/events/dossier/coverage + provider=sentry/signoz",
|
||||
"runsAndCicd": "/api/v1/platform/runs/list + /api/v1/platform/cicd/events",
|
||||
"aiRouteStatus": "/api/v1/platform/ai-route-status",
|
||||
"runsAndStatusChain": "/api/v1/platform/runs/list + /api/v1/platform/status-chain",
|
||||
@@ -546,7 +551,7 @@
|
||||
},
|
||||
"signal": {
|
||||
"metric": "來源 {sources} / refs {refs}",
|
||||
"detail": "missing refs {missing},duplicates {duplicates};Alert {alert} / Sentry {sentry} / SigNoz {signoz}"
|
||||
"detail": "missing refs {missing},duplicates {duplicates};Alert {alert} / Sentry(provider) {sentry} / SigNoz(provider) {signoz}"
|
||||
},
|
||||
"intake": {
|
||||
"metric": "Runs {runs} / linked {linked}",
|
||||
|
||||
@@ -193,6 +193,8 @@ interface HomepageAutomationBriefSnapshot {
|
||||
aiRouteStatus?: HomepageAiRouteStatusResponse | null
|
||||
kmStaleCandidates?: HomepageKmStaleCandidatesResponse | null
|
||||
dossierCoverage?: HomepageDossierCoverageResponse | null
|
||||
dossierCoverageSentry?: HomepageDossierCoverageResponse | null
|
||||
dossierCoverageSignoz?: HomepageDossierCoverageResponse | null
|
||||
eventRecurrence?: HomepageEventRecurrenceResponse | null
|
||||
runsList?: HomepageRunsListResponse | null
|
||||
cicdEvents?: HomepageCicdEventsResponse | null
|
||||
@@ -774,7 +776,7 @@ export default function Home({ params }: { params: { locale: string } }) {
|
||||
const controller = new AbortController()
|
||||
const encodedProjectId = encodeURIComponent('awoooi')
|
||||
let isCancelled = false
|
||||
let pendingRequests = 8
|
||||
let pendingRequests = 10
|
||||
const finishRequest = () => {
|
||||
pendingRequests -= 1
|
||||
if (pendingRequests <= 0 && !isCancelled) {
|
||||
@@ -829,6 +831,20 @@ export default function Home({ params }: { params: { locale: string } }) {
|
||||
controller.signal
|
||||
)
|
||||
)
|
||||
loadBriefPart(
|
||||
'dossierCoverageSentry',
|
||||
fetchHomepageJson<HomepageDossierCoverageResponse>(
|
||||
`${API_BASE}/api/v1/platform/events/dossier/coverage?project_id=${encodedProjectId}&provider=sentry&limit=100`,
|
||||
controller.signal
|
||||
)
|
||||
)
|
||||
loadBriefPart(
|
||||
'dossierCoverageSignoz',
|
||||
fetchHomepageJson<HomepageDossierCoverageResponse>(
|
||||
`${API_BASE}/api/v1/platform/events/dossier/coverage?project_id=${encodedProjectId}&provider=signoz&limit=100`,
|
||||
controller.signal
|
||||
)
|
||||
)
|
||||
loadBriefPart(
|
||||
'eventRecurrence',
|
||||
fetchHomepageJson<HomepageEventRecurrenceResponse>(
|
||||
@@ -875,6 +891,8 @@ export default function Home({ params }: { params: { locale: string } }) {
|
||||
const aiRouteStatusLoaded = hasAutomationBriefPart('aiRouteStatus')
|
||||
const kmStaleCandidatesLoaded = hasAutomationBriefPart('kmStaleCandidates')
|
||||
const dossierCoverageLoaded = hasAutomationBriefPart('dossierCoverage')
|
||||
const dossierCoverageSentryLoaded = hasAutomationBriefPart('dossierCoverageSentry')
|
||||
const dossierCoverageSignozLoaded = hasAutomationBriefPart('dossierCoverageSignoz')
|
||||
const eventRecurrenceLoaded = hasAutomationBriefPart('eventRecurrence')
|
||||
const runsListLoaded = hasAutomationBriefPart('runsList')
|
||||
const cicdEventsLoaded = hasAutomationBriefPart('cicdEvents')
|
||||
@@ -943,6 +961,12 @@ export default function Home({ params }: { params: { locale: string } }) {
|
||||
const hasKmStaleCandidates = automationBrief.kmStaleCandidates !== undefined && automationBrief.kmStaleCandidates !== null
|
||||
const canClaimFullAutoRepair = automationQualityAvailable && Boolean(automationQuality?.production_claim?.can_claim_full_auto_repair)
|
||||
const dossierCoverageSummary = automationBrief.dossierCoverage?.summary ?? null
|
||||
const dossierCoverageSentrySummary = automationBrief.dossierCoverageSentry?.summary ?? null
|
||||
const dossierCoverageSignozSummary = automationBrief.dossierCoverageSignoz?.summary ?? null
|
||||
const dossierSentryRefs = dossierCoverageSentrySummary?.sentry_ref_total ?? dossierCoverageSummary?.sentry_ref_total
|
||||
const dossierSignozRefs = dossierCoverageSignozSummary?.signoz_ref_total ?? dossierCoverageSummary?.signoz_ref_total
|
||||
const dossierProviderRefsLoaded = dossierCoverageSentryLoaded && dossierCoverageSignozLoaded
|
||||
const dossierProviderRefsLive = (dossierSentryRefs ?? 0) > 0 || (dossierSignozRefs ?? 0) > 0
|
||||
const recurrenceSummary = automationBrief.eventRecurrence?.summary ?? null
|
||||
const recentRuns = automationBrief.runsList?.runs ?? []
|
||||
const latestRun = recentRuns[0]
|
||||
@@ -999,6 +1023,10 @@ export default function Home({ params }: { params: { locale: string } }) {
|
||||
const cicdNeedsAttention = cicdItems.filter(item => item.needs_attention).length
|
||||
const kmOwnerReviewBurndown = automationBrief.kmOwnerReviewBurndown ?? null
|
||||
const kmBurndownSnapshot = kmOwnerReviewBurndown?.current_snapshot ?? null
|
||||
const kmStaleDisplayCount = kmBurndownSnapshot?.stale_count ?? kmStaleTotal
|
||||
const kmTotalDisplayCount = kmBurndownSnapshot?.total_count
|
||||
const kmEntriesToThreshold = kmOwnerReviewBurndown?.entries_to_threshold
|
||||
const kmGovernanceLoaded = kmOwnerReviewBurndownLoaded || kmStaleCandidatesLoaded
|
||||
const staleRatioLabel = typeof kmBurndownSnapshot?.stale_ratio === 'number'
|
||||
? `${(kmBurndownSnapshot.stale_ratio * 100).toFixed(1)}%`
|
||||
: kmOwnerReviewBurndownLoaded ? unavailableValue : loadingStatus
|
||||
@@ -1029,6 +1057,22 @@ export default function Home({ params }: { params: { locale: string } }) {
|
||||
href: `/${locale}/awooop/runs`,
|
||||
tone: 'live',
|
||||
},
|
||||
{
|
||||
key: 'sourceDossier',
|
||||
title: tDashboard('automationDelivery.delivered.sourceDossier.title'),
|
||||
status: !dossierProviderRefsLoaded
|
||||
? loadingStatus
|
||||
: dossierProviderRefsLive
|
||||
? tDashboard('automationDelivery.status.live')
|
||||
: tDashboard('automationDelivery.status.watching'),
|
||||
detail: tDashboard('automationDelivery.delivered.sourceDossier.detail', {
|
||||
sources: formatAutomationNumber(dossierCoverageSummary?.source_count, dossierCoverageLoaded),
|
||||
sentry: formatAutomationNumber(dossierSentryRefs, dossierCoverageSentryLoaded || dossierCoverageLoaded),
|
||||
signoz: formatAutomationNumber(dossierSignozRefs, dossierCoverageSignozLoaded || dossierCoverageLoaded),
|
||||
}),
|
||||
href: `/${locale}/alerts`,
|
||||
tone: dossierProviderRefsLive ? 'live' : dossierProviderRefsLoaded ? 'watching' : 'progress',
|
||||
},
|
||||
{
|
||||
key: 'callbackEvidence',
|
||||
title: tDashboard('automationDelivery.delivered.callbackEvidence.title'),
|
||||
@@ -1133,19 +1177,23 @@ export default function Home({ params }: { params: { locale: string } }) {
|
||||
{
|
||||
key: 'kmGovernance',
|
||||
title: tDashboard('automationDelivery.remaining.kmGovernance.title'),
|
||||
status: !kmStaleCandidatesLoaded
|
||||
status: !kmGovernanceLoaded
|
||||
? loadingStatus
|
||||
: typeof kmStaleTotal === 'number' && kmStaleTotal > 0
|
||||
: typeof kmStaleDisplayCount === 'number' && kmStaleDisplayCount > 0
|
||||
? tDashboard('automationDelivery.status.progress')
|
||||
: hasKmStaleCandidates
|
||||
? tDashboard('automationDelivery.status.live')
|
||||
: unavailableStatus,
|
||||
detail: tDashboard('automationDelivery.remaining.kmGovernance.detail', {
|
||||
stale: formatAutomationNumber(kmStaleTotal, kmStaleCandidatesLoaded),
|
||||
days: formatAutomationNumber(kmStaleThreshold, kmStaleCandidatesLoaded),
|
||||
stale: formatAutomationNumber(kmStaleDisplayCount, kmGovernanceLoaded),
|
||||
total: formatAutomationNumber(kmTotalDisplayCount, kmOwnerReviewBurndownLoaded),
|
||||
ratio: staleRatioLabel,
|
||||
pending: formatAutomationNumber(kmOwnerReviewBurndown?.pending_owner_reviews, kmOwnerReviewBurndownLoaded),
|
||||
remaining: formatAutomationNumber(kmEntriesToThreshold, kmOwnerReviewBurndownLoaded),
|
||||
days: formatAutomationNumber(kmStaleThreshold ?? kmBurndownSnapshot?.stale_days, kmGovernanceLoaded),
|
||||
}),
|
||||
href: `/${locale}/awooop/work-items?project_id=awoooi`,
|
||||
tone: typeof kmStaleTotal === 'number' && kmStaleTotal > 0 ? 'progress' : hasKmStaleCandidates ? 'live' : 'watching',
|
||||
tone: typeof kmStaleDisplayCount === 'number' && kmStaleDisplayCount > 0 ? 'progress' : hasKmStaleCandidates ? 'live' : 'watching',
|
||||
},
|
||||
{
|
||||
key: 'callbackBacklogDecay',
|
||||
@@ -1243,11 +1291,16 @@ export default function Home({ params }: { params: { locale: string } }) {
|
||||
missing: formatAutomationNumber(dossierCoverageSummary?.missing_source_refs_total, dossierCoverageLoaded),
|
||||
duplicates: formatAutomationNumber(dossierCoverageSummary?.duplicate_total, dossierCoverageLoaded),
|
||||
alert: formatAutomationNumber(dossierCoverageSummary?.alert_ref_total, dossierCoverageLoaded),
|
||||
sentry: formatAutomationNumber(dossierCoverageSummary?.sentry_ref_total, dossierCoverageLoaded),
|
||||
signoz: formatAutomationNumber(dossierCoverageSummary?.signoz_ref_total, dossierCoverageLoaded),
|
||||
sentry: formatAutomationNumber(dossierSentryRefs, dossierCoverageSentryLoaded || dossierCoverageLoaded),
|
||||
signoz: formatAutomationNumber(dossierSignozRefs, dossierCoverageSignozLoaded || dossierCoverageLoaded),
|
||||
}),
|
||||
source: tDashboard('automationDiagrams.workspace.liveEvidence.sources.dossierCoverage'),
|
||||
updated: formatLiveEvidenceTime(dossierCoverageSummary?.latest_received_at, dossierCoverageLoaded),
|
||||
source: tDashboard('automationDiagrams.workspace.liveEvidence.sources.dossierCoverageWithProviders'),
|
||||
updated: formatLiveEvidenceTime(
|
||||
dossierCoverageSummary?.latest_received_at
|
||||
?? dossierCoverageSentrySummary?.latest_received_at
|
||||
?? dossierCoverageSignozSummary?.latest_received_at,
|
||||
dossierCoverageLoaded || dossierProviderRefsLoaded
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1430,13 +1483,13 @@ export default function Home({ params }: { params: { locale: string } }) {
|
||||
nextAction: tDashboard('automationDiagrams.workspace.inspector.stages.verify.nextAction'),
|
||||
liveEvidence: {
|
||||
metric: tDashboard('automationDiagrams.workspace.liveEvidence.verify.metric', {
|
||||
stale: formatAutomationNumber(kmBurndownSnapshot?.stale_count ?? kmStaleTotal, kmOwnerReviewBurndownLoaded || kmStaleCandidatesLoaded),
|
||||
stale: formatAutomationNumber(kmStaleDisplayCount, kmGovernanceLoaded),
|
||||
ratio: staleRatioLabel,
|
||||
}),
|
||||
detail: tDashboard('automationDiagrams.workspace.liveEvidence.verify.detail', {
|
||||
pending: formatAutomationNumber(kmOwnerReviewBurndown?.pending_owner_reviews, kmOwnerReviewBurndownLoaded),
|
||||
completed: formatAutomationNumber(kmOwnerReviewBurndown?.completed_owner_reviews, kmOwnerReviewBurndownLoaded),
|
||||
remaining: formatAutomationNumber(kmOwnerReviewBurndown?.entries_to_threshold, kmOwnerReviewBurndownLoaded),
|
||||
remaining: formatAutomationNumber(kmEntriesToThreshold, kmOwnerReviewBurndownLoaded),
|
||||
}),
|
||||
source: tDashboard('automationDiagrams.workspace.liveEvidence.sources.kmBurndown'),
|
||||
updated: formatLiveEvidenceTime(kmOwnerReviewBurndown?.generated_at, kmOwnerReviewBurndownLoaded),
|
||||
|
||||
Reference in New Issue
Block a user