9 Commits
Author SHA1 Message Date
ayurishchevandClaude Opus 5.5 5f7bd6588a Состояния «Upgrade FW» и осознанный откат прошивки RouterBOARD
Пункт 18 ревью 2026-09-28 21:32 (docs/changes/027): после отката ROS
плата остаётся на более новой прошивке, а приложение сравнивало версии
на неравенство и показывало откат как обновление.
- devices.fw_state: unknown/update/downgrade/current; has_fw_update и
  фильтры не считают откат обновлением; метка «в ROS: X».
- upgrade_firmware не понижает прошивку; общая запись — _flash_firmware.
- Задача fw_downgrade: проверка → обязательный бэкап → запись →
  перезагрузка; API POST /devices/{id}/firmware/downgrade и
  /batch/fw_downgrade (target_version обязателен).
- UI: «Откатить прошивку…» (строка и группа), общее окно отката с kind.

Тесты: 39 из 39. Стенд: временное недоступное устройство — 422/202,
задачи failed на проверке, бэкапов нет. Реальная запись прошивки при
откате и ручная проверка UI не выполнялись.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 00:04:51 +03:00
ayurishchevandClaude Opus 5.5 ae826fc562 Состояния колонки «Upgrade ROS» и осознанный откат ROS до версии канала
После смены канала на long-term колонка показывала «актуально», хотя
версия канала (7.23.7) старше установленной (7.24.4) — docs/changes/023:
- состояния колонки: «↑ X», «актуально», «канал: X» (версия канала старше
  установленной), «проверка не удалась» (ошибка check-for-updates больше
  не маскируется под «актуально»), «—»;
- откат ROS до версии канала как отдельная задача ros_downgrade: проверка
  версии на устройстве → обязательный бэкап (сбой прерывает) → install;
- UI: «Откатить ROS…» в меню устройства и групповой пункт в «Обновление»,
  окно с вводом целевой версии, список не затрагиваемых устройств;
- API: POST /devices/{id}/update/downgrade и /batch/ros_downgrade с
  обязательным target_version. Штатное обновление откат не выполняет.

Тесты: 33 из 33. Стенд: 422 без версии, задачи отката на недоступном
устройстве завершаются на проверке без бэкапа. Реальный откат и ручная
проверка UI пользователем на момент коммита не выполнены.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 17:28:01 +03:00
ayurishchevandClaude Opus 5.5 0bda0038d0 Остаток п. 9 ревью: синхронная БД вне event loop, повторное ревью
Повторное ревью кодовой базы: docs/reviews/2026-09-28-1243-codebase-review.md
(статус 12 замечаний, новые замечания 13–16).

Остаток п. 9 (docs/changes/022):
- 14 async-функций API, UI и сервисов больше не обращаются к SQLite
  напрямую — через asyncio.to_thread; jobs.start_jobs стал async (БД в
  потоке, create_task в event loop); ops._conn для подключения к устройству;
- тест-линтер по AST: в async def нет прямых вызовов функций с
  session_scope — защита от регресса.

Тесты: 29 из 29. Стенд: задачи и актор событий в порядке, параллельные
запросы не ждут медленного устройства, боевые данные не изменены.
Ручная проверка UI пользователем на момент коммита не подтверждена.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 17:12:44 +03:00
ayurishchevandClaude Opus 5.5 ba8ac7be71 Кэш списка бакета, БД без блокировки event loop, один процесс на БД
Производительность и масштабирование, пункты 8–10 ревью (docs/changes/019):
- кэш списка бакета и связей файлов с копиями (BACKUPS_CACHE_TTL, 60 с):
  sync_rows только при реальном чтении бакета; сброс после бэкапа и
  удаления, счётчик поколений против гонки; refresh=1 и «Обновить список»;
- обработчики API/UI без await — обычные функции (пул потоков FastAPI),
  запуск задач остаётся async; запись статуса, задачи и sync_rows —
  через asyncio.to_thread; SQLite: WAL, synchronous=NORMAL, busy_timeout;
- файловая блокировка <файл БД>.lock: второй процесс на той же БД не
  стартует; раздел «Ограничения» в README.

Тесты: 24 из 24. Стенд (порт 8001): кэш 0,014 с против 0,138 с, второй
uvicorn на боевой БД отклонён блокировкой, боевые данные не изменены.
Ручная проверка UI пользователем на момент коммита не подтверждена.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:18:32 +03:00
ayurishchevandClaude Opus 5.5 123b5abdfc Ревью кодовой базы и исправления корректности по его итогам
Ревью кодовой базы: docs/reviews/2026-09-27-codebase-review.md.

Корректность и согласованность, пункты 5–7 ревью (docs/changes/018):
- одиночное удаление бэкапа в UI идёт через общий delete_many: пометка
  deleted_at и событие backup.deleted, как у группового удаления и API;
