diff --git a/docs/ux-ui-external-acceptance.md b/docs/ux-ui-external-acceptance.md index ab64a272..247ba200 100644 --- a/docs/ux-ui-external-acceptance.md +++ b/docs/ux-ui-external-acceptance.md @@ -1,6 +1,6 @@ # UX/UI: протокол внешней приёмки 12.5 -Статус на2026-10-08: backendbd3f996/frontendfd521f6, backend healthy. Мобильная GRE форма и native сохранение на обоих CHR приняты в12.5.57. Устойчивость меню GRE при live refresh на обоих CHR принята в12.5.55. GRE peer metadata и реальный lifecycle/API/UI/двусторонний Ping подтверждены в12.5.53. Browser retry/checkpoint на реальном HTTP/PG принят в границах12.5.43–45; Telegram sender responses подменены, реальная доставка не проверена. PG-1/2/3/4/5 приняты в описанных границах, PG-6 integrated для одного isolated instance, PG-7 real JWT/processcounts и browser restore passed. PG-8 real PG/native и browser unknown→history done приняты с fault injection после настоящего COMMIT. ROS-8/9 real API/SQL/native приняты в границах12.5.23; browser pair/duration change и delete приняты в12.5.24. ROS-2 authentication failure принят в12.5.25. PortalSSO, физический TCP disconnect, мультиэкземпляры и остальные ROS/Q/интеграции остаются открытыми. [Паспорт](ux-ui-test-server.md), [журнал](ux-ui-progress.md). +Статус на2026-10-08: backendbd3f996/frontendfd521f6, backend healthy. Мобильная GRE форма и native сохранение на обоих CHR приняты в12.5.57. WireGuard handshake/короткий Ping/native API/read-only UI приняты в границах12.5.58; обычное удаление интерфейса с IP ещё не проверено. Устойчивость меню GRE при live refresh на обоих CHR принята в12.5.55. GRE peer metadata и реальный lifecycle/API/UI/двусторонний Ping подтверждены в12.5.53. Browser retry/checkpoint на реальном HTTP/PG принят в границах12.5.43–45; Telegram sender responses подменены, реальная доставка не проверена. PG-1/2/3/4/5 приняты в описанных границах, PG-6 integrated для одного isolated instance, PG-7 real JWT/processcounts и browser restore passed. PG-8 real PG/native и browser unknown→history done приняты с fault injection после настоящего COMMIT. ROS-8/9 real API/SQL/native приняты в границах12.5.23; browser pair/duration change и delete приняты в12.5.24. ROS-2 authentication failure принят в12.5.25. PortalSSO, физический TCP disconnect, мультиэкземпляры и остальные ROS/Q/интеграции остаются открытыми. [Паспорт](ux-ui-test-server.md), [журнал](ux-ui-progress.md). ## Паспорт стенда @@ -417,3 +417,15 @@ DELETE200/200, own интерфейсы/IP и connected routes удалены; Скриншоты320px: [CHR1 dark](ux-ui/screens/gre-mobile-real-server1-dark-320-2026-10-08.png), [CHR1 light](ux-ui/screens/gre-mobile-real-server1-light-320-2026-10-08.png), [CHR2 dark](ux-ui/screens/gre-mobile-real-server2-dark-320-2026-10-08.png), [CHR2 light](ux-ui/screens/gre-mobile-real-server2-light-320-2026-10-08.png). CHR1 dark и CHR2 light визуально просмотрены: внутренние IP целиком видны. [Smoke](ux-ui/acceptance/deploy-browser-fd521f6-2026-10-08.json): dashboard/servers/uptime/settings/filters/alerts200,320px fit, JS/API errors0. DELETE200/200, собственные GRE/IP/connected routes удалены; выбранные GRE/IP/routes/IPv4 Firewall поля совпали с baseline, CHR1 — одно повторное чтение маршрутов через250ms. Эфемерный контейнер удалён; остались три основные Compose-службы. GRE revisions намеренно сохранены как история операций. Следующий12.5.58 — реальная собственная WireGuard пара, API/native/UI, handshake/связность, очистка и baseline; private/preshared keys не включать в публичные отчёты. Требование пользователя о настоящих VPN объектах сохраняется. Telegram/Portal/multi-instance и другие внешние ограничения остаются открытыми. Локальный коммит без push. + +## 12.5.58 — настоящая WireGuard пара, handshake и UI (2026-10-08) + +[Итоговый реальный lifecycle](ux-ui/acceptance/wg-real-lifecycle-2026-10-08.json): собственная пара mm-acceptance-wg-1791470702451 на двух CHR, UDP51879 и198.18.255.240/30 проверены на коллизии/пересечения. POST interfaces201/201 создали интерфейсы и IP; native чтение подтвердило автоматические ключи и адреса, POST peers201/201 — связь с публичным ключом другого устройства. Ключи проверялись в памяти и не записывались в публичные артефакты. Allowed адреса ограничены IP другого конца /32, persistent keepalive5s. Default routes/Firewall не менялись. Параметры и смысл last-handshake сверены с [официальной документацией MikroTik](https://help.mikrotik.com/docs/spaces/ROS/pages/69664792/WireGuard). + +На обоих peers появился native handshake и RX>0; двусторонний Ping3/3,0%loss, около54–56ms. PATCH MTU1380 и возврат1420 подтверждены native чтением. Каталог приложения совпал с адресами/peers/handshake и не содержал privateKey по умолчанию. Это короткая проверка защищённой WireGuard связности; throughput, RBAC, interrupted mutation, экспорт и import не проверены. + +[Production browser](ux-ui/acceptance/browser-wg-real-2026-10-08.json): два CHR × две темы,1280/320px без HTTP mocks. В деталях видны own peer name, Allowed IPs, endpoint, handshake и известные RX/TX; server/interface URL и вкладка peers пережили reload, page overflow отсутствует. На320px длинные имя и CIDR переносятся; исходная таблица сохраняет собственный горизонтальный scroll. Создание/изменение/удаление через UI не проверялись. JS/API errors0. Скриншоты: [CHR1 dark](ux-ui/screens/wg-real-server1-dark-320-2026-10-08.png), [CHR1 light](ux-ui/screens/wg-real-server1-light-320-2026-10-08.png), [CHR2 dark](ux-ui/screens/wg-real-server2-dark-320-2026-10-08.png), [CHR2 light](ux-ui/screens/wg-real-server2-light-320-2026-10-08.png); итоговыйCHR2 light просмотрен. Первый browser locator одновременно находил sr-only и родительскую подпись handshake, уточнение локатора дало успешный проход без изменения продукта. + +[Первый проход](ux-ui/acceptance/wg-real-first-attempt-2026-10-08.json) подтвердил связность/UI, но cleanup harness получил DELETE400: Content-Type application/json был передан без тела. Это ошибка harness, не доказательство ошибки приложения. [Восстановительная очистка](ux-ui/acceptance/wg-first-cleanup-recovery-2026-10-08.json) через правильные DELETE проверила ownership comment/name и отсутствие own interfaces/peers/IP/routes. Baseline первого прохода был только в памяти и после выхода потерян; точная сверка первого baseline не заявляется. Harness исправлен, создана новая пара и повторён полный lifecycle/browser; итоговый exit0 и все выбранные baseline поля совпали. + +В финальном cleanup собственные peers удалены API200/200, собственные IP явно удалены native API до удаления interfaces API200/200. Автоматическая очистка IP/peers при обычном удалении интерфейса НЕ проверена и остаётся следующим12.5.59. WireGuard/IP/routes/IPv4 Firewall выбранные настройки совпали с baseline; эфемерный контейнер удалён, работают только три основные Compose-службы. DB controls до/после servers2/speedHistory9/retention14/migrations9 совпали, backend healthy. WG revisions намеренно сохранены как история операций. Runtime backendbd3f996/frontendfd521f6 не менялся. Telegram/Portal/multi-instance и остальные внешние ограничения остаются открытыми. Локальный коммит без push. diff --git a/docs/ux-ui-plan.md b/docs/ux-ui-plan.md index 216eb6a7..0f5b7c80 100644 --- a/docs/ux-ui-plan.md +++ b/docs/ux-ui-plan.md @@ -1,12 +1,12 @@ # План реализации UX/UI по пятичасовым окнам -Актуальное продолжение 2026-10-08: 12.5.57 развернул frontendfd521f6, backendbd3f996 healthy. Мобильная GRE форма подтверждена без HTTP mocks на новой собственной паре CHR: две темы/320/640/1280px, полный native IPv4/CIDR, Tab, меню refresh и сохранение PATCH200/200 с независимым чтением RouterOS. Ping3/3 в обе стороны; own GRE/IP удалены, выбранный baseline и DB controls совпали. Smoke6 экранов passed. Следующий12.5.58 — настоящая WireGuard пара: API/native/UI, handshake/связность и очистка собственных объектов; секреты в отчёты не включать. Этап12.5 открыт. +Актуальное продолжение 2026-10-08: 12.5.58 подтвердил настоящую WireGuard пару на обоих CHR: API/native keys association, handshake/RX, Ping3/3, MTU и UI в двух темах/1280/320px, URL interface/server/tab/reload. Итоговый harness exit0, выбранный WG/peers/IP/routes/Firewall baseline и DB controls совпали; own объекты удалены. Первый DELETE harness400 из-за JSON header без тела исправлен, recovery и повторный полный проход сохранены отдельно. Runtime backendbd3f996/frontendfd521f6 healthy. Следующий12.5.59 — удалить собственный WireGuard интерфейс с peer/IP через обычный UI/API и проверить остаточные объекты; в58 IP удалялись явно. Этап12.5 открыт. Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-08. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат. ## Актуальная точка продолжения — 2026-10-08 -Этапы0–11 завершены в описанных локальных границах. Этап12 открыт. На тестовом сервере161.104.46.222 работают backendbd3f996/frontendfd521f6 и два CHR. Внешние проверки подтвердили PG backup/restore/rollback, остановку фоновой работы для одного экземпляра, API JWT/RBAC и браузерные состояния восстановления. Native TCP/UDP speed, история и UI проверены в границах журнала; доступ ко второму CHR восстановлен пользователем. Очередь Telegram проверена на реальном PG: dedupe, конкурентный claim, retry/version, ошибки сохранения и неопределённый исход; ответы отправителя подменялись, реальной доставки это не доказывает. Блоки12.5.43–45 подтвердили browser retry/checkpoint и развернули понятное пояснение HTTP500. 12.5.46 подтвердил browser JWT/RBAC очереди на реальном HTTP/PG; 12.5.47 подтвердил изоляцию checkpoint при смене двух реальных HTTP/PG источников в конфигурации local; 12.5.48 подтвердил scoped axe/клавиатуру в обеих темах и320px; 12.5.49 собрал Q-матрицу и подтвердил отсутствие настройки Telegram; 12.5.50 подтвердил GET-only инвентаризацию: VPN/BGP/OSPF пусты, роли home-router/home-router; По уточнению пользователя12.5.51 создал реальные GRE туннели и подтвердил lifecycle/связность; обнаружена потеря peer IP, 12.5.52 локально исправил сохранение peer metadata, профильные проверки passed; 12.5.53 развернул исправление и подтвердил его на реальной GRE паре/API/UI; 12.5.54 локально исправил устойчивость меню GRE, профильные проверки passed; 12.5.55 развернул frontend731803b и подтвердил устойчивость меню на реальной GRE паре; 12.5.56 локально адаптировал внутренние IP поля GRE для320px, обе темы и профильные проверки passed; 12.5.57 развернул frontendfd521f6 и подтвердил мобильную GRE форму на реальной паре CHR; следующий12.5.58 — собственная настоящая WireGuard пара с handshake/связностью и очисткой. Реальная Telegram доставка, Portal SSO, физический TCP disconnect, multi-instance и остальные профильные сетевые сценарии остаются открытыми. [Протокол](ux-ui-external-acceptance.md) и [журнал](ux-ui-stage-12.md) содержат доказательства и ограничения. +Этапы0–11 завершены в описанных локальных границах. Этап12 открыт. На тестовом сервере161.104.46.222 работают backendbd3f996/frontendfd521f6 и два CHR. Внешние проверки подтвердили PG backup/restore/rollback, остановку фоновой работы для одного экземпляра, API JWT/RBAC и браузерные состояния восстановления. Native TCP/UDP speed, история и UI проверены в границах журнала; доступ ко второму CHR восстановлен пользователем. Очередь Telegram проверена на реальном PG: dedupe, конкурентный claim, retry/version, ошибки сохранения и неопределённый исход; ответы отправителя подменялись, реальной доставки это не доказывает. Блоки12.5.43–45 подтвердили browser retry/checkpoint и развернули понятное пояснение HTTP500. 12.5.46 подтвердил browser JWT/RBAC очереди на реальном HTTP/PG; 12.5.47 подтвердил изоляцию checkpoint при смене двух реальных HTTP/PG источников в конфигурации local; 12.5.48 подтвердил scoped axe/клавиатуру в обеих темах и320px; 12.5.49 собрал Q-матрицу и подтвердил отсутствие настройки Telegram; 12.5.50 подтвердил GET-only инвентаризацию: VPN/BGP/OSPF пусты, роли home-router/home-router; По уточнению пользователя12.5.51 создал реальные GRE туннели и подтвердил lifecycle/связность; обнаружена потеря peer IP, 12.5.52 локально исправил сохранение peer metadata, профильные проверки passed; 12.5.53 развернул исправление и подтвердил его на реальной GRE паре/API/UI; 12.5.54 локально исправил устойчивость меню GRE, профильные проверки passed; 12.5.55 развернул frontend731803b и подтвердил устойчивость меню на реальной GRE паре; 12.5.56 локально адаптировал внутренние IP поля GRE для320px, обе темы и профильные проверки passed; 12.5.57 развернул frontendfd521f6 и подтвердил мобильную GRE форму на реальной паре CHR; 12.5.58 подтвердил настоящую WireGuard пару, handshake/Ping/native/UI и финальную очистку; следующий12.5.59 — обычное удаление WireGuard интерфейса с peer/IP через UI/API, проверка оставшихся объектов. Реальная Telegram доставка, Portal SSO, физический TCP disconnect, multi-instance и остальные профильные сетевые сценарии остаются открытыми. [Протокол](ux-ui-external-acceptance.md) и [журнал](ux-ui-stage-12.md) содержат доказательства и ограничения. Выполненные внешние сценарии не заменяют приёмку оставшихся интеграций и условий эксплуатации. Датированные продолжения ниже — история; точный следующий шаг указан в начале [журнала](ux-ui-progress.md). diff --git a/docs/ux-ui-progress.md b/docs/ux-ui-progress.md index d9300930..6f70cf43 100644 --- a/docs/ux-ui-progress.md +++ b/docs/ux-ui-progress.md @@ -1,6 +1,6 @@ # UX/UI: журнал реализации -Актуальное продолжение 2026-10-08: 12.5.57 развернул frontendfd521f6, backendbd3f996 healthy. Мобильная GRE форма подтверждена без HTTP mocks на новой собственной паре CHR: две темы/320/640/1280px, полный native IPv4/CIDR, Tab, меню refresh и сохранение PATCH200/200 с независимым чтением RouterOS. Ping3/3 в обе стороны; own GRE/IP удалены, выбранный baseline и DB controls совпали. Smoke6 экранов passed. Следующий12.5.58 — настоящая WireGuard пара: API/native/UI, handshake/связность и очистка собственных объектов; секреты в отчёты не включать. Этап12.5 открыт. +Актуальное продолжение 2026-10-08: 12.5.58 подтвердил настоящую WireGuard пару на обоих CHR: API/native keys association, handshake/RX, Ping3/3, MTU и UI в двух темах/1280/320px, URL interface/server/tab/reload. Итоговый harness exit0, выбранный WG/peers/IP/routes/Firewall baseline и DB controls совпали; own объекты удалены. Первый DELETE harness400 из-за JSON header без тела исправлен, recovery и повторный полный проход сохранены отдельно. Runtime backendbd3f996/frontendfd521f6 healthy. Следующий12.5.59 — удалить собственный WireGuard интерфейс с peer/IP через обычный UI/API и проверить остаточные объекты; в58 IP удалялись явно. Этап12.5 открыт. Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md). @@ -34,7 +34,19 @@ | 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–57 и ограничения ниже. Runtime backendbd3f996/frontendfd521f6. | +| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–58 и ограничения ниже. Runtime backendbd3f996/frontendfd521f6. | + +## 12.5.58 — настоящая WireGuard пара, handshake и UI (2026-10-08) + +[Итоговый реальный lifecycle](ux-ui/acceptance/wg-real-lifecycle-2026-10-08.json): собственная пара mm-acceptance-wg-1791470702451 на двух CHR, UDP51879 и198.18.255.240/30 проверены на коллизии/пересечения. POST interfaces201/201 создали интерфейсы и IP; native чтение подтвердило автоматические ключи и адреса, POST peers201/201 — связь с публичным ключом другого устройства. Ключи проверялись в памяти и не записывались в публичные артефакты. Allowed адреса ограничены IP другого конца /32, persistent keepalive5s. Default routes/Firewall не менялись. Параметры и смысл last-handshake сверены с [официальной документацией MikroTik](https://help.mikrotik.com/docs/spaces/ROS/pages/69664792/WireGuard). + +На обоих peers появился native handshake и RX>0; двусторонний Ping3/3,0%loss, около54–56ms. PATCH MTU1380 и возврат1420 подтверждены native чтением. Каталог приложения совпал с адресами/peers/handshake и не содержал privateKey по умолчанию. Это короткая проверка защищённой WireGuard связности; throughput, RBAC, interrupted mutation, экспорт и import не проверены. + +[Production browser](ux-ui/acceptance/browser-wg-real-2026-10-08.json): два CHR × две темы,1280/320px без HTTP mocks. В деталях видны own peer name, Allowed IPs, endpoint, handshake и известные RX/TX; server/interface URL и вкладка peers пережили reload, page overflow отсутствует. На320px длинные имя и CIDR переносятся; исходная таблица сохраняет собственный горизонтальный scroll. Создание/изменение/удаление через UI не проверялись. JS/API errors0. Скриншоты: [CHR1 dark](ux-ui/screens/wg-real-server1-dark-320-2026-10-08.png), [CHR1 light](ux-ui/screens/wg-real-server1-light-320-2026-10-08.png), [CHR2 dark](ux-ui/screens/wg-real-server2-dark-320-2026-10-08.png), [CHR2 light](ux-ui/screens/wg-real-server2-light-320-2026-10-08.png); итоговыйCHR2 light просмотрен. Первый browser locator одновременно находил sr-only и родительскую подпись handshake, уточнение локатора дало успешный проход без изменения продукта. + +[Первый проход](ux-ui/acceptance/wg-real-first-attempt-2026-10-08.json) подтвердил связность/UI, но cleanup harness получил DELETE400: Content-Type application/json был передан без тела. Это ошибка harness, не доказательство ошибки приложения. [Восстановительная очистка](ux-ui/acceptance/wg-first-cleanup-recovery-2026-10-08.json) через правильные DELETE проверила ownership comment/name и отсутствие own interfaces/peers/IP/routes. Baseline первого прохода был только в памяти и после выхода потерян; точная сверка первого baseline не заявляется. Harness исправлен, создана новая пара и повторён полный lifecycle/browser; итоговый exit0 и все выбранные baseline поля совпали. + +В финальном cleanup собственные peers удалены API200/200, собственные IP явно удалены native API до удаления interfaces API200/200. Автоматическая очистка IP/peers при обычном удалении интерфейса НЕ проверена и остаётся следующим12.5.59. WireGuard/IP/routes/IPv4 Firewall выбранные настройки совпали с baseline; эфемерный контейнер удалён, работают только три основные Compose-службы. DB controls до/после servers2/speedHistory9/retention14/migrations9 совпали, backend healthy. WG revisions намеренно сохранены как история операций. Runtime backendbd3f996/frontendfd521f6 не менялся. Telegram/Portal/multi-instance и остальные внешние ограничения остаются открытыми. Локальный коммит без push. ## 12.5.57 — развёртывание мобильной формы и реальная GRE приёмка (2026-10-08) diff --git a/docs/ux-ui-stage-12.md b/docs/ux-ui-stage-12.md index d5818ce8..b9f5ca14 100644 --- a/docs/ux-ui-stage-12.md +++ b/docs/ux-ui-stage-12.md @@ -1,6 +1,6 @@ # Этап 12: итоговая приёмка UX/UI -Актуальное продолжение 2026-10-08: 12.5.57 развернул frontendfd521f6, backendbd3f996 healthy. Мобильная GRE форма подтверждена без HTTP mocks на новой собственной паре CHR: две темы/320/640/1280px, полный native IPv4/CIDR, Tab, меню refresh и сохранение PATCH200/200 с независимым чтением RouterOS. Ping3/3 в обе стороны; own GRE/IP удалены, выбранный baseline и DB controls совпали. Smoke6 экранов passed. Следующий12.5.58 — настоящая WireGuard пара: API/native/UI, handshake/связность и очистка собственных объектов; секреты в отчёты не включать. Этап12.5 открыт. +Актуальное продолжение 2026-10-08: 12.5.58 подтвердил настоящую WireGuard пару на обоих CHR: API/native keys association, handshake/RX, Ping3/3, MTU и UI в двух темах/1280/320px, URL interface/server/tab/reload. Итоговый harness exit0, выбранный WG/peers/IP/routes/Firewall baseline и DB controls совпали; own объекты удалены. Первый DELETE harness400 из-за JSON header без тела исправлен, recovery и повторный полный проход сохранены отдельно. Runtime backendbd3f996/frontendfd521f6 healthy. Следующий12.5.59 — удалить собственный WireGuard интерфейс с peer/IP через обычный UI/API и проверить остаточные объекты; в58 IP удалялись явно. Этап12.5 открыт. План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push. @@ -1582,3 +1582,15 @@ DELETE200/200, own интерфейсы/IP и connected routes удалены; Скриншоты320px: [CHR1 dark](ux-ui/screens/gre-mobile-real-server1-dark-320-2026-10-08.png), [CHR1 light](ux-ui/screens/gre-mobile-real-server1-light-320-2026-10-08.png), [CHR2 dark](ux-ui/screens/gre-mobile-real-server2-dark-320-2026-10-08.png), [CHR2 light](ux-ui/screens/gre-mobile-real-server2-light-320-2026-10-08.png). CHR1 dark и CHR2 light визуально просмотрены: внутренние IP целиком видны. [Smoke](ux-ui/acceptance/deploy-browser-fd521f6-2026-10-08.json): dashboard/servers/uptime/settings/filters/alerts200,320px fit, JS/API errors0. DELETE200/200, собственные GRE/IP/connected routes удалены; выбранные GRE/IP/routes/IPv4 Firewall поля совпали с baseline, CHR1 — одно повторное чтение маршрутов через250ms. Эфемерный контейнер удалён; остались три основные Compose-службы. GRE revisions намеренно сохранены как история операций. Следующий12.5.58 — реальная собственная WireGuard пара, API/native/UI, handshake/связность, очистка и baseline; private/preshared keys не включать в публичные отчёты. Требование пользователя о настоящих VPN объектах сохраняется. Telegram/Portal/multi-instance и другие внешние ограничения остаются открытыми. Локальный коммит без push. + +## 12.5.58 — настоящая WireGuard пара, handshake и UI (2026-10-08) + +[Итоговый реальный lifecycle](ux-ui/acceptance/wg-real-lifecycle-2026-10-08.json): собственная пара mm-acceptance-wg-1791470702451 на двух CHR, UDP51879 и198.18.255.240/30 проверены на коллизии/пересечения. POST interfaces201/201 создали интерфейсы и IP; native чтение подтвердило автоматические ключи и адреса, POST peers201/201 — связь с публичным ключом другого устройства. Ключи проверялись в памяти и не записывались в публичные артефакты. Allowed адреса ограничены IP другого конца /32, persistent keepalive5s. Default routes/Firewall не менялись. Параметры и смысл last-handshake сверены с [официальной документацией MikroTik](https://help.mikrotik.com/docs/spaces/ROS/pages/69664792/WireGuard). + +На обоих peers появился native handshake и RX>0; двусторонний Ping3/3,0%loss, около54–56ms. PATCH MTU1380 и возврат1420 подтверждены native чтением. Каталог приложения совпал с адресами/peers/handshake и не содержал privateKey по умолчанию. Это короткая проверка защищённой WireGuard связности; throughput, RBAC, interrupted mutation, экспорт и import не проверены. + +[Production browser](ux-ui/acceptance/browser-wg-real-2026-10-08.json): два CHR × две темы,1280/320px без HTTP mocks. В деталях видны own peer name, Allowed IPs, endpoint, handshake и известные RX/TX; server/interface URL и вкладка peers пережили reload, page overflow отсутствует. На320px длинные имя и CIDR переносятся; исходная таблица сохраняет собственный горизонтальный scroll. Создание/изменение/удаление через UI не проверялись. JS/API errors0. Скриншоты: [CHR1 dark](ux-ui/screens/wg-real-server1-dark-320-2026-10-08.png), [CHR1 light](ux-ui/screens/wg-real-server1-light-320-2026-10-08.png), [CHR2 dark](ux-ui/screens/wg-real-server2-dark-320-2026-10-08.png), [CHR2 light](ux-ui/screens/wg-real-server2-light-320-2026-10-08.png); итоговыйCHR2 light просмотрен. Первый browser locator одновременно находил sr-only и родительскую подпись handshake, уточнение локатора дало успешный проход без изменения продукта. + +[Первый проход](ux-ui/acceptance/wg-real-first-attempt-2026-10-08.json) подтвердил связность/UI, но cleanup harness получил DELETE400: Content-Type application/json был передан без тела. Это ошибка harness, не доказательство ошибки приложения. [Восстановительная очистка](ux-ui/acceptance/wg-first-cleanup-recovery-2026-10-08.json) через правильные DELETE проверила ownership comment/name и отсутствие own interfaces/peers/IP/routes. Baseline первого прохода был только в памяти и после выхода потерян; точная сверка первого baseline не заявляется. Harness исправлен, создана новая пара и повторён полный lifecycle/browser; итоговый exit0 и все выбранные baseline поля совпали. + +В финальном cleanup собственные peers удалены API200/200, собственные IP явно удалены native API до удаления interfaces API200/200. Автоматическая очистка IP/peers при обычном удалении интерфейса НЕ проверена и остаётся следующим12.5.59. WireGuard/IP/routes/IPv4 Firewall выбранные настройки совпали с baseline; эфемерный контейнер удалён, работают только три основные Compose-службы. DB controls до/после servers2/speedHistory9/retention14/migrations9 совпали, backend healthy. WG revisions намеренно сохранены как история операций. Runtime backendbd3f996/frontendfd521f6 не менялся. Telegram/Portal/multi-instance и остальные внешние ограничения остаются открытыми. Локальный коммит без push. diff --git a/docs/ux-ui-test-server.md b/docs/ux-ui-test-server.md index c7d1a90d..6cd65367 100644 --- a/docs/ux-ui-test-server.md +++ b/docs/ux-ui-test-server.md @@ -425,3 +425,15 @@ DELETE200/200, own интерфейсы/IP и connected routes удалены; Скриншоты320px: [CHR1 dark](ux-ui/screens/gre-mobile-real-server1-dark-320-2026-10-08.png), [CHR1 light](ux-ui/screens/gre-mobile-real-server1-light-320-2026-10-08.png), [CHR2 dark](ux-ui/screens/gre-mobile-real-server2-dark-320-2026-10-08.png), [CHR2 light](ux-ui/screens/gre-mobile-real-server2-light-320-2026-10-08.png). CHR1 dark и CHR2 light визуально просмотрены: внутренние IP целиком видны. [Smoke](ux-ui/acceptance/deploy-browser-fd521f6-2026-10-08.json): dashboard/servers/uptime/settings/filters/alerts200,320px fit, JS/API errors0. DELETE200/200, собственные GRE/IP/connected routes удалены; выбранные GRE/IP/routes/IPv4 Firewall поля совпали с baseline, CHR1 — одно повторное чтение маршрутов через250ms. Эфемерный контейнер удалён; остались три основные Compose-службы. GRE revisions намеренно сохранены как история операций. Следующий12.5.58 — реальная собственная WireGuard пара, API/native/UI, handshake/связность, очистка и baseline; private/preshared keys не включать в публичные отчёты. Требование пользователя о настоящих VPN объектах сохраняется. Telegram/Portal/multi-instance и другие внешние ограничения остаются открытыми. Локальный коммит без push. + +## 12.5.58 — настоящая WireGuard пара, handshake и UI (2026-10-08) + +[Итоговый реальный lifecycle](ux-ui/acceptance/wg-real-lifecycle-2026-10-08.json): собственная пара mm-acceptance-wg-1791470702451 на двух CHR, UDP51879 и198.18.255.240/30 проверены на коллизии/пересечения. POST interfaces201/201 создали интерфейсы и IP; native чтение подтвердило автоматические ключи и адреса, POST peers201/201 — связь с публичным ключом другого устройства. Ключи проверялись в памяти и не записывались в публичные артефакты. Allowed адреса ограничены IP другого конца /32, persistent keepalive5s. Default routes/Firewall не менялись. Параметры и смысл last-handshake сверены с [официальной документацией MikroTik](https://help.mikrotik.com/docs/spaces/ROS/pages/69664792/WireGuard). + +На обоих peers появился native handshake и RX>0; двусторонний Ping3/3,0%loss, около54–56ms. PATCH MTU1380 и возврат1420 подтверждены native чтением. Каталог приложения совпал с адресами/peers/handshake и не содержал privateKey по умолчанию. Это короткая проверка защищённой WireGuard связности; throughput, RBAC, interrupted mutation, экспорт и import не проверены. + +[Production browser](ux-ui/acceptance/browser-wg-real-2026-10-08.json): два CHR × две темы,1280/320px без HTTP mocks. В деталях видны own peer name, Allowed IPs, endpoint, handshake и известные RX/TX; server/interface URL и вкладка peers пережили reload, page overflow отсутствует. На320px длинные имя и CIDR переносятся; исходная таблица сохраняет собственный горизонтальный scroll. Создание/изменение/удаление через UI не проверялись. JS/API errors0. Скриншоты: [CHR1 dark](ux-ui/screens/wg-real-server1-dark-320-2026-10-08.png), [CHR1 light](ux-ui/screens/wg-real-server1-light-320-2026-10-08.png), [CHR2 dark](ux-ui/screens/wg-real-server2-dark-320-2026-10-08.png), [CHR2 light](ux-ui/screens/wg-real-server2-light-320-2026-10-08.png); итоговыйCHR2 light просмотрен. Первый browser locator одновременно находил sr-only и родительскую подпись handshake, уточнение локатора дало успешный проход без изменения продукта. + +[Первый проход](ux-ui/acceptance/wg-real-first-attempt-2026-10-08.json) подтвердил связность/UI, но cleanup harness получил DELETE400: Content-Type application/json был передан без тела. Это ошибка harness, не доказательство ошибки приложения. [Восстановительная очистка](ux-ui/acceptance/wg-first-cleanup-recovery-2026-10-08.json) через правильные DELETE проверила ownership comment/name и отсутствие own interfaces/peers/IP/routes. Baseline первого прохода был только в памяти и после выхода потерян; точная сверка первого baseline не заявляется. Harness исправлен, создана новая пара и повторён полный lifecycle/browser; итоговый exit0 и все выбранные baseline поля совпали. + +В финальном cleanup собственные peers удалены API200/200, собственные IP явно удалены native API до удаления interfaces API200/200. Автоматическая очистка IP/peers при обычном удалении интерфейса НЕ проверена и остаётся следующим12.5.59. WireGuard/IP/routes/IPv4 Firewall выбранные настройки совпали с baseline; эфемерный контейнер удалён, работают только три основные Compose-службы. DB controls до/после servers2/speedHistory9/retention14/migrations9 совпали, backend healthy. WG revisions намеренно сохранены как история операций. Runtime backendbd3f996/frontendfd521f6 не менялся. Telegram/Portal/multi-instance и остальные внешние ограничения остаются открытыми. Локальный коммит без push. diff --git a/docs/ux-ui/acceptance/browser-wg-real-2026-10-08.json b/docs/ux-ui/acceptance/browser-wg-real-2026-10-08.json new file mode 100644 index 00000000..69b59839 --- /dev/null +++ b/docs/ux-ui/acceptance/browser-wg-real-2026-10-08.json @@ -0,0 +1,101 @@ +{ + "date": "2026-10-08", + "backendSource": "bd3f996", + "frontendSource": "fd521f6", + "name": "mm-acceptance-wg-1791470702451", + "httpMocks": false, + "actualCreatedWireguard": true, + "cases": [ + { + "serverId": 1, + "theme": "dark", + "widths": [ + { + "width": 1280, + "noPageOverflow": true, + "peerDetailsReadable": true + }, + { + "width": 320, + "noPageOverflow": true, + "peerDetailsReadable": true + } + ], + "interfaceContextPreserved": true, + "peersTabReload": true, + "nativeAllowedIpsAndEndpoint": true, + "handshakeVisible": true, + "countersKnown": true + }, + { + "serverId": 1, + "theme": "light", + "widths": [ + { + "width": 1280, + "noPageOverflow": true, + "peerDetailsReadable": true + }, + { + "width": 320, + "noPageOverflow": true, + "peerDetailsReadable": true + } + ], + "interfaceContextPreserved": true, + "peersTabReload": true, + "nativeAllowedIpsAndEndpoint": true, + "handshakeVisible": true, + "countersKnown": true + }, + { + "serverId": 2, + "theme": "dark", + "widths": [ + { + "width": 1280, + "noPageOverflow": true, + "peerDetailsReadable": true + }, + { + "width": 320, + "noPageOverflow": true, + "peerDetailsReadable": true + } + ], + "interfaceContextPreserved": true, + "peersTabReload": true, + "nativeAllowedIpsAndEndpoint": true, + "handshakeVisible": true, + "countersKnown": true + }, + { + "serverId": 2, + "theme": "light", + "widths": [ + { + "width": 1280, + "noPageOverflow": true, + "peerDetailsReadable": true + }, + { + "width": 320, + "noPageOverflow": true, + "peerDetailsReadable": true + } + ], + "interfaceContextPreserved": true, + "peersTabReload": true, + "nativeAllowedIpsAndEndpoint": true, + "handshakeVisible": true, + "countersKnown": true + } + ], + "pageErrors": [], + "badApiResponses": [], + "limits": [ + "Real API-created own pair; UI read/context/details verified, no UI create/export/delete tested", + "Keys omitted from report; screenshot shows own peer name instead of public key", + "Handshake age changes during polling; tested as present, not a fixed timestamp" + ] +} diff --git a/docs/ux-ui/acceptance/wg-first-cleanup-recovery-2026-10-08.json b/docs/ux-ui/acceptance/wg-first-cleanup-recovery-2026-10-08.json new file mode 100644 index 00000000..53706f4f --- /dev/null +++ b/docs/ux-ui/acceptance/wg-first-cleanup-recovery-2026-10-08.json @@ -0,0 +1,19 @@ +{ + "date": "2026-10-08", + "name": "mm-acceptance-wg-1791470457304", + "results": [ + { + "serverId": 1, + "ownInterfacePeerIpRouteAbsent": true + }, + { + "serverId": 2, + "ownInterfacePeerIpRouteAbsent": true + } + ], + "keysOmitted": true, + "limits": [ + "Recovery verified own objects absent; original in-memory baseline was lost after harness exit", + "Full selected baseline will be checked by a fresh complete run" + ] +} diff --git a/docs/ux-ui/acceptance/wg-real-first-attempt-2026-10-08.json b/docs/ux-ui/acceptance/wg-real-first-attempt-2026-10-08.json new file mode 100644 index 00000000..9598c890 --- /dev/null +++ b/docs/ux-ui/acceptance/wg-real-first-attempt-2026-10-08.json @@ -0,0 +1,197 @@ +{ + "date": "2026-10-08", + "backendSource": "bd3f996", + "frontendSource": "fd521f6", + "name": "mm-acceptance-wg-1791470457304", + "subnet": "198.18.255.240/30", + "listenPort": 51879, + "realRouterOs": true, + "changes": [ + { + "method": "POST", + "path": "/api/wireguard/interfaces", + "status": 201 + }, + { + "method": "POST", + "path": "/api/wireguard/interfaces", + "status": 201 + }, + { + "method": "POST", + "path": "/api/wireguard/peers", + "status": 201 + }, + { + "method": "POST", + "path": "/api/wireguard/peers", + "status": 201 + }, + { + "method": "PATCH", + "path": "/api/wireguard/interfaces/1/*5", + "status": 200 + }, + { + "method": "PATCH", + "path": "/api/wireguard/interfaces/1/*5", + "status": 200 + }, + { + "method": "GET", + "path": "/api/wireguard", + "status": 200 + }, + { + "method": "DELETE", + "path": "/api/wireguard/peers/1/*1", + "status": 400 + }, + { + "method": "DELETE", + "path": "/api/wireguard/peers/2/*1", + "status": 400 + } + ], + "pings": [ + { + "serverId": 1, + "target": "198.18.255.242", + "interface": "mm-acceptance-wg-1791470457304", + "received": 3, + "rows": [ + { + "sent": "1", + "received": "1", + "packet-loss": "0", + "time": "54ms733us", + "avg-rtt": "54ms733us" + }, + { + "sent": "2", + "received": "2", + "packet-loss": "0", + "time": "55ms573us", + "avg-rtt": "55ms153us" + }, + { + "sent": "3", + "received": "3", + "packet-loss": "0", + "time": "55ms260us", + "avg-rtt": "55ms188us" + } + ] + }, + { + "serverId": 2, + "target": "198.18.255.241", + "interface": "mm-acceptance-wg-1791470457304", + "received": 3, + "rows": [ + { + "sent": "1", + "received": "1", + "packet-loss": "0", + "time": "55ms569us", + "avg-rtt": "55ms569us" + }, + { + "sent": "2", + "received": "2", + "packet-loss": "0", + "time": "55ms190us", + "avg-rtt": "55ms379us" + }, + { + "sent": "3", + "received": "3", + "packet-loss": "0", + "time": "54ms747us", + "avg-rtt": "55ms168us" + } + ] + } + ], + "cleanup": [ + { + "serverId": 1, + "error": "Application request rejected, status 400" + }, + { + "serverId": 2, + "error": "Application request rejected, status 400" + } + ], + "nativeKeyGenerationConfirmed": true, + "connectedState": [ + { + "serverId": 1, + "interface": { + "rosId": "*5", + "appId": "1:*5", + "name": "mm-acceptance-wg-1791470457304", + "listenPort": "51879", + "mtu": "1420", + "running": "true", + "disabled": "false", + "userComment": "Temporary UX acceptance mm-acceptance-wg-1791470457304" + }, + "addresses": [ + "198.18.255.241/30" + ], + "peers": [ + { + "rosId": "*1", + "name": "mm-acceptance-wg-1791470457304-peer", + "allowedAddresses": "198.18.255.242/32", + "endpoint": "104.165.244.7:51879", + "handshake": "1s", + "rx": "180", + "tx": "272", + "disabled": "false", + "userComment": "Temporary UX acceptance mm-acceptance-wg-1791470457304" + } + ] + }, + { + "serverId": 2, + "interface": { + "rosId": "*A", + "appId": "2:*A", + "name": "mm-acceptance-wg-1791470457304", + "listenPort": "51879", + "mtu": "1420", + "running": "true", + "disabled": "false", + "userComment": "Temporary UX acceptance mm-acceptance-wg-1791470457304" + }, + "addresses": [ + "198.18.255.242/30" + ], + "peers": [ + { + "rosId": "*1", + "name": "mm-acceptance-wg-1791470457304-peer", + "allowedAddresses": "198.18.255.241/32", + "endpoint": "194.226.121.150:51879", + "handshake": "1s", + "rx": "124", + "tx": "180", + "disabled": "false", + "userComment": "Temporary UX acceptance mm-acceptance-wg-1791470457304" + } + ] + } + ], + "handshakeConfirmed": true, + "bidirectionalPingPassed": true, + "catalogMatchesNative": true, + "limits": [ + "Only own WireGuard interface/peer/IP and connected route changed; no default routes/firewall changes", + "Own IP addresses explicitly deleted via native API before interface deletion; automatic address cleanup was not tested", + "Private/public/preshared keys omitted from report; native generation and peer association checked in memory", + "Handshake and short ICMP connectivity, not throughput, RBAC or interrupted mutation", + "WireGuard audit revisions intentionally retained" + ] +} diff --git a/docs/ux-ui/acceptance/wg-real-lifecycle-2026-10-08.json b/docs/ux-ui/acceptance/wg-real-lifecycle-2026-10-08.json new file mode 100644 index 00000000..164c1650 --- /dev/null +++ b/docs/ux-ui/acceptance/wg-real-lifecycle-2026-10-08.json @@ -0,0 +1,233 @@ +{ + "date": "2026-10-08", + "backendSource": "bd3f996", + "frontendSource": "fd521f6", + "name": "mm-acceptance-wg-1791470702451", + "subnet": "198.18.255.240/30", + "listenPort": 51879, + "realRouterOs": true, + "changes": [ + { + "method": "POST", + "path": "/api/wireguard/interfaces", + "status": 201 + }, + { + "method": "POST", + "path": "/api/wireguard/interfaces", + "status": 201 + }, + { + "method": "POST", + "path": "/api/wireguard/peers", + "status": 201 + }, + { + "method": "POST", + "path": "/api/wireguard/peers", + "status": 201 + }, + { + "method": "PATCH", + "path": "/api/wireguard/interfaces/1/*6", + "status": 200 + }, + { + "method": "PATCH", + "path": "/api/wireguard/interfaces/1/*6", + "status": 200 + }, + { + "method": "GET", + "path": "/api/wireguard", + "status": 200 + }, + { + "method": "DELETE", + "path": "/api/wireguard/peers/1/*2", + "status": 200 + }, + { + "method": "DELETE", + "path": "/api/wireguard/interfaces/1/*6", + "status": 200 + }, + { + "method": "DELETE", + "path": "/api/wireguard/peers/2/*2", + "status": 200 + }, + { + "method": "DELETE", + "path": "/api/wireguard/interfaces/2/*B", + "status": 200 + } + ], + "pings": [ + { + "serverId": 1, + "target": "198.18.255.242", + "interface": "mm-acceptance-wg-1791470702451", + "received": 3, + "rows": [ + { + "sent": "1", + "received": "1", + "packet-loss": "0", + "time": "54ms795us", + "avg-rtt": "54ms795us" + }, + { + "sent": "2", + "received": "2", + "packet-loss": "0", + "time": "55ms61us", + "avg-rtt": "54ms928us" + }, + { + "sent": "3", + "received": "3", + "packet-loss": "0", + "time": "54ms865us", + "avg-rtt": "54ms907us" + } + ] + }, + { + "serverId": 2, + "target": "198.18.255.241", + "interface": "mm-acceptance-wg-1791470702451", + "received": 3, + "rows": [ + { + "sent": "1", + "received": "1", + "packet-loss": "0", + "time": "54ms790us", + "avg-rtt": "54ms790us" + }, + { + "sent": "2", + "received": "2", + "packet-loss": "0", + "time": "55ms69us", + "avg-rtt": "54ms929us" + }, + { + "sent": "3", + "received": "3", + "packet-loss": "0", + "time": "55ms78us", + "avg-rtt": "54ms979us" + } + ] + } + ], + "cleanup": [ + { + "serverId": 1, + "/interface/wireguard": true, + "/interface/wireguard/peers": true, + "/ip/address": true, + "/ip/route": true, + "/ip/firewall/filter": true, + "/ip/firewall/nat": true, + "/ip/firewall/mangle": true + }, + { + "serverId": 2, + "/interface/wireguard": true, + "/interface/wireguard/peers": true, + "/ip/address": true, + "/ip/route": true, + "/ip/firewall/filter": true, + "/ip/firewall/nat": true, + "/ip/firewall/mangle": true + } + ], + "nativeKeyGenerationConfirmed": true, + "connectedState": [ + { + "serverId": 1, + "interface": { + "rosId": "*6", + "appId": "1:*6", + "name": "mm-acceptance-wg-1791470702451", + "listenPort": "51879", + "mtu": "1420", + "running": "true", + "disabled": "false", + "userComment": "Temporary UX acceptance mm-acceptance-wg-1791470702451" + }, + "addresses": [ + "198.18.255.241/30" + ], + "peers": [ + { + "rosId": "*2", + "name": "mm-acceptance-wg-1791470702451-peer", + "allowedAddresses": "198.18.255.242/32", + "endpoint": "104.165.244.7:51879", + "handshake": "2s", + "rx": "272", + "tx": "452", + "disabled": "false", + "userComment": "Temporary UX acceptance mm-acceptance-wg-1791470702451" + } + ] + }, + { + "serverId": 2, + "interface": { + "rosId": "*B", + "appId": "2:*B", + "name": "mm-acceptance-wg-1791470702451", + "listenPort": "51879", + "mtu": "1420", + "running": "true", + "disabled": "false", + "userComment": "Temporary UX acceptance mm-acceptance-wg-1791470702451" + }, + "addresses": [ + "198.18.255.242/30" + ], + "peers": [ + { + "rosId": "*2", + "name": "mm-acceptance-wg-1791470702451-peer", + "allowedAddresses": "198.18.255.241/32", + "endpoint": "194.226.121.150:51879", + "handshake": "2s", + "rx": "304", + "tx": "304", + "disabled": "false", + "userComment": "Temporary UX acceptance mm-acceptance-wg-1791470702451" + } + ] + } + ], + "handshakeConfirmed": true, + "bidirectionalPingPassed": true, + "catalogMatchesNative": true, + "limits": [ + "Only own WireGuard interface/peer/IP and connected route changed; no default routes/firewall changes", + "Own IP addresses explicitly deleted via native API before interface deletion; automatic address cleanup was not tested", + "Private/public/preshared keys omitted from report; native generation and peer association checked in memory", + "Handshake and short ICMP connectivity, not throughput, RBAC or interrupted mutation", + "WireGuard audit revisions intentionally retained" + ], + "controlBefore": { + "servers": 2, + "speedHistory": 9, + "retentionDays": 14, + "migrations": 9 + }, + "controlAfter": { + "servers": 2, + "speedHistory": 9, + "retentionDays": 14, + "migrations": 9 + }, + "controlsUnchanged": true, + "backendHealthy": true +} diff --git a/docs/ux-ui/screens/wg-real-server1-dark-320-2026-10-08.png b/docs/ux-ui/screens/wg-real-server1-dark-320-2026-10-08.png new file mode 100644 index 00000000..cb6b7812 Binary files /dev/null and b/docs/ux-ui/screens/wg-real-server1-dark-320-2026-10-08.png differ diff --git a/docs/ux-ui/screens/wg-real-server1-light-320-2026-10-08.png b/docs/ux-ui/screens/wg-real-server1-light-320-2026-10-08.png new file mode 100644 index 00000000..5c648e67 Binary files /dev/null and b/docs/ux-ui/screens/wg-real-server1-light-320-2026-10-08.png differ diff --git a/docs/ux-ui/screens/wg-real-server2-dark-320-2026-10-08.png b/docs/ux-ui/screens/wg-real-server2-dark-320-2026-10-08.png new file mode 100644 index 00000000..ec4d5924 Binary files /dev/null and b/docs/ux-ui/screens/wg-real-server2-dark-320-2026-10-08.png differ diff --git a/docs/ux-ui/screens/wg-real-server2-light-320-2026-10-08.png b/docs/ux-ui/screens/wg-real-server2-light-320-2026-10-08.png new file mode 100644 index 00000000..e1da5418 Binary files /dev/null and b/docs/ux-ui/screens/wg-real-server2-light-320-2026-10-08.png differ