fix(web): parse string readiness checks on monitoring System tab
CI / changes (push) Successful in 6s
CI / commitlint (push) Skipped
CI / go (push) Skipped
CI / bird2 (push) Skipped
CI / openapi (push) Successful in 38s
CI / web (push) Successful in 54s
CI / release (push) Successful in 3m59s

Исправляет ложные «Ошибки проверок»: GET /v1/ready отдаёт строки ok/memory, а не boolean. Уплотнён ReUI Frame/donut layout на вкладке Система.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Denozordec
2026-08-12 13:41:58 +07:00
co-authored by Cursor
parent 32d9dc6acb
commit 6a25a3d137
8 changed files with 235 additions and 67 deletions
+43 -41
View File
@@ -81,7 +81,7 @@ function MonitoringComponent() {
.slice(0, 5)
return (
<div className="flex flex-col gap-6">
<div className="flex flex-col gap-2 md:gap-3">
<PageHeader
title="Мониторинг"
description={`Состояние API, BGP и задач для диагностики инцидентов${
@@ -110,11 +110,11 @@ function MonitoringComponent() {
{ value: 'runtime-logs', label: 'Файловые логи' },
]}
>
<TabsContent value="system" className="mt-0 flex flex-col gap-6">
<TabsContent value="system" className="mt-0 flex flex-col gap-2 md:gap-3">
{analyticsLoading ? (
<AnalyticsDashboardSkeleton />
) : (
<div className="grid gap-4 lg:grid-cols-2">
<div className="grid items-stretch gap-2 md:gap-3 lg:grid-cols-2">
<MonitoringHealthCard
healthOk={healthQ.data?.ok ?? false}
ready={readyQ.data}
@@ -124,7 +124,7 @@ function MonitoringComponent() {
</div>
)}
<div className="grid gap-4 lg:grid-cols-2">
<div className="grid items-stretch gap-2 md:gap-3 lg:grid-cols-2">
<FrameDataGrid
title="Доступность и готовность"
description="GET /v1/health · GET /v1/ready"
@@ -149,23 +149,24 @@ function MonitoringComponent() {
</span>
}
description="GET /v1/bird/status"
contentClassName="py-4"
className="h-full"
contentClassName="px-5 py-4"
>
<QueryState
data={birdQ.data}
isLoading={birdQ.isLoading}
isError={birdQ.isError}
error={birdQ.error}
skeleton={<div className="h-40" />}
onRetry={() => birdQ.refetch()}
>
{(bird) => <BirdSummary bird={bird} />}
</QueryState>
<QueryState
data={birdQ.data}
isLoading={birdQ.isLoading}
isError={birdQ.isError}
error={birdQ.error}
skeleton={<div className="h-40" />}
onRetry={() => birdQ.refetch()}
>
{(bird) => <BirdSummary bird={bird} />}
</QueryState>
</PanelCard>
</div>
<div className="grid gap-4 lg:grid-cols-2">
<div className="flex flex-col gap-4">
<div className="grid items-stretch gap-2 md:gap-3 lg:grid-cols-2">
<div className="flex flex-col gap-2 md:gap-3">
<SegmentedProgressCard
title="Задачи"
description="Последние 100 задач · GET /v1/jobs"
@@ -189,8 +190,8 @@ function MonitoringComponent() {
footer={`В выборке: ${jobs.length} задач`}
/>
{failedJobs.length > 0 ? (
<PanelCard title="Последние ошибки" contentClassName="space-y-2 py-4">
<ul className="space-y-2">
<PanelCard title="Последние ошибки" contentClassName="px-5 py-4">
<ul className="flex flex-col gap-2">
{failedJobs.map((job) => (
<li key={job.job_id} className="rounded-lg border px-3 py-2 text-sm">
<div className="flex items-start justify-between gap-2">
@@ -218,28 +219,29 @@ function MonitoringComponent() {
</span>
}
description="Краткая шпаргалка для первичной диагностики"
contentClassName="py-4"
className="h-full"
contentClassName="px-5 py-4"
>
<ul className="space-y-3 text-sm text-muted-foreground">
<li>
<span className="font-medium text-foreground">API недоступен.</span> Если{' '}
<code className="text-xs">/v1/health</code> возвращает ошибку — проверьте процесс API и
его логи.
</li>
<li>
<span className="font-medium text-foreground">Готовность не «Готов».</span> Сначала{' '}
<code className="text-xs">postgres</code>, затем <code className="text-xs">store</code>{' '}
и <code className="text-xs">jobs</code> в проверках.
</li>
<li>
<span className="font-medium text-foreground">Низкий ratio BGP.</span> Проверьте{' '}
<code className="text-xs">/v1/bird/status</code>, затем состояние пиров в Сети.
</li>
<li>
<span className="font-medium text-foreground">Ошибки задач.</span> Откройте Операции и
проверьте последние неуспешные задачи.
</li>
</ul>
<ul className="flex flex-col gap-3 text-sm text-muted-foreground">
<li>
<span className="font-medium text-foreground">API недоступен.</span> Если{' '}
<code className="text-xs">/v1/health</code> возвращает ошибку — проверьте процесс API и
его логи.
</li>
<li>
<span className="font-medium text-foreground">Готовность не «Готов».</span> Сначала{' '}
<code className="text-xs">postgres</code>, затем <code className="text-xs">store</code>{' '}
и <code className="text-xs">jobs</code> в проверках.
</li>
<li>
<span className="font-medium text-foreground">Низкий ratio BGP.</span> Проверьте{' '}
<code className="text-xs">/v1/bird/status</code>, затем состояние пиров в Сети.
</li>
<li>
<span className="font-medium text-foreground">Ошибки задач.</span> Откройте Операции и
проверьте последние неуспешные задачи.
</li>
</ul>
</PanelCard>
</div>
</TabsContent>
@@ -282,7 +284,7 @@ function BirdSummary({ bird }: { bird: import('@/types/api').BirdStatus }) {
? Math.round((bird.bgp_established / bird.bgp_sessions_total) * 100)
: null
return (
<div className="space-y-2">
<div className="flex flex-col gap-2">
<div className="flex items-center justify-between text-sm">
<span className="text-muted-foreground">Установлено / всего</span>
<span className="font-medium tabular-nums">