- единая система миграций: ручные ALTER из db._migrate перенесены в
  migrations.run (при user_version < 1, до замены ID);
- групповая смена канала выполняется фоновыми задачами set_channel;
  PUT /api/v1/batch/channel → 202 {"job_ids": [...]} (ломающее изменение
  API), меню «Канал» в UI выводит задачи в панель «Задачи».

Тесты: 22 из 22. Стенд проверен на порту 8001 (8000 занят посторонним
процессом), боевые данные не изменены. Ручная проверка UI пользователем
на момент коммита не подтверждена.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 21:23:34 +03:00
ayurishchevandClaude Sonnet 5 26dd1f8be4 Уникальные ID сущностей, журнал событий и его UI с ротацией и очисткой
Глобально уникальные ID (docs/changes/016):
- у устройств, групп, задач, резервных копий и записей журнала ID вида
  <префикс>_<uuid7> (dev_, grp_, job_, bkp_, evt_): типы не пересекаются,
  внутри типа ID не повторяются и сортируются по времени;
- миграция БД v1 заменяет числовые ID с пересчётом ссылок (копия файла БД
  перед миграцией, сверка числа строк, одна транзакция);
- резервная копия = пара файлов с одним bkp_ ID, файлы в S3 получают
  метаданные backup-id/device-id; синхронизация метаданных с бакетом;
- журнал событий в БД (events): создание/изменение/удаление, задачи, бэкапы,
  смена online/offline, вход в UI; API чтения GET /api/v1/events.

Журнал в UI, ротация и очистка (docs/changes/017):
- страница «Журнал»: фильтры, подгрузка «Показать ещё», окно записи;
- настройки ротации (срок и максимум записей) хранятся в БД (схема v2),
  ротация при старте, раз в час и после сохранения настроек;
- очистка журнала только через окно с паролем пользователя, блокировка
  после 5 неверных попыток, остаётся запись о факте очистки; через API
  очистки нет.

Тесты: 20 из 20.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 17:01:52 +03:00
ayurishchevandClaude Sonnet 5 1e5fb17755 Имя устройства задаётся только при создании
Имя входит в ключи бэкапов в S3 (backups/<имя>/…), поэтому после создания
не меняется (docs/changes/015):
- API: PATCH с другим именем → 400 «Имя устройства нельзя изменить»,
  то же имя допустимо;
- UI: в окне изменения поле имени только для чтения, форма изменения
  присланное имя игнорирует;
- вёрстка: минимальная ширина таблиц устройств и файлов — в узком окне
  колонка с именем не схлопывается, включается горизонтальная прокрутка.

Тесты: 12 из 12.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 15:53:08 +03:00
ayurishchevandClaude Sonnet 5 0914209bf8 Групповое удаление бэкапов, поддержка CHR, строгое сравнение версий ROS
Групповое удаление бэкапов (docs/changes/013):
- страница «Резервные копии»: чекбоксы, «выбрать все», панель «Выбрано: N /
  Удалить / Снять выбор» вместо фильтров, подтверждение, итог удаления;
- backups.delete_many: все ключи проверяются до удаления, удаление параллельное;
  UI POST /backups/delete-many, API POST /api/v1/backups/delete;
- выбор строк в app.js обобщён (data-select) для устройств и бэкапов.

Поддержка CHR (docs/changes/014):
- у CHR нет /system/routerboard (HTTP 400): устройство больше не считается
  недоступным, версия FW не показывается, обновление FW пропускается;
- «есть обновление ROS» определяется строгим сравнением версий (на канале
  long-term последняя версия может быть старше установленной);
- в таблице указана причина недоступности: авторизация / ошибка ответа /
  нет соединения.

Тесты: 11 из 11.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 14:11:32 +03:00
ayurishchevandClaude Sonnet 5 4c1841b61b ros_control: централизованное управление парком MikroTik RouterOS
Control Server (FastAPI) с WEB UI (Jinja2 + HTMX) и JSON API для группового
администрирования устройств RouterOS 7 через REST.

- Устройства: список, статус (модель, канал, версии ROS/FW, uptime, доступные
  обновления), примечания, пароли шифруются (Fernet); фоновый опрос каждые 30 с
  и быстрое обнаружение недоступности (таймаут соединения 4 с).
- Группы устройств и фильтры (устройства, резервные копии).
- Резервные копии: .backup и .rsc (show-sensitive) создаются через REST,
  скачиваются сервером и загружаются в S3 (Yandex Object Storage).
- Обновление ROS/FW и выбор канала, групповые операции задачами.
- Интерфейс по утверждённому макету: светлая/тёмная темы, окна, шрифты IBM Plex
  локально. Docker Compose, SQLite в томе, минимальный набор тестов.
- Планы и итоги каждого изменения — в docs/changes/.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 13:13:29 +03:00