fix(ui): восстанавливать задачу выпуска без повторной операции

This commit is contained in:
Denozordec committed 2026-10-01 14:29:56 +07:00
1 parent 97526bf06f
commit f5a71728ac
10 files changed
+322 -81

No files matched your search

+1 -1
View File
@@ -226,4 +226,4 @@ REST запрос → ожидание → подтверждённый output /
| Пользователи | [Профиль](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) |
Актуальная точка продолжения: 11А.21.4 — frontend checkpoint с requestId, resume и отмена выпуска. State API, reader, snapshot merge и nullable представление подключены в 11А.14–11А.17.3; таблица требований — [этап 11А](ux-ui-stage-11a.md). Сертификаты и весь 11А ещё не приняты.
Актуальная точка продолжения: 11А.22 — визуальная и профильная приёмка сертификатов, затем резервные копии. State API, reader, snapshot merge и nullable представление подключены в 11А.14–11А.17.3; таблица требований — [этап 11А](ux-ui-stage-11a.md). Сертификаты и весь 11А ещё не приняты.
+10 -1
View File
@@ -27,7 +27,7 @@
| 8 | Трафик и статистика | Завершён 2026-09-28 в границах локальной приёмки; ограничения в блоке 8.13 |
| 9 | VPN, Firewall и Filters | Завершён в границах локальной приёмки 2026-09-30; блоки 9.1–9.64, ограничения в 9.64 |
| 10 | Маршрутизация, диагностика, карта и терминал | Завершён в границах локальной приёмки 2026-10-01; блоки 10.1–10.71, внешние ограничения в 10.71 |
| 11А | Пользователи, контейнеры, сертификаты и резервные копии | В работе: 11А.1–11А.21.3; пользователи/контейнеры приняты локально, сертификаты: state/URL/API/renew/ACME готовы; далее 11А.21.4 |
| 11А | Пользователи, контейнеры, сертификаты и резервные копии | В работе: 11А.1–11А.21.4; пользователи/контейнеры приняты локально, сертификаты: state/URL/API/renew/ACME готовы; далее 11А.22 |
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Не начат |
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Не начат |
@@ -36,6 +36,15 @@
## Блок 11А.21.4 — сохраняемая задача выпуска на странице (2026-10-01)
- До POST создаётся requestId и immutable цель, записывается checkpoint sessionStorage по backend URL. Невозможность первоначальной записи не отправляет выпуск. Reload восстанавливает ту же задачу; моковый режим не показывает live checkpoint. Повреждённая запись блокирует новый выпуск.
- Принятый job повторно наблюдается GET/poll без POST. Неподтверждённый запрос сначала проверяет известный ID; при 404 повторяет тот же POST/requestId, защищённый backend от дублей. Read/write права разделены. Ошибка GET/чужая цель не считаются успешным или failed выпуском.
- Sheet/Stepper сохраняют цель и блокируют её изменение после принятия; реальный failed и частичное выполнение показаны явно. Новый выпуск после terminal требует отдельного действия и начинается с пустого имени/доменов. Закрытие формы не объявляется отменой server job. После done ошибка перечитывания каталога не меняет результат задачи. Неподключённый FileImportDialog с ложным callback удалён.
- При unmount отменяются POST/poll/задержки; поздние успех/ошибка не меняют другой backend/mode и не показывают старый toast.
- 3 checkpoint + 5 poll unit, 7 issue E2E, 8 source/context E2E, TypeScript/ESLint и production frontend прошли. Реальный PostgreSQL/ACME/RouterOS выпуск не проверен; pending job восстановление после перезапуска backend требует отдельной инфраструктурной приёмки.
- Следующий блок 11А.22: семантические токены, клавиатура/ПК/390/320, снимки и профильная регрессия сертификатов. Импорт/экспорт приватного ключа остаются явно недоступны; безопасный JSON снимок каталога можно добавить отдельно. Затем резервные копии и 11Б/12.
## Блок 11А.21.3 — устойчивое создание issue задачи (2026-10-01)
- В запрос выпуска добавлен необязательный UUID requestId. Backend использует существующий primary key задачи и INSERT ON CONFLICT DO NOTHING: повтор идентичной цели возвращает тот же jobId без повторной очереди, другая цель/source с тем же ID получает 409. Старые клиенты без requestId продолжают получать независимые UUID. Миграция БД не нужна.
+9
View File
@@ -263,3 +263,12 @@
- Request ID сохраняется и проверяется frontend API; чужое подтверждение отклоняется. Server ID должен быть безопасным положительным целым, имя/домены не могут быть пустыми после trim. Контракт нормализует поля перед созданием.
- 4 request helper unit (включая конкурентный повтор), HTTP handler fault проверки, backend test:certificates/build, 6 frontend API unit, polling unit, frontend TypeScript и профильный lint прошли. Проверки helper/HTTP используют тестовый repository; реальный PostgreSQL INSERT и RouterOS выпуск остаются внешней приёмкой. Runner и сетевой порядок операций не менялись.
- Следующий блок 11А.21.4: frontend checkpoint с заранее созданным requestId и неизменной целью, resume GET/poll без нового ID, сохранение в пределах источника, отмена и HTTP fault/context проверки.
## Блок 11А.21.4 — сохраняемая задача выпуска на странице (2026-10-01)
- До POST создаётся requestId и immutable цель, записывается checkpoint sessionStorage по backend URL. Невозможность первоначальной записи не отправляет выпуск. Reload восстанавливает ту же задачу; моковый режим не показывает live checkpoint. Повреждённая запись блокирует новый выпуск.
- Принятый job повторно наблюдается GET/poll без POST. Неподтверждённый запрос сначала проверяет известный ID; при 404 повторяет тот же POST/requestId, защищённый backend от дублей. Read/write права разделены. Ошибка GET/чужая цель не считаются успешным или failed выпуском.
- Sheet/Stepper сохраняют цель и блокируют её изменение после принятия; реальный failed и частичное выполнение показаны явно. Новый выпуск после terminal требует отдельного действия и начинается с пустого имени/доменов. Закрытие формы не объявляется отменой server job. После done ошибка перечитывания каталога не меняет результат задачи. Неподключённый FileImportDialog с ложным callback удалён.
- При unmount отменяются POST/poll/задержки; поздние успех/ошибка не меняют другой backend/mode и не показывают старый toast.
- 3 checkpoint + 5 poll unit, 7 issue E2E, 8 source/context E2E, TypeScript/ESLint и production frontend прошли. Реальный PostgreSQL/ACME/RouterOS выпуск не проверен; pending job восстановление после перезапуска backend требует отдельной инфраструктурной приёмки.
- Следующий блок 11А.22: семантические токены, клавиатура/ПК/390/320, снимки и профильная регрессия сертификатов. Импорт/экспорт приватного ключа остаются явно недоступны; безопасный JSON снимок каталога можно добавить отдельно. Затем резервные копии и 11Б/12.