fix(alerts): обозначить недоступность событий префиксов

This commit is contained in:
Denozordec committed 2026-10-03 19:55:31 +07:00
1 parent f3ec6b31ce
commit c7e1f75e2e
5 files changed
+29 -5

No files matched your search

+9 -3
View File
@@ -710,12 +710,13 @@ function SeverityBadge({ severity }: { severity: AlertSeverity }) {
// ─── alert rule row ───────────────────────────────────────────────────────────
function AlertRuleRow({ rule, onToggle, onDelete, onEdit, interactionsDisabled }: {
function AlertRuleRow({ rule, onToggle, onDelete, onEdit, interactionsDisabled,isLive }: {
rule: AlertRule
onToggle: (id: string, enabled: boolean) => void
onDelete: (id: string) => void
onEdit?: (id: string) => void
interactionsDisabled?: boolean
isLive:boolean
}) {
const { Icon, iconClass, bg } = TYPE_META[rule.type]
@@ -725,7 +726,7 @@ function AlertRuleRow({ rule, onToggle, onDelete, onEdit, interactionsDisabled }
!rule.enabled && "opacity-55",
)}>
{/* toggle */}
<FormToggle ariaLabel={"Включить правило "+rule.name} checked={rule.enabled} onChange={v => onToggle(rule.id, v)} disabled={interactionsDisabled} />
<FormToggle ariaLabel={"Включить правило "+rule.name} checked={rule.enabled} onChange={v => onToggle(rule.id, v)} disabled={interactionsDisabled||(isLive&&rule.type==="bgp-prefix"&&!rule.enabled)} />
{/* severity dot */}
<SeverityDot severity={rule.severity} />
@@ -737,6 +738,7 @@ function AlertRuleRow({ rule, onToggle, onDelete, onEdit, interactionsDisabled }
{/* name + target */}
<div className="flex-1 min-w-0">
{isLive&&rule.type==="bgp-prefix"?<p role="status" className="text-xs text-warning">Отслеживание появления и отзыва префиксов пока недоступно. Это правило не проверяется.</p>:null}
<p className="text-sm font-medium truncate">{rule.name}</p>
<p className="text-[11px] text-muted-foreground truncate">
{TYPE_META[rule.type].label} ·{" "}
@@ -1722,6 +1724,8 @@ function AddRuleSheet({
{/* ── scrollable body ── */}
<fieldset disabled={saving} className="min-h-0 min-w-0 flex-1 overflow-y-auto px-4 sm:px-6 py-5 flex flex-col gap-5 [&>div]:shrink-0">
{isLive&&form.type==="bgp-prefix"?<p role="status" className="text-xs text-warning">Отслеживание появления и отзыва префиксов пока недоступно. Сохранённое правило не проверяется; можно изменить его тип или отключить в списке.</p>:null}
{/* name */}
<div className="flex flex-col gap-1.5">
<div className="flex items-center justify-between gap-2">
@@ -1768,6 +1772,7 @@ function AddRuleSheet({
key={t}
type="button"
aria-pressed={active}
disabled={isLive&&t==="bgp-prefix"}
onClick={() => {
nameTouchedRef.current = false
@@ -1801,7 +1806,7 @@ function AddRuleSheet({
{active && <CheckIcon className="size-3.5 shrink-0 text-primary" />}
</div>
<span className="text-[10px] text-muted-foreground leading-tight pl-0">
{TYPE_EVENT_CARD_DESC[t]}
{isLive&&t==="bgp-prefix"?"Отслеживание префиксов пока недоступно":TYPE_EVENT_CARD_DESC[t]}
</span>
</button>
)
@@ -2739,6 +2744,7 @@ function AlertsContent() {
onDelete={id=>setPendingDelete({kind:"rule",id})}
onEdit={openRuleSheetEdit}
interactionsDisabled={writesDisabled}
isLive={isLive}
/>
))}
</div>
+1 -1
View File
@@ -4,7 +4,7 @@
## Актуальная точка продолжения — 2026-10-03
Этап 11Б в работе; последний проверенный блок 11Б.4.4.3.9; System DB принят локально с внешними ограничениями. Следующий блок 11Б.4.4.3.10: явно обозначить неподдерживаемый BGP-prefix evaluator в live UI, затем production build накопленных изменений. Далее processing recovery, компактность основной Alerts страницы, Releases/probe scheduling и приёмка 11Б/12.
Этап 11Б в работе; последний проверенный блок 11Б.4.4.3.10; System DB принят локально с внешними ограничениями. Следующий блок 11Б.4.4.3.11: компактность основной Alerts страницы и профильная приёмка ПК/320px; processing recovery проектировать отдельно с доказуемой остановкой всех отправителей. Затем Releases/probe scheduling и приёмка 11Б/12. Внешняя PG/Telegram приёмка обязательна перед выпуском.
Реальные pg_dump/pg_restore, PG rollback и остановка UDP worker требуют внешней приёмки. Датированные продолжения ниже — история; точный следующий шаг также указан в начале [журнала](ux-ui-progress.md).
+9 -1
View File
@@ -28,7 +28,7 @@
| 9 | VPN, Firewall и Filters | Завершён в границах локальной приёмки 2026-09-30; блоки 9.1–9.64, ограничения в 9.64 |
| 10 | Маршрутизация, диагностика, карта и терминал | Завершён в границах локальной приёмки 2026-10-01; блоки 10.1–10.71, внешние ограничения в 10.71 |
| 11А | Пользователи, контейнеры, сертификаты и резервные копии | Завершён в границах локальной приёмки 2026-10-01; 11А.1–11А.33, внешние ограничения в 11А.33 |
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | В работе: 11Б.1–11Б.4.4.3.9; scheduler и GeoIP приняты локально; NetFlow принят локально; Evolution принят локально; далее общие Settings |
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | В работе: 11Б.1–11Б.4.4.3.10; scheduler и GeoIP приняты локально; NetFlow принят локально; Evolution принят локально; далее общие Settings |
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Не начат |
@@ -36,6 +36,14 @@
## Блок 11Б.4.4.3.10 — честная доступность BGP-prefix и сборка (2026-10-03)
- Backend evaluate-rule для bgp-prefix возвращает null; live UI теперь прямо сообщает, что сохранённое правило не проверяется. Выбор этого типа для нового правила недоступен, выключенное legacy правило нельзя включить через switch. Existing enabled запись можно отключить; редактирование/смена типа/удаление сохраняются. Mock демонстрация и backend policies не менялись.
- Это честное ограничение UI, не реализация мониторинга prefix UPDATE и не запрет прямого API. Backend контракт сохраняет legacy тип для совместимости; внешнему клиенту нельзя считать его поддерживаемым по одному enabled:true.
- 12 browser picker/prefix/rules, typecheck/lint прошли. Финальная production build frontend/contracts и backend build прошли; Alerts DI/HTTP/реальные JWT gates и sidebar-counts профиль повторно прошли на итоговом состоянии. ReUI Frame checklist применён к адаптации; глобальную ReUI/этап12 приёмку не объявляем.
- Полная Alerts приёмка не завершена: основная страница требует компактности, processing recovery не реализован; реальный PG isolation/CAS/rollback, migrations0008/0009 и Telegram не проверены. Все выполненные блоки сохранены локально без push; чужие изменения skill/AGENTS/config/cache не включены.
- Следующий точный шаг 11Б.4.4.3.11: компактность основной Alerts страницы и профильная приёмка ПК/320px; processing recovery проектировать отдельно с доказуемой остановкой всех отправителей. Затем Releases/probe scheduling и приёмка 11Б/12. Внешняя PG/Telegram приёмка обязательна перед выпуском.
## Блок 11Б.4.4.3.9 — доступный выбор и одна прокрутка формы (2026-10-03)
- Existing object/condition cards теперь native toggle buttons с aria-pressed в labelled group: UI не обещает listbox/option keyboard model без реализации arrow navigation. Type cards тоже сообщают выбранное состояние. Manual object input имеет имя. Список объектов доступен сразу, не требует фокуса на постороннем поле.
+4
View File
@@ -316,3 +316,7 @@ Backend sidebar optional counts не выдают timeout/partial/error как0,
### Продолжение 2026-10-03 — 11Б.4.4.3.9
Picker keyboard semantics/one parent scroll/initial objects accepted locally; browser21/typecheck/lint/ReUI audit passed, 320px screenshot reviewed. Общий Alerts экран не принят. Следующий блок 11Б.4.4.3.10: явно обозначить неподдерживаемый BGP-prefix evaluator в live UI, затем production build накопленных изменений. Далее processing recovery, компактность основной Alerts страницы, Releases/probe scheduling и приёмка 11Б/12.
### Продолжение 2026-10-03 — 11Б.4.4.3.10
Live BGP-prefix честно помечен unsupported, legacy записи не удалены; browser12/typecheck/lint и production frontend/contracts/backend build прошли. Финальный Alerts/backend sidebar профиль прошёл. Основной Alerts экран/processing recovery/внешняя PG и Telegram приёмка остаются. Следующий блок 11Б.4.4.3.11: компактность основной Alerts страницы и профильная приёмка ПК/320px; processing recovery проектировать отдельно с доказуемой остановкой всех отправителей. Затем Releases/probe scheduling и приёмка 11Б/12. Внешняя PG/Telegram приёмка обязательна перед выпуском.
+6
View File
@@ -0,0 +1,6 @@
import {test,expect} from "@playwright/test"
import {emptyAlerts,emptyOutbox,alertsRule} from "./fixtures/alerts"
test("Unsupported BGP prefix is visible as unavailable, existing disabled rule cannot be enabled and remains editable",async({page})=>{
let writes=0;const rule={...alertsRule,id:"prefix",name:"Legacy prefix",type:"bgp-prefix",groupId:null,enabled:false,target:"любой префикс",targets:["любой префикс"],condition:"был отозван",conditions:["был отозван"]}
await page.route("**/health",r=>r.fulfill({json:{status:"ok"}}));await page.route("**/api/**",r=>{const path=new URL(r.request().url()).pathname;if(r.request().method()!=="GET")writes++;return r.fulfill({json:path==="/api/auth/config"?{required:false}:path==="/api/alerts"?{...emptyAlerts,rules:[rule]}:path==="/api/alerts/outbox"?emptyOutbox:path==="/api/filters/gre-tunnels"?{tunnels:[],failures:[]}:[]})});await page.goto("/alerts");await expect(page.getByText("Отслеживание появления и отзыва префиксов пока недоступно. Это правило не проверяется.")).toBeVisible();await expect(page.getByRole("switch",{name:"Включить правило Legacy prefix"})).toBeDisabled();await page.getByRole("button",{name:"Изменить правило Legacy prefix"}).click();const dialog=page.getByRole("dialog");await expect(dialog.getByRole("status")).toContainText("Сохранённое правило не проверяется");await expect(dialog.getByRole("button",{name:/^BGP-префикс/})).toBeDisabled();await dialog.getByRole("button",{name:/^Сервер Доступность/}).click();await expect(dialog.getByRole("status")).toHaveCount(0);expect(writes).toBe(0)
})