import { useCallback, useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { AlertCircle, Loader2 } from "lucide-react"; import { LineChart, PieChart } from "./command-center/charts/recharts"; import type { LineChartSeries, PieChartDatum } from "./command-center/charts/recharts"; import "./ReliabilityView.css"; type ReliabilityResponse = { windowDays: number; generatedAt: string; resetAt: string | null; headline: { inReviewFailureRate7d: number | null; reason?: string }; perDay: Array<{ date: string; tasksEnteredInReview: number; tasksBouncedToInProgress: number; postMergeAuditFailures: { block: number; warn: number; off: number } | null; fileScopeInvariantFailures: number | null; recoverAlreadyMergedReviewTasksRecoveries: number | null; hasSamples?: boolean; }>; duration: { p50Ms: number | null; p95Ms: number | null; sampleCount: number; reason?: string }; mergeAttempts: { mean: number | null; max: number | null; histogram: Record; reason?: string }; }; function formatPercent(value: number): string { return `${(value * 100).toFixed(1)}%`; } function formatDuration(value: number | null): string { if (value === null) { return "—"; } return `${(value / 60_000).toFixed(1)}m`; } function formatDateTime(value: string | null | undefined): string { if (!value) { return "—"; } const parsed = new Date(value); return Number.isNaN(parsed.getTime()) ? value : parsed.toLocaleString(); } export function ReliabilityView() { const { t } = useTranslation("app"); const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [showEmptyDays, setShowEmptyDays] = useState(false); const [showResetConfirm, setShowResetConfirm] = useState(false); const [resetError, setResetError] = useState(null); const load = useCallback(async () => { setIsLoading(true); setError(null); try { const response = await fetch("/api/health/reliability"); if (!response.ok) { throw new Error(`Failed to load reliability metrics (${response.status})`); } const payload = (await response.json()) as ReliabilityResponse; setData(payload); } catch (loadError: unknown) { setError(loadError instanceof Error ? loadError.message : t("reliability.failedToLoad", "Failed to load reliability metrics")); } finally { setIsLoading(false); } }, [t]); const resetStats = useCallback(async () => { setResetError(null); const response = await fetch("/api/health/reliability/reset", { method: "POST" }); if (!response.ok) { throw new Error(`Failed to reset reliability metrics (${response.status})`); } await load(); setShowResetConfirm(false); }, [load]); useEffect(() => { void load(); const pollInterval = setInterval(() => { void load(); }, 60_000); return () => clearInterval(pollInterval); }, [load]); const failureRate = data?.headline.inReviewFailureRate7d; const reliabilityRate = useMemo(() => { if (failureRate === null || failureRate === undefined) return null; return Math.max(0, Math.min(1, 1 - failureRate)); }, [failureRate]); const headlineColorVar = useMemo(() => { if (reliabilityRate === null) return "var(--text-muted)"; if (reliabilityRate >= 0.95) return "var(--color-success)"; if (reliabilityRate >= 0.9) return "var(--color-warning)"; return "var(--color-error)"; }, [reliabilityRate]); const totalEntered = useMemo(() => (data?.perDay ?? []).reduce((sum, row) => sum + row.tasksEnteredInReview, 0), [data?.perDay]); const totalBounced = useMemo(() => (data?.perDay ?? []).reduce((sum, row) => sum + row.tasksBouncedToInProgress, 0), [data?.perDay]); const perDayRows = useMemo(() => { if (!data?.perDay) return []; const filteredRows = showEmptyDays ? data.perDay : data.perDay.filter((row) => row.hasSamples !== false); return [...filteredRows].sort((left, right) => left.date.localeCompare(right.date)); }, [data?.perDay, showEmptyDays]); /* FNXC:Reliability 2026-06-19-00:00: The in-review trend chart must reuse the same perDayRows source as the table, including the Show empty days filter, so visual and tabular reliability surfaces never disagree about which dates are represented. */ const flowChartSeries = useMemo(() => { const hasFlowSamples = perDayRows.some((row) => row.tasksEnteredInReview > 0 || row.tasksBouncedToInProgress > 0); if (!hasFlowSamples) return []; return [ { label: t("reliability.flowChart.entered", "Entered"), values: perDayRows.map((row) => row.tasksEnteredInReview) }, { label: t("reliability.flowChart.bounced", "Bounced"), values: perDayRows.map((row) => row.tasksBouncedToInProgress) }, ]; }, [perDayRows, t]); const mergeAttemptsHistogramEntries = useMemo( () => Object.entries(data?.mergeAttempts.histogram ?? {}).sort(([left], [right]) => left.localeCompare(right, undefined, { numeric: true })), [data?.mergeAttempts.histogram], ); const mergeAttemptsChartData = useMemo( () => mergeAttemptsHistogramEntries.map(([bucket, count]) => ({ label: bucket, value: count })), [mergeAttemptsHistogramEntries], ); const mergeAttemptTaskCount = useMemo( () => mergeAttemptsHistogramEntries.reduce((sum, [, count]) => sum + count, 0), [mergeAttemptsHistogramEntries], ); const windowStartLabel = data ? formatDateTime(data.resetAt ?? new Date(Date.parse(data.generatedAt) - data.windowDays * 86_400_000).toISOString()) : "—"; if (isLoading && data === null) { return (

{t("reliability.loading", "Loading reliability data...")}

); } if (error !== null && data === null) { return (

{error}

); } return (

{t("reliability.heading", "Reliability")}

{failureRate === null || failureRate === undefined ? t("reliability.insufficientData", "Insufficient data — {{reason}}", { reason: data?.headline.reason ?? "unknown" }) : formatPercent(reliabilityRate ?? 0)}
{reliabilityRate !== null ?
{t("reliability.successRateLabel", "In-review success rate (last 7d)")}
: null} {data?.resetAt ?
{t("reliability.countingSince", "Counting since {{date}}", { date: formatDateTime(data.resetAt) })}
: null}
{t("reliability.details", "Details")}
{t("reliability.bouncedEntered", "{{bounced}} bounced / {{entered}} entered (last {{days}}d)", { bounced: totalBounced, entered: totalEntered, days: data?.windowDays ?? 7 })}
{failureRate !== null && failureRate !== undefined ?
{t("reliability.failureRate", "Failure rate: {{rate}}", { rate: formatPercent(failureRate) })}
: null}
{t("reliability.window", "Window: {{start}} → {{end}}", { start: windowStartLabel, end: formatDateTime(data?.generatedAt) })}
{data?.resetAt ?
{t("reliability.resetBaseline", "Reset baseline: {{date}}", { date: formatDateTime(data.resetAt) })}
: null} {data?.headline.reason ?
{t("reliability.reason", "Reason: {{reason}}", { reason: data.headline.reason })}
: null}

{t("reliability.inReviewFlow", "In-review flow")}

{t("reliability.flowChart.heading", "Entered vs bounced trend")}

{perDayRows.map((row) => ( ))}
{t("reliability.table.date", "Date")}{t("reliability.table.entered", "Entered")}{t("reliability.table.bounced", "Bounced")}
{row.date}{row.tasksEnteredInReview}{row.tasksBouncedToInProgress}

{t("reliability.duration.heading", "Duration")}

{t("reliability.duration.p50", "P50")}{formatDuration(data?.duration.p50Ms ?? null)}
{t("reliability.duration.p95", "P95")}{formatDuration(data?.duration.p95Ms ?? null)}
{t("reliability.duration.samples", "Samples: {{count}}", { count: data?.duration.sampleCount ?? 0 })}
{t("reliability.duration.moreStats", "More stats")}
{t("reliability.duration.p50Raw", "P50 raw: {{value}} ms", { value: data?.duration.p50Ms ?? "—" })}
{t("reliability.duration.p95Raw", "P95 raw: {{value}} ms", { value: data?.duration.p95Ms ?? "—" })}
{t("reliability.duration.sampleCount", "Sample count: {{count}}", { count: data?.duration.sampleCount ?? 0 })}
{data?.duration.reason ?
{t("reliability.duration.reason", "Reason: {{reason}}", { reason: data.duration.reason })}
: null}

{t("reliability.mergeAttempts.heading", "Merge attempts")}

{t("reliability.mergeAttempts.mean", "Mean")}{data?.mergeAttempts.mean?.toFixed(2) ?? "—"}
{t("reliability.mergeAttempts.max", "Max")}{data?.mergeAttempts.max ?? "—"}

{t("reliability.mergeAttemptsChart.heading", "Attempts distribution")}

    {mergeAttemptsHistogramEntries.map(([bucket, count]) => (
  • {bucket}
    {count}
  • ))}
{t("reliability.mergeAttempts.moreStats", "More stats")}
{t("reliability.mergeAttempts.tasksCounted", "Tasks counted: {{count}}", { count: mergeAttemptTaskCount })}
{t("reliability.mergeAttempts.histogramTotal", "Histogram total: {{count}}", { count: mergeAttemptTaskCount })}
{data?.mergeAttempts.reason ?
{t("reliability.mergeAttempts.reason", "Reason: {{reason}}", { reason: data.mergeAttempts.reason })}
: null}
{showResetConfirm ? (

{t("reliability.resetModal.title", "Reset reliability stats?")}

{t("reliability.resetModal.description", "This sets a new baseline for reliability statistics. Historical events older than the reset time are excluded from counts but are not deleted.")}

{resetError ?
{resetError}
: null}
) : null}
); }