Files
MikrotikManager/docs/ux-ui-external-acceptance.md
T

18 KiB
Raw Blame History

UX/UI: протокол внешней приёмки 12.5

Статус на 2026-10-07: стенд161.104.46.222/source673e5ba развёрнут; PG-1 проверен в границах bootstrap/restart/schema/control-row, PG-2 проверен архивом и отдельной БД, PG-5 — реальными конкурентными backup/restore HTTP200/409. PG-7 — HTTP RBAC 401/403 при AUTH_REQUIRED=true, без доказательства отсутствия процессов и реального Portal SSO. Native TCP transmit/receive/both по3s и первоначальный отказ подключения проверены на паре CHR; прочие ROS/PG/Q/интеграционные сценарии остаются открытыми. PG evidence, паспорт, журнал, план.

Паспорт стенда

Перед внешним запуском зафиксировать отдельные PostgreSQL и RouterOS тестовые устройства, версии server/client PostgreSQL и RouterOS, HEAD backend/frontend, роли пользователей, число экземпляров backend/планировщика/отправителей и способ их остановки. Для Telegram использовать тестовый чат, для остальных интеграций — тестовые endpoints и учётные записи. Зафиксировать ожидаемые изменения и способ восстановления стенда.

Пароли, JWT, REUI_LICENSE_KEY, DATABASE_URL, дампы БД и исходные приватные журналы хранить вне Git. В отчёт включать очищенные ответы, ID тестовых объектов, UTC-время, request ID, HTTP-код и проверенные изменения. Контрольный снимок данных должен позволять сравнить состояние до/после; успешный toast без независимой проверки не завершает сценарий.

PostgreSQL и восстановление

ID Сценарий Проверяемый результат Доказательство
PG-1 Штатный bootstrap чистой тестовой БД и повторный старт Миграции 0008/0009 отражены в schema_migrations; constraint допускает pending/processing/unknown/sent/failed; resolution_version неотрицательна. Повторный старт сохраняет данные Версии, очищенный журнал миграций, контрольные строки и ограничения
PG-2 GET /api/system/database/backup с mm:settings:admin Архив сформирован pg_dump, открывается совместимым pg_restore; контрольные бизнес-записи/схема присутствуют Размер/SHA256 архива, список объектов, receipt и предупреждения
PG-3 POST /api/system/database/restore из доверенного тестового архива Данные тестовой БД соответствуют архиву; последующая запись получает корректный новый ID. UI различает завершение restore и ошибки перезапуска listener/scheduler/event Сравнение схемы/контрольных записей, проверка последовательностей, HTTP/UI
PG-4 Ошибка внутри реального pg_restore Восстановление не объявляется успешным. Проверить rollback по контрольным бизнес-строкам и схеме, отдельно проверить последовательности Ошибка процесса, HTTP/UI и независимые запросы до/после
PG-5 Два конкурентных backup/restore запроса Advisory lock исключает конкурирующее выполнение; второй запрос сообщает конфликт Два request ID, HTTP-коды, журнал фактических процессов
PG-6 Длительная фоновая запись и UDP-приём во время подготовки restore Подтверждена остановка всех writers и отсутствие записей в критическом интервале; после операции потребители восстановлены либо показано предупреждение Процесс/worker lifecycle, счётчики приёма/записей, состояния jobs
PG-8 Ошибка записи speed snapshot/history и потеря commit acknowledgement Снимок/история атомарны; неизвестный commit не выдаётся за гарантированный rollback и не вызывает автоматический повтор native test Состояние PG после восстановления соединения, runId, HTTP/UI
PG-7 Неавторизованный пользователь и обычный settings writer Backup/restore требуют settings admin, отказ происходит до выполнения процесса 401/403, неизменные контрольные данные, отсутствие pg_dump/pg_restore

Реализация: bootstrap, migrations, 0008, 0009, database operation, restore execution.

Приложение использует pg_dump -Fc и pg_restore --single-transaction --clean --if-exists. Транзакционный режим описан в документации PostgreSQL. Проверка пяти байтов PGDMP проверяет заголовок, но не полноту и не доверие к архиву. Для rollback нужен сценарий с ошибкой исполнения restore, а не только отказ HTTP до его начала.

В локальном блоке12.5.8 добавлено ожидание текущих scheduler jobs с закрытием admission, но этот код ещё не развёрнут на стенде673e5ba. Блок12.5.9 добавляет отдельный graceful shutdown worker для database operation, serial flush, pool.end и обязательные acknowledgement/exit0. Локальные protocol tests и настоящий isolated collector/UDP/blocked SQL drain12.5.10 прошли: evidence. Основной код на стенде ещё не обновлён; app-wide quiescence этим не подтверждена. Блок12.5.11 локально добавляет admission/drain всех API handlers иtraffic live streams; новые tests/build passed, на стенде patch не развёрнут. Detached backup jobs/audit иRIPE background persistence ещё неохвачены и требуют12.5.12. Другие экземпляры/хосты требуют отдельного контроля. PG-6 остаётся открытым до наблюдаемого подтверждения; восстановление стенда выполняется после его получения. Реальные тесты backend, способные очищать таблицы, запускаются только против выделенной тестовой БД.

После bootstrap достаточно следующих запросов чтения для начальной проверки, без вывода секретов:

SELECT id FROM schema_migrations
WHERE id IN ('0008_alert_outbox_outcomes', '0009_alert_outbox_resolution');
SELECT status, count(*) FROM alert_outbox GROUP BY status;
SELECT min(resolution_version), max(resolution_version) FROM alert_outbox;

Очередь уведомлений и Telegram

ID Сценарий Проверяемый результат
Q-1 Два конкурентных claim одной записи Один sender получает право отправить; duplicate claim не отправляет второй запрос
Q-2 Telegram принял сообщение, затем settlement/history transaction отказала Ответ Telegram не подменяет DB receipt; запись удерживается в unknown/processing, автоматического повторения нет
Q-3 Timeout после возможной отправки UI сообщает неизвестный исход; сообщение в чате и состояние БД проверяются независимо
Q-4 POST /api/alerts/outbox/:id/retry для unknown с текущим expectedVersion Одна транзакция переводит запись в pending и увеличивает resolutionVersion ровно на1; stale version даёт409 без нового изменения
Q-5 Повтор processing или unknown без подтверждённой остановки всех отправителей Processing не разрешается вручную через этот API. Перед повтором unknown зафиксированы остановка всех senders и осознанный риск дубликата
Q-6 Два enqueue с одинаковым dedupe key В PostgreSQL создана одна запись; нет двух отправок из-за race
Q-7 Нарушение прав, malformed receipt, изменение источника при pending Отказ до действия; UI сохраняет checkpoint/черновик и не переносит результат в другой источник

Для Q-1/Q-6 нужны конкурентные соединения реального PG; in-memory DI не доказывает изоляцию. Для Q-2 проверить атомарность status/history при ошибке внутри транзакции. Остановка senders подтверждается процессами/контейнерами и завершением in-flight requests; checkbox, timeout и отсутствие недавних логов достаточным доказательством не являются. Различать принятие Telegram API и прочтение пользователем.

Источники: outbox, delivery, retry, HTTP.

RouterOS и сетевые операции

ID Сценарий Проверяемый результат
ROS-1 Bandwidth-test transmit/receive/both на паре тестовых устройств Реальный REST shape содержит native completion; TX — отправка клиента, RX — приём. Неизмеренная сторона null, измеренный0 сохраняется
ROS-2 Authentication failed, unreachable, busy, disconnect и прерванный тест Backend не пишет done и не заменяет старые probe averages; error run/HTTP/UI согласованы
ROS-3 Выбранный srcInterface и тест скорости Независимо проверить маршрут bandwidth-test и interface after-ping. UI не выдаёт выбор Ping-интерфейса за доказательство WAN скоростного теста
ROS-4 Home→JH и JH↔Exit с асимметричной скоростью Направления DL/UL соответствуют клиентской стороне; model limits применяются к правильному направлению
ROS-5 OSPF preview → действие → перечитывание templates Preview соответствует исправленным RX/DL и TX/UL. Применение подтверждается фактическим cost; частичный отказ не становится полным успехом
ROS-6 WireGuard/IPsec/GRE/VXLAN/Firewall/BGP/маршруты Проблема→устройство→форма→подтверждённое действие→возврат сохраняет контекст. Права и повторное нажатие проверены; фактическая конфигурация и connectivity сверены
ROS-9 Смена пары или параметров измерения в каталоге и конкурентное завершение native test Новый snapshot unknown, старый run сохранён с actual endpoints; enable/reorder сохраняют измеренный0. Проверить row locks/условный UPDATE в реальном PG
ROS-8 Смена пары, интерфейсов, протокола, направления, длительности или удаление speed-пробы до запуска и во время теста Preflight409 до команды; при поздней смене новый snapshot не перезаписан, actual run сохранён без stale probe association
ROS-10 POST speed-test и последующий GET истории/пробы с разными часовыми поясами браузера и сервера createdAt сохраняет серверный instant и совпадает с записью; nullable Ping не становится timeout. Это время перед after-ping, не начало bandwidth-test; legacy receipt без createdAt отдельно обозначить в evidence
ROS-7 Удаление/отсутствие доступа/частичный отказ одного устройства Ошибка не стирает форму, последний снимок и объекты остальных устройств; неизвестные метрики не превращаются в0

Для ROS-1/ROS-2 зафиксировать версию RouterOS и очищенный сырой ответ. Строковый status подтверждается по официальному CLI reference; несовместимый REST shape требует отдельной коррекции контракта. Тест скорости способен нагрузить канал — длительность и endpoints выбираются для выделенного стенда. Команды и правила маршрутизации этой UX/UI-серией не расширялись.

Остальные интеграции

Область Минимальная реальная проверка
MaxMind/RIPE Валидный ответ, отказ/timeout, свежесть источника и неизвестное значение; реальные данные сверены с тестовыми адресами
Portal/Evolution Настоящие роли/JWT, истечение/отзыв прав, scope приложения и смена backend; отказ происходит до операции
Сертификаты/S3/контейнеры Реальный job/файл/объект и права после receipt; ошибка/частичный исход, восстановление контекста
Gitea/CI/релизы Сборка и delivery в выделенном стенде, отображение фактического статуса и версия. Git-коммиты текущей задачи остаются локальными; публикация — отдельное действие

BGP-prefix evaluator, отдельное live GRE расписание и recovery processing не считать реализованными по UI или локальным тестам: текущие ограничения описаны в журналах11Б/12.

Запись результата и критерий завершения

Для каждого ID сохранить: HEAD, UTC, идентификатор стенда/версию, роль, исходное состояние, действие, HTTP/native receipt, независимо подтверждённое итоговое состояние, результат passed/failed/blocked, способ возврата стенда и ссылку на очищенное доказательство. Пример строки:

ID HEAD / стенд Доказательство Результат Следующий шаг
ROS-1 Заполнить при запуске Очищенные native rows + GET истории + снимок UI Не выполнен Проверить transmit/receive/both

12.5 закрывается после выполнения обязательных сценариев и разбора отказов на согласованном стенде. Подготовленный протокол, успешные browser/DI tests и автоматический axe-аудит не заменяют внешние результаты или ручную работу со screen reader.