Files
MikrotikManager/docs/ux-ui-plan.md
T

657 lines
154 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# План реализации UX/UI по пятичасовым окнам
Актуальное продолжение 2026-10-15: 256 — collector renewal использует подтверждённые dates без выдуманного revocation status; профиль/build/lint прошли, backend ux-certificates256/source528/dist1080 healthy. Реальное scheduler renewal выполнилось, served TLS SHA-256 сменился и совпал с новым native leaf, но импорт создал2 одинаковых имени: общая приёмка не завершена. Все own native/DNS/jobs/settings очищены/восстановлены; оба CHR доступны. Следующий257 — запрет ложного success при неоднозначном импорте и стратегия уникальной замены; отдельно лимит REST logins6. Этап12.5 открыт.
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-14. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
## 12.5.256 — реальный scheduler renewal, дубликаты native имён и полный откат (2026-10-15)
Начат2026-10-14, завершён2026-10-15 по Новосибирску. Пятичасовой лимит сбросился, недельный остался ограниченным. По действующему разрешению254 снят новый native/SQL baseline, own jobs/certificates/DNS0, token/zone/account проверены. Первый UI issue exact mmt253-8e62a941.pngs.top/manual →done, trusted TLS/private-key/native SHA-256 подтверждены. [UI](ux-ui/acceptance/acme256-live-ui.json), [before](ux-ui/acceptance/acme256-tls-before.json).
Native date reader255 теперь правильно даёт validFrom/validUntil в UTC и daysLeft90, совпадающие с X509. Но statusunknown: REST7.24.5 не присылает flags/revoked/expired. Первый enable-triggered run был skipped/renewed0, без нового ACME order; comparator expectation renewed1 не прошёл и сохранён отдельно [skip](ux-ui/acceptance/acme256-renewal-skipped.json). Каталог не должен выдумывать revocation state. Для renewal правило уточнено: достаточно подтверждённого срока и начавшегося непротиворечивого validity window; unknown/missing/changed clock, missing start, future start и reversed window по-прежнему не создают job. Это соответствует прежнему разрешённому renewal даже для explicit revoked/expired, не объявляет сертификат valid.
Collector native-clock→canonical-state→issue тесты: stable offset создаёт одну задачу, changed/missing не создаёт; отсутствующие REST revocation flags с известными dates позволяют renewal, неизвестные/future/reversed dates блокируют. Все8 profile scripts, contracts/backend build, scoped lint passed. Production backend ux-certificates256/source528/compiled1080 совпал, healthy, frontend251/DB/Portal сохранены. Изменённый scope не требовал повтора полной регрессии249.
После исправления один enable-triggered scheduler run (interval86400/threshold90), без run-now: scheduler issue →done, receipt ok/renewed1/errors0, затем enabledfalse до следующего интервала. Реально served TLS сменился с342d36bc… на70b7b9f1… и совпал с новым private-key native leaf; доверие/SNI не отключались. [After](ux-ui/acceptance/acme256-tls-after.json), [jobs](ux-ui/acceptance/acme256-jobs.json), [run](ux-ui/acceptance/acme256-renewal.json).
Приёмка renewal всё равно открыта: /certificate содержит2 leaf с одинаковым logical name mmt253-8e62a941, разными .id/SHA-256 и private-key=true. [Duplicate leaves](ux-ui/acceptance/acme256-duplicate-leaves.json). Next collector отвергнет неоднозначность; import ACK + done не доказывают устойчивую замену. Fresh TLS действительно served new leaf, поэтому не заявляем, что TLS остался старым. До fresh sample ошибочно скопированный вручную fingerprint не прошёл SHA-256 validation; затем использован точный файл native report через SCP. Предусловие statusvalid оказалось неверным для REST flags; первый scheduler run безопасно skipped, после уточнения policy выполнен один реальный order. Не суммируем skip как успешное renewal.
Cleanup сначала столкнулся с REST401/500; точный ответ resource500: too many concurrent logins (6). Временно остановлен только backend, затем восстановлены configured www-ssl/api-ssl, удалены оба own leaf/chain/PEM. Certificates/file stable metadata/configured services/normalized export совпали с fresh baseline; исключены dynamic connections и directory mtime. [Native](ux-ui/acceptance/acme256-native.json). Backend снова запущен и healthy, Portal послеcleanup оба CHR читает безошибочно; пароли не менялись. REST concurrency остаётся отдельным воспроизведённым ограничением.
TXT приложение удалило; own A удалена по exact name/type/content/ID, DNS0 обоихимён [DNS](ux-ui/acceptance/acme256-cloudflare.json). ACME/renew settings восстановлены целиком, scheduler refresh применён, его empty-run metadata затем восстановлена exact SQL compare. Own issue jobs удалены, private token/baseline/helper/SQL файлы удалены с Debian и локальный secret fixture удалён. Historical events/scheduler receipts/CA records сохранены; CA revocation не заявляется.
Следующий257 — post-import подтверждение unique logical name/expected X509 fingerprint/private key перед применением/успехом и безопасная стратегия уникальной замены без потери старого working leaf. Дополнительно проработать per-device REST concurrency/login cap. Эти дефекты не маскируются сообщением successful acceptance; новое разрешение на тот же согласованный сценарий не запрашивается без изменения его риска/объёма.
## 12.5.255 — native даты с подтверждённым offset для каталога и renewal (2026-10-14)
После измерения254 добавлен общий readCertificateRowsWithClock: читает gmt-offset перед каталогом, для native timezone-less дат повторно читает clock после; принимает только одинаковые валидные offsets. Native YYYY-MM-DD HH:mm:ss преобразуется в offset-qualified datetime с проверкой календаря, затем UTC; explicit ISO сохраняет свой offset. Не предполагается UTC/пояс backend/будущий DST. rawValidFrom/rawValidUntil остаются исходными. Отсутствующий/некорректный/сменившийся/недоступный clock сохраняет unknown/null и не обходит renewal guard252; ошибка самого каталога сохраняет error. Legacy старые форматы без надёжного контекста не угадываются.
Общий reader подключён к live catalog и default renewal dependency, disabled/strict-ID guards сохранены. В штатном цикле добавлены read-only clock запросы, мутаций native/DNS нет. Успех этой калибровки подтверждён для CHR7.24.5; другие версии/форматы остаются ограничением до соответствующих измерений. Все восемь certificate profile scripts прошли, contracts/backend build и scoped lint passed. Новые проверки покрывают точные from/until254, январский expiry с текущим +02:00, raw preservation, explicit ISO, неверный календарь/offset и missing/changed/failed clock. Полная регрессия249 не повторялась для ограниченного изменения.
Production backend ux-certificates255 собран и развёрнут, source528/compiled1080 matched, healthy; frontend ux-certificates251 и DB/Portal сохранены. Read-only Portal/state после обновления: оба CHR200 без ошибки,1440/390 без overflow/JS errors/API writes. [Проверки/deployment](ux-ui/acceptance/certificates255-deployment.json), [live](ux-ui/acceptance/certificates255-live-ui.json). Собственных сертификатов после cleanup254 нет, поэтому этот read не объявляется real native-date/renewal acceptance нового образа. Новые выпуски255 не запускались.
Следующий256: по уже полученному разрешению254 снова снять свежий baseline, выполнить first issue exact mmt253-8e62a941.pngs.top, подтвердить canonical date против trusted X509; затем один enable-triggered scheduler renewal с порогом90/интервалом86400 без дополнительного run-now, сравнить изменённый native/TLS fingerprint и выполнить полный откат. Если импорт оставит старый TLS leaf или даты останутся unknown — зафиксировать реальный отказ, не маскировать. Из-за малого остатка лимита новый внешний цикл сейчас не начат: для него нужен запас на cleanup. Повторное разрешение на этот же сценарий не требуется.
## 12.5.254 — реальный выпуск и выявленное препятствие renewal (2026-10-14)
Пользователь разрешил first issue + scheduler renewal + полный откат для exact mmt253-8e62a941.pngs.top на CHR104. Сняты свежие приватные native/SQL baselines: сертификаты0, issue jobs0, CF token отсутствует. Renewal временно выключен штатным API. Token/zone/account проверены200; один UI POST с сохранённым requestId → terminal done/stepdone, UI завершение и JS errors0. [UI](ux-ui/acceptance/acme254-live-ui.json).
Native leaf exact name/private-key=true, SHA-256 89b6bd15857aaa548a26137fed6378aa2750440565ba0516240ff22e3a5e7e91. Acceptance helper сделал доверенный TLS к104:443 с SNI, rejectUnauthorized=true: hostname/private-key metadata/native fingerprint совпали с served leaf. [TLS before](ux-ui/acceptance/acme254-tls-before.json). Это первый выпуск, не подтверждение смены leaf после renewal.
Препятствие из реального state: native invalid-before=2026-10-14 15:37:47 и invalid-after=2027-01-12 15:37:46 без timezone. Канонический parser принимает offset-qualified datetime, поэтому validFrom/validUntil/daysLeft=null и statusunknown. По процедуре253 второй order не запускался, порог90/enable/run-now не применялись; unknown guard252 не обходился и время устройства не менялось. [Renewal limitation](ux-ui/acceptance/acme254-renewal.json). Следующий255 — определить корректную семантику native времени/публичного X509 без предположения о timezone и только затем повторить реальный scheduler renewal в рамках уже данного разрешения.
Откат: www-ssl/api-ssl исходные поля восстановлены, own certificates/PEM files/job удалены. TXT приложение очистило; собственная A удалена по exact name/type/content/ID; оба имени DNS0. [DNS](ux-ui/acceptance/acme254-cloudflare.json). ACME/renew settings восстановлены полностью; scheduler refresh применил исходное enabled/interval, после его пустого run metadata восстановлена ещё раз и exact SQL comparison passed. Секреты/private baselines/restore SQL удалены с Debian и локальный token fixture удалён. Historical event приложения/публичная CA запись не объявляются отозванными.
Native первый strict whole-collection assertion остановился на volatile metadata, а не неполном удалении: flash directory last-modified изменился при записи собственных файлов, /ip/service включает dynamic connections. Повтор только read-only сравнил exact configured services, file IDs/name/type/size и certificates; исключены directory mtime и dynamic connections, normalized full export совпал. [Native](ux-ui/acceptance/acme254-native.json). Один контрольный REST read вернул401, следующий read resource/certificate/file/services200 со старым паролем; Portal после cleanup оба устройства читает без ошибок. Не делаем вывод о смене пароля из transient401.
Дополнительная read-only калибровка254: system/clock Europe/Warsaw, gmt-offset +02:00, autodetect=true. Доверенный X509 before=13:37:47Z и until=13:37:46Z; оба native timestamps15:37 соответствуют текущему +02:00, включая будущий январский expiry. Поэтому нельзя просто дописать Z или применить исторический/будущий Warsaw offset +01:00 к январскому endpoint. Нужен явно наблюдаемый offset и проверка его стабильности вместе с чтением native дат; при неизвестном/сменившемся offset сохранять null. Это доказано для конкретного CHR7.24.5, не для всех версий RouterOS.
Production source/images не менялись, backend ux-certificates252/frontend ux-certificates251; rebuild/regression не повторялись. Продление и замена leaf ещё не приняты; ограничения описаны без объявления failed/blocked теста успешным.
## 12.5.253 — подготовка проверки реальной замены сертификата при renewal (2026-10-14)
Подготовлен exact mmt253-8e62a941.pngs.top/certName mmt253-8e62a941 на CHR104/server2. Read-only preflight с Debian: точный FQDN и challenge name имеют0 Cloudflare records, оба CHR REST200 с прежними паролями. Ни DNS/settings/native writes, ни ACME orders не выполнялись. Это не свежий приватный baseline для будущей мутации: его нужно снять непосредственно перед запуском.
Новый ручной helper backend/scripts/acceptance/acme-renew-tls.mjs делает bounded15s TLS к фиксированному104:443 с exact SNI и rejectUnauthorized=true. Сверяет hostname, native SHA-256/private-key/name и served leaf. Compare требует изменения SHA-256 после повторного выпуска, совпадения native/TLS, корректных дат; output не перезаписывается. Ввод содержит только публичную native сводку, не keys/passwords. Один positive и11 negative comparator случаев passed без сети/CA; syntax и scoped ESLint passed. Это проверка проверяющего инструмента, не реального renewal. Native fingerprint другого алгоритма сначала пересчитывается из публичного PEM, не угадывается.
Процедура в [TEST-ACME](../deploy/TEST-ACME.md) включает свежий private baseline/settings/managed targets, единственный собственный target, первый UI выпуск, initial TLS, canonical date guard252 и один scheduler renewal. Code review пути settings выявил важное условие: PUT enabled=true вызывает refreshScheduler с немедленным запуском, поэтому дополнительный run-now запрещён. После terminal renewal выключается до следующего интервала. Если дата unknown, повторный выпуск не запускается и ограничение фиксируется. Job done без нового served fingerprint считается провалом, старый leaf не удаляется ради прохождения теста.
Откат описан по exact IDs/fingerprints/files/record content и исходным settings/services/normalized export, контрольный CHR194 не меняется, перезагрузки/смена паролей не нужны. Публичная CA выдача не объявляется revoked. Справка native полей/import: [MikroTik Certificates](https://help.mikrotik.com/docs/spaces/ROS/pages/2555969/Certificates); факт замены проверяется измерением, документация его не подтверждает для текущего приложения.
Production код не менялся, Docker build/deploy не нужен, backend ux-certificates252/frontend ux-certificates251 сохранены. Следующий шаг — согласование конкретных двух выдач/renewal с включением www-ssl/api-ssl и полным откатом; разрешение250 относилось к уже завершённому выпуску. До согласия только подготовка/чтение. Реальное renewal, CA revoke и multi-instance остаются открыты.
## 12.5.252 — выключенные серверы и достоверность результата renewal (2026-10-14)
Общий getter сертификатов теперь использует parseDbServerId и SQL enabled=true: numeric prefix/небезопасные ID не доходят до БД, выключенные серверы не возвращаются. Executor повторно отклоняет disabled перед DNS/native вызовами. Renewal использует каноническое наблюдаемое состояние вместо legacy expiry=0: неизвестный срок/статус пропускается, ошибка чтения/неоднозначное имя не запускает выпуск. После runner читается свежая запись задачи и проверяются id/server/name/source/domains/keyType/trustStore; renewed увеличивается только при status=done и step=done. Failed даёт error, queued/running и неподтверждённый результат не дают успеха. Local singleflight сохраняется; атомарная защита нескольких backend не заявляется.
Factory collector позволяет отдельно проверить зависимости без RouterOS/CA. test:certificates включает восемь scripts; новый набор покрывает done/failed/pending, missing/disabled, неизвестный срок, offline/malformed/ambiguous, выключенные настройки, активную задачу, неправильный контекст результата и конкурентный запуск. Executor включает11 сценариев. Локально и в acceptance image профиль прошёл; contracts/backend build, scoped ESLint и diff-check прошли. Полная регрессия249 не повторялась для ограниченного изменения сертификатов.
Расширенный network-disabled-server harness выполнен на собственной SQL БД с отдельной ограниченной ролью:39 API/SQL checks для home-router/jump-host/exit-node, включая certificates issue404/no job и state200/empty, zero RouterOS contacts. Enabled positive control и bigint IDs above int32/MAX_SAFE_INTEGER прошли без округления. После теста контейнер/БД/роль удалены, отсутствие подтверждено. Это выполняет ранее пропущенную152 ветку в текущем scope; monthly149/IPv6 UDP-worker144 этим тестом не покрыты. [Проверки](ux-ui/acceptance/certificates252-regression.json).
Production backend ux-certificates252 развёрнут, healthy; source526 и compiled1080 совпали с локальным снимком. Frontend ux-certificates251 и PostgreSQL/Portal сохранены. [Deployment](ux-ui/acceptance/certificates252-deployment.json). Настоящий Portal/read без mocks: certificate state и renew settings200, оба CHR без ошибки чтения;1440/390 без overflow/JS errors/API writes. Первый запуск Edge не стартовал внутри filesystem sandbox; повтор с разрешённым доступом прошёл, это не дефект приложения. [Live UI](ux-ui/acceptance/certificates252-live-ui.json).
Новых сертификатов, ACME orders, DNS записей, настроек устройств не создавали; native пароли не менялись. Успех fixtures доказывает счётчик/guards, не реальное продление/замену ключа/CA revoke. Следующий253: подготовить конкретную повторную выдачу собственного mmt-домена, сравнение leaf fingerprint и доверенного TLS до/после, восстановление исходных SSL/certs/files/settings/DNS. Выполнение с повторным назначением SSL требует отдельного согласования конкретного сценария; разрешение250 покрывало тот уже очищенный тест.
## 12.5.251 — понятные последствия выпуска и доступные мастера ReUI (2026-10-14)
После250 форма явно сообщает: импорт назначает сертификат обоим www-ssl/api-ssl и включает их; trust-store переключатели задают trust-store, не отменяют назначение. Итоговая сводка показывает DNS A-sync как попытку синхронизации с IPv4 сервера и сохранение CNAME. Сетевая логика/API не менялись. Оба trust-store switches получили доступные имена.
Scoped axe live preview выявил прежние aria-required-children/parent и aria-valid-attr-value: установленный Stepper root role=tablist охватывал nav и контент, nav мешал родительской роли tabs, Content не передавал id/role/aria props. [API](https://reui.io/docs/components/base/stepper?ref=mcp), [preview](https://reui.io/components/stepper?ref=mcp) и примеры прочитаны через MCP; актуальный @reui/stepper прочитан shadcn view и имеет те же пропуски. Установка/переопределение vendor не решает их и не выполнена.
Добавлен reui-kit/accessible-stepper: переиспользует установленные компоненты/keyboard/focus/styles, добавляет прозрачные display:contents обёртки с tablist/tabpanel, rootgroup без неподходящего aria-orientation, React useId для tab/panel namespace. Контент forceMount с штатным hidden сохраняет все IDREF. Vendor файл, shared theme и animation timings не менялись. Все три потребителя — сертификаты, создание/редактирование серверов, создание бэкапа — переведены на адаптер.
69 уникальных E2E:57 existing certificates issue/layout + servers + backup operations и12 backup job + новые3 ARIA сценария. Первый набор57 прошёл2.1m, второй12 —32.1s; первоначальные7 issue повторяются в57 и не суммируются. Проверены операции/checkpoints/отказы/права/контекст, серверный wizard320/390/1440, certificate layout320/390/1440, связь каждой tab со своей существующей panel/unique IDs/одна видимая панель и4 ARIA rules во всех трёх формах. TypeScript и scoped ESLint passed. Не заявляем полного axe/WCAG аудита всех трёх страниц.
Production frontend ux-certificates251 собран и развёрнут, source528 matched, backend ux-containers249 healthy сохранён, PostgreSQL/Portal не пересоздавались. До обнаружения ARIA дефекта выполнялись промежуточные сборки copy/labels; окончательный образ содержит adapter и все последние изменения. Это повтор из-за новых найденных ошибок, не дополнительные принятые сценарии. Для следующих сложных форм сначала локальный scoped axe, затем production build. [Deployment](ux-ui/acceptance/certificates251-deployment.json).
Настоящий Portal/live preview1440/390: trust www переключается Space, step3/4 показывают назначение SSL независимо от trust toggle и DNS/CNAME; нет overflow/JS errors, четыре scoped axe WCAG2/2.1/2.2 scans violations0. Формы отменены Escape, API writes0/никаких выпусков/новых DNS/native objects. [Live UI](ux-ui/acceptance/certificates251-live-ui.json), [desktop](ux-ui/screens/certificates251-review-desktop.png), [mobile](ux-ui/screens/certificates251-review-mobile.png). Mobile screenshot просмотрен. ReUI checklist пройден в изменённом scope: reuse/семантика/security/scroll/typecheck/lint; неизменённые части не объявляются заново принятыми.
Следующий252: чтение certificates-service поID всё ещё принимает numeric prefix и disabled row; renewal collector опрашивает его. Collector после runIssueJob прибавляет renewed без чтения terminal job status, хотя runner записывает failed и возвращается без throw; legacy parser подменяет неизвестный срок0. Исправить эти достоверные code-path дефекты и проверить соответствующие service/SQL случаи. Реальная повторная выдача/renewal/CA revoke/multi-instance остаются отдельными неподтверждёнными вариантами, первичный ACME250 уже принят.
## 12.5.250 — production ACME / Cloudflare / TLS через реальный UI (2026-10-14)
Пользователь предоставил pngs.top/Cloudflare и разрешил поддомены с префиксом mmt*. После уточнения звёздочки получено согласие на точное имя mmt250-c22a9715.pngs.top и временное назначение www-ssl/api-ssl с откатом. Cloudflare token verify и exact zone query200/success, token/zone active/account matched; оба собственных DNS имени до начала имели0 records. Ключ/почта/account ID только в ignored private fixture; на Debian ключ поступил через разрешённый временный API settings, отдельный secret файл туда не передавался. Native/private settings baseline снят до начала.
Настоящий Portal/UI без mocks: app Cloudflare test200, settings save200; выбран server2/CHR104, один POST issue с точным CN →200/jobId; backend queued/running →done, UI terminal «Завершена». Production directory Let's Encrypt, не staging/fake CA. CSR/DNS-01/импорт leaf+key+chain прошли; native leaf CN/private-key=true и оба SSL сервиса enabled с этим сертификатом подтверждены. [UI](ux-ui/acceptance/acme250-live-ui.json).
Независимая проверка: DNS A104.165.244.7; TLSv1.2, обычный rejectUnauthorized=true, peer authorized/SAN exact domain, issuerYR2, срок2026-10-14→2027-01-12; REST по HTTPS200 с прежними учётными данными. TLS проверка не отключалась, CA в локальное доверие не добавлялась. Это проверка конкретного CA/RouterOS клиента, не всех TLS версий/клиентских ОС. [TLS](ux-ui/acceptance/acme250-tls.json).
Очистка: сначала исходные disabled/certificate/port SSL сервисов, затем только собственные cert/root-chain и PEM files. Исходные certificate/file коллекции и полный нормализованный export совпали. ACME settings восстановлены полностью, включая accountPrivateKey/updatedAt; own terminal job удалён, чтобы не оставлять managed renewal target. Историческое событие теста в журнале приложения сохраняется. После фактического COMMIT начальная проверка Date vs JSON string дала assertion; исправлена только JSON-нормализация и повторное read-only сравнение, native/SQL операции не повторялись. Приватный baseline удалён. [Native](ux-ui/acceptance/acme250-native.json).
Application TXT cleanup подтверждён GET0; A-sync создал единственную собственную A с content104/proxied=false, она удалена по exact name/type/content/ID. Final FQDN/challenge records0. Остальные DNS записи/zone settings не менялись. [Cloudflare](ux-ui/acceptance/acme250-cloudflare.json). Post-cleanup app settings tokenConfigured=false, own job404/certificate absent, оба CHR certificate read доступны. Выданный сертификат не объявляется отозванным у CA; запись о выпуске остаётся, native экземпляры/ключевые файлы удалены. Все временные credential файлы блока удалены после проверки.
Runtime backend ux-containers249/frontend ux-containers248 unchanged; source changes только manual acceptance helper/документация, не production код. [Процедура](../deploy/TEST-ACME.md), helper acme-live-issue.mjs syntax/ESLint passed. Backend-профили и E2E не повторялись для документального блока:25 профилей249 и29 E2E248 уже проверены в своих границах. Дополнительный local locator/copy helper ремонт не считается новым live сценарием.
Следующий251 — явное пояснение последствий в форме: текущий issuer всегда включает www-ssl/api-ssl и синхронизирует DNS A, а экран говорит лишь об импорте/trust-store. Изменить copy существующих шагов, сохранив сетевую логику; профильные UI проверки/build/deploy. Automatic renewal, CA revocation, remote release publishing/multi-instance/WAN и остальные обязательные варианты матрицы ещё не приняты этим выпуском.
## 12.5.249 — достоверное legacy чтение контейнеров и общая backend-регрессия (2026-10-14)
Аудит выявил: GET выбранного сервера обходил enabled gate; legacy mapper считал отсутствие status остановкой, memory-high — фактической памятью, скрывал ошибки загрузки пустым массивом. Прямой GET теперь даёт409 для выключенного и404 для отсутствующего сервера до dispatch; прямой service/read тоже не создаёт RouterOS клиент для disabled, aggregate исключает disabled до reader factory. Ошибки/частичные ответы legacy GET дают502; unsupported сохраняет прежний legacy [] для совместимости, подробное availability предоставляется /api/containers/state. ID разбирается общим строгим parseDbServerId, без принятия префикса1abc.
Legacy service переиспользует канонический readContainerServerState вместо второго скрывающего ошибки опроса. Общий mapper учитывает running/stopped/error flags и unknown, envlists/mountlists и современные list aliases, nullable startOnBoot, memory-current с известным нулём; memory-high и имя контейнера не подменяют расход памяти и неизвестный образ. Десятичный/неверный CPU не обрезается parseInt. Изменение legacy status включает unknown; потребители нового UI уже используют этот статус. В репозитории frontend не обращается к старым GET.
test:containers дополнен legacy service profile и включён в общий test:all/CI. Настоящий loopback HTTP-транспорт без DB: valid/native running;401/malformed/dependency error не становятся empty; unsupported сохраняет []. Disabled makes0 requests; invalid ID returnsnull до DB. HTTP проверяет selected disabled/missing без read dispatch и502 вместо fake success. Direct state иaggregate disabled guards проверены отдельно. Первый sandbox запуск loopback получил EACCES и не принят; elevated профиль прошёл. Contracts/backend build и ESLint passed; Docker Node22 профиль тоже exit0.
Из-за изменения общей основы выполнены все25 профилей test:all на собственной ограниченной PostgreSQL БД/роли, без production DSN. Все exit0; сумма378124ms (6мин18с), это не число индивидуальных assertions. Три специальные SQL-ветки пропущены из-за отдельных env/namespace: Monthly149, IPv6 UDP/worker144, network-disabled-server152 (MMAPP_OWN_TEST_DB). Это известные явные ограничения текущего объединённого запуска, не приёмка этих веток. Остальные conditional skip строки сохраняются числом в протоколе, не превращаются в live доказательства. Собственная БД/роль/контейнер удалены, отсутствие проверено. [Регрессия](ux-ui/acceptance/containers249-regression.json).
Backend ux-containers249 собран/развёрнут и healthy; frontend ux-containers248 сохранён, PostgreSQL/Portal не пересоздавались. Backend source524/compiled1080 совпали без missing/different; версия1.0.0-test.backup249 — метка лабораторной сборки, неGitSHA. [Deployment](ux-ui/acceptance/containers249-deployment.json). Настоящий Portal/read UI1440/390: typed state200 показывает оба CHR unsupported после удаления пакета248, legacy global/selected GET200[] совместимы, overflow/JS errors0, non-auth API writes0. Никаких новых native объектов/перезагрузок/изменений паролей. [Live UI](ux-ui/acceptance/containers249-live-ui.json). ReUI audit checklist для alert-dialog прочитан: используются существующие props/copy; vendored компоненты/стили/тайминги не менялись.
Пользователь предоставил стенд ACME: pngs.top и разрешённые поддомены с префиксом mmt*. Read-only Cloudflare token verify и exact zone query вернули200/success; token/zone active, account matched. Токен/почта/account ID сохранены только в ignored private fixture, в Git не добавляются. Следующий250 — issuance/импорт/результат через реальный API/UI с очисткой собственных DNS/certificate/file объектов и возвратом исходных настроек. Пока реальная выдача не выполнена. Обнаружено, что текущий issue автоматически назначает сертификат www-ssl/api-ssl; перед применением подготовлен private baseline этих сервисов/сертификатов/файлов/settings. Remote publishing, multi-instance/WAN и прочие ограничения матрицы сохраняются.
## 12.5.248 — подтверждённое удаление контейнера через UI (2026-10-14)
В 247 UI отправлял DELETE работающего контейнера и получал 502. Теперь dialog использует последнее состояние выбранного serverId/rosId: удалить можно только stopped; для running/unknown/error показана инструкция остановки и обновления. Backend независимо читает native список и проверяет однозначное stopped, не останавливает контейнер скрыто. Отсутствующий target или неподходящее состояние дают 409 без DELETE; после DELETE каталог читается снова, сохранённый target/сбой/некорректный ответ не становятся ok=true. Выключенный сервер отклоняется до команды. Каталоги/файлы не удаляются отдельными командами приложения; поведение native remove не подменяется обещанием очистки.
Проверки: test:containers включает новый removal-профиль в общий test:all/CI; проверены native running/unknown/conflicting/transient, отсутствие target, неверный каталог, read failure, удаление только выбранного stopped, повтор без удаления другого target и сбой подтверждения. HTTP проверяет disabled/missing server без dispatch, 409 conflict, 502 uncertainty, ok=true и существующий write-permission contract. Это изолированные service/HTTP проверки, не отдельный live RBAC сценарий. Backend/contracts build, production frontend build и профильный ESLint прошли. 29 уникальных E2E containers-data/operations прошли за 58.8 секунды; ранее в 247 webServer не стартовал, нынешний elevated запуск стартовал успешно, точная причина прошлого таймаута не доказана. В E2E обычный HTTP-путь с тестовыми ответами, не встроенные демонстрационные данные. Полная регрессия не повторялась.
Пользователь отдельно разрешил повторную установку того же проверенного container NPK из источника 246 и две перезагрузки. Native baseline снят до передачи. Создан собственный mmc248-busybox с veth mmc248-e57b223b и pinned BusyBox digest из 247; core/option/version/device-mode/пароли/registry credentials/bridge/IP/NAT не менялись. Настоящий Portal без моков: UI start200 и native running; dialog1440/390 блокирует удаление и прямой API409; UI stop200 и native stopped; UI remove200/ok=true, строка отсутствует; повторный API409 «уже отсутствует». JS ошибок нет. При изменении viewport закрывающееся меню временно давало scrollWidth780 при width390; после штатной анимации ширина390. Helper ждёт стабилизации, ReUI styles/timings не менялись. Изначальный неверный heading locator исправлен на существующий breadcrumb. [Live UI](ux-ui/acceptance/containers248-live-ui.json).
Собственные контейнер/veth/image/root/NPK отсутствуют. Container package удалён второй однократной подтверждённой перезагрузкой; исходные installed routeros/option7.24.5 и полный нормализованный export совпали. Автоматический timezone вернулся к исходному Europe/Warsaw после reboot; helper ждёт полного совпадения без исключения clock и не печатает приватный export при ошибке. Двойная запись create в native stages означает дополнительное read-only получение имени существующего объекта, не второе создание. Оба CHR доступны; приватные baseline удалены. SFTP с прежним паролем и прямой workstation REST200 подтвердились: один вход прервался auth timeout до завершения аутентификации, поэтому не означает неверный пароль. Причина прежнего401 не доказана. [Native/cleanup](ux-ui/acceptance/containers248-native.json).
Backend и frontend ux-containers248 собраны/развёрнуты, backend healthy; frontend не имеет Docker healthcheck. Замороженные build inputs: backend523/frontend527 совпали, compiled backend1080 без missing/different. Поздние acceptance-only helper правки не входят в этот source audit; runtime TS/TSX соответствуют сборке. Изменены только два image tag в приватном .env; PostgreSQL/Portal не пересоздавались. Первая frontend сборка предшествовала уточнению текста о дополнительной очистке, выполнена финальная сборка из уточнённого context. [Deployment](ux-ui/acceptance/containers248-deployment.json). Подход с native флагами и envlists согласуется с [RouterOS manual](https://manual.mikrotik.com/docs/containers/); требование stopped — явная политика безопасного удаления приложения.
Контейнерная приёмка start/stop/restart/remove закрыта в этих границах; работающий контейнер нужно сначала остановить. Следующий 249 — legacy GET контейнеров: проверить, что прямое чтение выбранного выключенного сервера не опрашивает RouterOS, затем согласовать статусы старого DTO с native flags. ACME Cloudflare token/test-domain, удалённая публикация Gitea, multi-instance/WAN/client OS и остальные ограничения матрицы остаются открытыми. Сам тестовый пакет снова удалён, новое применение без согласия не планируется.
## 12.5.247 — фактические состояния и жизненный цикл контейнера (2026-10-14)
Пользователь разрешил конкретный пакет 246 и две перезагрузки. На 104.165.244.7 установлен только container-7.24.5.npk из указанного источника mikrotik.ltd → MikroTikPatch, с ранее проверенным SHA256. Core/option/python/keygen/patch scripts не применялись; версия RouterOS осталась 7.24.5. Образ BusyBox 1.37.0 linux/amd64 закреплён digest busybox@sha256:bdf57e528e45e4433820e045b29b45978255a1c9e38353532d90a01445013f82e. Созданы только собственные контейнер mmc247-busybox, veth mmc247-39da5c21 и каталог; bridge, IP, NAT, маршруты и глобальные registry credentials не изменялись.
Реальный REST отдаёт stopped/running флаги вместо status и envlists вместо envlist. Общая обработка теперь поддерживает эти поля, сохраняет unknown при переходе, неверном значении или противоречии; отсутствие статуса не считается stopped. Для envlists проверена backend-фикстура, отдельное live создание envlist не выполнялось. test:containers (service + HTTP), сборка contracts/backend и профильный ESLint прошли. Добавлены девять проверок native флагов и проверка alias. E2E containers-data/containers-operations не стартовали: тестовый webServer :3100 превысил 120 секунд; успешной E2E приёмки этот блок не заявляет.
Через настоящий Portal без моков в UI 1440×1000 получены start 200 → stop 200 → start 200 → restart 200 с ok=true и проверкой rosId. Native состояния независимо подтвердили running → stopped → running. Удаление работающего контейнера через UI вернуло 502/ok=false; причина не доказана, сценарий НЕ принят. Ошибок JavaScript нет. [UI-протокол](ux-ui/acceptance/containers247-live-ui.json).
Очистка выполнена native API: собственный контейнер остановлен и удалён, veth/image/root/NPK отсутствуют. Container package удалён второй однократной перезагрузкой; оба reboot получили подтверждение. Доступные, но не установленные пакеты RouterOS имеют пустую version — при сравнении учитываются только установленные. После reboot автоматическое определение часового пояса временно отличалось от исходного, затем вернулось к Europe/Warsaw. Попытка PATCH singleton clock получила 400 и ничего не изменила; manual clock restore не применён. Итоговый нормализованный export и исходные installed routeros/option 7.24.5 совпали. Приватный baseline удалён. [Native-проверка и очистка](ux-ui/acceptance/containers247-native.json).
Backend ux-containers247 развёрнут и healthy; frontend ux-backups237 сохранён. При сборке совпали 521 исходный файл и 1076 compiled файлов; последующие исправления только CLI helper для cleanup не входят в замороженный source audit. [Deployment](ux-ui/acceptance/containers247-deployment.json). Агент не менял passwords/device-mode/keys. С Debian REST работает после обеих перезагрузок; прямой REST с рабочего компьютера возвращал 401, SSH с прежним паролем сначала прошёл, повторный вход не прошёл. Причина расхождения неизвестна; глобальную исправность SSH/пароля не заявляем. Контрольный CHR 194.226.121.150 доступен.
Следующий блок 248: понятная и безопасная обработка удаления работающего контейнера, приёмка удаления остановленного через UI и повторного действия, затем диагностика запуска E2E и корреляция авторизации без изменения паролей. RBAC/повторное действие в live 247 не проверены. ACME, внешняя публикация релизов и другие ранее записанные ограничения остаются открытыми. Полная регрессия не повторялась.
## 12.5.246 — пакет контейнеров из указанного пользователем источника (2026-10-14)
User отклонил official244 с причиной«нужно использовать пакеты с сайтаmikrotik.ltd». Перезагрузки/installation не выполнялись. Прочитан [сайт](https://mikrotik.ltd/) и его ссылка [MikroTikPatch](https://github.com/elseif/MikroTikPatch); inline download template указывает GitHub releases. Зафиксирован [точный7.24.5/x86 archive](https://github.com/elseif/MikroTikPatch/releases/download/7.24.5/all_packages-x86-7.24.5.zip), size29,675,363 иSHA256b293b380e680aece7fd0895889fd77b01133ea5ed6d89b32fb6d53af1936acc9 совпали сGitHub API asset digest/size. Извлечён толькоcontainer-7.24.5.npk1,163,409bytes/SHA25670f1c5281a3d37b347e9a83c81d9daaac511357fe26cfbac11321e2dc1407259. Он отличаетсяотофициального244; подменаартефактаоднимfilenameнепринимается.
Архив/NPK толькоignored tmp, вGit не публикуются и наCHRнепередавались. Option/main/python packages иpatch/keygen/shell scripts не выбраны/не выполнялись; license/device-mode/password/version/keys не изменялись. Наличиеoption наCHR подтверждено243; происхождение установленногоcore/optionпоhash не сверялось и не объявляетсядоказанным. Совместимость/подписьновогоNPK ещё должнапроверяться самимтекущимRouterOS, беззаменыключей.
[Процедура](../deploy/TEST-CONTAINERS.md) обновлена: источникомприменениябудетэтот246artifact, официальный244помеченrejectedhistory. Target104.165.244.7/control194.226.121.150/двеplannedcontrolled перезагрузки/ownlifecycle/cleanup остаются. Посколькупредыдущеесогласиепользовательнедал, installation/rebootновогокомплекта ещёсогласуются. Positivecontainerlifecycle непринятподготовкой. [Протокол](ux-ui/acceptance/containers246-requested-source.json).
Runtimebackend ux-geoip242/frontend ux-backups237 сохранены, nativewrites/reboots0. Следующий247 — реальнаяконтейнернаяприёмкапослесогласия; ожиданиеответанеявляетсяразрешением. Другиеобязательныевнешниесценариитребуютграницвыпуска/конкретныхдоступов.
## 12.5.245 — новый GeoIP HTTP тест входит в общий CI-профиль (2026-10-14)
В backend/package.json test:traffic-flow добавленgeoip-download.test.ts передcollector тестом. test:all вызываетэтотprofile один раз, backend/scripts/test.mjs выполняетего черезnpm test; Gitea backend-test вызываетnpm run test --prefix backend. Новой зависимости и отдельного дублирующего test:geoip вtest:all нет. test:geoip остаётся удобной профильной командой. Это только dev/test command metadata, compiledruntime242/API/UI не изменяются; production Docker не пересобирался ради списка тестов, при следующей сборке метаданные попадутвобраз.
Local24 scripts прошли; SQLbranches безlocal PG честноskipped. Source acceptance image на code242/cache build с текущим package245 command overlay выполнил тотжеprofile в собственной PostgreSQL ролиNOSUPERUSER/NOCREATEDB/NOCREATEROLE/NOBYPASSRLS:exit0/57,066ms/newHTTPtest observedonce. Обычные SQLветки исполнились; ровно2 специализированныеbranches monthly/IPv6 требуютдругих отдельноименованныхown DB иskipped. Ониневыдаются за новуюприёмку; предыдущие222 протоколы остаютсяисторическими. ВременныеDB/role/container удалены и отсутствиеDB/roleподтверждено.
Первыйharness запуск не нашёлpg из/checks; исправлен createRequire(/app/backend/package.json), DB/role очищены. Затем guardharness ошибочно запрещалобаизвестныхoptional skips при успешномnpm exit0; скорректирован точныйallowlist, финальныйrun57,066ms passed. Повторныепроверки не суммируются. stdoutтестов сохранёнprivately, publicJSON содержитлишьscope/duration/skips/cleanup. [Протокол](ux-ui/acceptance/traffic-flow245.json); helperstraffic-flow-regression.mjs/run-traffic-flow-regression.sh проходятnode --check.
Userотклонилприменениеофициальногоcontainer244 из-заисточника иуказалmikrotik.ltd. ЭтотNPKнеприменяется, upload/reboot0. Следующий246 фиксируетзапрошенный7.24.5/x86artifact/source/digest иобновлённуюпроцедуру; конкретное согласие на installation/reboot ещё не получено. Productionbackend ux-geoip242/frontend ux-backups237 неизменны.
## 12.5.244 — конкретный пакет и процедура контейнерной приёмки (2026-10-14)
Для104.165.244.7 подготовлен официальный [all_packages-x867.24.5](https://download.mikrotik.com/routeros/7.24.5/all_packages-x86-7.24.5.zip), HEAD/GET200,10,476,996bytes. Архив прочитан как данные, извлечён толькоcontainer-7.24.5.npk1,175,697bytes. SHA256 zip6acfd80b3f6edfd23cea14bfcdbbb183a6258acb3aedb3d7b0a23f60a19e51c6, NPK7515c52499bd11b063517c7b48a6553519976098040d9dec67f6bf087876a3c9. Это локально вычисленные отпечаткиHTTPSvendor payload, не отдельнаяvendor checksum; native signature/installation ещё не проверены. Файлы толькоignored tmp, вGitбинарники не добавлены. SSH22 reachable, вход/передача NPK не выполнялись.
[Процедура](../deploy/TEST-CONTAINERS.md) задаёт target104/control194, private baseline, бинарную передачу с pinned SSH key, single reboot/no retry onunknownack, native7.24.5/package/endpoint proof, own pinned container/veth/bridge lifecycle через Portal, cleanup и возврат исходныхpackages вторымreboot. Device-mode ужеcontainer=true и не меняется; пароли/version/reset не меняются. Это конкретная подготовка, не разрешение/успех установки: upload/install/reboot0. Применение ждёт отдельного согласия пользователя, поскольку меняет пакеты и временно прерывает доступ к CHR.
Протокол: [artifact preparation](ux-ui/acceptance/containers244-preparation.json). Positive containerstart/stop/restart/remove остаётся открытым. Пока ожидается согласие —245 проверяет независимыйCI regression profile: новый streaming HTTP GeoIP тест242 должен выполняться не только отдельной командойtest:geoip, но и общимtest:all/CI путём без дублей.
## 12.5.243 — реальные предпосылки контейнеров, ACME и релизов (2026-10-14)
Десять direct read-only RouterOS запросов:system/package/resource/device-mode/disk/container ×2CHR. Оба доступны7.24.5 stable/x86_64, installed routeros иoption, container feature=true/flagged=false, freeHDD около10GiB/freeRAM около0.8GiB. /container400 на обоих; пакет с именемcontainer не обнаружен. Публичный отчёт сохраняет status/error SHA256, неcredentials/полные error bodies. Приложение GET containers/state200 классифицирует обаunsupported. Это доступность текущего набора функций, а не доказательство отсутствия контейнеров по пустому snapshot или успешного lifecycle.
Vendor [Container](https://help.mikrotik.com/docs/spaces/ROS/pages/84901929/Container) и [Packages](https://help.mikrotik.com/docs/spaces/ROS/pages/40992872/Packages) указывают требуемый container package. Для positive lifecycle нужны проверенный пакет текущей версии и контролируемая подготовка CHR; установка/перезапуск не выполнены. Новые manual URLs были недоступны web tool; использованы доступные официальные vendor pages, без вывода о совместимости конкретного будущего image по памяти.
ACME public settings:tokenConfigured=false/defaultZoneConfigured=false; Let’s Encrypt production directory GET200 с ожидаемыми endpoints. Это неDNS challenge, issuance, renew или deployment сертификата. Нужны явный test-domain/Cloudflare scoped token/право на временныеTXT и staging ACME. Секреты и зоны не выдумывались, DNS/account/certificate writes0.
Gitea — pipeline.gitea/workflows/docker.yml с push main/workflow_dispatch, registry uploads/releases/webhook; соответствующего backend polling job нет. По поручениюno push публикация не запускалась. compute-release.mjs отработал в ignored tmp output, candidate1.47.7/schema valid/current-candidate notes coherent, tagsCreated/pushes/GiteaAPIwrites/registryUploads0. Candidate не является выпущенной версией и не меняетpackage.json/publicmanifest. Отдельно real Portal UIcontainers/releases1440/320 passed:unsupported states, labversion1.0.0-test.backups237, globaloverflow/pageerrors0/non-auth APIwrites0. Первичный UI счётчик включал2 login POST; исправлено разделение auth и business operations, не приложение.
node --check availability helper passed; runtime code/images unchanged, профильная регрессия не повторялась без оснований. Два собственных сообщения локальных коммитов239/240 приведены к русскому тексту; author/date/trees/workspace dirty files сохранены, downstream commit IDs изменились, push0.
Протоколы: [native/ACME availability](ux-ui/acceptance/external-jobs243-availability.json), [live UI](ux-ui/acceptance/external-jobs243-live-ui.json), [release dry-run](ux-ui/acceptance/release243-dry-run.json). Следующий244 готовит конкретный vendor package/artifact для контейнерного lifecycle; применение и перезапуск согласовать отдельно после подготовки. REST root cause, multi-instance, clientOS/WAN/publicIPv6 и границы выпуска остаются по матрице.
## 12.5.242 — реальный GeoIP mirror job и честное состояние cache (2026-10-14)
В collector обнаруженыfalse-success304 при отсутствующей локальной базе (старый тест прямо принимал это), race до acquisition lock из-за await settings и освобождение timeout после headers вместо body. Теперь gate захватывается до первогоawait; concurrent force409/backgroundskip. Conditional ETag отправляется только после проверки локальной MMDB; missing/corrupt cache требует200 полного файла.304 без validated cache — ошибка, неskippedUnchanged. Partial failures сохраняют дату последнего успешного update и предыдущий файл, добавляя lastError. Новая downloadGeoipDatabase держит120s deadline через streaming body, ограничивает declared/chunked file64MiB и закрывает непригодное тело. Базы проходят existing Country/ASN validation до atomic swap; формат/layout ReUI не менялись.
Local test:geoip прошёл: реальный HTTP healthy/304, stalls after headers→AbortError, declared/chunked oversize→reject, recovery; collector invalid/cache/concurrent gates; JWT reader cannotmutate/writer/admin allowed. Backend/contracts build и scoped ESLint прошли.15 unique GeoIP settings/responsive/data-collection E2E прошли25.2s; ошибочная первоначальная команда с несуществующимиspec далаNo tests found и не считалась проверкой. Три автоматически перегенерированных старыхGeoIP PNG возвращены к исходным байтам; чужие GRE/VXLAN changes сохранены.
Final production source516/compiled1072 matched. В own PostgreSQL/files scope выполнены7 укрупнённых сценариев: actual mirror download обеих MMDB12,380,575bytes, Google8.8.8.8→US/ASN15169, actual conditional304/hash unchanged иconcurrent409, missing-country refetch безETag, corrupt-country refetch, controlled invalid MMDB200/uncached304 сохраняютlastSuccessAt, actual recovery иdisabled background0fetch.12 реальных mirror GET200/304; negative country responses явно контролируемые и не выдаются за native WAN failure. Валидация MMDB не подменялась. Temporary DB/role/container/files удалены, CHRcontacts0/mainDBwrites0 в этом scope. Предварительная сборка с иным downloader отдельно проверялась; повтор не прибавлен кunique приёмке.
Развёрнут только backend ux-geoip242; frontend ux-backups237 image/container ID неизменны. Backendhealthy; real Portal/live GET GeoIP200 иUI1440/320, обе main bases alreadyloaded, globaloverflow0/pageerrors0, POSTupdate0. Main GeoIP job через UI не запускался; реальная загрузка доказана в isolated scope, а не заявлена обновлением данных приложения. Откатbackend ux-backups237 и приватная прежняя.env сохранены на сервере.
Протоколы: [mirror/SQL](ux-ui/acceptance/geoip-mirror242.json), [deployment](ux-ui/acceptance/geoip242-deployment.json), [live read UI](ux-ui/acceptance/geoip242-live-ui.json). MirrorP3TERX — фактический источник collector без account key. Прямой licensed MaxMind download не реализован текущим collector и не принят этим тестом; актуальность/геолокационная точность всех IP, publicIPv6 geography, multi-process lock, physical WAN failures отдельно.
| Референс | Схема состояний |
| --- | --- |
| [ReUI Settings16](https://reui.io/preview/base/settings-16?ref=mcp) | validated cache → conditional304; missing/corrupt → full200 → validate → swap; error → last-good + last-success + warning |
Следующий243 — read-only availability audit контейнерных/ACME/release jobs на текущем стенде и согласованная матрица реальных remaining dependencies. Не выдумывать Cloudflare/registry credentials и не обновлять RouterOS без отдельной команды.
## 12.5.241 — тысяча бэкапов со смешанными состояниями файлов (2026-10-14)
Изменение237 проверено на1000 обычных live-path HTTP DTO (199062bytes), по250 local/missing,both/missing,local/unknown,local/available. Два сценария1440/320 прошли25.2s. UI сохраняет pagination50 строк:DOM2477/2239, ready1203/806ms в dev fixture окружении. Это измерение конкретного запуска, не production SLA/сетевой latency и не доказательство скорости filesystem API1000 файлов.
Глобальный поиск находит997–999 вне первой страницы и показывает правильные действия:missing local disabled download/restore иrecord-only dialog;both missing допускаетS3;unknown не превращается вmissing. При503 last-good row иdisabled state сохранены; после200 ошибка снята. Страница2/row51 сохранилась послеrefresh. Keyboard Enter/cancel возвращает focus на правильный delete trigger, global overflow отсутствует. Scoped axe по текущимWCAG tags:0violations; UI writes0. Эта проверка не заменяет screen-reader/manual WCAG приёмку.
Новый large-backups-file-state.spec.ts и scoped ESLint прошли. Existing PNG/screens не перезаписывались; runtime код/образы не изменялись. [ПК metrics](ux-ui/acceptance/backups241-large-1440.json), [320px metrics](ux-ui/acceptance/backups241-large-320.json). Прежняя большая таблица с иными сценариями не считалась повторно новой приёмкой.
Следующий242 — доступный GeoIP mirror job в own SQL/file scope. В коде есть публичный mirror без licence key; actual paid MaxMind, Cloudflare DNS ACME, registry/container/Gitea jobs требуют отдельного контроля и прав. Остальные внешние группы остаются в матрице.
## 12.5.240 — retention на реальном S3 и частичный отказ удаления (2026-10-14)
В production image ux-backups237 запущен compiled pruneBackupsForServer/delete/read service в отдельной PostgreSQL базе с собственным NOSUPERUSER/NOCREATEDB/NOCREATEROLE/NOBYPASSRLS пользователем. Основной каталог/настройки не использовались. Seed8 harmless copies на3 собственных fixture servers:5 точных объектов в новом UUID S3 prefix и5 local files (both учитываются в обеих группах). RouterOS не опрашивался и не применялся; cfg bucket virtual-hosted Selectel, настройки бакета не менялись.
При keepCount2 первого сервера и намеренно неправильном S3 secret local old copy удалена первой, затем remote delete отказал:BackupPruneError.pruned=1. Failed row/object сохранены, две новые копии и остальные servers неизменны. После возвращения верного secret retry удалил1, следующий prune вернул0. Второй сервер keepCount1 удалил2 старых copies, сохранилlatest both; третий unselected manual local copy не затронут. Все4 retained files прочитаны compiled service с точными исходными байтами/hash; remote-only localFileStatus=not-stored, остальныеavailable.
Пять укрупнённых SQL/S3 проверок прошли. Cleanup удалил только planned keys и их5 versions/2delete markers (итого7), final listing0, own catalog0. Wrapper удалил temporary DB/role/container и подтвердил отсутствие DB/role. Временные ключевые файлы workstation/Debian удалены; секреты в публичном JSON отсутствуют. node --check passed; runtime источники/образы не менялись, повторной полной регрессии нет.
Протокол: [retention240](ux-ui/acceptance/s3-retention240.json). Helpers:s3-backup-retention.mjs/run-s3-backup-retention.sh. Это реальное хранилище с контролируемыми SQL/file fixtures, не native scheduler production collection и не физический lost ACK; продолжительная работа, version lifecycle policy, миграция buckets и multiple backend/writers остаются отдельно. Ошибка S3 signature намеренно введена, пароли CHR не менялись.
Следующий241 проверяет1000 строк нового missing/unknown/both UX237:поиск, pagination, last-good и mobile controls. Затем уточнить доступные external jobs и границы выпуска; семь общих групп не превращать в обещание фиксированного числа проверок.
## 12.5.239 — восстановление из Selectel S3 через реальный интерфейс (2026-10-14)
Пользователь явно разрешил передачу тестовых S3 access/secret keys на Debian после отказа automatic approval review. Ключи находились только в приватных ignored/0600 файлах и временных настройках приложения. Перед изменением сохранены raw SQL storage/schedule и10 исходных backup rows приватно. Расписание временно остановлено, virtual-hosted S3 сохранён и проверен через live UI с реальным Portal1.3.1/JWT. Использован новый UUID prefix и ровно один собственный95-byte .rsc: добавление bridge mm-ui239-* с comment=mm-ui239 без портов/адресов. Это специально ограниченный скрипт, не native full export и не полное восстановление CHR.
Собственный объект записан и прочитан SDK, затем только его строка добавлена в каталог. Через обычный UI скачан файл с совпавшими байтами/SHA256; restore вернул HTTP200 с нужными backupId/serverId. Direct RouterOS на194.226.121.150 подтвердил ровно один bridge, comment, отсутствие bridge ports/IP addresses и неизменность исходных bridges. Через UI удалена только собственная строка/объект:HTTP204, строка исчезла; pageerrors0. Восстановление на втором CHR и полный config restore этим блоком не проверялись.
Cleanup удалил свой bridge и загруженный .rsc, все версии/delete markers только точного ключа UUID prefix, сверил исходные10 SQL-строк и оба settings rows целиком. Первая попытка остановилась уже после удаления объектов: проверочный SQL-column guard не допускал цифру3 в s3_*; исправлен allowlist имён, повторная очистка прошла. Final-attempt removed0 означает, что версии удалены первой попыткой; конечный listing0 подтверждён. Общее число удалённых версий первой попытки не записано и не выдумывается. Bucket settings, чужие объекты и пароли не менялись. Приватный SQL-снимок и временные ключевые файлы workstation/Debian удалены; production-код и образы ux-backups237 не менялись.
Acceptance helpers s3-ui-limited-restore.mjs/.cjs проходят node --check. [UI-протокол](ux-ui/acceptance/s3-ui239-browser.json) и [native/cleanup](ux-ui/acceptance/s3-ui239-native.json) фиксируют точные границы. Общая регрессия не повторялась: новых runtime изменений нет.
| Референс | Схема принятого сценария |
| --- | --- |
| [ReUI Data Grid Filtering2](https://reui.io/preview/base/data-grid-filtering-2?ref=mcp), [Sheet8](https://reui.io/preview/base/sheet-8?ref=mcp) | Собственный объект S3 → строка истории → download → подтверждение restore → native bridge → delete → cleanup и исходные настройки |
Следующий240 — retention в изолированном scope без удаления существующего каталога. Полная конфигурация, массовые экспорты на реальном CHR, миграция buckets, multi-instance, другие ОС/WAN/jobs остаются отдельной приёмкой.
## 12.5.238 — REST за пределами десятиминутного окна (2026-10-14)
Read-only workstation-наблюдение длилось763.844s (07:01:21.663Z–07:14:05.507Z):26 циклов с целевым периодом30s, шесть endpoints × два CHR × compiled MikrotikClient/fetch Connection:close. 624 samples и24 diagnostics, все HTTP200; повторные запросы при отказе не выполнялись, потому что отказов не было. Учётные данные передавались из приватного process env, временный env-файл удалён; Basic/JWT/пароли в публичный отчёт не включены. RouterOS configurationWrites0/passwordChanges0.
На обоих CHR7.24.5 до/после было по2 записи via=api для configured user; SHA256 от id/when изменились. Retained via=rest-api rows844→846 и320→322. Наблюдалась смена записей сессий в окне более10 минут без отказов. Это не доказательство точного cached-login механизма7.24.5 и не контроль firmware: vendor docs уже описывают7.25. Найденный236 vendor fix удаления inactive REST sessions остаётся гипотезой; причины прежних401/500 не установлены. Большое число сохранённых rows нельзя приравнивать к concurrent www sessions или доказанному исчерпанию ресурса.
Acceptance helper chr-rest-correlated.mjs теперь принимает ограниченные cycles1–32, period1–60s и maxMs10–960s, сохраняя прежние defaults8/12s. Deadline проверяется между циклами, запросы имеют timeout6s; failure diagnostics/финальное чтение могут выйти за целевую длительность. Это не жёсткий end-to-end deadline. Сохранён именно протестированный helper; node --check passed. Production-код и Docker образы после237 не менялись, полная регрессия не повторялась без основания.
Протокол: [REST763.844s](ux-ui/acceptance/chr238-rest-renewal.json). Следующий239 — реальный S3 restore через UI только собственного bridge без портов/адресов, затем retention в отдельном own scope. REST остаётся открытым для корреляции воспроизведённого сбоя/согласованного сравнения firmware; обновление RouterOS не выполнялось.
## 12.5.237 — отсутствующие файлы бэкапов и безопасное удаление записи (2026-10-14)
API добавляет необязательный localFileStatus: available/missing/unknown/not-stored. Локальные проверки ограничены восемью workers и не опрашивают S3. Ошибка доступа/каталог/некорректный путь не превращаются в «файл отсутствует». Для local/missing существующая таблица ReUI показывает «Нет файла», описание и блокирует скачивание/restore. Для both/missing остаётся запрос S3; состояние unknown и старый DTO не блокируются по догадке. Проверка наличия файла перед импортом остаётся обязательной на backend.
Подтверждение удаления отсутствующего локального файла обещает только удаление строки истории. UI отправляет recordOnly=true и требует HTTP204 с X-Backup-Delete-Mode:record-only. Backend повторно проверяет missing/local/no-S3; появившийся файл даёт409 с сохранением файла и каталога. В этом режиме unlink никогда не вызывается, включая внешнее появление файла после проверки. Общий gate обеспечивает координацию одного процесса; несколько writers/instances остаются отдельной приёмкой.
Contracts/backend build, TypeScript и scoped ESLint прошли. test:backups прошёл после разрешённого запуска локальных HTTP-фикстур: первоначальный sandbox EACCES127.0.0.1 не был ошибкой приложения. E2E:37 исходных сценариев file/data/operations/storage и2 новых record-only receipt; после поздней защиты повторены20 затронутых сценариев. Итого39 уникальных, повторные запуски не прибавлены. Production owned SQL/API:5 статусов, download200/404, restore400/not-applied/nativeRequests0, сохранение каталога, recreated-file409 и record-only204/header. Собственные DB/role/container удалены; S3/CHR из этой SQL-фикстуры не опрашивались.
Production backend/frontend ux-backups237 собраны и развёрнуты:508 backend source/1068 compiled и529 frontend source совпали с локальными манифестами. Реальный Portal login и UI1440/390 показали10 существующих local/missing записей, disabled download/restore, корректное описание удаления (только открытие и отмена), pageerrors0/backupwrites0/globaloverflow0. Исходные10 SQL-строк сравнивались целиком до/после; ни одна не удалена. Отсутствующие старые файлы не восстановлены и не объявлены доступными. Приватный SQL-снимок удалён после сверки. Откат: backend ux-backup234/frontend ux-routing218 сохранены.
Доказательства: [SQL/API](ux-ui/acceptance/backup-availability237.json), [live UI](ux-ui/acceptance/backups237-live-ui.json), [production сверка](ux-ui/acceptance/backups237-deployment.json). Снимки: [ПК](ux-ui/screens/backups237-missing-desktop.png), [телефон](ux-ui/screens/backups237-missing-mobile.png).
| Референс | Схема доработки |
| --- | --- |
| [ReUI Data Grid Filtering2](https://reui.io/preview/base/data-grid-filtering-2?ref=mcp) | История → статус файла → доступные действия → подтверждённый результат; missing → только запись → проверка409/receipt204 |
Следующий238 фиксирует уже выполненное длительное REST-наблюдение. Затем — S3 restore через реальный UI в пределах собственного bridge и retention. Полная конфигурация CHR, arbitrary PKI, другие ОС, public IPv6, multi-instance и внешние jobs не приняты этим блоком.
## Актуальная точка продолжения — 2026-10-14
Этапы0–11 завершены в локальных границах журнала. История выполненных внешних блоков и доказательства сохранены в [журнале](ux-ui-stage-12.md) и [протоколе](ux-ui-external-acceptance.md). Реальная Telegram доставка201 и Portal SSO195–199 приняты в описанных границах. Multi-instance, внешние аккаунты/клиентские ОС и оставшиеся профильные сетевые ограничения открыты.
По поручению2026-10-09 работать укрупнёнными разделами, последовательно на текущей модели: карта возможностей → исправления → профильные тесты → build/deploy → собственные реальные сценарии → cleanup → один локальный коммит без push. Проверять квоту после завершённого раздела; незавершённые проверки явно переносить в журнал.
## Остаток приёмки по группам — 2026-10-14
Этапы0–11 завершены в локальных границах. Этап12.5 открыт: ниже7 групп проверок, а не7 обещанных окон или точное число тестов. Детали и исторические ограничения сохраняются в [матрице](ux-ui-remaining-acceptance.md).
| Группа | Что уже подтверждено | Оставшийся результат / что требуется |
| --- | --- | --- |
| REST и достоверность данных | Ошибки OSPF/BFD/BGP/GRE/WAN215–221 явные; latest API smoke222 прошёл | Причина единичных native401/500 неизвестна. Короткое независимое наблюдение возможно сейчас; оно не даст SLA |
| Клиентские ОС и внешняя сеть | CHR↔CHR/Linux, private IPv4/ULA и synthetic IPv6/IPFIX; Android full-tunnel/reconnect227 подтверждены пользователем | Windows/macOS/iOS VPN, расширенная Android приёмка, независимые WAN/multi-WAN и public IPv6; public IPv6 на текущем стенде отсутствует |
| Масштаб и длительная устойчивость | Контролируемые lock/dedupe/loss/recovery и короткие native проверки | Несколько backend/worker/writers, длительный rekey/REST/traffic, physical disconnect и maximum throughput |
| Внешние хранилища и jobs | Локальные API/errors/RBAC/owned SQL; реальные Portal1.3.1/Telegram195–201 и Selectel S3/client/API/ownSQL228–229 | Native S3 backup/restore/live UI/retention; provider/container/Gitea/MaxMind jobs с соответствующими endpoints/аккаунтами; private/paid credentials не выдумывать |
| Расширенные сетевые конфигурации | GRE/WG/VXLAN/IPsec/OSPF/BFD/BGP сценарии и точные границы записаны | from-pool/EUI-64/multiple-address import/export, outer IPv6, произвольная PKI/OID/policy/path-length и длительные переходы; BFD-only gate гарантией не стал |
| Общий UX, доступность и производительность | Полная UI192 исторически; latest backend25/UI52, scoped contrast/live218 и keyboard206 | Финальная свежая UI-регрессия перед выпуском, профильный performance и ручная accessibility/screen-reader приёмка; scoped axe не полный WCAG |
| Границы выпуска | План/доказательства/датированные блоки сохранены; коммиты локальные | Определить требуемые конфигурации и принять результат в этих границах; невыполненные варианты остаются явными ограничениями |
Portal offline JWT действует доexp после logout/role change; это принятая граница198, а не мгновенная revocation. Controlled Telegram unknown/retry201 не доказывает physical WAN lost ACK. User screenshots и vendor ReUI/theme сохранены.
## Цель и обязательные требования
Информативный, лаконичный и интуитивно понятный интерфейс с полноценной обработкой API, ошибок, прав и состояний данных. ReUI PRO, Frame и стиль `base-nova`; переиспользование установленных компонентов и общих композиций KpiStatGrid, ServerTileRail, CodeExportSheet. Основной сценарий — ПК с адаптацией для телефона; доступность обязательна.
Изменения выполняются как fullstack-работа: проверять контракт и поведение backend, а не только внешний вид. Не показывать успешную операцию до подтверждения API, не подменять неизвестные значения нулями. Локальные проверки используют реальные HTTP-пути с подменой ответов. Моки достаточны для локальной проверки UI и обработки ответов, но не доказывают применение конфигурации RouterOS, работу JWT в реальном окружении или точность IPFIX.
## Распределение работы и лимиты
- Пятичасовое окно — квота использования, а не пять часов непрерывной разработки. Расход заранее неизвестен; этап ограничивается конкретным результатом и проверками.
- По умолчанию один крупный этап на окно. Небольшие блоки объединять после проверки доступной квоты. Учитывать и общий недельный лимит аккаунта.
- Проверять квоту в начале этапа и после законченного блока. Базовый резерв — 25% пятичасового окна: не начинать новый блок, завершать проверки и сохранять состояние.
- Последующие прямые указания пользователя «до конца лимитов» разрешают работать ниже базового резерва, сохраняя возможность завершить проверки, журнал и коммит. Не начинать блок, который нельзя безопасно закончить.
- Работать последовательно, без параллельных агентских задач. Не менять модель посреди этапа без необходимости.
- После каждого завершённого этапа или самостоятельного проверенного блока делать локальный коммит. **Без push.** Сообщение коммита — по AGENTS.md, с русским subject после префикса.
- Исторические проценты и даты сброса из первоначального плана не являются текущими: перед работой получать актуальные лимиты.
## Этапы и критерии завершения
| Этап | Объём | Точка завершения | Распределение |
| --- | --- | --- | --- |
| 0. Подготовка | Зафиксировать состояние проекта, базовые проверки, таблицы и потребителей Filters, исходные экраны | Журнал, исходные ошибки, карта миграции | Первое окно |
| 1. Достоверность операций | Сохранение, удаление, опрос серверов; сохранение формы и данных при ошибках | Проверены успех, ошибка API, отсутствие доступа, повторное нажатие | Вместе с 0 при достаточном резерве |
| 2. Основа миграции | Связанная группа ReUI Data Grid/TanStack, общая оболочка, одна таблица серверов, подготовка Filters | Эталонная таблица, зависимости и образец миграции | Отдельное окно |
| 3. Основные таблицы | Обзор, серверы, мониторинг, трафик, статистика, справочники | Проверены таблицы группы, оставшиеся потребители перечислены | Отдельное окно |
| 4. Остальные таблицы | VPN, маршрутизация, управление, системные разделы; удаление старого API Filters | Нет смешения старого и нового API, общие проверки проходят | Отдельное окно |
| 5. Состояния данных | Частичные сбои дашборда, последние данные, свежесть, гонки запросов | Проверены первоначальная ошибка, частичный сбой, фоновое обновление | Отдельное окно |
| 6. Оболочка и дашборд | Навигация, контекст, подписи, сводка, очередь проблем, переходы к объектам | Проверены схемы и экраны ПК/телефона, переходы работают | Отдельное окно |
| 7. Серверы и мониторинг | Единый UX таблиц, деталей и форм; URL-контекст, права | Сценарий «проблема → сервер → действие → возврат» работает | Отдельное окно |
| 8. Трафик и статистика | Периоды, единицы, фильтры среза, связь графиков и таблиц, пустые состояния | Нет смешения live/истории и подмены неизвестных значений нулями | Отдельное окно; допускается несколько блоков |
| 9. VPN и сетевые операции | WireGuard, IPsec, GRE, VXLAN, Firewall, Filters; выбор устройства, формы | Контекст устройства сохраняется, результат операций подтверждён API | Отдельное окно |
| 10. Маршрутизация и диагностика | BGP, OSPF, рекурсивные маршруты, оптимизатор, диагностика, карта, терминал | Проверены профильные сценарии без изменения правил сетевых операций | Отдельное окно |
| 11. Администрирование | Пользователи, контейнеры, сертификаты, резервирование, оповещения, сбор данных, релизы, настройки | Общие шаблоны применены, ошибки операций и интеграций понятны | Разделено на 11А и 11Б |
| 12. Итоговая приёмка | Доступность, адаптивность, права, производительность, сквозная регрессия | Production build, тесты, ReUI checklist, список ограничений | Отдельное окно |
Это 13 контрольных этапов, а не обещание уложиться в 13 окон. Основная неопределённость — миграция компонентов и применение изменений в сетевых разделах.
Этапы 2–4 выполняются в отдельной ветке миграции (`codex/reui-v9-migration`). Промежуточные остановки допустимы с точным перечнем ошибок; выпуск до завершения этапа 4 не допускается. Само завершение этапа не является разрешением на push или deployment.
## Референсы и схемы
Для каждой группы экранов сначала использовать одну схему как эталон, затем применять её последовательно. Не пересобирать весь визуальный план в каждом окне.
| Этапы | Референсы ReUI PRO | Схема доработки |
| --- | --- | --- |
| 6 | [App Shell 12](https://reui.io/preview/base/app-shell-12?ref=mcp), [Stats 12](https://reui.io/preview/base/stats-12?ref=mcp) | Навигация → сводка → проблемы → измерения |
| 2–4, 7–8 | [Data Grid Filtering 2](https://reui.io/preview/base/data-grid-filtering-2?ref=mcp) | Фильтры → таблица → детали → результат |
| 7, 9–10 | [List 9](https://reui.io/preview/base/list-9?ref=mcp), [Sheet 8](https://reui.io/preview/base/sheet-8?ref=mcp) | Сервер → объект → форма → подтверждение API |
| 11 | [Settings 16](https://reui.io/preview/base/settings-16?ref=mcp) | Секция → состояние → действие → результат |
```mermaid
flowchart LR
A["0–1: подготовка и операции"] --> B["2–4: миграция ReUI"]
B --> C["5: достоверность данных"]
C --> D["6–8: основные экраны"]
D --> E["9–10: сетевые разделы"]
E --> F["11: администрирование"]
F --> G["12: приёмка"]
```
```text
ПК: [Навигация] [Контекст и действия ]
[Период / фильтры ]
[Сводка ]
[Список объектов] [Детали / результат]
Телефон: [Навигация и контекст]
[Действия / фильтры ]
[Сводка ]
[Список объектов ]
[Детали / результат ]
Данные: контекст → загрузка → подтверждённые данные
↘ ошибка + повтор
новый контекст ≠ старые данные; неизвестное ≠ ноль
```
## Текущая точка продолжения
По журналу этапы 0–8 завершены в границах локальной приёмки; внешние ограничения сохраняются. Этап 9 начат (блоки 9.1–9.34 — IPsec/GRE/VXLAN и переключение Firewall); этапы 10–12 не начаты. Этап 11 разделён: 11А — пользователи, контейнеры, сертификаты, резервирование; 11Б — оповещения, сбор данных, интеграции, релизы, настройки.
Подробные планы: [этап 6](ux-ui-stage-6.md), [этап 7](ux-ui-stage-7.md), [этап 8 и итоговая матрица](ux-ui-stage-8.md), [этап 9](ux-ui-stage-9.md).
Этап 8 завершён блоком 8.13: периоды и URL статистики, достоверность REST/SSE, защита от гонок, свежесть и разрывы графиков, месячный отчёт с каталогом неактивных серверов, адаптивность и профильная клавиатурная приёмка. Повреждённые ответы статистики показывают ошибку с повтором. Точный состав проверок и ограничений сохранён в журнале.
Ближайший оставшийся объём:
1. Этап 9: карта разделов и схема сохранены; удаление, импорт, создание, переключение, контекст экспорта и выбор пира WireGuard исправлены в 9.1–9.7; в 9.8 проверено подтверждение восстановления. В 9.9 исправлены разметка и сохранение подтверждения при ошибке у всех шести потребителей. В 9.10 исправлены ошибки и поздние ответы загрузки истории WireGuard. В 9.11 подтверждение восстановления проверено у остальных пяти потребителей. В 9.12 обработаны ошибка/повтор/поздние ответы истории IPsec. В 9.13 подключены ошибка/повтор/защита поздних ответов остальных четырёх разделов и общая валидация ревизий всех шести. В 9.14 исправлены подтверждение инициализации IPsec, сохранение формы и защита повторной отправки. В 9.15 проверены создание/редактирование пользователей IPsec и сохранение формы. В 9.16 проверены получение/повторный экспорт сертификатов, поздние ответы и соответствие отображаемого пароля архиву. В 9.17 подтверждены ответы удаления четырёх типов объектов IPsec и исправлен диалог повторов. В 9.18 исправлено подтверждение сохранения peer IPsec и поведение формы. В 9.19 исправлено подтверждение удаления GRE и сохранение диалога при ошибке. В 9.20 исправлено подтверждение включения/выключения GRE и защита повторов. В 9.21 исправлены подтверждение создания/сохранения GRE и защита формы. В 9.22 исправлены контейнер ответа, первоначальные KPI и сохранение данных при ошибке VXLAN. В 9.23 backend сообщает частичные сбои VXLAN, UI сохраняет данные неответивших устройств и показывает неизвестное состояние. В 9.24 добавлены схемы payload и тесты гонок VXLAN. В 9.25 подтверждены включение/отключение правил Firewall и защита повторов. В 9.26 подтверждены включение/отключение address-list с общим замком переключений. В 9.27 удаление правил/address-list перенесено в диалог с подтверждением API и защитой повторов. В 9.28 создание/редактирование правил и address-list требуют подтверждения API, сохраняют ввод/ошибку и блокируют повторы/закрытие. В 9.29 перемещение Firewall требует ok=true, откатывает порядок при ошибке и использует общий замок. В 9.30 восстановление истории подключено к общему замку, ручное обновление и открытие истории заблокированы во время записи. В 9.31 добавлены схемы ответа Firewall/серверов, сохранение последних данных при ошибке и поколение чтения с отменой применения при начале записи. В 9.32 backend сообщает частичные сбои по устройству/семейству/таблице, UI сохраняет недоступные срезы и блокирует изменения неполного среза. В 9.33 состояние изолировано по backend/режиму; поздние операции старого экрана не запускают чтение и не показывают уведомления в новом контексте. В 9.34 показано время получения срезов Firewall: успешные обновляются, недоступные сохраняют прежнее время или остаются неизвестными. В 9.35 сохранение Filters ожидает ok=true, сохраняет ввод при ошибке и блокирует повторную отправку/закрытие; live-список меняется после подтверждения. В 9.36 копирование Filters ждёт подтверждения, сохраняет цель/правила/режим при ошибке и блокирует повторы/закрытие. В 9.37 удаление Filters перенесено в диалог с сохранением ошибки, подтверждением API и защитой повторов. В 9.38 перемещение Filters подтверждается API; поиск использует полный порядок для приоритета и границ, действия таблицы блокируются на время операции. В 9.39 обновление/восстановление Filters используют общий замок до чтения правил/истории; ошибка чтения сохраняет подтверждение, чужой ruleset и stale отклоняются. В 9.40 добавлены схемы правил/ответов Filters, ошибка первоначальной загрузки с повтором без подмены моками и сохранение последних данных. В 9.41 запись выбранного устройства требует успешного чтения live=true, старые ответы отклоняются поколением запросов при переключении/применении. В 9.42 состояние Filters изолировано по backend/режиму, старые операции не уведомляют новый контекст. В 9.43 копирование Filters читает актуальный целевой набор под общим замком до PUT, ошибки чтения блокируют отправку. В 9.44 схемы/ошибки каталогов Filters сохраняют последние шлюзы, блокируют недостоверный route/маппинг; выборный GRE GET сообщает 503 при отказе. В 9.45 показано время получения правил/каталогов Filters и отдельное подтверждение записи, сбои сохраняют прежнее время. Далее — профильная клавиатурная/адаптивная приёмка Filters; ограничения счётчика, свежести и записи VXLAN остаются открытыми; загрузка данных IPsec и общая приёмка остаются открытыми.
2. Сохранять контекст устройства, введённые значения при ошибке и подтверждать результат операций по API; локальные моки проверяют клиентские сценарии, реальные сетевые операции требуют тестового окружения.
3. В этапе 12 выполнить полный аудит доступности (скринридер, контраст), производительности и сквозную регрессию. Ограничения этапа 8 — удалённые серверы месячного каталога, отсутствие экспорта и автоматического переподключения SSE — остаются явно зафиксированными, без заявления о реализации.
## Проверенные экраны Filters — блок 9.46
| Референс плана | ПК | Телефон |
| --- | --- | --- |
| Data Grid Filtering 2: устройство → свежесть → таблица | [Экран](ux-ui/screens/filters-desktop.png) | [Экран](ux-ui/screens/filters-mobile.png) |
| Sheet 8: Community → действие → подтверждение API | [Форма](ux-ui/screens/filters-rule-desktop.png) | [Форма](ux-ui/screens/filters-rule-mobile.png) |
Снимки HTTP-фикстур просмотрены; в блоке 9.47 прошли общая регрессия Filters (33 E2E) и production build frontend (34 страницы). Этап 9 остаётся в работе; следующие блоки — ограничения IPsec/VXLAN и общего GRE-каталога по журналу.
В блоках 9.48–9.52 исправлены чтение, readiness, свежесть и контекст IPsec; прошли профильные операции, ПК/телефон и frontend build. Этап 9 открыт; далее VXLAN/GRE.
| IPsec — проверенные экраны | ПК | Телефон |
| --- | --- | --- |
| Устройство → свежесть → клиенты | [Экран](ux-ui/screens/ipsec-desktop.png) | [Экран](ux-ui/screens/ipsec-mobile.png) |
| Клиент → форма → подтверждение API | [Форма](ux-ui/screens/ipsec-client-desktop.png) | [Форма](ux-ui/screens/ipsec-client-mobile.png) |
| Устройство → peer/сертификаты → действия | [Серверы](ux-ui/screens/ipsec-servers-desktop.png) | [Сервер](ux-ui/screens/ipsec-servers-mobile.png) |
## Порядок продолжения и журналирования
Перед работой читать этот план, начало журнала, git status и последние коммиты; сохранять чужие изменения. Затем проверить квоту и выбрать завершённый по смыслу блок текущего этапа.
После блока записать в `ux-ui-progress.md`:
- результат и затронутые компоненты;
- выполненные проверки и известные ошибки;
- оставшийся объём и точный следующий шаг;
- решения по API и совместимости;
- границы локальной проверки и текущую квоту.
Профильные проверки выполнять после каждого блока. Полная регрессия — после миграции и при итоговой приёмке; между этапами расширять её при изменении общей основы. Не объявлять этап завершённым только по успешной сборке или тестам на моках.
Для новой задачи:
> Продолжи UX/UI-план из docs/ux-ui-plan.md по журналу docs/ux-ui-progress.md. Сначала проверь состояние файлов и остаток лимита. Выполни следующий незавершённый блок, проверь результат, обнови журнал и сделай локальный коммит без push.
## GRE/VXLAN — локальная визуальная приёмка 2026-09-30
| Экран / референс | ПК | Телефон | Схема |
| --- | --- | --- | --- |
| GRE · List 9 / Stats 12 | [Снимок](ux-ui/screens/gre-desktop.png) | [Снимок](ux-ui/screens/gre-mobile.png) | Устройство → сводка среза → туннели |
| GRE · Sheet 8 | [Форма](ux-ui/screens/gre-form-desktop.png) | [Форма](ux-ui/screens/gre-form-mobile.png) | Контекст → поддерживаемые поля → подтверждение API |
| VXLAN · Data Grid Filtering 2 | [Снимок](ux-ui/screens/vxlan-desktop.png) | [Снимок](ux-ui/screens/vxlan-mobile.png) | Устройство → подтверждённый срез → просмотр |
| VXLAN · Sheet 8 | [Экспорт](ux-ui/screens/vxlan-export-desktop.png) | [Экспорт](ux-ui/screens/vxlan-export-mobile.png) | Снимок → актуальность → код → копирование/файл |
HTTP-фикстуры; layout/клавиатура проверены. Production frontend build и 183 E2E прошли в 9.63. RouterOS/JWT остаются отдельной приёмкой; актуальная точка продолжения — в журнале.
Этап 9 завершён 2026-09-30 в границах локальной приёмки (209 E2E, frontend/backend build). Внешние ограничения — журнал 9.64. Следующий этап — маршрутизация/диагностика (10); схема и референсы сохраняются, сетевые правила применения не меняются.
Этап 10 начат 2026-09-30. Карта API, референсы, схема и совместимость: [ux-ui-stage-10.md](ux-ui-stage-10.md). Точная точка продолжения — в журнале.
## BGP — локальная визуальная приёмка 2026-09-30
| Экран / референс | ПК | Телефон | Схема |
| --- | --- | --- | --- |
| BGP · List 9 / Data Grid Filtering 2 | [Снимок](ux-ui/screens/bgp-desktop.png) | [Снимок](ux-ui/screens/bgp-mobile.png) | Устройство → свежесть → сводка → фильтры/сессии |
| BGP · Data Grid детали | [Детали](ux-ui/screens/bgp-detail-desktop.png) | [Детали](ux-ui/screens/bgp-detail-mobile.png) | URL сессии → подтверждённые поля / неизвестные значения |
| BGP · Stats 12 / Frame | [Аналитика](ux-ui/screens/bgp-analytics-desktop.png) | [Аналитика](ux-ui/screens/bgp-analytics-mobile.png) | Точный срез → достоверные суммы → сравнение |
27 E2E/сборки прошли; реальные RouterOS/JWT/БД не проверены. Далее — OSPF, точное продолжение в журнале.
## OSPF — локальная визуальная приёмка 2026-09-30
| Экран / референс | ПК | Телефон | Схема |
| --- | --- | --- | --- |
| Интерфейсы · [List 9](https://reui.io/preview/base/list-9?ref=mcp) / [Stats 12](https://reui.io/preview/base/stats-12?ref=mcp) | [Снимок](ux-ui/screens/ospf-interfaces-desktop.png) | [Снимок](ux-ui/screens/ospf-interfaces-mobile.png) | Устройство → свежесть → интерфейсы → подтверждённая операция |
| Соседи · [Data Grid Filtering 2](https://reui.io/preview/base/data-grid-filtering-2?ref=mcp) | [Снимок](ux-ui/screens/ospf-neighbors-desktop.png) | [Снимок](ux-ui/screens/ospf-neighbors-mobile.png) | Поиск → один срез графа/таблицы → фактическое состояние |
| Детали · Frame | [Снимок](ux-ui/screens/ospf-detail-desktop.png) | [Снимок](ux-ui/screens/ospf-detail-mobile.png) | URL узла → Router ID → соседи/интерфейсы → возврат фокуса |
| BFD · Data Grid / Stats 12 | [Снимок](ux-ui/screens/ospf-bfd-desktop.png) | [Снимок](ux-ui/screens/ospf-bfd-mobile.png) | Срез → состояния → наблюдаемые таймеры/счётчики |
HTTP-фикстуры; локальная приёмка: 43 основных + 8 source E2E, 9 unit, production frontend. Реальный RouterOS/JWT/БД не проверен. Далее рекурсивные маршруты; точное продолжение в журнале.
## Рекурсивные маршруты — локальная визуальная приёмка 2026-09-30
| Экран / референс | ПК | Телефон | Схема |
| --- | --- | --- | --- |
| [Data Grid Filtering 2](https://reui.io/preview/base/data-grid-filtering-2?ref=mcp) / [List 9](https://reui.io/preview/base/list-9?ref=mcp) | [Детали](ux-ui/screens/recursive-routes-detail-desktop.png) | [390 px](ux-ui/screens/recursive-routes-detail-mobile.png), [320 px](ux-ui/screens/recursive-routes-detail-narrow.png) | Устройство → свежесть → группа/таблица → endpoints |
| [Sheet 8](https://reui.io/preview/base/sheet-8?ref=mcp) | [Форма](ux-ui/screens/recursive-routes-form-desktop.png) | [390 px](ux-ui/screens/recursive-routes-form-mobile.png), [320 px](ux-ui/screens/recursive-routes-form-narrow.png) | Полный снимок → параметры → подтверждение API → возврат фокуса |
48 основных + 8 source E2E, backend recursive regression и production frontend прошли. HTTP-фикстуры; RouterOS/DB/JWT остаются внешней приёмкой. Далее оптимизатор по журналу.
## Оптимизатор — локальная визуальная приёмка 2026-10-01
| Экран / референс | ПК | Телефон | Схема |
| --- | --- | --- | --- |
| Сводка · [Stats 12](https://reui.io/preview/base/stats-12?ref=mcp) / Frame | [Снимок](ux-ui/screens/route-optimizer-overview-desktop.png) | [390 px](ux-ui/screens/route-optimizer-overview-mobile.png), [320 px](ux-ui/screens/route-optimizer-overview-narrow.png) | Источник → объяснение модели → сводка → OSPF |
| Настройки · [Settings 16](https://reui.io/preview/base/settings-16?ref=mcp) | [Снимок](ux-ui/screens/route-optimizer-settings-desktop.png) | [390 px](ux-ui/screens/route-optimizer-settings-mobile.png), [320 px](ux-ui/screens/route-optimizer-settings-narrow.png) | Пороги → вес → локальный пересчёт |
| Community · [Data Grid Filtering 2](https://reui.io/preview/base/data-grid-filtering-2?ref=mcp) | [Снимок](ux-ui/screens/route-optimizer-community-desktop.png) | [390 px](ux-ui/screens/route-optimizer-community-mobile.png), [320 px](ux-ui/screens/route-optimizer-community-narrow.png) | Устройство → базовый расчёт → модельная рекомендация → закрепление |
47 основных + 8 source E2E, backend optimizer/live-maps, production frontend/backend прошли. Исходные значения отдельно от модели; Community apply недоступен, демо только симуляция. HTTP/DI фикстуры; реальный RouterOS/JWT/БД остаётся внешней приёмкой. Далее карта/терминал; ограничения и точное продолжение — в журнале.
## Карта сети — промежуточные экраны 2026-10-01
| Экран / референс | ПК | Телефон | Схема |
| --- | --- | --- | --- |
| Оболочка · [Frame](https://reui.io/components/frame?ref=mcp) / [API](https://reui.io/docs/components/base/frame?ref=mcp) | [Обзор](ux-ui/screens/network-map-overview-desktop.png) | [390 px](ux-ui/screens/network-map-overview-mobile.png), [320 px](ux-ui/screens/network-map-overview-narrow.png) | Источник → свежесть → слои/фильтры → карта |
| Детали · Frame / [List 9](https://reui.io/preview/base/list-9?ref=mcp) | [Детали](ux-ui/screens/network-map-detail-desktop.png) | [390 px](ux-ui/screens/network-map-detail-mobile.png), [320 px](ux-ui/screens/network-map-detail-narrow.png) | Устройство → фактические поля → действия → возврат |
Оболочка и клавиатурные действия проверены (35 + 12 E2E). Камера и читаемость малой топологии доработаны в 10.53 (16 E2E + 2 unit). Pointer/touch и пустые состояния приняты в 10.54: 39 основных + 12 source E2E, 10 unit и production frontend build. Реальные RouterOS/JWT/БД остаются внешней приёмкой; далее терминал.
### Терминал: локальная приёмка 10.57
REST запрос → ожидание → подтверждённый output / ошибка с сохранением команды. Выбор устройства и поле команды остаются доступными на ПК и телефоне. Референс — существующий ReUI Frame и List 9; детали проверок в журнале.
| Экран | ПК | Телефон |
| --- | --- | --- |
| Готовность | [PNG](ux-ui/screens/terminal-ready-desktop.png) | [390 px](ux-ui/screens/terminal-ready-mobile.png), [320 px](ux-ui/screens/terminal-ready-narrow.png) |
| Вывод | [PNG](ux-ui/screens/terminal-output-desktop.png) | [390 px](ux-ui/screens/terminal-output-mobile.png), [320 px](ux-ui/screens/terminal-output-narrow.png) |
### Диагностика: экраны 10.69
Референс — существующий ReUI Frame/FramePanel и List 9. Устройство → параметры → подтверждённый ответ API/ошибка → копирование или удаление. Расписание относится к 11Б.
| Экран | ПК | Телефон |
| --- | --- | --- |
| Готовность | [PNG](ux-ui/screens/probes-ready-desktop.png) | [390 px](ux-ui/screens/probes-ready-mobile.png), [320 px](ux-ui/screens/probes-ready-narrow.png) |
| Вывод | [PNG](ux-ui/screens/probes-output-desktop.png) | [390 px](ux-ui/screens/probes-output-mobile.png), [320 px](ux-ui/screens/probes-output-narrow.png) |
## Актуальное продолжение 2026-10-01
Этап 10 принят локально (10.71): 235 основных + 52 source E2E, 42 unit, frontend/backend build. Реальный RouterOS/Portal/PostgreSQL остаётся внешней приёмкой. Далее 11А — пользователи, контейнеры, сертификаты, резервирование; затем 11Б и 12. История прежних контрольных точек выше не заменяет актуальный журнал.
Карта этапа 11А: [API, референсы и схемы](ux-ui-stage-11a.md). Точный следующий блок и ограничения — журнал.
### Администрирование: экраны 11А
Пользователи и контейнеры приняты локально (11А.8/11А.13); референсы Settings 16 / Stats 12 / Sheet 8 и схемы — [карта 11А](ux-ui-stage-11a.md). Далее сертификаты и резервирование.
| Экран | ПК | Телефон |
| --- | --- | --- |
| Пользователи | [Профиль](ux-ui/screens/users-profile-desktop.png), [ошибка](ux-ui/screens/users-error-desktop.png) | [390](ux-ui/screens/users-profile-mobile.png), [320](ux-ui/screens/users-profile-narrow.png) |
| Контейнеры | [Обзор](ux-ui/screens/containers-overview-desktop.png), [снимок](ux-ui/screens/containers-export-desktop.png) | [390](ux-ui/screens/containers-export-mobile.png), [320](ux-ui/screens/containers-export-narrow.png) |
Каталог Evolution защищён от неполного HTTP-ответа в 11Б.3.3.4.1; Подтверждение testConnection исправлено в 11Б.3.3.4.2; состояния интеграции остаются в объёме 11Б. Актуальная точка продолжения: 11Б.3.4.4 — строгие NetFlow API и backend эффекты, затем форма. GeoIP принят локально в 11Б.3.4.3 (13 основных + 6 source E2E, ПК/390/320); реальные интеграции не проверены. GeoIP known/dirty/partial/unknown guard приняты в 11Б.3.4.2. GeoIP RBAC исправлен в 11Б.3.4.1 (traffic read/write вместо catch-all dashboard read). Scheduler принят локально в 11Б.3.3.7 (46 основных + 6 backend source E2E, ПК/390/320); внешние интеграции не доказаны. Параллельных агентов не использовать. Ручные run-now/refresh, общий lock/права и сообщения skipped/partial/event/status приняты в 11Б.3.3.6.3. Точечные операции настроек, ввод и подтверждённый сброс dirty приняты в 11Б.3.3.6.2. Независимые strict settings readers и защита черновиков подключены в 11Б.3.3.5; реальные интеграции остаются внешней приёмкой. Независимые scheduler status/runs и достоверные KPI приняты в 11Б.3.3.3. Strict history/unknown/свежесть приняты в 11Б.3.3.2. Контекст/abort/revision и исходный lint исправлены в 11Б.3.3.1; далее независимые readers/dirty states и операции. GeoIP API принят в 11Б.3.2. Scheduler API основа проверена в 11Б.3.1, пока не подключена к странице. Совместимость JSONB/legacy snapshot и foreign guard проверены в 11Б.2; исходные lint/context ограничения страницы описаны в журнале. Общий runner исправлен в 11Б.1; карта оставшегося этапа — [11Б](ux-ui-stage-11b.md). Этап 11А принят локально в 11А.33: backups 71 основных + 28 source E2E, 27 frontend unit, backend профиль и production build. Backup scheduler cleanup проверен в 11А.32; общий dispatcher/journal status исправлен в 11Б.1, реальные интеграции остаются внешней приёмкой. S3/partial job/initial errors приняты в 11А.31.2.2. Диалоги ошибок приняты в 11А.31.2.1. Frame/первые 9 экранов приняты в 11А.31.1. URL/Filters контекст принят в 11А.30. Клиентский checkpoint restore принят в 11А.29.5. Backend outcome неизвестного импорта принят в 11А.29.4. Идентичность receipt принята в 11А.29.3. Backend cleanup удаления принят в 11А.29.2. Frontend delete/restore/download принят в 11А.29.1, затем URL/Frame/визуальная приёмка и scheduler cleanup. Frontend checkpoint/создание/serial polling приняты локально в 11А.28.2. API/основа наблюдения реализованы в 11А.28.1. Настройки расписания/S3 реализованы в 11А.27.1–11А.27.2. Каталоги/source/права реализованы в 11А.25, backend результат ручных операций исправлен в 11А.26. Сертификаты приняты локально в 11А.24, backups API стал строгим. State API, reader, snapshot merge и nullable представление подключены в 11А.14–11А.17.3; таблица требований — [этап 11А](ux-ui-stage-11a.md). Резервные копии и весь 11А приняты локально в 11А.33; внешние ограничения — журнал.
| Экран | ПК | Телефон |
| --- | --- | --- |
| История | [PNG](ux-ui/screens/backups-history-desktop.png) | [390](ux-ui/screens/backups-history-mobile.png), [320](ux-ui/screens/backups-history-narrow.png) |
| Настройки | [PNG](ux-ui/screens/backups-settings-desktop.png) | [390](ux-ui/screens/backups-settings-mobile.png), [320](ux-ui/screens/backups-settings-narrow.png) |
| Создание | [PNG](ux-ui/screens/backups-create-desktop.png) | [390](ux-ui/screens/backups-create-mobile.png), [320](ux-ui/screens/backups-create-narrow.png) |
Референсы: [Settings 16](https://reui.io/preview/base/settings-16?ref=mcp), [Data Grid Filtering 2](https://reui.io/preview/base/data-grid-filtering-2?ref=mcp), [Sheet 8](https://reui.io/preview/base/sheet-8?ref=mcp). Схема: источник → сводка → история/настройки → immutable цель → подтверждение API/неизвестный результат.
| Экран | ПК | Телефон |
| --- | --- | --- |
| Ошибка удаления | [PNG](ux-ui/screens/backups-delete-error-desktop.png) | [390](ux-ui/screens/backups-delete-error-mobile.png), [320](ux-ui/screens/backups-delete-error-narrow.png) |
| Неизвестный импорт | [PNG](ux-ui/screens/backups-restore-unknown-desktop.png) | [390](ux-ui/screens/backups-restore-unknown-mobile.png), [320](ux-ui/screens/backups-restore-unknown-narrow.png) |
| Экран | ПК | Телефон |
| --- | --- | --- |
| S3 ошибка | [PNG](ux-ui/screens/backups-s3-error-desktop.png) | [390](ux-ui/screens/backups-s3-error-mobile.png), [320](ux-ui/screens/backups-s3-error-narrow.png) |
| Partial job | [PNG](ux-ui/screens/backups-partial-job-desktop.png) | [390](ux-ui/screens/backups-partial-job-mobile.png), [320](ux-ui/screens/backups-partial-job-narrow.png) |
| Initial error | [PNG](ux-ui/screens/backups-initial-error-desktop.png) | [390](ux-ui/screens/backups-initial-error-mobile.png), [320](ux-ui/screens/backups-initial-error-narrow.png) |
Продолжение 2026-10-03: завершён 11Б.3.4.4.1 (строгие NetFlow API, 5 unit и 3 collector/probes E2E, typecheck/ESLint). Следующий блок — 11Б.3.4.4.2: backend экспорт/права и подтверждение сохранения отдельно от запуска listener. Purge и форма ещё требуют доработки.
Завершён 11Б.3.4.4.2: private export требует traffic write, GET не создаёт ключи, PUT отделяет сохранение от ошибки запуска listener. HTTP/JWT, backend build, lint и permissions прошли. Далее 11Б.3.4.4.3: конкурентное создание ключей/выборочные patch; purge и UI ещё не приняты.
Завершён 11Б.3.4.4.3: выборочная запись NetFlow patch и условная установка host keys, свежая подтверждённая пара; DI гонка/HTTP/JWT/build/lint прошли. Реальная PG гонка не проверена. Далее 11Б.3.4.4.4 — атомарность purge и частичные результаты.
Завершён 11Б.3.4.4.4: 6 таблиц/counters purge в общей транзакции, отдельные partition/listener/event warnings и nullable размер файлов. DI/HTTP/API/typecheck/build/lint прошли; реальный PG purge не запускался. Следующий шаг 11Б.3.4.4.5 — форма NetFlow и подтверждённые/частичные/неизвестные операции.
Завершён 11Б.3.4.4.5: форма NetFlow known/dirty/rights/lock, selective PUT, partial outcomes и review после unknown POST; 12 E2E/form unit/typecheck/lint/production build прошли. Далее 11Б.3.4.4.6 — source/adaptive приёмка, затем общий контракт IP/CIDR/DNS.
Завершён 11Б.3.4.4.6: 10 NetFlow backend source E2E, 3 responsive, 6 снимков (320 и ПК просмотрены), регрессия GeoIP/collector прошли. Далее 11Б.3.4.4.7: общий IP/CIDR/DNS ввод/фактический порт и отказ конкурентному purge вместо очереди. Затем приёмка NetFlow и Evolution.
Завершён 11Б.3.4.4.7.1: конкурентный purge получает 409 до удаления, неподтверждённый session lock соединения исключается из пула; DI/backend/build/lint/conflict E2E прошли. Реальный PG overlap не проверен. Далее 11Б.3.4.4.7.2 — общий IP/CIDR/DNS контракт и фактические порты.
Завершён 11Б.3.4.4.7.2: общий NetFlow IP/CIDR/DNS/ports patch, draft и backend проверяют его; инструкция использует фактический порт. 14 E2E, unit/HTTP/JWT, lint и оба builds прошли. Далее 11Б.3.4.4.7.3 — согласованный host export/маска, затем приёмка NetFlow и Evolution.
Завершён 11Б.3.4.4.7.3: host export из одного снимка, фактические mask/WG/IPFIX ports, strict keys/peers и безопасные однострочные комментарии. Builder/key/HTTP/JWT/build/lint прошли без запуска host/RouterOS. Далее 11Б.3.4.4.8 — приёмка NetFlow; затем 11Б.3.5 Evolution. Нестандартные prefix allocator не приняты.
Локальная приёмка NetFlow 11Б.3.4.4.8: 19 основных и 10 source E2E, backend JWT с purge, backend/frontend builds и API tests прошли в описанных блоках. Дублирующий purge Settings заменён переходом к единой панели (link E2E/typecheck). Исходные lint ошибки Settings остаются до его блока. Внешние PG/WG/RouterOS/Portal/нестандартный IPv4 prefix не приняты. Далее 11Б.3.5.1 — строгие Evolution settings/save/test API и затем provider/форма.
Завершён 11Б.3.5.1 — contracts/Evolution strict settings/save/test API: 3 unit, contracts build/typecheck/lint прошли. Новый PUT helper пока не подключён (backend старый receipt). Далее 11Б.3.5.2 backend selective save/подтверждение, затем provider и форма.
Завершён 11Б.3.5.2: Evolution backend selective RETURNING save/public receipt и проверка items upstream/test; DI HTTP/JWT, backend build/lint прошли. Старый provider совместим с публичными полями, ещё не мигрирован. Далее 11Б.3.5.3 — provider known/error/time/source; затем форма и upstream catalog validation.
Завершён 11Б.3.5.3.1: Evolution provider known/error/time/readers/source/strict receipts, статус Settings; 8 provider (один selector повторён), 2 прежних и 6 source E2E, lint/typecheck/production build прошли. Форма/consumer mocks ещё не приняты. Далее 11Б.3.5.3.2 — upstream catalog strict/unknown counts; затем 11Б.3.5.4 форма/consumers.
Завершён 11Б.3.5.3.2: strict upstream catalog, nullable ASN/community counts, unknown «—» вместо 0. Parser/aggregation/HTTP/JWT/build/typecheck/lint и provider/counts E2E прошли; locator inline details исправлен. Реальный Evolution/PG не принят. Далее 11Б.3.5.4.1 — форма Evolution dirty/rights/lock/key clear/source.
Завершён 11Б.3.5.4.1: отдельная форма Evolution dirty/rights/lock/clear confirmation/source; 17 основных, 8 source и 3 responsive E2E, typecheck/lint/build прошли. 6 снимков, 320/ПК/clear просмотрены. Общие Settings и live consumer mocks ещё не приняты. Далее 11Б.3.5.4.2 — consumers/sidebar unknown/disabled/no fallback.
Завершён 11Б.3.5.4.2: live catalog consumers/sidebar/Filters без demo fallback, unknown/disabled/last snapshot и current details; 25 E2E, typecheck/профильный lint/build прошли. 3 community screenshots, 320/ПК просмотрены. Sidebar sync-effect baseline error и Filters unused warnings описаны в журнале. Далее 11Б.3.5.5 — HTTP/JWT catalog и приёмка Evolution.
Завершён 11Б.3.5.5: Evolution catalog DI HTTP/JWT, один settings snapshot, backend test/build/lint прошли. Evolution принят локально в границах предыдущих form/provider/source/consumer/adaptive проверок; реальный upstream/PG/Portal/RouterOS не принят. Далее 11Б.3.6.1 — достоверные общие Settings без фиктивных сохранений/API keys/MFA; затем system DB, Alerts/Releases/probes.
Завершён 11Б.3.6.1: общие Settings без фиктивных сохранений/demo keys/MFA, реальная тема/source URL, переходы к инструментам; 32 E2E с одним исправленным locator, 3 source с исправленным alert locator, 8 Evolution source, typecheck/lint/build прошли. 6 screenshots, 320 просмотрены. System DB ещё не принят. Далее 11Б.3.6.1.2 health/source guards; затем 11Б.3.6.2 DB operations.
Завершён 11Б.3.6.1.2: DataSource health token/revision/abort/ABA, explicit checking и validated health body. 2 unit, 10 source/health, 16 Settings/Evo provider и 8 Evo source E2E, typecheck/lint/build прошли; два test setup уточнены. System monitor остаётся отдельным reader. Далее 11Б.3.6.2.1 — system DB API/credentials in events; затем backend outcomes и UI.
Завершён 11Б.3.6.2.1: system DB export PGDMP/leaf filename и restore strict receipt/limits/abort без повтора; DATABASE_URL удалён из новых event payload. 3 unit группы/typecheck/lint/backend и frontend builds прошли. UI/backend partial/restore transaction не приняты. Далее 11Б.3.6.2.2 — backend transaction/outcomes/DI HTTP/JWT, затем 11Б.3.6.2.3 форма.
Завершён 11Б.3.6.2.2.1: DI restore executor/--single-transaction/cleanup warning, file choose без фиктивного success, confirmation до receipt. 4 DI/3 API/2 browser tests, backend/frontend builds/typecheck/lint прошли; реальный PG restore не запускался. System DB не принят полностью. Следующий точный шаг 11Б.3.6.2.2.2 — backend core/restart/event partial outcomes + DI HTTP/JWT/concurrency; затем 11Б.3.6.2.3 source/lock/unknown UI.
2026-10-03: завершён 11Б.3.6.2.2.2, подтверждённый backup/restore отделён от restart/audit warnings; nonqueued concurrency, HTTP/JWT/API/UI проверки прошли локально. Далее DB форма 11Б.3.6.2.3.
2026-10-03: завершён 11Б.3.6.2.3.1, отдельная DB форма/lock/checkpoint/адаптивность; 10 E2E, API/proxy tests и build прошли. Далее source/ABA/unmount и приёмка DB.
2026-10-03: 11Б.3.6.2.3.2 — 6 source и 18 соседних E2E прошли; база принята в локальных границах. Далее 11Б.4.1 Alerts contracts/API.
2026-10-03: 11Б.4.1 — строгие Alerts output schemas/API и сверка save receipts; 5 unit/builds/typecheck/lint прошли. Module пока не подключён. Далее 11Б.4.2.1 backend Telegram.
2026-10-03: 11Б.4.2.1.1 — selective Telegram UPDATE RETURNING, strict send receipt; 7 DI/send tests/build/lint прошли. confirm-stability пропущен без PG. Далее HTTP/JWT 11Б.4.2.1.2.
2026-10-03: 11Б.4.2.1.2 — реальные Alerts HTTP/JWT gates и один Telegram stored snapshot, профильные tests/build/typecheck/lint прошли. Далее rules/groups 11Б.4.2.2.1.
2026-10-03: 11Б.4.2.2.1.1 — общая нормализация rules/groups и 400 до удаления; 8 unit и backend profile/builds/typecheck/lint прошли. Далее transaction receipt 11Б.4.2.2.1.2.
2026-10-03: 11Б.4.2.2.1.2 — transaction rules receipt/readback/lock, DI/API/JWT/build/typecheck/lint прошли. Реальный PG rollback/overlap и optimistic revision не приняты. Далее Alerts UI 11Б.4.3.1.
2026-10-03: 11Б.4.3.1.1 — live Alerts без первоначальных demo/0, strict primary reader/known/time, 3 E2E/lint/typecheck/build прошли. Далее independent secondary readers/source 11Б.4.3.1.2.
2026-10-03: 11Б.4.3.1.2.1 — strict secondary API (GRE partial failures/unknown status), 4 unit/typecheck/lint прошли. Module не подключён. Далее 11Б.4.3.1.2.2 independent UI/source.
## 12.5.51 — реальная GRE пара, связность и lifecycle (2026-10-08)
По прямому поручению пользователя VPN-приёмка продолжается с созданием реальных тестовых туннелей, особенно GRE. [Lifecycle](ux-ui/acceptance/gre-real-lifecycle-2026-10-08.json): production backend8782054, два CHR7.24.5, собственные имена mm-acceptance-gre-* и комментарий владения. Перед записью проверены локальные внешние адреса и отсутствие пересечения198.18.255.248/30 с существующей адресацией/недефолтными маршрутами. POST application API создал обе GRE стороны и /ip/address:201/201. Внешние endpoints194.226.121.150 ↔104.165.244.7, внутренние198.18.255.249/30 ↔198.18.255.250/30, MTU1400,keepalive2s/3. Дополнительных static/default routes и Firewall правил не создавалось.
После running=true независимый RouterOS Ping через указанный GRE интерфейс:3/3 в каждом направлении,0%loss,~54ms. Это реальная point-to-point связность, не benchmark и не шифрованный IPsec. PATCH MTU первого конца1360, disable и enable дали200 и подтверждены отдельным чтением RouterOS. [Browser](ux-ui/acceptance/browser-gre-real-2026-10-08.json): настоящие созданные объекты, формы обоих устройств, local IP и server/tunnel URL-контекст/reload/320px, JS errors0; browser проход читает/отменяет формы, создание/изменение выполнял production API. [ФормаCHR1](ux-ui/screens/gre-real-form-server1-320-2026-10-08.png) просмотрена, [CHR2](ux-ui/screens/gre-real-form-server2-320-2026-10-08.png) сохранена.
Первый запуск Ping до готовности получил timeout; [повтор после running](ux-ui/acceptance/gre-ready-ping-2026-10-08.json) подтвердил3/3. Первый harness остановил свою очистку на слишком строгом сравнении baseline, включавшем runtime IDs; причина конкретного несовпадения не была сохранена полностью. [Независимая очистка](ux-ui/acceptance/gre-cleanup-recovery-2026-10-08.json) удалила оставшуюся собственную сторону и подтвердила отсутствие интерфейсов/IP/connected route, исходные количества0GRE/1–2addresses/4–5routes. Harness исправлен: сначала очистить обе стороны, сравнивать конфигурационные поля без runtime IDs, сохранить evidence до assertion. Повторный полный lifecycle прошёл с exitCode0: DELETE200/200, все выбранные поля GRE/IP/route/IPv4 Firewall совпали с baseline. Прямое административное восстановление чужих объектов не выполнялось.
Обнаружен настоящий дефект: принятый remoteInnerIp возвращается пустым, затем теряется в форме редактирования. Связность обеспечивается настройкой обоих реальных /ip/address, но сохранение формы этим не считается исправленным. Следующий12.5.52 — исправить metadata persistence/restore peer IP и профильные тесты, затем развернуть и повторить настоящий GRE цикл. Ограничения ROS6 для остальных VPN/прав/частичных отказов остаются. Control main2servers/9speed/retention14 сохранён; application GRE revisions намеренно остаются журналом выполненных действий. Временный контейнер/туннель8018 удалены; RouterOS тестовые объекты очищены. Локальный коммит без push.
Официальная схема пары и keepalive: [MikroTik GRE](https://manual.mikrotik.com/docs/virtual-private-networks/gre/). Документация текущей версии проверена, реальные команды/ответы — RouterOS7.24.5.
## 12.5.76 — VXLAN: достоверность, экспорт и полная профильная приёмка (2026-10-09)
По поручению пользователя работа укрупнена по разделам. В одном блоке выполнены code/API/UI, профильные проверки, production Docker build обеих частей, deploy, реальная приёмка и очистка; один локальный коммит в конце, без push.
Прямой GET /api/servers/:id/vxlan теперь возвращает409 для выключенного сервера до обращения к RouterOS. Защита есть также в native reader и агрегаторе, для home-router и exit-node. Неполные/некорректные параметры интерфейса, повторные ID/имена и неизвестные/некорректные статические VTEP считаются ошибкой устройства вместо выдуманных VNI/port/L2MTU/флагов. Сохранение последних успешных данных и частичная ошибка остаются прежними. VTEP сопоставляется с именем или RouterOS ID интерфейса.
Реальный MTU передаётся в модель, виден в таблице и экспортируется; для старого снимка без MTU показывается «—», параметр не придумывается, экспорт просит проверить его отдельно. CodeExportSheet прямо описывает fragment: interface/известный MTU/static VTEP, без IP/bridge/FDB. Стабильная actions cell получает callback через контекст, поэтому открытое меню сохраняется при refresh и экспорт использует последние данные. Frame/base-nova и установленные ReUI primitives сохранены; registry migration не выполнялась.
Проверки: backend mapping/HTTP route/export tests, backend и scoped frontend TypeScript, ESLint изменённых файлов и diff check passed. Профильный browser набор23/23 (VXLAN и два связанных layout cases), context-race4/4. В тесте1000 строк отображаются50 строк; измерено2245 DOM nodes, payload227787 bytes и829ms до ready в данном локальном запуске — это наблюдение, не универсальный performance SLA. Общая регрессия проекта не повторялась.
На161.104.46.222 развёрнуты backend/frontend mmapp-test/*:ux-vxlan76, version1.0.0-test.vxlan76. Сборочный source — git archive базового HEAD6b068ac с явными13 working-file overrides, а не отдельный уже закоммиченный revision. SHA256 архива b69f8eb8b5830e85930aca0974cd83a94940e2e162101b8798208720ccf3e1ae; [manifest](ux-ui/acceptance/vxlan-section-source-manifest-2026-10-09.json) позволяет сверить каждый изменённый файл. Production builds passed; Compose3 services running, backend/PostgreSQL healthy; frontend healthcheck отсутствует, HTTP/browser passed. Backup2441206 bytes/0600, pg_restore --list passed, .env сохранён приватно на сервере, прежние образы доступны для rollback.
Реальная собственная VXLAN пара на194.226.121.150 и104.165.244.7: VNI160075, UDP51880, MTU1400, публичные local/static remote VTEP, IP198.18.255.245/30↔198.18.255.246/30. Native параметры совпали с каталогом приложения; Ping3/3 в обе стороны. [Browser4/4](ux-ui/acceptance/browser-vxlan-section-2026-10-09.json) подтвердил URL выбранного устройства/туннеля, экспорт и отсутствие page overflow на1280/320px. Экспорт каждой стороны заново применён через строго ограниченный native REST adapter к собственным интерфейсам: только interface/VTEP команды, IP добавлены отдельно; MTU1400 и Ping3/3 повторно подтверждены. Это проверка параметров fragment, не запуск произвольного .rsc скрипта в терминале.
Две временные выключенные записи home-router/exit-node указывали на отдельный HTTP probe. Прямые GET вернули409, nativeProbeCalls0; временные записи удалены. [Native protocol](ux-ui/acceptance/vxlan-section-native-2026-10-09.json): cleanup сравнил исходные VXLAN/VTEP/IP/routes/IPv4 firewall/bridge/bridge-port на обоих устройствах, все проверки true. DB controls после: servers2/speedHistory9/retention14/migrations9. Пароли не менялись, SSH и оба CHR доступны. [Smoke шести страниц](ux-ui/acceptance/deploy-browser-vxlan-section-2026-10-09.json): HTTP200, mobile fits, JS errors0/API errors0.
| Референс | Схема применённого решения |
| --- | --- |
| [ReUI Data Grid](https://reui.io/docs/components/base/data-grid?ref=mcp) / [Filtering2](https://reui.io/preview/base/data-grid-filtering-2?ref=mcp) | Контекст устройства → достоверная таблица/MTU → устойчивое меню |
| [Sheet8](https://reui.io/preview/base/sheet-8?ref=mcp) | Актуальный снимок → границы fragment → код → независимая native проверка |
```mermaid
flowchart LR
A[Устройство] --> B{Включено?}
B -->|Нет| C[409: без опроса]
B -->|Да| D{Снимок достоверен?}
D -->|Нет| E[Ошибка и последние данные]
D -->|Да| F[Таблица с MTU]
F --> G[Экспорт interface и VTEP]
G --> H[Повторное применение и Ping]
```
Границы: app VXLAN API read-only, create/delete выполнены native REST только на собственных объектах. IPv6/bridge/FDB/throughput/RBAC/concurrency и произвольный терминальный .rsc import не приняты; динамический ARP/FDB baseline не сравнивался. Первый запуск Edge в sandbox завершился до страницы; повторный разрешённый запуск прошёл. Этап12.5 целиком не закрыт. Следующий раздел12.5.77 — IPsec; остаточные VXLAN/WireGuard ограничения остаются в протоколе.
## 12.5.77 — основной блок IPsec (2026-10-09)
Подробный объём, протоколы, схема и ограничения: [12.5.77 в журнале](ux-ui-progress.md).