fix(routes): подтвердить применение и восстановление рекурсивных маршрутов

This commit is contained in:
Denozordec committed 2026-10-09 21:08:10 +07:00
1 parent 36c6a21ca5
commit 5b3133ce73
19 files changed
+659 -28

No files matched your search

+32
View File
@@ -749,3 +749,35 @@ POST optimize при отказе записи возвращает502 и reques
**Runtime.** Backend ux-optimizer87c/version1.0.0-test.optimizer87c, image sha256:22cc9a09a89038e58c15dfd6224191d1fab7ad63f7af6f80ecc9e7577483d390; frontend ux-optimizer87/version1.0.0-test.optimizer87, image sha256:22f05c341a7dc0e40e04f23b0da61ba5cfbf31d741d4e22b0c9bcd71c85e0c49. Backend/PG healthy, frontend served/browser passed. Backend entry/node --check/pg_restore18.6, frontend entry/node --check и compose --wait passed. Три backend builds87/87b/87c по двум реальным flag incompatibilities; frontend build один, apt cache сохранён. Context backend routing83 +2 routes, затем4 файлов final-c; override SHA c04289ab57294d57cc9aed292e247e144c171ade3d1101f6ebb84129e41b065be; frontend ipsec77 +OSPF page, override dab57aad2cb248553b0fee9da73069f7a31cb627b26c414f03320315a299756db. Labels не Git SHA; это рабочие файлы до локального коммита. .env backup приватный, миграций нет. Один локальный commit без push.
Продолжение88 — recursive routes, затем диагностика. BFD sustained/alternate-path failover, IPv6/scale/maximum throughput, Portal SSO/browser auth и другие внешние ограничения сохраняются; lab AUTH_REQUIRED=false, RBAC checked отдельно. API /get и .proplist/query подтверждены [RouterOS REST API](https://help.mikrotik.com/docs/spaces/ROS/pages/47579162/REST%2BAPI) и реальным устройством. Квота23% использовано, этап12.5 открыт.
## 12.5.88 — рекурсивные маршруты: реальные операции и история (2026-10-09)
**Исправления.** Все6 путей catalog/gateways/catalog/legacy reads/PUT/restore проверяют enabled=false и возвращают409 до опроса/применения любого типа устройства. История остаётся доступным чтением БД. Создание RouterOS route исправлено с POST без add на PUT. Весь управляемый набор проходит strict parse до записей: неподдерживаемая owned row не исключается молча перед удалением. IPv4 destination/gateway и check-gateway проверяются до native writes. Замена кэша выполняется в транзакции вместо независимых delete/insert.
Request-local receipt сохраняет подтверждённые createdIds/deletedIds и число записей. RouterOS4xx после успешных шагов → partial; первый4xx → rejected; потерянный ACK/неправильный ответ/transport → unknown; ошибка кэша/истории после native completion → applied/metadataRecorded=false. После успешного apply, но отказа заключительного чтения кэша → applied/metadataRecorded=true. Ошибки операций возвращают502, последующие записи не выполняются, automatic retry/rollback не добавлены. Старые/default/foreign routes не удаляются при отказе создания новых; полная distributed transaction/idempotency не заявляется.
| Проверка | Подтверждённый результат |
| --- | --- |
| Disabled Home Router и Exit Node | По6 запросов409; контрольный HTTP probe0 |
| Native PUT + strict catalog | Формат/ID/flags подтверждены на двух CHR отдельным малым probe |
| Recursive resolution | gateway198.18.189.peer → resolver host route → immediate-gw198.18.88.peer%ownGRE |
| Data plane | Own loopback Ping3/3 в обе стороны в окончательном run |
| API/history | Apply, изменение distance/disabled, restore своей версии; invalid CIDR400 без записи |
| Fault injection | partial1/unknown1/applied2 подтверждённых записей; независимый native GET |
| Browser | 4/4 ПК/320px, две реальные формы добавления; reload context, pageerror0 |
**Стенд.** Свои GRE и link198.18.88.0/30, bridge loopbacks198.18.188.1/32↔2/32 и probe IP198.18.189.1/32↔2/32. Неуправляемый собственный resolver /32 имеет scope10; управляемый remote loopback /32, gateway probe IP, scope30/target-scope11/distance150/check-gateway none. Native immediate-gw доказал двухступенчатое разрешение через GRE, Ping подтвердил передачу. Это проверка recursion/data plane, не loss-based failover или SLA. Default/public/metadata routes и195.195.195.195/32 сохранены.
**Доказательства.** [Native/API/DB отчёт](ux-ui/acceptance/recursive-routes-2026-10-09.json). Production API применил конфигурацию обоих устройств, прочитал каталог, изменил distance/disabled и восстановил только созданную в этом run версию. Revisions baseline≤35 проверен, чтобы тестовые записи не вызвали pruning старой истории. HTTP409 проверены на двух собственных disabled DB rows с probe на private Docker DNS; fake rows и их revisions удалены каскадно.
Ошибки инъецированы в тот же native executor: второй PUT отклонён до передачи → partial и сохранён старый маршрут; второй PUT выполнен, ACK заменён исключением → unknown, фактические3 owned rows прочитаны отдельно; persist callback отказал после replace → applied, новый набор уже на RouterOS. API-обёртка этих receipts и поздний getRoutes отказ проверены HTTP/unit. Реальный отказ PostgreSQL/физический TCP disconnect не создавался.
**Браузер.** Настоящий backend/frontend без mocks: два устройства×1280/320. Раскрытый endpoint и URL/reload, document fits, затем на320px заполнена и отправлена форма: gateway probe IP/scope30/target11/none/distance152, новый private prefix198.18.188.250/32. API подтвердил два маршрута, sheet закрылась, две группы видны. [Browser отчёт](ux-ui/acceptance/browser-recursive-2026-10-09.json), [ПК](ux-ui/screens/recursive-real-server1-1280-2026-10-09.png), [320px форма](ux-ui/screens/recursive-real-form-server1-320-2026-10-09.png) просмотрена. Общие Data Grid Filtering2/Sheet8/Frame из плана сохранены, frontend source не менялся.
**Проверки/оснастка.** 29 профильных E2E data/values/links passed. Backend recursive HTTP/catalog/executor tests, TypeScript, scoped ESLint/diff passed. Проверены invalid before writes, foreign retention, create/delete ordering, unsupported owned preflight, malformed ACK, rejected/partial/unknown/applied, поздняя ошибка чтения и disabled обоих типов. Первый native run Ping0/3: обратный маршрут ещё не создан; порядок исправлен на предварительное применение обеих сторон. Второй начальный Ping2/3: ограниченное ожидание готовности пути добавлено, до3 коротких попыток с сохранением результатов. Финальный run получил3/3 с первой попытки на обоих CHR. Ошибки оснастки не считаются приёмкой; оба cleanup passed.
**Очистка.** Native managed routes сверены по уникальному name-prefix, остальные свои GRE/bridge/IP/resolver по exact ID/атрибутам. Свои объекты удалены, baseline IDs4 коллекций×2 совпали. Исходно пустой recursive cache восстановлен; удалены только новые собственные revisions после проверки payload/comment и ID, прежние revision IDs сохранены. Последовательности PG увеличились из-за тестовых insert; это не побитовый restore БД. Оба CHR доступны, credentials неизменны, fixture containers удалены.
**Runtime/фиксация.** Одна backend сборка ux-recursive88/version1.0.0-test.recursive88, image sha256:d358ec1d6ea87ea7f29a12cc4fd3c1a6a7929b854bcdc732d956c702fe4dc587. Backend/PG healthy, frontend ux-optimizer87 сохранён и принят браузером. Context optimizer87 final-c +6 backend файлов, override SHA de4caf2aced38ba7e490f6a459a19d359cc92cb5b098564b799c05bc86be1365; label не Git SHA, рабочее состояние до коммита. Entry/node --check/pg_restore18.6, compose --wait passed, apt cached. .env backup приватный, миграций нет. Один локальный commit без push. REST метод подтверждён [RouterOS REST API](https://help.mikrotik.com/docs/spaces/ROS/pages/47579162/REST%2BAPI).
Следующий89 — диагностика/терминал: реальный запуск, ограниченные команды, ошибки, права и контекст. Routing alternate-path/BFD sustained failover, IPv6/scale/physical disconnect/durable retry/Portal SSO и остальные внешние границы остаются открытыми. Квота38% использовано после блока; этап12.5 открыт.
+1 -1
View File
@@ -1,6 +1,6 @@
# План реализации UX/UI по пятичасовым окнам
Актуальное продолжение 2026-10-09: 12.5.87 принял production OSPF optimizer preview/apply/repeat на двух своих GRE парах, partial/unknown с проверкой native costs и4 live UI проверки1280/320. Исправлены права кнопки и чтение эффективного disabled OSPF templates/instances/areas. Baseline7 коллекций×2 восстановлен. Backend ux-optimizer87c/frontend ux-optimizer87, healthy/served. Следующий12.5.88 — рекурсивные маршруты: запрет опроса выключенных устройств, реальные чтение/применение/история и достоверность поздних ошибок; далее диагностика. Квота23% использовано после блока, этап12.5 открыт.
Актуальное продолжение 2026-10-09: 12.5.88 завершил рекурсивные маршруты: disabled guard всех6 native путей, PUT/строгий preflight/кэш transaction/partial-unknown-applied receipts. Реальный recursive gateway через свой GRE, Ping3/3×2, API apply/restore,12 disabled409/probe0 и4 live UI cases с2 добавлениями на320px. Native baseline4 коллекций×2 и прежние cache/history восстановлены. Backend ux-recursive88/frontend ux-optimizer87. Следующий12.5.89 — реальная диагностика и терминал, права/ошибки/контекст; затем оставшиеся routing failover и внешние границы. Квота38% использовано; этап12.5 открыт.
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-09. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
+34 -2
View File
@@ -1,6 +1,6 @@
# UX/UI: журнал реализации
Актуальное продолжение 2026-10-09: 12.5.87 принял production OSPF optimizer preview/apply/repeat на двух своих GRE парах, partial/unknown с проверкой native costs и4 live UI проверки1280/320. Исправлены права кнопки и чтение эффективного disabled OSPF templates/instances/areas. Baseline7 коллекций×2 восстановлен. Backend ux-optimizer87c/frontend ux-optimizer87, healthy/served. Следующий12.5.88 — рекурсивные маршруты: запрет опроса выключенных устройств, реальные чтение/применение/история и достоверность поздних ошибок; далее диагностика. Квота23% использовано после блока, этап12.5 открыт.
Актуальное продолжение 2026-10-09: 12.5.88 завершил рекурсивные маршруты: disabled guard всех6 native путей, PUT/строгий preflight/кэш transaction/partial-unknown-applied receipts. Реальный recursive gateway через свой GRE, Ping3/3×2, API apply/restore,12 disabled409/probe0 и4 live UI cases с2 добавлениями на320px. Native baseline4 коллекций×2 и прежние cache/history восстановлены. Backend ux-recursive88/frontend ux-optimizer87. Следующий12.5.89 — реальная диагностика и терминал, права/ошибки/контекст; затем оставшиеся routing failover и внешние границы. Квота38% использовано; этап12.5 открыт.
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
@@ -36,7 +36,39 @@
| 10 | Маршрутизация, диагностика, карта и терминал | Завершён в границах локальной приёмки 2026-10-01; блоки 10.1–10.71, внешние ограничения в 10.71 |
| 11А | Пользователи, контейнеры, сертификаты и резервные копии | Завершён в границах локальной приёмки 2026-10-01; 11А.1–11А.33, внешние ограничения в 11А.33 |
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 |
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–87 и ограничения ниже. Runtime backend ux-optimizer87c/frontend ux-optimizer87. |
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–88 и ограничения ниже. Runtime backend ux-recursive88/frontend ux-optimizer87. |
## 12.5.88 — рекурсивные маршруты: реальные операции и история (2026-10-09)
**Исправления.** Все6 путей catalog/gateways/catalog/legacy reads/PUT/restore проверяют enabled=false и возвращают409 до опроса/применения любого типа устройства. История остаётся доступным чтением БД. Создание RouterOS route исправлено с POST без add на PUT. Весь управляемый набор проходит strict parse до записей: неподдерживаемая owned row не исключается молча перед удалением. IPv4 destination/gateway и check-gateway проверяются до native writes. Замена кэша выполняется в транзакции вместо независимых delete/insert.
Request-local receipt сохраняет подтверждённые createdIds/deletedIds и число записей. RouterOS4xx после успешных шагов → partial; первый4xx → rejected; потерянный ACK/неправильный ответ/transport → unknown; ошибка кэша/истории после native completion → applied/metadataRecorded=false. После успешного apply, но отказа заключительного чтения кэша → applied/metadataRecorded=true. Ошибки операций возвращают502, последующие записи не выполняются, automatic retry/rollback не добавлены. Старые/default/foreign routes не удаляются при отказе создания новых; полная distributed transaction/idempotency не заявляется.
| Проверка | Подтверждённый результат |
| --- | --- |
| Disabled Home Router и Exit Node | По6 запросов409; контрольный HTTP probe0 |
| Native PUT + strict catalog | Формат/ID/flags подтверждены на двух CHR отдельным малым probe |
| Recursive resolution | gateway198.18.189.peer → resolver host route → immediate-gw198.18.88.peer%ownGRE |
| Data plane | Own loopback Ping3/3 в обе стороны в окончательном run |
| API/history | Apply, изменение distance/disabled, restore своей версии; invalid CIDR400 без записи |
| Fault injection | partial1/unknown1/applied2 подтверждённых записей; независимый native GET |
| Browser | 4/4 ПК/320px, две реальные формы добавления; reload context, pageerror0 |
**Стенд.** Свои GRE и link198.18.88.0/30, bridge loopbacks198.18.188.1/32↔2/32 и probe IP198.18.189.1/32↔2/32. Неуправляемый собственный resolver /32 имеет scope10; управляемый remote loopback /32, gateway probe IP, scope30/target-scope11/distance150/check-gateway none. Native immediate-gw доказал двухступенчатое разрешение через GRE, Ping подтвердил передачу. Это проверка recursion/data plane, не loss-based failover или SLA. Default/public/metadata routes и195.195.195.195/32 сохранены.
**Доказательства.** [Native/API/DB отчёт](ux-ui/acceptance/recursive-routes-2026-10-09.json). Production API применил конфигурацию обоих устройств, прочитал каталог, изменил distance/disabled и восстановил только созданную в этом run версию. Revisions baseline≤35 проверен, чтобы тестовые записи не вызвали pruning старой истории. HTTP409 проверены на двух собственных disabled DB rows с probe на private Docker DNS; fake rows и их revisions удалены каскадно.
Ошибки инъецированы в тот же native executor: второй PUT отклонён до передачи → partial и сохранён старый маршрут; второй PUT выполнен, ACK заменён исключением → unknown, фактические3 owned rows прочитаны отдельно; persist callback отказал после replace → applied, новый набор уже на RouterOS. API-обёртка этих receipts и поздний getRoutes отказ проверены HTTP/unit. Реальный отказ PostgreSQL/физический TCP disconnect не создавался.
**Браузер.** Настоящий backend/frontend без mocks: два устройства×1280/320. Раскрытый endpoint и URL/reload, document fits, затем на320px заполнена и отправлена форма: gateway probe IP/scope30/target11/none/distance152, новый private prefix198.18.188.250/32. API подтвердил два маршрута, sheet закрылась, две группы видны. [Browser отчёт](ux-ui/acceptance/browser-recursive-2026-10-09.json), [ПК](ux-ui/screens/recursive-real-server1-1280-2026-10-09.png), [320px форма](ux-ui/screens/recursive-real-form-server1-320-2026-10-09.png) просмотрена. Общие Data Grid Filtering2/Sheet8/Frame из плана сохранены, frontend source не менялся.
**Проверки/оснастка.** 29 профильных E2E data/values/links passed. Backend recursive HTTP/catalog/executor tests, TypeScript, scoped ESLint/diff passed. Проверены invalid before writes, foreign retention, create/delete ordering, unsupported owned preflight, malformed ACK, rejected/partial/unknown/applied, поздняя ошибка чтения и disabled обоих типов. Первый native run Ping0/3: обратный маршрут ещё не создан; порядок исправлен на предварительное применение обеих сторон. Второй начальный Ping2/3: ограниченное ожидание готовности пути добавлено, до3 коротких попыток с сохранением результатов. Финальный run получил3/3 с первой попытки на обоих CHR. Ошибки оснастки не считаются приёмкой; оба cleanup passed.
**Очистка.** Native managed routes сверены по уникальному name-prefix, остальные свои GRE/bridge/IP/resolver по exact ID/атрибутам. Свои объекты удалены, baseline IDs4 коллекций×2 совпали. Исходно пустой recursive cache восстановлен; удалены только новые собственные revisions после проверки payload/comment и ID, прежние revision IDs сохранены. Последовательности PG увеличились из-за тестовых insert; это не побитовый restore БД. Оба CHR доступны, credentials неизменны, fixture containers удалены.
**Runtime/фиксация.** Одна backend сборка ux-recursive88/version1.0.0-test.recursive88, image sha256:d358ec1d6ea87ea7f29a12cc4fd3c1a6a7929b854bcdc732d956c702fe4dc587. Backend/PG healthy, frontend ux-optimizer87 сохранён и принят браузером. Context optimizer87 final-c +6 backend файлов, override SHA de4caf2aced38ba7e490f6a459a19d359cc92cb5b098564b799c05bc86be1365; label не Git SHA, рабочее состояние до коммита. Entry/node --check/pg_restore18.6, compose --wait passed, apt cached. .env backup приватный, миграций нет. Один локальный commit без push. REST метод подтверждён [RouterOS REST API](https://help.mikrotik.com/docs/spaces/ROS/pages/47579162/REST%2BAPI).
Следующий89 — диагностика/терминал: реальный запуск, ограниченные команды, ошибки, права и контекст. Routing alternate-path/BFD sustained failover, IPv6/scale/physical disconnect/durable retry/Portal SSO и остальные внешние границы остаются открытыми. Квота38% использовано после блока; этап12.5 открыт.
## 12.5.87 — OSPF optimizer: права, реальные costs и частичный результат (2026-10-09)
+32
View File
@@ -2058,3 +2058,35 @@ POST optimize при отказе записи возвращает502 и reques
**Runtime.** Backend ux-optimizer87c/version1.0.0-test.optimizer87c, image sha256:22cc9a09a89038e58c15dfd6224191d1fab7ad63f7af6f80ecc9e7577483d390; frontend ux-optimizer87/version1.0.0-test.optimizer87, image sha256:22f05c341a7dc0e40e04f23b0da61ba5cfbf31d741d4e22b0c9bcd71c85e0c49. Backend/PG healthy, frontend served/browser passed. Backend entry/node --check/pg_restore18.6, frontend entry/node --check и compose --wait passed. Три backend builds87/87b/87c по двум реальным flag incompatibilities; frontend build один, apt cache сохранён. Context backend routing83 +2 routes, затем4 файлов final-c; override SHA c04289ab57294d57cc9aed292e247e144c171ade3d1101f6ebb84129e41b065be; frontend ipsec77 +OSPF page, override dab57aad2cb248553b0fee9da73069f7a31cb627b26c414f03320315a299756db. Labels не Git SHA; это рабочие файлы до локального коммита. .env backup приватный, миграций нет. Один локальный commit без push.
Продолжение88 — recursive routes, затем диагностика. BFD sustained/alternate-path failover, IPv6/scale/maximum throughput, Portal SSO/browser auth и другие внешние ограничения сохраняются; lab AUTH_REQUIRED=false, RBAC checked отдельно. API /get и .proplist/query подтверждены [RouterOS REST API](https://help.mikrotik.com/docs/spaces/ROS/pages/47579162/REST%2BAPI) и реальным устройством. Квота23% использовано, этап12.5 открыт.
## 12.5.88 — рекурсивные маршруты: реальные операции и история (2026-10-09)
**Исправления.** Все6 путей catalog/gateways/catalog/legacy reads/PUT/restore проверяют enabled=false и возвращают409 до опроса/применения любого типа устройства. История остаётся доступным чтением БД. Создание RouterOS route исправлено с POST без add на PUT. Весь управляемый набор проходит strict parse до записей: неподдерживаемая owned row не исключается молча перед удалением. IPv4 destination/gateway и check-gateway проверяются до native writes. Замена кэша выполняется в транзакции вместо независимых delete/insert.
Request-local receipt сохраняет подтверждённые createdIds/deletedIds и число записей. RouterOS4xx после успешных шагов → partial; первый4xx → rejected; потерянный ACK/неправильный ответ/transport → unknown; ошибка кэша/истории после native completion → applied/metadataRecorded=false. После успешного apply, но отказа заключительного чтения кэша → applied/metadataRecorded=true. Ошибки операций возвращают502, последующие записи не выполняются, automatic retry/rollback не добавлены. Старые/default/foreign routes не удаляются при отказе создания новых; полная distributed transaction/idempotency не заявляется.
| Проверка | Подтверждённый результат |
| --- | --- |
| Disabled Home Router и Exit Node | По6 запросов409; контрольный HTTP probe0 |
| Native PUT + strict catalog | Формат/ID/flags подтверждены на двух CHR отдельным малым probe |
| Recursive resolution | gateway198.18.189.peer → resolver host route → immediate-gw198.18.88.peer%ownGRE |
| Data plane | Own loopback Ping3/3 в обе стороны в окончательном run |
| API/history | Apply, изменение distance/disabled, restore своей версии; invalid CIDR400 без записи |
| Fault injection | partial1/unknown1/applied2 подтверждённых записей; независимый native GET |
| Browser | 4/4 ПК/320px, две реальные формы добавления; reload context, pageerror0 |
**Стенд.** Свои GRE и link198.18.88.0/30, bridge loopbacks198.18.188.1/32↔2/32 и probe IP198.18.189.1/32↔2/32. Неуправляемый собственный resolver /32 имеет scope10; управляемый remote loopback /32, gateway probe IP, scope30/target-scope11/distance150/check-gateway none. Native immediate-gw доказал двухступенчатое разрешение через GRE, Ping подтвердил передачу. Это проверка recursion/data plane, не loss-based failover или SLA. Default/public/metadata routes и195.195.195.195/32 сохранены.
**Доказательства.** [Native/API/DB отчёт](ux-ui/acceptance/recursive-routes-2026-10-09.json). Production API применил конфигурацию обоих устройств, прочитал каталог, изменил distance/disabled и восстановил только созданную в этом run версию. Revisions baseline≤35 проверен, чтобы тестовые записи не вызвали pruning старой истории. HTTP409 проверены на двух собственных disabled DB rows с probe на private Docker DNS; fake rows и их revisions удалены каскадно.
Ошибки инъецированы в тот же native executor: второй PUT отклонён до передачи → partial и сохранён старый маршрут; второй PUT выполнен, ACK заменён исключением → unknown, фактические3 owned rows прочитаны отдельно; persist callback отказал после replace → applied, новый набор уже на RouterOS. API-обёртка этих receipts и поздний getRoutes отказ проверены HTTP/unit. Реальный отказ PostgreSQL/физический TCP disconnect не создавался.
**Браузер.** Настоящий backend/frontend без mocks: два устройства×1280/320. Раскрытый endpoint и URL/reload, document fits, затем на320px заполнена и отправлена форма: gateway probe IP/scope30/target11/none/distance152, новый private prefix198.18.188.250/32. API подтвердил два маршрута, sheet закрылась, две группы видны. [Browser отчёт](ux-ui/acceptance/browser-recursive-2026-10-09.json), [ПК](ux-ui/screens/recursive-real-server1-1280-2026-10-09.png), [320px форма](ux-ui/screens/recursive-real-form-server1-320-2026-10-09.png) просмотрена. Общие Data Grid Filtering2/Sheet8/Frame из плана сохранены, frontend source не менялся.
**Проверки/оснастка.** 29 профильных E2E data/values/links passed. Backend recursive HTTP/catalog/executor tests, TypeScript, scoped ESLint/diff passed. Проверены invalid before writes, foreign retention, create/delete ordering, unsupported owned preflight, malformed ACK, rejected/partial/unknown/applied, поздняя ошибка чтения и disabled обоих типов. Первый native run Ping0/3: обратный маршрут ещё не создан; порядок исправлен на предварительное применение обеих сторон. Второй начальный Ping2/3: ограниченное ожидание готовности пути добавлено, до3 коротких попыток с сохранением результатов. Финальный run получил3/3 с первой попытки на обоих CHR. Ошибки оснастки не считаются приёмкой; оба cleanup passed.
**Очистка.** Native managed routes сверены по уникальному name-prefix, остальные свои GRE/bridge/IP/resolver по exact ID/атрибутам. Свои объекты удалены, baseline IDs4 коллекций×2 совпали. Исходно пустой recursive cache восстановлен; удалены только новые собственные revisions после проверки payload/comment и ID, прежние revision IDs сохранены. Последовательности PG увеличились из-за тестовых insert; это не побитовый restore БД. Оба CHR доступны, credentials неизменны, fixture containers удалены.
**Runtime/фиксация.** Одна backend сборка ux-recursive88/version1.0.0-test.recursive88, image sha256:d358ec1d6ea87ea7f29a12cc4fd3c1a6a7929b854bcdc732d956c702fe4dc587. Backend/PG healthy, frontend ux-optimizer87 сохранён и принят браузером. Context optimizer87 final-c +6 backend файлов, override SHA de4caf2aced38ba7e490f6a459a19d359cc92cb5b098564b799c05bc86be1365; label не Git SHA, рабочее состояние до коммита. Entry/node --check/pg_restore18.6, compose --wait passed, apt cached. .env backup приватный, миграций нет. Один локальный commit без push. REST метод подтверждён [RouterOS REST API](https://help.mikrotik.com/docs/spaces/ROS/pages/47579162/REST%2BAPI).
Следующий89 — диагностика/терминал: реальный запуск, ограниченные команды, ошибки, права и контекст. Routing alternate-path/BFD sustained failover, IPv6/scale/physical disconnect/durable retry/Portal SSO и остальные внешние границы остаются открытыми. Квота38% использовано после блока; этап12.5 открыт.
+3 -1
View File
@@ -1,6 +1,6 @@
# Тестовый сервер UX/UI — 2026-10-09
Сервер161.104.46.222 предоставлен для временного тестирования. Backend ux-optimizer87c/version1.0.0-test.optimizer87c, frontend ux-optimizer87/version1.0.0-test.optimizer87; backend/PG healthy, frontend HTTP/browser passed. Основной блок IPsec77 принят в границах журнала, own fixtures/fake DB rows удалены; каталог flash CHR2 сохранён из-за неподтверждённого ownership. SSH/оба CHR доступны, пароли прежние.
Сервер161.104.46.222 предоставлен для временного тестирования. Backend ux-recursive88/version1.0.0-test.recursive88, frontend ux-optimizer87/version1.0.0-test.optimizer87; backend/PG healthy, frontend HTTP/browser passed. Основной блок IPsec77 принят в границах журнала, own fixtures/fake DB rows удалены; каталог flash CHR2 сохранён из-за неподтверждённого ownership. SSH/оба CHR доступны, пароли прежние.
| Параметр | Проверенное состояние |
| --- | --- |
@@ -713,3 +713,5 @@ flowchart LR
Подробный объём, протоколы, схема и ограничения: [12.5.77 в журнале](ux-ui-progress.md).
12.5.87 (2026-10-09): OSPF optimizer native/API и4 browser checks passed, собственные объекты очищены, baseline7 коллекций×2 сохранён. Подробности/runtime происхождение — в журнале.
12.5.88 (2026-10-09): recursion/GRE/Ping, apply/restore и4 browser checks passed; native baseline4 коллекций×2, cache/history сохранены. Backend recursive88, frontend optimizer87.
@@ -0,0 +1,39 @@
{
"date": "2026-10-09",
"phase": "2 320",
"cases": [
{
"serverId": 1,
"width": 1280,
"recursiveRouteVisible": true,
"urlRestore": true,
"documentFits": true,
"realBrowserAddReceipt": false
},
{
"serverId": 1,
"width": 320,
"recursiveRouteVisible": true,
"urlRestore": true,
"documentFits": true,
"realBrowserAddReceipt": true
},
{
"serverId": 2,
"width": 1280,
"recursiveRouteVisible": true,
"urlRestore": true,
"documentFits": true,
"realBrowserAddReceipt": false
},
{
"serverId": 2,
"width": 320,
"recursiveRouteVisible": true,
"urlRestore": true,
"documentFits": true,
"realBrowserAddReceipt": true
}
],
"errors": []
}
@@ -0,0 +1,383 @@
{
"date": "2026-10-09",
"name": "mm-rec88-1791554488522",
"devices": [
{
"serverId": 1,
"applied": {
"ok": true,
"serverId": 1,
"routes": [
{
"id": "11",
"dstAddress": "198.18.188.2/32",
"gateway": "198.18.189.2",
"distance": 150,
"scope": 30,
"targetScope": 11,
"routingTable": "main",
"checkGateway": "none",
"country": "",
"comment": "mm-rec88-1791554488522",
"disabled": false
}
],
"pushedRoutes": 1
},
"catalog": {
"serverId": 1,
"routes": [
{
"id": "*80000014",
"dstAddress": "198.18.188.2/32",
"gateway": "198.18.189.2",
"distance": 150,
"disabled": false,
"routingTable": "main",
"checkGateway": "none",
"scope": 30,
"targetScope": 11,
"country": "",
"comment": "mm-rec88-1791554488522"
}
],
"live": true,
"stale": false
},
"recursiveNative": {
".id": "*80000014",
"active": "true",
"check-gateway": "none",
"comment": "MikrotikManager:recursive mm-rec88-1791554488522",
"disabled": "false",
"distance": "150",
"dst-address": "198.18.188.2/32",
"dynamic": "false",
"gateway": "198.18.189.2",
"immediate-gw": "198.18.88.2%mm-rec88-1791554488522",
"inactive": "false",
"routing-table": "main",
"scope": "30",
"static": "true",
"target-scope": "11"
},
"pingReceived": 3,
"historyRestore": true,
"invalidInputNoWrites": true
},
{
"serverId": 2,
"applied": {
"ok": true,
"serverId": 2,
"routes": [
{
"id": "18",
"dstAddress": "198.18.188.1/32",
"gateway": "198.18.189.1",
"distance": 150,
"scope": 30,
"targetScope": 11,
"routingTable": "main",
"checkGateway": "none",
"country": "",
"comment": "mm-rec88-1791554488522",
"disabled": false
}
],
"pushedRoutes": 1
},
"catalog": {
"serverId": 2,
"routes": [
{
"id": "*80000012",
"dstAddress": "198.18.188.1/32",
"gateway": "198.18.189.1",
"distance": 150,
"disabled": false,
"routingTable": "main",
"checkGateway": "none",
"scope": 30,
"targetScope": 11,
"country": "",
"comment": "mm-rec88-1791554488522"
}
],
"live": true,
"stale": false
},
"recursiveNative": {
".id": "*80000012",
"active": "true",
"check-gateway": "none",
"comment": "MikrotikManager:recursive mm-rec88-1791554488522",
"disabled": "false",
"distance": "150",
"dst-address": "198.18.188.1/32",
"dynamic": "false",
"gateway": "198.18.189.1",
"immediate-gw": "198.18.88.1%mm-rec88-1791554488522",
"inactive": "false",
"routing-table": "main",
"scope": "30",
"static": "true",
"target-scope": "11"
},
"pingReceived": 3,
"historyRestore": true,
"invalidInputNoWrites": true
}
],
"disabled": [
{
"type": "home-router",
"path": "/recursive-routes/catalog",
"status": 409
},
{
"type": "home-router",
"path": "/recursive-routes/gateways/catalog",
"status": 409
},
{
"type": "home-router",
"path": "/recursive-routes",
"status": 409
},
{
"type": "home-router",
"path": "/recursive-routes/gateways",
"status": 409
},
{
"type": "home-router",
"path": "/recursive-routes",
"method": "PUT",
"status": 409
},
{
"type": "home-router",
"path": "/recursive-routes/revisions/7c8be412-5139-455a-a910-f61d20a9159c/restore",
"method": "POST",
"status": 409
},
{
"type": "exit-node",
"path": "/recursive-routes/catalog",
"status": 409
},
{
"type": "exit-node",
"path": "/recursive-routes/gateways/catalog",
"status": 409
},
{
"type": "exit-node",
"path": "/recursive-routes",
"status": 409
},
{
"type": "exit-node",
"path": "/recursive-routes/gateways",
"status": 409
},
{
"type": "exit-node",
"path": "/recursive-routes",
"method": "PUT",
"status": 409
},
{
"type": "exit-node",
"path": "/recursive-routes/revisions/940ee856-a382-4713-b100-a548b70505c2/restore",
"method": "POST",
"status": 409
}
],
"faults": [
{
"mode": "partial",
"receipt": {
"state": "partial",
"confirmedWrites": 1,
"createdIds": [
"*80000017"
],
"deletedIds": [],
"needsReview": true,
"metadataRecorded": false
},
"nativeIds": [
"*80000016",
"*80000017"
],
"nativeCount": 2,
"faultInjection": true,
"physicalDisconnect": false
},
{
"mode": "unknown",
"receipt": {
"state": "unknown",
"confirmedWrites": 1,
"createdIds": [
"*80000019"
],
"deletedIds": [],
"needsReview": true,
"metadataRecorded": false
},
"nativeIds": [
"*80000018",
"*80000019",
"*8000001A"
],
"nativeCount": 3,
"faultInjection": true,
"physicalDisconnect": false
},
{
"mode": "applied",
"receipt": {
"state": "applied",
"confirmedWrites": 2,
"createdIds": [
"*8000001C"
],
"deletedIds": [
"*8000001B"
],
"needsReview": true,
"metadataRecorded": false
},
"nativeIds": [
"*8000001C"
],
"nativeCount": 1,
"faultInjection": true,
"physicalDisconnect": false
}
],
"cleanup": [
{
"serverId": 1,
"dbCacheEmpty": true,
"historyBaseline": true,
"/interface/gre": true,
"/interface/bridge": true,
"/ip/address": true,
"/ip/route": true
},
{
"serverId": 2,
"dbCacheEmpty": true,
"historyBaseline": true,
"/interface/gre": true,
"/interface/bridge": true,
"/ip/address": true,
"/ip/route": true
}
],
"probeRequests": 0,
"pingAttempts": {
"1": [
{
"received": 3,
"sent": 3
}
],
"2": [
{
"received": 3,
"sent": 3
}
]
},
"nativeProbe": {
"date": "2026-10-09",
"out": [
{
"serverId": 1,
"raw": {
".id": "*8000000C",
"active": "true",
"check-gateway": "none",
"comment": "MikrotikManager:recursive mm-rec88-probe-1791553666907",
"disabled": "false",
"distance": "150",
"dst-address": "198.18.88.250/32",
"dynamic": "false",
"gateway": "194.226.121.1",
"immediate-gw": "194.226.121.1%ether1",
"inactive": "false",
"routing-table": "main",
"scope": "30",
"static": "true",
"target-scope": "10"
},
"mapped": {
"id": "*8000000C",
"dstAddress": "198.18.88.250/32",
"gateway": "194.226.121.1",
"distance": 150,
"disabled": false,
"routingTable": "main",
"checkGateway": "none",
"scope": 30,
"targetScope": 10,
"country": "",
"comment": "mm-rec88-probe-1791553666907"
}
},
{
"serverId": 2,
"raw": {
".id": "*8000000C",
"active": "true",
"check-gateway": "none",
"comment": "MikrotikManager:recursive mm-rec88-probe-1791553667075",
"disabled": "false",
"distance": "150",
"dst-address": "198.18.88.250/32",
"dynamic": "false",
"gateway": "104.165.244.1",
"immediate-gw": "104.165.244.1%ether1",
"inactive": "false",
"routing-table": "main",
"scope": "30",
"static": "true",
"target-scope": "10"
},
"mapped": {
"id": "*8000000C",
"dstAddress": "198.18.88.250/32",
"gateway": "104.165.244.1",
"distance": 150,
"disabled": false,
"routingTable": "main",
"checkGateway": "none",
"scope": 30,
"targetScope": 10,
"country": "",
"comment": "mm-rec88-probe-1791553667075"
}
}
]
},
"initialAttempts": [
{
"result": "Ping0/3 before reverse route was configured",
"cleanupPassed": true
},
{
"result": "Initial Ping2/3 during path startup",
"cleanupPassed": true
}
],
"runtime": {
"backend": "ux-recursive88",
"frontend": "ux-optimizer87",
"labelsAreGitSha": false
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB