diff --git a/app/(main)/ospf/page.tsx b/app/(main)/ospf/page.tsx index 8c75409a..71082590 100644 --- a/app/(main)/ospf/page.tsx +++ b/app/(main)/ospf/page.tsx @@ -15,7 +15,7 @@ import { DataPageToolbar } from "@/components/data-page-toolbar" import { PageHeader } from "@/components/page-header" import { DataPageCard } from "@/components/data-page-card" import { OspfNeighborsDataGrid } from "@/components/data-grids/ospf-neighbors-data-grid" -import { OspfRoutesDataGrid, routeTypeClass } from "@/components/data-grids/ospf-routes-data-grid" +import { OspfRoutesDataGrid, OspfRouteTypeBadge } from "@/components/data-grids/ospf-routes-data-grid" import { OspfBfdDataGrid } from "@/components/data-grids/ospf-bfd-data-grid" import { Frame, FramePanel } from "@/components/reui/frame" import { KpiStatGrid } from "@/components/reui-kit/kpi-stat-grid" @@ -1026,9 +1026,7 @@ function RoutesTab({ routes, hasSearch }: { routes: OspfRoute[]; hasSearch: bool
{routes.some(r => r.dataUnknown) ? "Последний снимок: " : ""}{routes.length} маршрутов {typeCount.map(([type, count]) => ( - - {type === "Unknown" ? "Тип неизвестен" : type}: {count} - + ))}
@@ -1043,7 +1041,7 @@ function RoutesTab({ routes, hasSearch }: { routes: OspfRoute[]; hasSearch: bool { type: "O E2", desc: "External Type 2" }, ] as const).map(({ type, desc }) => ( - {type} + {desc} ))} diff --git a/components/data-grids/bgp-sessions-data-grid.tsx b/components/data-grids/bgp-sessions-data-grid.tsx index 747e1c13..24d07894 100644 --- a/components/data-grids/bgp-sessions-data-grid.tsx +++ b/components/data-grids/bgp-sessions-data-grid.tsx @@ -8,6 +8,7 @@ import { useTable, } from "@tanstack/react-table" import { cn } from "@/lib/utils" +import { Badge } from "@/components/reui/badge" import { DataGridShell } from "@/components/data-grids/shared/data-grid-shell" import { DATA_GRID_CELL_PAD, @@ -22,83 +23,20 @@ import { BGP_AS_NAMES } from "@/lib/bgp/types" import { fmtBgpNum } from "@/lib/bgp/helpers" import { ChevronDownIcon, ChevronRightIcon, NetworkIcon } from "lucide-react" -const STATE_STYLE: Record = { - Unknown: { bg: "bg-muted", text: "text-muted-foreground", dot: "bg-muted-foreground", label: "Неизвестно" }, - Established: { - bg: "bg-emerald-500/10", - text: "text-emerald-600 dark:text-emerald-400", - dot: "bg-emerald-500", - label: "Established", - }, - Active: { - bg: "bg-amber-500/10", - text: "text-amber-600 dark:text-amber-400", - dot: "bg-amber-500", - label: "Active", - }, - Idle: { - bg: "bg-slate-500/10", - text: "text-slate-500 dark:text-slate-400", - dot: "bg-slate-500", - label: "Idle", - }, - Connect: { - bg: "bg-blue-500/10", - text: "text-blue-600 dark:text-blue-400", - dot: "bg-blue-500", - label: "Connect", - }, - OpenSent: { - bg: "bg-violet-500/10", - text: "text-violet-600 dark:text-violet-400", - dot: "bg-violet-500", - label: "OpenSent", - }, - OpenConfirm: { - bg: "bg-violet-500/10", - text: "text-violet-600 dark:text-violet-400", - dot: "bg-violet-500", - label: "OpenConfirm", - }, -} - -const TYPE_STYLE: Record = { - Unknown: { bg: "bg-muted", text: "text-muted-foreground" }, - eBGP: { bg: "bg-blue-500/10", text: "text-blue-600 dark:text-blue-400" }, - iBGP: { bg: "bg-purple-500/10", text: "text-purple-600 dark:text-purple-400" }, +const STATE_DOT: Record = { + Unknown: "bg-muted-foreground", Established: "bg-success", Active: "bg-warning", + Idle: "bg-muted-foreground", Connect: "bg-info", OpenSent: "bg-info", OpenConfirm: "bg-info", } function StateBadge({ state }: { state: BgpState }) { - const s = STATE_STYLE[state] - return ( - - - {s.label} - - ) + return + } function TypeBadge({ type }: { type: BgpType }) { - const s = TYPE_STYLE[type] - return ( - - {type === "Unknown" ? "Тип неизвестен" : type} - - ) + return {type === "Unknown" ? "Тип неизвестен" : type} } interface BgpSessionsDataGridProps { @@ -227,7 +165,7 @@ function BgpSessionsDataGrid({ sessions, emptyTitle, selectedSessionId, onSelect cell: ({ row }) => { const n = row.original.prefixesRx return n !== null ? ( - + {fmtBgpNum(n)} ) : ( diff --git a/components/data-grids/ospf-routes-data-grid.tsx b/components/data-grids/ospf-routes-data-grid.tsx index febc98ea..c5cda34c 100644 --- a/components/data-grids/ospf-routes-data-grid.tsx +++ b/components/data-grids/ospf-routes-data-grid.tsx @@ -8,6 +8,7 @@ import { useTable, } from "@tanstack/react-table" import { cn } from "@/lib/utils" +import { Badge } from "@/components/reui/badge" import { DataGridShell } from "@/components/data-grids/shared/data-grid-shell" import { DATA_GRID_CELL_PAD, @@ -31,12 +32,10 @@ export interface OspfRouteRow { area: string } -function routeTypeClass(type: OspfRouteRow["type"]) { - if (type === "Unknown") return "bg-muted text-muted-foreground border-border" - if (type === "O") return "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border-emerald-500/25" - if (type === "O IA") return "bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/25" - if (type === "O E1") return "bg-purple-500/10 text-purple-600 dark:text-purple-400 border-purple-500/25" - return "bg-orange-500/10 text-orange-600 dark:text-orange-400 border-orange-500/25" +function OspfRouteTypeBadge({ type, count }: { type: OspfRouteRow["type"]; count?: number }) { + return + {type === "Unknown" ? "Тип неизвестен" : type}{count === undefined ? "" : ": " + count} + } interface OspfRoutesDataGridProps { @@ -67,14 +66,7 @@ function OspfRoutesDataGrid({ routes, emptyTitle }: OspfRoutesDataGridProps) { accessorKey: "type", header: ({ column }) => , cell: ({ row }) => ( - - {row.original.type === "Unknown" ? "Тип неизвестен" : row.original.type} - + ), meta: { headerTitle: "Тип", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, }, @@ -189,4 +181,4 @@ function OspfRoutesDataGrid({ routes, emptyTitle }: OspfRoutesDataGridProps) { ) } -export { OspfRoutesDataGrid, type OspfRoutesDataGridProps, routeTypeClass } +export { OspfRoutesDataGrid, type OspfRoutesDataGridProps, OspfRouteTypeBadge } diff --git a/docs/ux-ui-external-acceptance.md b/docs/ux-ui-external-acceptance.md index e1fa7e12..c783867b 100644 --- a/docs/ux-ui-external-acceptance.md +++ b/docs/ux-ui-external-acceptance.md @@ -1,6 +1,6 @@ # UX/UI: протокол внешней приёмки 12.5 -Актуальное продолжение 2026-10-14: блок217 завершён. Legacy WAN runtime больше не скрывает ошибки DHCP/addresses/routes и не опрашивает выключенные Home Router/Exit Node. Empty success сохранён. Production15, профиль snapshot/build, live API2/native6/anonymous2/dashboard smoke1440/320 прошли. Backend ux-wan217/compiled1052/source484 matched, frontend ux-gre214; own DB/roles удалены, пароли не менялись. Следующий218 — доступность заполненных таблиц маршрутизации. Этап12.5 открыт. +Актуальное продолжение 2026-10-14: блок218 завершён. Заполненные BGP state/type/prefix RX и OSPF route type переведены на читаемые ReUI Badge/основной цвет чисел. Baseline22 violations; fixed104 scoped cells0, E2E22, TypeScript/ESLint/build прошли. Own GRE/OSPF/BGP поднялись, UI8 прошли, own objects удалены и static projection10×2 совпал. Frontend ux-routing218/source527 matched, backend ux-wan217. Следующий219 — скрытые ошибки GRE source snapshots для оповещений. Этап12.5 открыт. IPsec78: реальный PSK responder established, mode-config198.18.78.10 и online=true подтверждены API; точные собственные объекты удалены. Сертификатный/DN online, late failure и history restore остаются открытыми. [Отчёт](ux-ui/acceptance/ipsec-mode-config-2026-10-09.json), [журнал](ux-ui-progress.md). @@ -2595,3 +2595,7 @@ Production compiled SQL/API29 на собственной ограниченно ## 12.5.217 — WAN runtime (2026-10-14) Read failures/malformed collections дают502, выключенные устройства409 без native poll, empty success сохранён. Production15 и реальная сверка API/native прошли. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-wan217, frontend ux-gre214; следующий218 — routing table accessibility. + +## 12.5.218 — заполненные routing tables (2026-10-14) + +BGP/OSPF contrast: baseline22/fixed104 cells0 violations; E2E22 и real UI8 passed. Own GRE/OSPF/BGP objects удалены; статическая сверка10×2 прошла. Подробности и границы — [журнал](ux-ui-progress.md). Frontend ux-routing218, backend ux-wan217; следующий219 — GRE snapshot source errors. diff --git a/docs/ux-ui-plan.md b/docs/ux-ui-plan.md index 992b7d76..76ba8be1 100644 --- a/docs/ux-ui-plan.md +++ b/docs/ux-ui-plan.md @@ -1,6 +1,6 @@ # План реализации UX/UI по пятичасовым окнам -Актуальное продолжение 2026-10-14: блок217 завершён. Legacy WAN runtime больше не скрывает ошибки DHCP/addresses/routes и не опрашивает выключенные Home Router/Exit Node. Empty success сохранён. Production15, профиль snapshot/build, live API2/native6/anonymous2/dashboard smoke1440/320 прошли. Backend ux-wan217/compiled1052/source484 matched, frontend ux-gre214; own DB/roles удалены, пароли не менялись. Следующий218 — доступность заполненных таблиц маршрутизации. Этап12.5 открыт. +Актуальное продолжение 2026-10-14: блок218 завершён. Заполненные BGP state/type/prefix RX и OSPF route type переведены на читаемые ReUI Badge/основной цвет чисел. Baseline22 violations; fixed104 scoped cells0, E2E22, TypeScript/ESLint/build прошли. Own GRE/OSPF/BGP поднялись, UI8 прошли, own objects удалены и static projection10×2 совпал. Frontend ux-routing218/source527 matched, backend ux-wan217. Следующий219 — скрытые ошибки GRE source snapshots для оповещений. Этап12.5 открыт. Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-13. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат. diff --git a/docs/ux-ui-progress.md b/docs/ux-ui-progress.md index f72ac053..a51a2910 100644 --- a/docs/ux-ui-progress.md +++ b/docs/ux-ui-progress.md @@ -1,6 +1,6 @@ # UX/UI: журнал реализации -Актуальное продолжение 2026-10-14: блок217 завершён. Legacy WAN runtime больше не скрывает ошибки DHCP/addresses/routes и не опрашивает выключенные Home Router/Exit Node. Empty success сохранён. Production15, профиль snapshot/build, live API2/native6/anonymous2/dashboard smoke1440/320 прошли. Backend ux-wan217/compiled1052/source484 matched, frontend ux-gre214; own DB/roles удалены, пароли не менялись. Следующий218 — доступность заполненных таблиц маршрутизации. Этап12.5 открыт. +Актуальное продолжение 2026-10-14: блок218 завершён. Заполненные BGP state/type/prefix RX и OSPF route type переведены на читаемые ReUI Badge/основной цвет чисел. Baseline22 violations; fixed104 scoped cells0, E2E22, TypeScript/ESLint/build прошли. Own GRE/OSPF/BGP поднялись, UI8 прошли, own objects удалены и static projection10×2 совпал. Frontend ux-routing218/source527 matched, backend ux-wan217. Следующий219 — скрытые ошибки GRE source snapshots для оповещений. Этап12.5 открыт. Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md). @@ -38,6 +38,18 @@ | 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 | | 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–196 и ограничения ниже. Runtime backend/frontend ux-peak196. | +## 12.5.218 — контраст заполненных BGP и OSPF таблиц (2026-10-14) + +Baseline104 explicitly scrolled cell checks:22 нарушений в light на1440/320. BGP Established3,31:1, Active2,96:1, Idle4,21:1, prefix RX3,65:1; OSPF O E2 3,23:1. Ручные state/type spans заменены штатным ReUI Badge invert-light; BGP состояния дополнительно различаются семантическим индикатором и прежним текстом. Protocol type — текстовая категория без оценки здоровья. Prefix RX читает основной цвет. OSPF type Badge общий для строк, counts и легенды; vendor components/theme не менялись. + +Fixed104 scoped cells0 violations, E2E22 (8 contrast fixtures + BGP data13 + OSPF values1), ESLint0, TypeScript и production build прошли. Первый локальный tsc исчерпал4GB heap: include захватывал игнорируемые tmp source copies. tmp/temp/test-results/playwright-report исключены из TypeScript, исходники и тесты остались включены; повтор прошёл без увеличения heap. Это scoped colour audit, не полная WCAG приёмка. + +На Debian свободное место упало до157MB. Удалён неиспользуемый build-cache старше15m и51 старый неиспользуемый тег mmapp-test/frontend:ux-* без force, с защитой image IDs всех контейнеров. ux-gre214 и предыдущий ux-gre213 сохранены; свободно5,5GB перед build. Backend/Portal/Postgres/volumes не удалялись. Frontend ux-routing218/source527 matched, backend ux-wan217 healthy сохранён. + +Созданы собственные GRE2, OSPF instances/areas/templates и BGP instances/connections со scoped prefix filters: OSPF Full, BGP Established с received prefixes и два own remote routes active на каждом CHR. Восемь live UI BGP/OSPF ×light/dark ×1440/320 проверили16 scrolled cells без violations/page errors/mutation requests. Все собственные объекты удалены; hash projection перечисленных статических полей10 collections×2 совпал с baseline, dynamic state исключён. Пароли не менялись. Packet-loss SLA/полный протоколный regression этим UI-блоком не принимаются. + +Протоколы: [contrast](ux-ui/acceptance/routing218-contrast-2026-10-14.json), [source](ux-ui/acceptance/routing218-source-proof-2026-10-14.json), [deployment](ux-ui/acceptance/routing218-deployment-2026-10-14.json), [storage cleanup](ux-ui/acceptance/routing218-storage-cleanup.json), [native/UI/cleanup](ux-ui/acceptance/routing218-native-live-2026-10-14.json). Следующий219 — GRE источник snapshots: сейчас fetchGreTunnelLiveRows подавляет ошибки устройств и сообщает успешный пустой результат. + ## 12.5.217 — достоверный WAN runtime и disabled no-poll (2026-10-14) /api/servers/:id/wan-runtime подавлял ошибки DHCP, addresses и routes через [] и опрашивал выключенные устройства. Добавлены409 перед native client (с повторной проверкой актуальной DB row) и строгая валидация трёх коллекций тем же readInternetPathRows, что используется Internet path collector. Read failure/malformed row возвращает502 с WAN error; успешный envelope defaultGateway/immediateGateway/defaultInterface/uplinks и корректный empty200 сохранены. Методы/права/алгоритм выбора default route не менялись. Активный dashboard читает сохранённый Internet path, поэтому legacy WAN endpoint не объявляется его единственным источником. diff --git a/docs/ux-ui-remaining-acceptance.md b/docs/ux-ui-remaining-acceptance.md index 26029bf5..5ec89819 100644 --- a/docs/ux-ui-remaining-acceptance.md +++ b/docs/ux-ui-remaining-acceptance.md @@ -1,10 +1,10 @@ # Оставшаяся внешняя приёмка — 2026-10-13 -Актуальное продолжение 2026-10-14: блок217 завершён. Legacy WAN runtime больше не скрывает ошибки DHCP/addresses/routes и не опрашивает выключенные Home Router/Exit Node. Empty success сохранён. Production15, профиль snapshot/build, live API2/native6/anonymous2/dashboard smoke1440/320 прошли. Backend ux-wan217/compiled1052/source484 matched, frontend ux-gre214; own DB/roles удалены, пароли не менялись. Следующий218 — доступность заполненных таблиц маршрутизации. Этап12.5 открыт. +Актуальное продолжение 2026-10-14: блок218 завершён. Заполненные BGP state/type/prefix RX и OSPF route type переведены на читаемые ReUI Badge/основной цвет чисел. Baseline22 violations; fixed104 scoped cells0, E2E22, TypeScript/ESLint/build прошли. Own GRE/OSPF/BGP поднялись, UI8 прошли, own objects удалены и static projection10×2 совпал. Frontend ux-routing218/source527 matched, backend ux-wan217. Следующий219 — скрытые ошибки GRE source snapshots для оповещений. Этап12.5 открыт. -Это актуальная матрица после 12.5.217. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии. +Это актуальная матрица после 12.5.218. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии. -Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-wan217`, frontend `ux-gre214`; production lab с195 использует AUTH_REQUIRED=true и Portal1.3.1. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись. +Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-wan217`, frontend `ux-routing218`; production lab с195 использует AUTH_REQUIRED=true и Portal1.3.1. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись. | Раздел | Подтверждено | Осталось / условие завершения | | --- | --- | --- | @@ -1513,3 +1513,7 @@ Production compiled SQL/API29 на собственной ограниченно ## 12.5.217 — WAN runtime (2026-10-14) Read failures/malformed collections дают502, выключенные устройства409 без native poll, empty success сохранён. Production15 и реальная сверка API/native прошли. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-wan217, frontend ux-gre214; следующий218 — routing table accessibility. + +## 12.5.218 — заполненные routing tables (2026-10-14) + +BGP/OSPF contrast: baseline22/fixed104 cells0 violations; E2E22 и real UI8 passed. Own GRE/OSPF/BGP objects удалены; статическая сверка10×2 прошла. Подробности и границы — [журнал](ux-ui-progress.md). Frontend ux-routing218, backend ux-wan217; следующий219 — GRE snapshot source errors. diff --git a/docs/ux-ui-stage-12.md b/docs/ux-ui-stage-12.md index dfb14228..264b4e02 100644 --- a/docs/ux-ui-stage-12.md +++ b/docs/ux-ui-stage-12.md @@ -1,6 +1,6 @@ # Этап 12: итоговая приёмка UX/UI -Актуальное продолжение 2026-10-14: блок217 завершён. Legacy WAN runtime больше не скрывает ошибки DHCP/addresses/routes и не опрашивает выключенные Home Router/Exit Node. Empty success сохранён. Production15, профиль snapshot/build, live API2/native6/anonymous2/dashboard smoke1440/320 прошли. Backend ux-wan217/compiled1052/source484 matched, frontend ux-gre214; own DB/roles удалены, пароли не менялись. Следующий218 — доступность заполненных таблиц маршрутизации. Этап12.5 открыт. +Актуальное продолжение 2026-10-14: блок218 завершён. Заполненные BGP state/type/prefix RX и OSPF route type переведены на читаемые ReUI Badge/основной цвет чисел. Baseline22 violations; fixed104 scoped cells0, E2E22, TypeScript/ESLint/build прошли. Own GRE/OSPF/BGP поднялись, UI8 прошли, own objects удалены и static projection10×2 совпал. Frontend ux-routing218/source527 matched, backend ux-wan217. Следующий219 — скрытые ошибки GRE source snapshots для оповещений. Этап12.5 открыт. План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push. @@ -3954,3 +3954,16 @@ Compiled1052/source484 matched; backend healthy, frontend ux-gre214 сохран Протоколы: [baseline](ux-ui/acceptance/wan217-baseline.json), [fixed](ux-ui/acceptance/wan217-fixed.json), [build](ux-ui/acceptance/wan217-build-proof-2026-10-14.json), [deployment](ux-ui/acceptance/wan217-deployment-2026-10-14.json), [live](ux-ui/acceptance/wan217-live-2026-10-14.json). Следующий218 — accessibility заполненных таблиц маршрутизации: контраст статусов и метрик в light/dark на ПК/телефоне. + +## 12.5.218 — контраст заполненных BGP и OSPF таблиц (2026-10-14) + +Baseline104 explicitly scrolled cell checks:22 нарушений в light на1440/320. BGP Established3,31:1, Active2,96:1, Idle4,21:1, prefix RX3,65:1; OSPF O E2 3,23:1. Ручные state/type spans заменены штатным ReUI Badge invert-light; BGP состояния дополнительно различаются семантическим индикатором и прежним текстом. Protocol type — текстовая категория без оценки здоровья. Prefix RX читает основной цвет. OSPF type Badge общий для строк, counts и легенды; vendor components/theme не менялись. + +Fixed104 scoped cells0 violations, E2E22 (8 contrast fixtures + BGP data13 + OSPF values1), ESLint0, TypeScript и production build прошли. Первый локальный tsc исчерпал4GB heap: include захватывал игнорируемые tmp source copies. tmp/temp/test-results/playwright-report исключены из TypeScript, исходники и тесты остались включены; повтор прошёл без увеличения heap. Это scoped colour audit, не полная WCAG приёмка. + +На Debian свободное место упало до157MB. Удалён неиспользуемый build-cache старше15m и51 старый неиспользуемый тег mmapp-test/frontend:ux-* без force, с защитой image IDs всех контейнеров. ux-gre214 и предыдущий ux-gre213 сохранены; свободно5,5GB перед build. Backend/Portal/Postgres/volumes не удалялись. Frontend ux-routing218/source527 matched, backend ux-wan217 healthy сохранён. + +Созданы собственные GRE2, OSPF instances/areas/templates и BGP instances/connections со scoped prefix filters: OSPF Full, BGP Established с received prefixes и два own remote routes active на каждом CHR. Восемь live UI BGP/OSPF ×light/dark ×1440/320 проверили16 scrolled cells без violations/page errors/mutation requests. Все собственные объекты удалены; hash projection перечисленных статических полей10 collections×2 совпал с baseline, dynamic state исключён. Пароли не менялись. Packet-loss SLA/полный протоколный regression этим UI-блоком не принимаются. + +Протоколы: [contrast](ux-ui/acceptance/routing218-contrast-2026-10-14.json), [source](ux-ui/acceptance/routing218-source-proof-2026-10-14.json), [deployment](ux-ui/acceptance/routing218-deployment-2026-10-14.json), [storage cleanup](ux-ui/acceptance/routing218-storage-cleanup.json), [native/UI/cleanup](ux-ui/acceptance/routing218-native-live-2026-10-14.json). Следующий219 — GRE источник snapshots: сейчас fetchGreTunnelLiveRows подавляет ошибки устройств и сообщает успешный пустой результат. + diff --git a/docs/ux-ui-test-server.md b/docs/ux-ui-test-server.md index 068ea261..5a512b8c 100644 --- a/docs/ux-ui-test-server.md +++ b/docs/ux-ui-test-server.md @@ -1,6 +1,6 @@ # Тестовый сервер UX/UI — 2026-10-10 -Актуальное продолжение 2026-10-14: блок217 завершён. Legacy WAN runtime больше не скрывает ошибки DHCP/addresses/routes и не опрашивает выключенные Home Router/Exit Node. Empty success сохранён. Production15, профиль snapshot/build, live API2/native6/anonymous2/dashboard smoke1440/320 прошли. Backend ux-wan217/compiled1052/source484 matched, frontend ux-gre214; own DB/roles удалены, пароли не менялись. Следующий218 — доступность заполненных таблиц маршрутизации. Этап12.5 открыт. +Актуальное продолжение 2026-10-14: блок218 завершён. Заполненные BGP state/type/prefix RX и OSPF route type переведены на читаемые ReUI Badge/основной цвет чисел. Baseline22 violations; fixed104 scoped cells0, E2E22, TypeScript/ESLint/build прошли. Own GRE/OSPF/BGP поднялись, UI8 прошли, own objects удалены и static projection10×2 совпал. Frontend ux-routing218/source527 matched, backend ux-wan217. Следующий219 — скрытые ошибки GRE source snapshots для оповещений. Этап12.5 открыт. | Параметр | Проверенное состояние | | --- | --- | @@ -2326,3 +2326,7 @@ Production compiled SQL/API29 на собственной ограниченно ## 12.5.217 — WAN runtime (2026-10-14) Read failures/malformed collections дают502, выключенные устройства409 без native poll, empty success сохранён. Production15 и реальная сверка API/native прошли. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-wan217, frontend ux-gre214; следующий218 — routing table accessibility. + +## 12.5.218 — заполненные routing tables (2026-10-14) + +BGP/OSPF contrast: baseline22/fixed104 cells0 violations; E2E22 и real UI8 passed. Own GRE/OSPF/BGP objects удалены; статическая сверка10×2 прошла. Подробности и границы — [журнал](ux-ui-progress.md). Frontend ux-routing218, backend ux-wan217; следующий219 — GRE snapshot source errors. diff --git a/docs/ux-ui/acceptance/routing218-contrast-2026-10-14.json b/docs/ux-ui/acceptance/routing218-contrast-2026-10-14.json new file mode 100644 index 00000000..3ef22d2e --- /dev/null +++ b/docs/ux-ui/acceptance/routing218-contrast-2026-10-14.json @@ -0,0 +1,988 @@ +{ + "date": "2026-10-14", + "block": "12.5.218", + "baseline": { + "cases": 8, + "cellChecks": 104, + "failedCells": 22, + "casesDetail": [ + { + "date": "2026-10-14", + "section": "bgp", + "theme": "light", + "width": 1440, + "scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells", + "findings": [ + { + "row": 0, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 0, + "cell": 5, + "text": "Established", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + ".bg-emerald-500\\/10" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.31 (foreground color: #009966, background color: #e6f8f2, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 0, + "cell": 7, + "text": "12", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 1, + "cell": 4, + "text": "iBGP", + "violations": [] + }, + { + "row": 1, + "cell": 5, + "text": "Active", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + ".text-amber-600" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 2.96 (foreground color: #e17100, background color: #fff5e6, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 1, + "cell": 7, + "text": "12", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 2, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 2, + "cell": 5, + "text": "Idle", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + ".bg-slate-500\\/10" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 4.21 (foreground color: #62748e, background color: #eff1f4, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 2, + "cell": 7, + "text": "12", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 3, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 3, + "cell": 5, + "text": "Connect", + "violations": [] + }, + { + "row": 3, + "cell": 7, + "text": "12", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 4, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 4, + "cell": 5, + "text": "OpenSent", + "violations": [] + }, + { + "row": 4, + "cell": 7, + "text": "12", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 5, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 5, + "cell": 5, + "text": "OpenConfirm", + "violations": [] + }, + { + "row": 5, + "cell": 7, + "text": "12", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 6, + "cell": 4, + "text": "Тип неизвестен", + "violations": [] + }, + { + "row": 6, + "cell": 5, + "text": "Неизвестно", + "violations": [] + }, + { + "row": 6, + "cell": 7, + "text": "12", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + } + ] + }, + { + "date": "2026-10-14", + "section": "bgp", + "theme": "light", + "width": 320, + "scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells", + "findings": [ + { + "row": 0, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 0, + "cell": 5, + "text": "Established", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + ".bg-emerald-500\\/10" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.31 (foreground color: #009966, background color: #e6f8f2, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 0, + "cell": 7, + "text": "12", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 1, + "cell": 4, + "text": "iBGP", + "violations": [] + }, + { + "row": 1, + "cell": 5, + "text": "Active", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + ".text-amber-600" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 2.96 (foreground color: #e17100, background color: #fff5e6, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 1, + "cell": 7, + "text": "12", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 2, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 2, + "cell": 5, + "text": "Idle", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + ".bg-slate-500\\/10" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 4.21 (foreground color: #62748e, background color: #eff1f4, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 2, + "cell": 7, + "text": "12", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 3, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 3, + "cell": 5, + "text": "Connect", + "violations": [] + }, + { + "row": 3, + "cell": 7, + "text": "12", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 4, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 4, + "cell": 5, + "text": "OpenSent", + "violations": [] + }, + { + "row": 4, + "cell": 7, + "text": "12", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 5, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 5, + "cell": 5, + "text": "OpenConfirm", + "violations": [] + }, + { + "row": 5, + "cell": 7, + "text": "12", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 6, + "cell": 4, + "text": "Тип неизвестен", + "violations": [] + }, + { + "row": 6, + "cell": 5, + "text": "Неизвестно", + "violations": [] + }, + { + "row": 6, + "cell": 7, + "text": "12", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + } + ] + }, + { + "date": "2026-10-14", + "section": "bgp", + "theme": "dark", + "width": 1440, + "scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells", + "findings": [ + { + "row": 0, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 0, + "cell": 5, + "text": "Established", + "violations": [] + }, + { + "row": 0, + "cell": 7, + "text": "12", + "violations": [] + }, + { + "row": 1, + "cell": 4, + "text": "iBGP", + "violations": [] + }, + { + "row": 1, + "cell": 5, + "text": "Active", + "violations": [] + }, + { + "row": 1, + "cell": 7, + "text": "12", + "violations": [] + }, + { + "row": 2, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 2, + "cell": 5, + "text": "Idle", + "violations": [] + }, + { + "row": 2, + "cell": 7, + "text": "12", + "violations": [] + }, + { + "row": 3, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 3, + "cell": 5, + "text": "Connect", + "violations": [] + }, + { + "row": 3, + "cell": 7, + "text": "12", + "violations": [] + }, + { + "row": 4, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 4, + "cell": 5, + "text": "OpenSent", + "violations": [] + }, + { + "row": 4, + "cell": 7, + "text": "12", + "violations": [] + }, + { + "row": 5, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 5, + "cell": 5, + "text": "OpenConfirm", + "violations": [] + }, + { + "row": 5, + "cell": 7, + "text": "12", + "violations": [] + }, + { + "row": 6, + "cell": 4, + "text": "Тип неизвестен", + "violations": [] + }, + { + "row": 6, + "cell": 5, + "text": "Неизвестно", + "violations": [] + }, + { + "row": 6, + "cell": 7, + "text": "12", + "violations": [] + } + ] + }, + { + "date": "2026-10-14", + "section": "bgp", + "theme": "dark", + "width": 320, + "scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells", + "findings": [ + { + "row": 0, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 0, + "cell": 5, + "text": "Established", + "violations": [] + }, + { + "row": 0, + "cell": 7, + "text": "12", + "violations": [] + }, + { + "row": 1, + "cell": 4, + "text": "iBGP", + "violations": [] + }, + { + "row": 1, + "cell": 5, + "text": "Active", + "violations": [] + }, + { + "row": 1, + "cell": 7, + "text": "12", + "violations": [] + }, + { + "row": 2, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 2, + "cell": 5, + "text": "Idle", + "violations": [] + }, + { + "row": 2, + "cell": 7, + "text": "12", + "violations": [] + }, + { + "row": 3, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 3, + "cell": 5, + "text": "Connect", + "violations": [] + }, + { + "row": 3, + "cell": 7, + "text": "12", + "violations": [] + }, + { + "row": 4, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 4, + "cell": 5, + "text": "OpenSent", + "violations": [] + }, + { + "row": 4, + "cell": 7, + "text": "12", + "violations": [] + }, + { + "row": 5, + "cell": 4, + "text": "eBGP", + "violations": [] + }, + { + "row": 5, + "cell": 5, + "text": "OpenConfirm", + "violations": [] + }, + { + "row": 5, + "cell": 7, + "text": "12", + "violations": [] + }, + { + "row": 6, + "cell": 4, + "text": "Тип неизвестен", + "violations": [] + }, + { + "row": 6, + "cell": 5, + "text": "Неизвестно", + "violations": [] + }, + { + "row": 6, + "cell": 7, + "text": "12", + "violations": [] + } + ] + }, + { + "date": "2026-10-14", + "section": "ospf", + "theme": "light", + "width": 1440, + "scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells", + "findings": [ + { + "row": 0, + "cell": 1, + "text": "O", + "violations": [] + }, + { + "row": 1, + "cell": 1, + "text": "O IA", + "violations": [] + }, + { + "row": 2, + "cell": 1, + "text": "O E1", + "violations": [] + }, + { + "row": 3, + "cell": 1, + "text": "O E2", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .bg-orange-500\\/10.text-orange-600.dark\\:text-orange-400" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.23 (foreground color: #f54900, background color: #fff0e6, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 4, + "cell": 1, + "text": "Тип неизвестен", + "violations": [] + } + ] + }, + { + "date": "2026-10-14", + "section": "ospf", + "theme": "light", + "width": 320, + "scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells", + "findings": [ + { + "row": 0, + "cell": 1, + "text": "O", + "violations": [] + }, + { + "row": 1, + "cell": 1, + "text": "O IA", + "violations": [] + }, + { + "row": 2, + "cell": 1, + "text": "O E1", + "violations": [] + }, + { + "row": 3, + "cell": 1, + "text": "O E2", + "violations": [ + { + "id": "color-contrast", + "nodes": [ + { + "target": [ + "#own218-audit > .bg-orange-500\\/10.text-orange-600.dark\\:text-orange-400" + ], + "summary": "Fix any of the following:\n Element has insufficient color contrast of 3.23 (foreground color: #f54900, background color: #fff0e6, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1" + } + ] + } + ] + }, + { + "row": 4, + "cell": 1, + "text": "Тип неизвестен", + "violations": [] + } + ] + }, + { + "date": "2026-10-14", + "section": "ospf", + "theme": "dark", + "width": 1440, + "scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells", + "findings": [ + { + "row": 0, + "cell": 1, + "text": "O", + "violations": [] + }, + { + "row": 1, + "cell": 1, + "text": "O IA", + "violations": [] + }, + { + "row": 2, + "cell": 1, + "text": "O E1", + "violations": [] + }, + { + "row": 3, + "cell": 1, + "text": "O E2", + "violations": [] + }, + { + "row": 4, + "cell": 1, + "text": "Тип неизвестен", + "violations": [] + } + ] + }, + { + "date": "2026-10-14", + "section": "ospf", + "theme": "dark", + "width": 320, + "scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells", + "findings": [ + { + "row": 0, + "cell": 1, + "text": "O", + "violations": [] + }, + { + "row": 1, + "cell": 1, + "text": "O IA", + "violations": [] + }, + { + "row": 2, + "cell": 1, + "text": "O E1", + "violations": [] + }, + { + "row": 3, + "cell": 1, + "text": "O E2", + "violations": [] + }, + { + "row": 4, + "cell": 1, + "text": "Тип неизвестен", + "violations": [] + } + ] + } + ] + }, + "fixed": { + "cases": 8, + "cellChecks": 104, + "failedCells": 0 + }, + "regression": { + "startTime": "2026-10-13T17:51:31.476Z", + "duration": 63706.111, + "expected": 22, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "scope": "Scrolled cells only: BGP type/state/prefixRX and OSPF type. No blanket WCAG certification.", + "typeScriptPassed": true, + "eslintErrors": 0, + "typeScriptInitialFailure": "Local default include compiled ignored temporary source copies; exhausted4GB heap. Generated directories now excluded." +} diff --git a/docs/ux-ui/acceptance/routing218-deployment-2026-10-14.json b/docs/ux-ui/acceptance/routing218-deployment-2026-10-14.json new file mode 100644 index 00000000..2d049f8b --- /dev/null +++ b/docs/ux-ui/acceptance/routing218-deployment-2026-10-14.json @@ -0,0 +1,20 @@ +{ + "date": "2026-10-14", + "block": "12.5.218", + "frontendSourceMatched": 527, + "backendChanged": false, + "services": { + "backend": { + "image": "mmapp-test/backend:ux-wan217", + "imageId": "sha256:f5fac6167453e180e7aacb3b88de14e49860479dfcf46bc7a9ffd34db682e42b", + "running": true, + "health": "healthy" + }, + "frontend": { + "image": "mmapp-test/frontend:ux-routing218", + "imageId": "sha256:ec658b9da88c19d60987be5bfc0c15fb339a0310d7a42dc761b40a70a3428c5a", + "running": true, + "health": null + } + } +} \ No newline at end of file diff --git a/docs/ux-ui/acceptance/routing218-native-live-2026-10-14.json b/docs/ux-ui/acceptance/routing218-native-live-2026-10-14.json new file mode 100644 index 00000000..15ae1657 --- /dev/null +++ b/docs/ux-ui/acceptance/routing218-native-live-2026-10-14.json @@ -0,0 +1,127 @@ +{ + "date": "2026-10-14", + "block": "12.5.218", + "passed": true, + "backend": "ux-wan217", + "frontend": "ux-routing218", + "devices": [ + { + "host": "194.226.121.150", + "serverId": 1, + "greOwned": true, + "bgpEstablished": true, + "bgpPrefixesRx": 1, + "ospfFull": true, + "remotePrefixesActive": 2 + }, + { + "host": "104.165.244.7", + "serverId": 2, + "greOwned": true, + "bgpEstablished": true, + "bgpPrefixesRx": 1, + "ospfFull": true, + "remotePrefixesActive": 2 + } + ], + "ui": [ + { + "section": "bgp", + "theme": "light", + "width": 1440, + "scrolledCellChecks": 3, + "contrastViolations": 0, + "nativeData": true, + "pageErrors": 0, + "mutationRequests": 0 + }, + { + "section": "bgp", + "theme": "light", + "width": 320, + "scrolledCellChecks": 3, + "contrastViolations": 0, + "nativeData": true, + "pageErrors": 0, + "mutationRequests": 0 + }, + { + "section": "bgp", + "theme": "dark", + "width": 1440, + "scrolledCellChecks": 3, + "contrastViolations": 0, + "nativeData": true, + "pageErrors": 0, + "mutationRequests": 0 + }, + { + "section": "bgp", + "theme": "dark", + "width": 320, + "scrolledCellChecks": 3, + "contrastViolations": 0, + "nativeData": true, + "pageErrors": 0, + "mutationRequests": 0 + }, + { + "section": "ospf", + "theme": "light", + "width": 1440, + "scrolledCellChecks": 1, + "contrastViolations": 0, + "nativeData": true, + "pageErrors": 0, + "mutationRequests": 0 + }, + { + "section": "ospf", + "theme": "light", + "width": 320, + "scrolledCellChecks": 1, + "contrastViolations": 0, + "nativeData": true, + "pageErrors": 0, + "mutationRequests": 0 + }, + { + "section": "ospf", + "theme": "dark", + "width": 1440, + "scrolledCellChecks": 1, + "contrastViolations": 0, + "nativeData": true, + "pageErrors": 0, + "mutationRequests": 0 + }, + { + "section": "ospf", + "theme": "dark", + "width": 320, + "scrolledCellChecks": 1, + "contrastViolations": 0, + "nativeData": true, + "pageErrors": 0, + "mutationRequests": 0 + } + ], + "cleanup": [ + { + "host": "194.226.121.150", + "ownedObjectsRemoved": 15, + "collectionsMatched": 10, + "scope": "Listed static configuration fields; dynamic state excluded" + }, + { + "host": "104.165.244.7", + "ownedObjectsRemoved": 15, + "collectionsMatched": 10, + "scope": "Listed static configuration fields; dynamic state excluded" + } + ], + "realPortalJWT": true, + "apiMocks": false, + "passwordsUnchanged": true, + "scope": "Owned GRE/BGP/OSPF convergence and filled-table scoped contrast; no packet-loss SLA or complete WCAG claim" +} diff --git a/docs/ux-ui/acceptance/routing218-source-proof-2026-10-14.json b/docs/ux-ui/acceptance/routing218-source-proof-2026-10-14.json new file mode 100644 index 00000000..c60cd4e1 --- /dev/null +++ b/docs/ux-ui/acceptance/routing218-source-proof-2026-10-14.json @@ -0,0 +1,10 @@ +{ + "date": "2026-10-14", + "block": "12.5.218", + "kinds": [ + { + "kind": "frontend", + "matched": 527 + } + ] +} diff --git a/docs/ux-ui/acceptance/routing218-storage-cleanup.json b/docs/ux-ui/acceptance/routing218-storage-cleanup.json new file mode 100644 index 00000000..cacb5bfd --- /dev/null +++ b/docs/ux-ui/acceptance/routing218-storage-cleanup.json @@ -0,0 +1,63 @@ +{ + "date": "2026-10-14", + "repository": "mmapp-test/frontend", + "preservedTags": [ + "mmapp-test/frontend:ux-gre213", + "mmapp-test/frontend:ux-gre214" + ], + "inUseImagesProtected": true, + "force": false, + "removedTags": [ + "mmapp-test/frontend:ux-gre212", + "mmapp-test/frontend:ux-gre210", + "mmapp-test/frontend:ux-gre209", + "mmapp-test/frontend:ux-native208", + "mmapp-test/frontend:ux-history207", + "mmapp-test/frontend:ux-accessibility205", + "mmapp-test/frontend:ux-portal199", + "mmapp-test/frontend:ux-peak196", + "mmapp-test/frontend:ux-peak191", + "mmapp-test/frontend:ux-warning183", + "mmapp-test/frontend:ux-status181", + "mmapp-test/frontend:ux-volume180", + "mmapp-test/frontend:ux-live179", + "mmapp-test/frontend:ux-history178", + "mmapp-test/frontend:ux-ping173", + "mmapp-test/frontend:ux-targets171", + "mmapp-test/frontend:ux-bfd158", + "mmapp-test/frontend:ux-ospf153", + "mmapp-test/frontend:ux-wg152", + "mmapp-test/frontend:ux-gre151", + "mmapp-test/frontend:ux-sessions150", + "mmapp-test/frontend:ux-scope148", + "mmapp-test/frontend:ux-http147", + "mmapp-test/frontend:ux-labels146", + "mmapp-test/frontend:ux-traffic141", + "mmapp-test/frontend:ux-log133", + "mmapp-test/frontend:ux-ike124", + "mmapp-test/frontend:ux-bound116", + "mmapp-test/frontend:ux-keepcert115", + "mmapp-test/frontend:ux-alias112-version", + "mmapp-test/frontend:ux-alias112", + "mmapp-test/frontend:ux-a11y101", + "mmapp-test/frontend:ux-ospf91", + "mmapp-test/frontend:ux-optimizer87", + "mmapp-test/frontend:ux-ipsec77", + "mmapp-test/frontend:ux-vxlan76", + "mmapp-test/frontend:ux-479f2ad", + "mmapp-test/frontend:ux-c16fc0c", + "mmapp-test/frontend:ux-c82e8fa", + "mmapp-test/frontend:ux-bf43263", + "mmapp-test/frontend:ux-6a46fb1", + "mmapp-test/frontend:ux-3722fad", + "mmapp-test/frontend:ux-fd521f6", + "mmapp-test/frontend:ux-731803b", + "mmapp-test/frontend:ux-bd3f996", + "mmapp-test/frontend:ux-b55588f", + "mmapp-test/frontend:ux-f194e72", + "mmapp-test/frontend:ux-aa7dbdf", + "mmapp-test/frontend:ux-8782054", + "mmapp-test/frontend:ux-673e5ba", + "mmapp-test/frontend:ux-4d88b97" + ] +} \ No newline at end of file diff --git a/tests/e2e/routing-contrast.spec.ts b/tests/e2e/routing-contrast.spec.ts new file mode 100644 index 00000000..9b3d3f72 --- /dev/null +++ b/tests/e2e/routing-contrast.spec.ts @@ -0,0 +1,17 @@ +import {test,expect} from '@playwright/test' +import axe from 'axe-core' +import {writeFileSync} from 'node:fs' +const states=['Established','Active','Idle','Connect','OpenSent','OpenConfirm','Unknown'] +const server={id:1,name:'Own218 router',host:'192.0.2.1',enabled:true,country:'RU',status:null} +const host={serverId:1,serverName:server.name,serverSite:'',serverCountry:'RU'} +for(const theme of ['light','dark'])for(const width of [1440,320])for(const section of ['bgp','ospf'])test(`Routing contrast ${section} ${theme} ${width}`,async({page})=>{ + test.setTimeout(90000);await page.setViewportSize({width,height:1000});await page.addInitScript(t=>localStorage.setItem('rl-theme',t),theme) + let writes=0;const sessions=states.map((state,index)=>({...host,id:'*'+(index+1),name:'own218-'+state,peerIp:'192.0.2.2',remoteAs:64513,localAs:64512,localId:'192.0.2.1',remoteId:'192.0.2.2',state,type:index===1?'iBGP':index===6?'Unknown':'eBGP',uptime:'1h',holdTime:90,keepalive:30,prefixesRx:12,prefixesTx:2,inputMessages:20,outputMessages:10,capabilities:[],lastError:null})) + const catalog={neighbors:[],interfaces:[],instances:[],bfdSessions:[],routes:['O','O IA','O E1','O E2','Unknown'].map((type,index)=>({...host,id:'r'+index,destination:'192.0.'+(index+2)+'.0/24',type,cost:10,nextHop:'192.0.2.2',via:'ether1',area:'backbone'})),failures:[]} + await page.route('**/health',r=>r.fulfill({json:{ok:true}}));await page.route('**/api/**',r=>{if(r.request().method()!=='GET')writes++;const p=new URL(r.request().url()).pathname;return r.fulfill({json:p==='/api/auth/config'?{required:false}:p==='/api/servers'?[server]:p==='/api/bgp/catalog'?{sessions,failures:[]}:p==='/api/ospf/catalog'?catalog:{}})}) + await page.goto('/'+section);if(section==='ospf')await page.getByRole('button',{name:'Маршруты',exact:true}).click() + const rows=page.locator('tr[data-row-id]');await expect(rows).toHaveCount(section==='bgp'?7:5);await page.evaluate(()=>document.fonts.ready);await page.waitForTimeout(900);await page.addScriptTag({content:axe.source});const findings=[] + for(let index=0;indexel.id='own218-audit');const result=await page.evaluate(async()=>(window as unknown as {axe:typeof axe}).axe.run({include:['#own218-audit']},{runOnly:{type:'rule',values:['color-contrast']}}));findings.push({row:index,cell:cellIndex,text:(await cell.innerText()).trim(),violations:result.violations.map(v=>({id:v.id,nodes:v.nodes.map(n=>({target:n.target,summary:n.failureSummary}))}))});await cell.evaluate(el=>el.removeAttribute('id'))} + writeFileSync(`tmp/routing218-${section}-${theme}-${width}.json`,JSON.stringify({date:'2026-10-14',section,theme,width,scope:'Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells',findings},null,2)) + if(process.env.MMAPP_A11Y_BASELINE!=='true')expect(findings.filter(f=>f.violations.length)).toEqual([]);expect(writes).toBe(0);expect(await page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth+1)).toBe(true) +}) diff --git a/tsconfig.json b/tsconfig.json index 34d254dd..638708d4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -30,5 +30,5 @@ ".next/dev/types/**/*.ts", "**/*.mts" ], - "exclude": ["node_modules", "backend", "packages"] + "exclude": ["node_modules", "backend", "packages", "tmp", "temp", "test-results", "playwright-report"] }