63 KiB
Этап 10: маршрутизация и диагностика
Статус: начат 2026-09-30. Работа последовательно, ReUI PRO/base-nova и существующий Frame. Правила применения сетевых операций не меняются.
Референсы и схема
| Область | Референс | Схема доработки |
|---|---|---|
| Устройства и сессии | List 9 | Контекст → подтверждённые объекты → проблемы |
| Таблицы | Data Grid Filtering 2 | Срез → фильтры → состояние данных → детали |
| Детали и диагностика | Sheet 8 | Объект → запрос → результат / ошибка с сохранением контекста |
Референсы перенесены из принятого плана; новые registry-компоненты не требуются.
[Устройство / URL] → [Подтверждённый снимок + время получения]
↓
[Сессии / маршруты / карта]
↙ ↘
[Частичный отказ] [Детали / диагностика]
последние данные контекст сохранён
статус неизвестен ↓
[Результат API / повтор]
Карта работ и порядок
| Порядок | Раздел / API | Обнаруженная проблема | Проверка результата |
|---|---|---|---|
| 1 | BGP: /bgp/sessions, новый /bgp/catalog | Отказ устройства превращается в []; нет проверки ответа/частичных ошибок; неизвестный мониторинг выдаётся за online | Успех, пустой опрос, частичный/полный сбой, повтор, смена источника |
| 2 | OSPF: /ospf/all | Частичный отказ подменяется пустыми neighbors/areas/interfaces/BFD/routes | Последний снимок, неизвестные статусы и показатели |
| 3 | Рекурсивные маршруты | Ответы каталогов и смена устройства требуют проверки; операции связаны с историей | Readiness, точный serverId, повтор/ошибка, URL |
| 4 | Оптимизатор | Ошибка зависимого каталога скрывается; общий сбой удаляет последние данные | Неполнота явно показана, применение требует достоверного контекста |
| 5 | Карта сети | GRE failures игнорируются; отказ GRE/probes превращается в пустые данные; нет общей защиты поздних ответов | Кэш и неизвестные рёбра/узлы, смена источника, пустые/ошибочные состояния |
| 6 | Терминал | Проверить права, готовность устройства, поздний вывод и повторные отправки | Точный контекст, сохранение вывода, подтверждение выполнения |
| 7 | Диагностика GRE: /servers/:id/probes/run, ros-src-address, filters/gre-tunnels | Отмена показана как done, нет строгого output/single-flight/source cleanup; каталоги маскируют ошибки | Подтверждённый результат, отмена отдельно, точный контекст, ошибки и права; расписание в 11Б |
| 8 | Приёмка | ПК/телефон, клавиатура, переходы и профильная регрессия | Схемы/PNG, сборки, сценарии; внешние ограничения отдельно |
Совместимость и границы
- Новый BGP-каталог sessions/failures. Старый агрегат /bgp/sessions сохраняет массив для оповещений; его миграция — 11Б. Новый экран не должен использовать неоднозначный агрегат.
- Отказ выборного BGP-опроса должен иметь ошибочный HTTP-статус вместо успешного пустого массива.
- Время получения браузером не объявляется временем измерения RouterOS. При сбое прошлые данные доступны, но не считаются текущими.
- Неизвестные счётчики/статусы не подменяются нулями/успехом. Не добавляем недоступные API или фиктивные действия.
- HTTP-фикстуры не подтверждают реальные RouterOS/JWT/БД и применение маршрутов/команд. Полный accessibility/performance аудит — этап 12.
Блок 10.1 — подготовка
Прочитаны реализации BGP, OSPF, карты, оптимизатора и точки интеграции рекурсивных маршрутов/терминала. Сохранены порядок, схема, референсы и решение по совместимости BGP. Далее — серверный каталог с failures и проверкой контекста.
Блок 10.2 — BGP API
Каталог sessions/failures и проверка контекста добавлены; старый агрегат совместим. Выборный отказ возвращает 503. Unit/Fastify/TypeScript/lint/backend build прошли. Следующий блок — потребитель нового каталога на экране BGP.
Блок 10.3 — данные BGP
Экран мигрирован на каталог: валидация, кэш отказавшего устройства, неизвестные состояния, постоянный повтор и изоляция источника. 12 E2E/TypeScript/lint прошли. Далее — поля BGP, URL/свежесть и визуальная приёмка.
Блок 10.4 — поля BGP
Новый parser сохраняет неизвестные таймеры/счётчики/AFI, не подменяет префиксы UPDATE-счётчиками; legacy API сохранён. Удалён придуманный экспорт. 13 E2E/unit/live-maps/TypeScript/lint/backend build прошли. Далее — URL/свежесть/источник/layout.
Блок 10.5 — BGP URL/свежесть
server/session/tab и возврат/reload сохраняют контекст; недоступный объект не подменяется. Время успешного опроса каждого устройства не обновляется при отказе. 19 различных E2E/TypeScript/lint прошли. Далее — ASN/type, URL фильтров и layout.
Блок 10.6 — BGP ASN/type
Отсутствующие/невалидные ASN и тип неизвестны; legacy parser сохранён. Unit/15 E2E/TypeScript/lint прошли. Далее — URL фильтров и layout.
Блок 10.7 — фильтры BGP URL
Поиск/тип/состояние/FilterQuery сохраняются и валидируются; AFI варианты соответствуют снимку. 21 E2E, четыре unit, TypeScript/lint прошли. Далее — desktop/mobile и сборка BGP, затем OSPF.
Блок 10.8 — BGP приёмка
27 E2E, unit/TypeScript/lint, frontend/backend build прошли. Шесть PNG просмотрены, мобильные подписи/детали исправлены. Далее — строгий каталог OSPF (BFD/routes сейчас скрывают свои ошибки). Внешние границы — журнал.
Блок 10.9 — OSPF каталог
Строгий /ospf/catalog возвращает failures устройства; BFD/routes ошибки не скрываются. Снимок устройства атомарен, legacy /all и правила оптимизации сохранены. Unit/HTTP/backend build прошли; два исходных lint warning. Далее — экран OSPF.
Блок 10.10 — OSPF данные
Каталог/inventory валидируются, кэш отказавшего устройства сохраняется, состояния/KPI неизвестны, топология не подменяет полный опрос. Убраны фиктивные live costs/mock применение. 17 E2E/TypeScript/lint прошли (два старых warning). Далее — операции/URL/свежесть/поля/layout.
Блок 10.11 — OSPF операции
Lock/readiness, существующее mm:servers:write, валидация подтверждения и постоянная ошибка с повторным чтением. Поздний read/write не действует в другом источнике. 21 OSPF E2E/TypeScript/lint прошли (два старых warning). Далее — URL/времена/поля/layout.
Блок 10.12 — OSPF времена
Время успешного опроса устройства сохраняется при отказах; подтверждение оптимизации API имеет отдельную отметку. Семь E2E/TypeScript/lint прошли. Далее — поля/URL/layout.
10.13. Состояния соседства и BFD
Все восемь состояний из RouterOS OSPF сохранены. Переходные состояния — amber/Pending, неизвестные — neutral/Unknown, подтверждённый Down — red. Строгий каталог не подставляет Down при отсутствующем BFD state; старые endpoints совместимы. 14 E2E, два unit-теста, TS и обе production-сборки прошли. Далее неизвестные показатели, URL и визуальная приёмка.
10.14. Неизвестный cost соседа
Отсутствующий интерфейс не означает cost=10: таблица/линия/панель показывают «—». 11 E2E и TS прошли. Backend defaults/nullable показатели остаются следующим блоком.
10.15. Диапазон AS клиента BGP
Схема клиента принимает null либо 1..4294967295, согласованно со строгим backend parser. Неверный ответ сохраняет кэш как неизвестный. 13 data E2E и TS прошли.
10.16. Cost в области OSPF
Ключ включает устройство/interface/areaId. Конфликты шаблонов и недопустимый cost остаются неизвестными. 4 unit, 7 E2E и TS прошли; алгоритм оптимизации не изменён.
Следующий блок: nullable показатели строгого каталога
| Поля | Текущее поведение | Требуемый результат и проверка |
|---|---|---|
| BFD packets-rx/tx, state-changes | Отсутствие/ошибка превращается в 0 | null при отсутствии/ошибке, подтверждённый 0 сохраняется; сумма неизвестна при неполном составе |
| BFD multiplier | Отсутствие превращается в 3 | null без фактического значения; диапазон проверить отдельно от состояния |
| BFD tx/rx/hold timers | parseMs возвращает 0, UI скрывает даже известный 0 | Разделить null/0; проверить RouterOS duration, не подменять actual-tx желаемым интервалом |
| Neighbor priority/state-changes | Подстановка 1/0 | null при неизвестности, priority=0 сохраняется; таблица показывает «—» |
| Interface cost/priority/hello/dead | Подстановка 10/1/0 | Строгий parser отдельно от legacy/optimizer; неизвестный cost запрещает предложение оптимизации по неполному каталогу |
| Route metric | ospf-metric подменяется distance | Distance не является OSPF cost; отсутствие metric остаётся null, отдельная проверка legacy совместимости |
| Instance version/router-id | Подстановка/default значения | Сверить реальные признаки RouterOS; не дописывать измерения без источника |
Порядок: отдельные catalog DTO и strict parser → backend fixtures (missing/zero/malformed/known) → Zod → таблицы/сводка/топология → readiness операций → API E2E → профильная сборка. Старые endpoints и оптимизатор сохраняют совместимость, пока отдельный контракт не проверен. Значения cache при отказе помечаются последним снимком; времена чтения/записи остаются раздельными.
После nullable блока: URL устройства/вкладки/поиска с back/reload и отсутствующим устройством; при переходе по истории во время write обязательно освободить lock прежней операции только в соответствующем контексте. Затем одна desktop/mobile схема и скриншоты; не считать OSPF принятым до этих проверок.
10.18. Nullable BFD и соседство
Строгий каталог сохраняет null/0 отдельно для BFD timers/counters/multiplier и priority/stateChanges соседа. Actual TX не подменяется desired TX; units/clock duration проверяются строго. 15 HTTP E2E, raw backend fixtures, TS/backend build прошли. Далее interface/instance/route nullable contract и readiness. RouterOS BFD и OSPF — источники семантики.
10.19. Nullable интерфейсы и метрики
Строгий catalog DTO сохраняет неизвестные поля interface/instance; route metric не подменяется distance. Наблюдаемый interface cost=0 сохранён согласно RouterOS OSPF; политика записи min=1 прежняя. При unknown costs/flags операция не предлагается. 21 E2E, 4 unit, backend regression и обе production-сборки прошли. Далее URL/layout и дополнительная проверка метаданных.
10.20. URL и завершение записи после history
Device/tab сохранены в URL; invalid/missing context не расширяет срез. Unmounted child освобождает lock только живого родителя, который перечитывает каталог; source unmount игнорирует старый callback. 17 основных + 8 source E2E, два unit, TS/lint прошли. Далее search/object context/layout.
10.21. Поиск и узел
q/node сохраняются вместе с server/tab. Таблица и топология отражают один срез; пустой поиск не утверждает отсутствие конфигурации. 28 разных E2E, 3 unit, TS/lint и frontend production прошли. Accessible search/close; операция явно относится ко всем интерфейсам устройства. Далее metadata/layout/keyboard.
10.22. Подтверждённые метаданные/узлы
Route subtype и BFD multihop неизвестны без наблюдения. Router ID refs/ambiguity не создают ложную связь устройств; только уникальный фактический ID объединяет узлы. 13 E2E, 2 identity unit, backend regression/build и TS/lint прошли. Далее layout/keyboard/motion/приёмка.
10.23. Приёмка OSPF на ПК/телефоне
Срез устройства → свежесть → профильная сводка → граф/таблица → детали → подтверждение API. Детали на телефоне под графом; Escape возвращает фокус; reduced motion соблюдается. 43 основных + 8 source E2E, 9 unit и production frontend прошли; screenshot/keyboard/motion проверены. Прежние BGP/OSPF backend fixtures/build прошли в 10.22. OSPF принят локально, следующий раздел — рекурсивные маршруты. Реальный RouterOS/JWT/DB не проверен.
10.24. Операции рекурсивных маршрутов
Strict receipts/serverId, общая блокировка save/delete/restore, форма и последний снимок при ошибке; разные routing tables и скрытые поиском endpoints сохранены. 35 E2E, TS/lint, обе сборки и config-sync прошли; 11 общих history повторно прошли после разделения доступности read/write. Далее backend validation, URL/source и observed metadata/layout. Legacy parser пока не мигрирован; сетевые правила применения прежние.
10.25. Валидация PUT/restore
Явный список и точный serverId обязательны; повреждённая версия не превращается в empty/default конфигурацию. HTTP injection проверяет отказ до сети; auth/config-sync/build/lint прошли. Intentional empty и canonical snapshot без id совместимы; алгоритм применения прежний. Далее URL/source, observed parser и layout.
10.26. URL/history/source
server/q/route/table принадлежат экрану; default replace, выбор/раскрытие history. Missing-device fallback панели запрещён. Source lock сохраняется над device context; late write освобождает lock и запускает чтение текущего среза только соответствующего источника. 38 разных основных + 8 source E2E, 2 unit, TS/lint и production frontend прошли. Далее observed metadata и layout.
10.27. Строгий наблюдаемый каталог
Отдельные catalog endpoints сохраняют legacy потребителей. Неполный owned snapshot отклоняется целиком до сохранения; нули, disabled и unset scope сохранены. Gateway active означает использование в маршруте, без заявления о reachability; страна только явная. 42 основных + повторные 18 data/values, 8 source, backend parser/HTTP/config-sync/build и TS/lint прошли. Далее визуальная приёмка. Реальная версия RouterOS требует отдельной проверки.
10.28. Локальная приёмка рекурсивных маршрутов
48 основных + 8 source E2E, backend recursive tests, lint/production frontend прошли. 1440/390/320 px, keyboard раскрытие, trap и возврат фокуса, parent-owned scroll; шесть экранов в плане. Неизвестный тип не подменяется EN. ReUI audit consumer-композиции выполнен без изменения vendor/theme. Далее оптимизатор; RouterOS/DB/JWT остаются внешней приёмкой.
10.29. Community: расчёт и симуляция
Live таймерный успех убран; demo симуляция явно подписана, cleanup/lock сохранены. Модельная базовая цепочка и индекс в баллах обозначены; автоприменение недоступно, ECMP/RPF/VRF локальные. Исправлены mock-ID матриц. 6 E2E, TS/lint прошли. Далее strict чтение и OSPF операции; раздел ещё не принят.
10.30. Согласованные источники расчёта
Строгие inventory/rules/probes, Promise.allSettled и публикация только полного valid snapshot. Partial сбой сохраняет предыдущее; initial неизвестность без нулей; epoch/freshness. 16 E2E + 2 unit, lint/production frontend прошли. Далее OSPF preview/apply; модельные fallback и metadata legacy пока явно ограничены.
10.31. Строгий preview OSPF
Контекст serverId/веса, полный список изменений/counts/ids; metadata strict catalog, повтор/last preview/late context. 12 профильных + ранее 16 существующих (24 разных), TS/lint прошли. Apply receipt и происхождение backend модельных значений ещё требуют проверки; далее 10.32.
10.32. Подтверждённое OSPF применение и RBAC
Strict receipt/server/weight, ref lock, readonly/disabled контекст и reread любого результата. 16 E2E, readonly повтор, TS/lint, обе production сборки и auth tests прошли. Specific OSPF rights согласованы: preview read, apply write; signed JWT со stub handlers без RouterOS/DB. Далее backend provenance: legacy cost/metric defaults ещё не приняты как observed данные.
10.33. Backend cost и валидация плана
Observed selector вместо default cost/disabled; неоднозначные шаблоны отклоняются до write. Полный план валидируется, disabled сервер 409. DI HTTP/unit без RouterOS/DB, live-maps regression/backend build прошли; lint два прежних unused warning. Ранжирование прежнее, model fallback/clamp ещё требуют отдельного отображения. Далее layout/контекст.
10.34. Адаптивность оптимизатора
1440/390/320 px, keyboard/ARIA и disabled ECMP; native fieldset композиция исправлена после визуального обнаружения невидимых KPI. Семантические токены четырёх таблиц, девять снимков в плане; 35 E2E, TS/lint и production frontend прошли. Teardown catalog отказ backend записан в журнале. URL/source и model provenance ещё открыты.
10.35. Отсутствующие индексы Community
Без полной цепочки индексы неизвестны, рекомендации нет даже при пороге 0. 7 E2E, 3 unit, TS/lint прошли; расчёт существующих цепочек прежний. Далее URL/source-контекст.
10.36. URL устройства оптимизатора
server сохраняет выбор/reload/history без потери других параметров. Неизвестный/disabled/malformed explicit контекст не подменяется и не запускает preview/metadata; явный select восстанавливает работу. 22 E2E, 3 unit, TS/lint и production frontend прошли. Далее source/provenance; Home tabs URL пока вне блока.
10.37. Source isolation оптимизатора
8 E2E late preview/apply success/failure × backend/mode через настройки, новый снимок и отсутствие старых receipt/error/reread. TS/lint прошли. Production frontend из 10.36; реальные операции вне локальной приёмки. Далее model provenance и карта/терминал.
10.38. Смысл метрик preview
Короткое пояснение расчётных Ping/скорости, без изменения ranking/write. Lint и 14 preview E2E прошли. Далее provenance полей с сохранением observed 0/null; снимки 10.34 ещё без нового текста. Оптимизатор/этап 10 целиком не приняты.
10.39. Observed метрики WAN–JH/JH–Exit
Исходные значения/дата пробы отдельно от неизменной модели. Матрица не подменяет unknown моделью, полные цепочки явно расчётные. 2 unit, 9 E2E, TS/lint и ReUI audit прошли. Далее backend OSPF provenance; screenshots ещё требуют обновления.
10.40. OSPF provenance API
Shared контракт и backend observed исходные значения/даты, UI модель отдельно от снимка. Legacy без observed даёт неизвестность; rank/write прежние. Backend optimizer/live-maps, 30 E2E, TS/lint и обе production сборки прошли. Далее Router ID ambiguity, затем visual acceptance.
10.41. Однозначность Router ID
Полный опрос enabled inventory без first-match; duplicate ownership/unknown/failed каталог отклоняет план до write. Known disabled/empty и одинаковый ID одного устройства допустимы. Optimizer suite/backend build прошли, lint два прежних warning. Реальный RouterOS каталог ещё внешняя приёмка; далее screenshots.
10.42. Live WAN без подстановки
Нет mock catalog/synthetic WAN в live topology; отсутствие uplinks объяснено с переходом к серверу. 6 unit, 16 E2E, TS/lint прошли. Далее подписи и Community scope перед визуальной приёмкой.
10.43. Настройки/Community scope
Порог в баллах, обновление расчёта, инертный гистерезис недоступен; рекомендации только своего home. 4 unit, 10 E2E, TS/lint прошли. Девять снимков обновлены; header clipping ещё исправить перед acceptance.
10.44. Локальная приёмка оптимизатора
47 разных основных + 8 source E2E, backend optimizer/live-maps, production frontend/backend прошли; девять финальных снимков, ReUI audit/TS/lint. Исходные метрики отдельно от модели, full receipts/URL/source, без mock WAN/foreign Community. Внешние RouterOS/DB/JWT ограничения в журнале. Далее карта сети и терминал, этап 10 ещё открыт.
Блок 10.45 — согласованный снимок карты сети (2026-10-01)
- Servers/GRE/probes публикуются вместе после строгой проверки схем, уникальности и владельцев. Частичный каталог GRE и неизвестные ссылки отклоняются; первоначальный отказ не становится пустым успешным ответом. При фоновом сбое сохраняется последний полный снимок с явным предупреждением.
- Время ответа браузера отделено от измерений. Новый источник пересоздаёт контекст; epoch/alive запрещают позднему ответу и DNS изменять новую карту.
- 2 unit, 9 HTTP E2E и TypeScript прошли. ESLint карты содержит 5 исходных ошибок и 1 warning; сравнение с HEAD подтвердило отсутствие новых. Их исправление включено в дальнейшую приёмку карты. Next dev имеет собственный пустой alert, поэтому тест восстановления проверяет именно сообщение карты.
- Далее неизвестный статус, ресурсы и GRE без синтетических live значений; Flow/DNS, URL/доступность и приёмка карты ещё не завершены.
Блок 10.46 — неизвестный статус карты (2026-10-01)
- Nullable API status преобразуется в unknown: нейтральный узел/бейдж, отдельные фильтр и счётчик. Неизвестность не увеличивает offline. Общий ServerStatus расширен; потребители users/optimizer передают неизвестность как null, dashboard SVG имеет нейтральный стиль.
- 104 E2E карты/дашборда/серверов/мониторинга и TypeScript прошли. Новых lint ошибок нет: карта — прежние 5 ошибок/1 warning, users — прежний set-state-in-effect, dashboard helper — прежние 2 unused warning. В серверном URL тесте был внутренний Next dev warning; сценарий завершился успешно.
- Далее убрать синтетические live CPU/RAM/HDD/uptime/history и GRE, затем проверить Flow/DNS и доступность карты.
Блок 10.47 — измерения карты без синтетических live значений (2026-10-01)
- CPU/RAM/uptime читаются независимо из API, сохраняют нули и неизвестность; HDD, температура и история CPU не генерируются для live. Указано фактическое polledAt либо неизвестное время. Демо-ресурсы доступны только с явным demo=true.
- GRE fallback по id отключён по умолчанию, карта явно включает его только в mock. Общий helper также убрал выдуманный fallback из live internet path. Probe DL/UL не округляются до целых, неизвестный Ping имеет нейтральный цвет. Catalog latency сохраняет дробь; модель WAN→JH ещё требует отдельного пояснения.
- 4 unit, 19 E2E карты/дашборда и TypeScript прошли. Lint сравнен с HEAD: новых проблем нет; прежние prefer-const в layout и React правила карты будут устранены при её приёмке.
- Далее Flow Map/DNS: строгие envelopes, частичный отказ/свежесть/гонки; модельные линии, URL-контекст, доступность и адаптивность ещё впереди.
Блок 10.48 — достоверность NetFlow и DNS карты (2026-10-01)
- NetFlow принимает полный DTO backend за 5 минут: поля/flags/счётчики не заменяются default нулями. При отказе сохраняется предыдущий снимок, первоначальная неизвестность и время ответа браузера обозначены отдельно; статус приёмника не выдаётся за свежесть измерения. Обновить повторяет оба независимых чтения.
- Опрос не перекрывает и не отменяет медленный запрос каждые 4 секунды. Cleanup/epoch запрещают старый ответ; скрытие обеих flow групп приостанавливает обновление без потери последнего снимка.
- DNS envelope проверяет точный набор имён и IPv4/null. Новая topology не использует прежний DNS; отказ/неразрешённые имена явно предупреждают о неподтверждённых связях. Неполные API данные выводят краткую понятную ошибку вместо технического JSON Zod.
- 6 unit, 20 разных E2E (19 общих + новый slow, 8 Flow повторены после финального изменения) и TypeScript прошли. Новых lint проблем нет. Первые Flow фикстуры не перехватывали health и получили ECONNREFUSED; фикстуры исправлены, повтор чистый.
- Далее отдельные source/race E2E, достоверность модельных WAN линий/выбранных объектов, затем URL и доступность/адаптивность карты.
Блок 10.49 — поздние ответы при смене источника карты (2026-10-01)
- Добавлена отдельная source-конфигурация Playwright (:3101, исходный backend :8000 и новый :8101). 12 сценариев snapshot/Flow/DNS × backend/mock × успех/отказ подтверждают, что прежняя карта, сервис и ошибка не попадают в новый источник, а старый ответ не запускает дополнительные чтения.
- Все 12 E2E и lint новых тестов/config прошли. Default suite исключает source-файл; Next серверы запускаются последовательно.
- Далее выбранные детали из текущего снимка, подписи модельных WAN связей и прежние lint ошибки карты; затем URL, клавиатура, телефон и визуальная приёмка.
Блок 10.50 — актуальные детали и модель связности карты (2026-10-01)
- Открытые детали server/GRE заново разрешаются по стабильной идентичности в текущем снимке: свежие name/status/resources не остаются на сохранённом объекте. Unknown latency/sessions/IPsec выводятся как неизвестность, не offline/0/Plain. Primary/backup GRE — только приоритет визуализации; WAN API — аплинк каталога.
- Пунктир WAN→JH прямо обозначен моделью связности. Live модель не анимируется как активный маршрут и не показывает сумму latency как RTT линии; Ping модели подписан отдельно в деталях. Probe значения сохраняют нули/частичные DL/UL; подпись показывает probe ID, дату Ping и неизвестное время скорости.
- Узлы всех ролей получили имя устройства и keyboard Enter/Space. Пульсация размера нарушала стабильность области кнопки; удалена, имя видно и для JH/Exit. Прежние React set-state/refs/immutability/exhaustive-deps и prefer-const устранены без подавления lint.
- 24 E2E карты, TypeScript и lint карты/helpers/tests прошли. Новая проверка подтверждает 0 Ping, дробную DL при неизвестной UL и старую дату пробы. Реальная сеть остаётся внешней приёмкой.
- Далее URL-контекст, клавиатурные действия остальных объектов и адаптивность/Frame/screenshots карты.
Блок 10.51 — URL-контекст карты (2026-10-01)
- URL сохраняет server/WAN, status filter, q и режим services/countries. Перезагрузка и история восстанавливают детали/срез; поиск заменяет текущий history entry. Посторонние query/hash сохраняются. Выбор GRE/сервиса пока локальный, pan/zoom/drag также локальные.
- Строго проверяются дубли, длины и enum. Неверный URL показывает ошибку до чтения inventory, сброс очищает только поля карты. Отсутствующий server или WAN явно недоступен; первый другой объект не выбирается. Nullable server status совместим с unknown filter.
- 2 URL unit, 11 E2E URL/details (7 URL повторены после исправления тестового encoded-space matcher), TypeScript и lint прошли. В production ещё требуется общий build после адаптивной композиции.
- Далее ReUI Frame, панели и интерактивные SVG controls: keyboard/focus, телефон, reduced motion, скриншоты и локальная приёмка карты.
Блок 10.52 — Frame, доступные действия и детали карты (2026-10-01)
- Установленный ReUI Frame объединяет toolbar, SVG и детали с parent-owned высотой. На ПК детали справа; на телефоне занимают рабочую область, закрытие возвращает карту. Выбор устройства доступен вне SVG, длинные имена переносятся по словам, отсутствует горизонтальный overflow на 1440/390/320 px.
- Действия устройства используют стандартный Base UI Dialog с действительными ссылками и обработкой отказа clipboard. Слои — Popover; Escape возвращает фокус и сохраняет server URL. Узлы устройств/WAN/сервисов и метрики GRE/Flow доступны Enter/Space; кнопки названы, декоративные иконки скрыты от screen reader.
- SVG использует semantic tokens; reduced motion отключает animateMotion. Экспорт сохраняет CSS переменные/фон и сериализуется XMLSerializer как standalone SVG. Nullable UL не выводится строкой null; неизвестный IPsec явно подписан.
- 35 основных + 12 source E2E, TypeScript и lint прошли; ReUI Frame checklist прочитан. Первые регрессионные тесты выбирали скрытые option после добавления селектора: селекторы ограничены SVG, повтор чистый. 6 снимков проверены визуально.
- Далее 10.53: камера по границам объектов и читаемость малой топологии, pointer/touch и пустые состояния; текущие overview снимки ещё показывают слишком мелкий граф. Production build — после этого блока. Реальные RouterOS/JWT/БД не проверены.
Блок 10.53 — камера и читаемость карты (2026-10-01)
- ViewBox учитывает реальное соотношение сторон canvas; начальное вписывание включает устройства, WAN, сервисы и подписи. Оно выполняется один раз на источник и не сбрасывает ручной zoom после обновления API. Кнопка/горячая клавиша вписывают текущие объекты; wheel/drag используют ту же геометрию.
- Название вынесено под узел; на телефоне размер текста компенсирует SVG масштаб, длинная подпись сокращена при сохранённом полном accessible name/деталях. Страна обозначена ISO при отсутствии площадки и до загрузки внешнего изображения флага. Легенда — доступные раскрываемые обозначения вне SVG.
- WAN карточка получила Enter/Space и aria-pressed. 2 camera unit + 16 E2E layout/details/URL, TypeScript и lint прошли; после ISO fallback повторены 5 layout E2E, TypeScript и lint. Снимки обновлены.
- Далее pointer/touch, закрытие деталей с возвратом фокуса, пустой inventory/пустой срез; затем production build и локальная приёмка карты. Реальная сеть не проверена.
Блок 10.54 — Pointer/touch и локальная приёмка карты (2026-10-01)
- Pointer Events/capture удерживают drag за пределами canvas; основной указатель отделён от остальных, cancel/lost capture завершают жест без залипания. Touch-action отключает прокрутку только на SVG; детали продолжают прокручиваться. Фокусируемый canvas поддерживает стрелки, zoom/fit имеют клавиатурные альтернативы.
- Закрытие деталей кнопкой/Escape возвращает фокус к выбору устройства. Пустой inventory явно предлагает серверы; поиск без результатов даёт сброс только среза. Без подтверждённого снимка экспорт недоступен; загрузка объявляется role=status.
- Карта принята локально: 39 основных + 12 source E2E, 10 unit, TypeScript, lint и production frontend build прошли. ReUI Frame checklist повторён, адаптивные снимки обновлены. Touch проверен через реальный Chromium input protocol; физических телефонов в приёмке нет.
- Границы: HTTP фикстуры не подтверждают RouterOS/JWT/БД; WAN пунктир остаётся моделью, Flow свежесть — время браузерного ответа; SVG флаги зависят от существующего CDN. Фильтр сохраняет приглушённые узлы как контекст, pan/zoom/drag локальные. SVG XML валиден, сторонние SVG viewers отдельно не проверены.
- Далее 10.55: терминал — API-контракт, выбранное устройство/host из URL, достоверность выполнения и ошибки/повтор/права. Этап 10 ещё не завершён.
Блок 10.55 — достоверный REST терминал и URL (2026-10-01)
- Frame/ServerRailLayout сохранены; нет фиктивного Connected/admin prompt/LIVE/SSH или обещания Tab completion. Устройство выбирается явно, server/host восстанавливаются из URL; неизвестный/неоднозначный host не выбирает другое устройство. History/reload/query/hash сохраняются. Неверный URL останавливает чтение каталога.
- Каталог и output проверяются строго; первоначальная ошибка отличается от пустого списка. Фоновый отказ сохраняет каталог/черновик и приостанавливает новые команды до успешного обновления. Ключ источника/device/host и abort cleanup запрещают прежний вывод; запрос защищён немедленным lock.
- При API/legacy error или таймауте команда остаётся в поле; успех показан только после валидного output, пустой вывод подписан. Поле/кнопка остаются видимыми во время ожидания, после завершения фокус возвращается. Быстрые команды только подставляют; clear — локальная очистка без API, история до 100 команд/вывод до 1000 строк.
- Frontend права соответствуют текущему backend: каталог mm:servers:read, POST exec mm:servers:write. Терминал в permissionForPath связан с servers:read. Правила RouterOS команд не расширены.
- 12 E2E, 3 unit, TypeScript и lint прошли; clear добавлен затем проверен повтором quick/history E2E и lint. ReUI checklist прочитан. Production/screenshots — после backend/source/адаптивной приёмки терминала.
- Далее 10.56: backend exec не должен маскировать BFD/API отказ пустым успехом; DI route тесты. Реальная сеть/JWT/БД не проверены.
Блок 10.56 — честный backend exec (2026-10-01)
- BFD/API отказ не подменяется пустым успехом: upstream ошибка возвращает 502/error, неподдерживаемая команда или неверные аргументы — 400/error; успешный output сохраняет прежнюю форму. Frontend 10.55 понимает новые ошибки и legacy error: output.
- Прежний диагностический allowlist сохранён. Ping/log парсятся целиком, нулевые/частичные/повторные аргументы отклонены до обращения RouterOS; прежние caps count=20, limit=200 сохранены. Сетевые write команды не добавлены; RBAC не изменён.
- Отсутствующие BGP/BFD status, OSPF cost/type/BFD/version/area/changes и firewall counter не выдаются за active/down/10/broadcast/no/2/0. Ping timeout виден без TTL, неизвестная packet loss — ?, нулевые измерения сохранены. Resource memory отказывается от NaN/overflow.
- createExecRoutes допускает DI для тестов; production defaults — прежние DB/MikrotikClient. test:exec включён в backend test. Route/RBAC DI тесты, backend test:auth, build и lint прошли. Подписанные JWT проверяют текущий middleware до device lookup; это не приёмка реального портала/RouterOS/БД.
- Далее source/cancel/timeout/пустой/disabled/invalid URL E2E терминала, адаптивные снимки и production frontend; затем локальное завершение этапа 10.
Блок 10.57 — локальная приёмка терминала (2026-10-01)
- Терминал принят локально: 20 основных E2E (17 данных и 3 адаптивных), 8 source E2E, TypeScript, lint и production frontend build прошли. Проверены timeout/поздний ответ, пустой/disabled каталог, неверный URL, сохранение команды, смена режима/backend и 1200 строк вывода.
- Снимки ready/output для ПК, 390 и 320 px сохранены. Общая мобильная кнопка ServerRail теперь ограничена шириной и сокращает длинное имя; гидратация учитывает cleanup. 12 регрессионных сценариев GRE/VXLAN/IPsec/OSPF/recursive прошли; восемь обновлённых снимков просмотрены и сохранены. ReUI Frame checklist повторён.
- Границы: HTTP fixtures/DI доказывают обработку UI/API, не реальный RouterOS/БД/портал. REST терминал не является SSH-сессией; clear локальный, отмена/timeout не подтверждают остановку на устройстве.
- Этап 10 остаётся в работе: обнаружен отдельный /probes (Диагностика GRE), который ещё требует приёмки. Далее 10.58: строгий результат, single-flight и отмена запросов диагностики; каталоги/URL/права и backend — отдельными блоками. Расписание относится к 11Б.
Блок 10.58 — достоверный результат диагностики GRE (2026-10-01)
- /probes проверяет строковый output и legacy error; неверный контракт не превращается в пустой успех. Пустой подтверждённый вывод подписан, цель/параметры сохраняются после отказа.
- Немедленный single-flight lock закрывает повторный Enter; disabled устройство и неподтверждённый каталог не запускают запрос. Стоп/Остановить все отменяют ожидание со статусом cancelled, без заявления об остановке RouterOS. Таймаут 60 с показывает неизвестность результата и требует ручного повтора.
- Cleanup отменяет запрос; ключ режима/backend исключает перенос прежней истории/вывода. Удаление выполняющегося теста отменяет ожидание. Существующие Frame/состав инструментов/сетевые правила сохранены.
- 7 основных и 4 source E2E, 2 unit, TypeScript и production frontend прошли. Новые helper/test файлы проходят lint. Страница сохраняет исходные 8 set-state-in-effect ошибок и 2 предупреждения: сравнение ESLint HEAD/current подтвердило одинаковые counts; это не чистый lint страницы.
- Далее 10.59: каталог серверов/ошибка/повтор и неизвестный status; затем URL-контекст, права, GRE каталог, backend probes и адаптивная приёмка. Расписание отдельно в 11Б. Реальный RouterOS не проверен.
Блок 10.59 — каталог устройств диагностики (2026-10-01)
- Каталог проверяется по типам id/host/status/enabled/type, уникальности id и конечной неотрицательной latency. Неизвестный status отображается как unknown, не offline. Abort/cleanup запрещают прежний результат после ухода/смены источника.
- Отказ сохраняет последний список и черновик; ошибка API показана отдельно от пустого каталога. Обновить допускает ручной повтор. Во время обновления/ошибки запуск приостановлен; время получения последнего каталога видимо. Фоновая загрузка не удаляет форму.
- 12 основных + 4 source E2E, 3 unit, TypeScript и production frontend прошли. Первый прогон новых тестов остановился на пересечении role=alert с Next route announcer; alert каталога именован, повтор 12/12 чистый. Helper/tests проходят lint; исходные ошибки страницы остаются (catalog эффект исправлен, остальные эффекты/расписание ещё не приняты).
- Далее 10.60: права страницы/запуска должны соответствовать фактическим /api/servers read/write. Затем GRE каталог, URL/device context, backend и адаптивная приёмка. Внутреннее sessions=0 не отображается в диагностике и не является измерением; заменить при общей типизации. Реальная сеть не проверена.
Блок 10.60 — права диагностики (2026-10-01)
- permissionForPath(/probes) соответствует каталогу servers:read, вместо прежнего fallback dashboard:read. Запуск и Enter требуют servers:write, как текущий POST /servers/:id/probes/run; серверный RBAC не расширен. Нет servers:read — каталог не запрашивается.
- GRE каталог требует filters:read; без него не выполняется GET, BW запуск недоступен с понятной причиной. Остальная разрешённая диагностика остаётся доступной. Права расписания будут приняты отдельно в 11Б.
- 14 E2E, TypeScript, production frontend, профильный lint и backend test:exec/test:auth прошли. Auth exec тест теперь проверяет также probes HTTP путь подписанными JWT на настоящем requireAuth/permissionForRequest со stub handler: read/network write запрещены, servers write/admin допущены. Это не проверка production probes handler/RouterOS/портала.
- Далее 10.61: GRE каталог — ошибка не равна пустому списку, строгий контракт/cleanup/повтор. Затем URL, backend probes и адаптивная приёмка. Исходные 7 эффектных lint ошибок страницы ещё открыты.
Блок 10.61 — достоверный GRE-каталог диагностики (2026-10-01)
- Переиспользован filtersGreResponseSchema; подтверждается форма ответа, уникальность и принадлежность serverId. Только enabled текущий сервер вызывает GET. Abort/cleanup запрещают поздние GRE после смены устройства/источника.
- Ошибка сохраняет прошлый список, отдельно подписана и даёт Повторить GRE. Loading/error не выдаются за пустой каталог. BW требует ready, включённый выбранный туннель и непустой remoteAddress; отказ объяснён. Ping и другие инструменты не блокируются независимым GRE отказом.
- 18 основных E2E + 2 поздних GRE + 2 disabled/no-address BW, 4 source E2E, 3 unit, TypeScript и production frontend прошли. Профильный test lint чистый. В странице остаются 6 прежних эффектных lint ошибок и 2 предупреждения; GRE эффект устранён без suppressions.
- Далее 10.62: проверить точность подписи/preview DNS (сейчас имитирует /resolve server=1.1.1.1, backend использует DNS приложения); затем URL выбор без fallback, ros-src-address контракт, backend probes ошибки/аргументы/метрики, адаптивные снимки и локальная приёмка. /probes пока не принят, этап 10 не завершён.
- Остаток окна при сохранении около 4%; RouterOS/БД/внешний DNS не проверены. История локальная, отмена HTTP не подтверждает остановку устройства. Расписание/формы сбора остаются 11Б.
Блок 10.62 — честный DNS preview и inline ошибка (2026-10-01)
- DNS в /probes подписан как DNS приложения; preview описывает параметры резолвера хоста backend. Не обещает /resolve MikroTik или server=1.1.1.1, которых текущий dnsLookupText не использует. Демонстрационный источник отмечен отдельно.
- readProbeOutput отклоняет DNS ;; ERROR: внутри многострочного output, а не только error: в начале; inline отказ не превращается в done/live. Цель и тип остаются для ручного повтора. Backend DNS реализация/сетевые правила не изменены.
- 4 unit, 5 профильных E2E (DNS/error/retry, malformed/legacy/timeout и GRE malformed), lint helper/tests, TypeScript в production frontend build прошли. Первый DNS тест использовал description как accessible name; исправлен на реальное имя DNS, повтор 5/5 чистый. Production build повторён отдельно после завершения E2E.
- Остановка при 98% использования пятичасового окна; все блоки сохранены локальными коммитами без push. Следующий шаг 10.63: восстановление /probes server из URL без первого-device fallback, сохранение query/hash/back/reload, контракт/cleanup ros-src-address. Затем backend probes DI (невалидные id/аргументы, HTTP ошибки вместо legacy output, DNS/MTU/неизвестные метрики), доступность/адаптивные снимки и приёмка.
- Этап 10 ещё в работе; /probes не принят. Остались 6 прежних set-state-in-effect ошибок и 2 предупреждения страницы, включая расписание (11Б). История локальная; HTTP моки не подтверждают реальные RouterOS/БД/DNS/портал.
Блок 10.63 — устройство диагностики из URL (2026-10-01)
- /probes читает server через useSearchParams/Suspense. Выбор явно сохраняется pushState; остальные query/hash, back и reload сохранены. Нет автоматического выбора первого устройства в live/демо; ServerRail preserveSelection удерживает исходный контекст.
- Повторный/пустой/некорректный server останавливает API до монтирования содержимого. Отсутствующее устройство показывает отдельную ошибку/сброс выбора, выключенное — причину недоступности. Без выбора запуск и зависимые запросы не выполняются. GET ros-src-address также ограничен подтверждённым enabled устройством.
- 29 основных + 4 source E2E, 2 URL unit, профильный lint, TypeScript и production frontend прошли. Старые тесты выбирают server=1 явно; при переходе в demo выбирают реальное demo устройство вместо прежнего fallback.
- Далее 10.64: строгий ros-src-address контракт и привязка preview к id/host с отменой/повтором; затем backend probes DI/аргументы/ошибки/метрики, доступность/адаптивная приёмка. Этап 10 остаётся в работе. Моки не доказывают реальные RouterOS/DNS/БД.
Блок 10.64 — IPv4 источника preview (2026-10-01)
- ros-src-address проверяет host текущего устройства и канонический IPv4/null. Preview привязан к id+host; поздний ответ/ошибка отменяются при смене устройства/источника. Запрос идёт только для enabled устройства и инструментов ping/traceroute/mtu; DNS приложения не запрашивает этот источник.
- Error/loading/null отличаются; ошибка имеет ручной повтор. В UI явно указано: preview справочный, backend повторно определяет src-address при запуске. Ошибка preview не меняет сетевые правила и не запрещает разрешённую диагностику; неизвестный FQDN адрес показан ?, а не прежним IP.
- 36 основных E2E (29 данных + 7 IPv4), 4 source E2E, unit decoder, профильный lint, TypeScript и production frontend прошли. Реальный DNS/RouterOS не проверен.
- Далее 10.65: DI backend probes, честные HTTP ошибки вместо legacy error output, сохранение allowlist/методов; затем строгие аргументы и MTU/неизвестные измерения. Доступность, адаптивная приёмка /probes и прежние lint эффекты ещё открыты. Расписание остаётся 11Б.