Files
MikrotikManager/docs/ux-ui-stage-10.md
T

38 KiB
Raw Blame History

Этап 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 Приёмка ПК/телефон, клавиатура, переходы и профильная регрессия Схемы/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, скриншоты и локальная приёмка карты.