# Итоги: 018 — корректность и согласованность (по ревью 2026-09-27) Источник — ревью `docs/reviews/2026-09-27-codebase-review.md`, раздел «Корректность и согласованность» (пункты 5–7). ## Сделано - **п. 5 — одиночное удаление бэкапа** (`app/ui/routes.py::backup_delete`): идёт через `backups.delete_many([key])`, как групповое и API. Проверка ключа, удаление, `sync_rows` (пометка `deleted_at`, событие `backup.deleted`) теперь общие; ответ — редирект `/backups?deleted=N&failed=M`. - **п. 6 — единая система миграций**: `db._migrate` удалён; колонки старой схемы (`use_tls`, `group_id`, `note`) добавляет `migrations._add_legacy_columns` при `user_version < 1` **до** `_to_v1` (та читает эти колонки). `SCHEMA_VERSION` = 2, схема не менялась. - **п. 7 — групповая смена канала фоновыми задачами**: тип задачи `set_channel` (`ops.run_set_channel` поверх `ops.set_channel`); `jobs.start_jobs(job_type, device_ids, params)` передаёт `params` раннеру и в `data` события `job.created`. `PUT /api/v1/batch/channel` → **202 `{"job_ids": [...]}`** (было: синхронный список устройств). UI: меню «Канал» создаёт задачи и обновляет панель «Задачи»; подпись «Смена канала» в таблице задач. Смена канала одного устройства (API и меню строки) не менялась. - README: таблица API, число тестов, строка 018 в истории изменений, каталог `docs/reviews`. ## Проверено - `pytest`: 22 из 22 (новые: `test_batch_channel_runs_as_jobs`, `test_migration_adds_legacy_columns_before_id_migration`; `test_bulk_delete_backups` дополнен одиночным удалением). - Стенд `ros_control-ros_control-1` пересобран, отдаёт новый код (`grep set_channel` в контейнере), `/login` → 200, старт без ошибок. - Сценарий на стенде с временным устройством `192.0.2.1`: `PUT /batch/channel` → 202; задача `set_channel` → `failed` (`ConnectTimeout`, ожидаемо); в `job.created` записан `{"channel": "stable"}`; неверный канал → 422; временное устройство удалено (204). - Боевые данные: группы 4/4, устройства 12/12, бэкапы 41/41 — совпадают по ID до и после; добавились только 1 задача и 7 событий проверки; `user_version` = 2. ## Оговорки - **Ломающее изменение API**: `PUT /api/v1/batch/channel` возвращает 202 и ID задач вместо списка устройств — клиентам нужно опрашивать `/api/v1/jobs/{id}`. - Порт 8000 на хосте занят посторонним процессом (`telemetry_web`), поэтому стенд временно запущен на 8001 через override-файл вне репозитория; `docker-compose.yml` не менялся. После освобождения порта — `docker compose up -d --force-recreate`. - Одиночное удаление на стенде не выполнялось (удалило бы реальный файл из бакета) — покрыто тестом. - Ручная проверка UI пользователем на момент коммита не подтверждена. - Записи проверки (тестовое устройство, задача, события) остались в журнале как обычные события.