diff --git a/apps/web/src/app/[locale]/reports/page.tsx b/apps/web/src/app/[locale]/reports/page.tsx index 242789a76..0599f4210 100644 --- a/apps/web/src/app/[locale]/reports/page.tsx +++ b/apps/web/src/app/[locale]/reports/page.tsx @@ -59,11 +59,16 @@ interface IncidentSummary { total?: number resolved?: number unresolved?: number + total_incidents?: number + resolved_rate?: number + status_distribution?: Array<{ status: string; count: number }> } interface ResolutionStats { resolutionRate?: number avgResolutionTime?: string | number + avg_minutes?: number | null + sample_size?: number } interface ReportStatusCard { @@ -157,8 +162,8 @@ export default function ReportsPage({ params }: { params: { locale: string } }) setLoading(true) setError(false) Promise.all([ - fetchJson('/api/v1/stats/incident-summary'), - fetchJson('/api/v1/stats/resolution-stats'), + fetchJson('/api/v1/stats/incidents/summary?days=30'), + fetchJson('/api/v1/stats/incidents/resolution?days=30'), fetchJson('/api/v1/stats/disposition'), fetchJson('/api/v1/agents/agent-report-status-board'), ]) @@ -182,11 +187,23 @@ export default function ReportsPage({ params }: { params: { locale: string } }) useEffect(() => { fetchAll() }, []) const ds = disposition?.summary + const incidentTotal = summary?.total ?? summary?.total_incidents ?? 0 + const resolvedFromDistribution = summary?.status_distribution + ?.filter(item => item.status.toLowerCase().includes('resolved')) + .reduce((sum, item) => sum + item.count, 0) + const resolvedCount = summary?.resolved ?? resolvedFromDistribution + const unresolvedCount = summary?.unresolved ?? ( + resolvedCount != null ? Math.max(incidentTotal - resolvedCount, 0) : undefined + ) + const incidentResolvedRate = summary?.resolved_rate ?? resolution?.resolutionRate + const avgResolutionTime = resolution?.avgResolutionTime ?? ( + resolution?.avg_minutes != null ? `${Math.round(resolution.avg_minutes)}m` : undefined + ) const sourceOkCount = Object.values(sourceState).filter(Boolean).length const sourceTotal = Object.keys(sourceState).length const allZeroSignal = Boolean( sourceOkCount > 0 && - (summary?.total ?? 0) === 0 && + incidentTotal === 0 && (ds?.total ?? 0) === 0 && (ds?.auto_repair ?? 0) === 0 && (ds?.human_approved ?? 0) === 0 @@ -275,7 +292,7 @@ export default function ReportsPage({ params }: { params: { locale: string } }) } label={t('command.metrics.alerts')} - value={summary?.total ?? '--'} + value={incidentTotal || '--'} detail={allZeroSignal ? t('command.details.noSignal') : t('command.details.alertSignal')} tone={allZeroSignal ? 'warn' : 'neutral'} /> @@ -356,8 +373,8 @@ export default function ReportsPage({ params }: { params: { locale: string } })
} title={t('funnel.title')} subtitle={t('funnel.subtitle')} />
- - + + 0 ? 'danger' : 'ok'} /> @@ -464,16 +481,16 @@ export default function ReportsPage({ params }: { params: { locale: string } })

{t('incidentSummary')}

- - - + + +

{t('resolutionStats')}

- - + +