# История разработки app-autotest # v1.0.74 (27.07.2026) — version bump for push ### Что изменилось - В `site/templates/index.html` create-операция отделена от обычных операций: CREATE использует фиксированный префикс `autotest-`, а non-create берёт имя выбранного инстанса. - Из non-create ветки убран случайный fallback `tut` и общий create-style `displayName`. - В `site/routes/api_test.py` backend больше не подставляет create-имя по умолчанию для обычных операций и возвращает `displayName` для финального статуса. - В `site/routes/main.py` список autotest-инстансов теперь строится cloud-first без старой склейки через map по имени; tracker остался только как временный fallback, если cloud ещё не вернул новый инстанс. ### Что это чинит - Путаницу между CREATE и обычными операциями. - Ситуацию, когда в UI появлялся лишний `tut`. - Дубли `running/creating` на одном autotest-инстансе. - Неясный финальный статус, где было видно операцию, но не было понятно, над каким инстансом она выполнялась. # v1.0.72 (27.07.2026) — service list keeps one autotest row per displayName ### Что изменилось - В `site/routes/main.py` сервисный список теперь cloud-first и не склеивает разные строки в одну map. - Tracker остаётся только как fallback, если cloud ещё не вернул конкретный autotest-инстанс. ### Что это чинит - Дубли `running/creating` на одном и том же autotest-инстансе. # v1.0.71 (27.07.2026) — finished status shows instance name ### Что изменилось - В `site/templates/index.html` финальная строка после `OK/FAIL` теперь показывает имя инстанса. - Имя операции и длительность остаются рядом, отдельно от имени инстанса. ### Что это чинит - Ситуацию, когда после завершения delete/modify было видно только название операции, но не ясно, над каким инстансом она выполнялась. # v1.0.70 (27.07.2026) — dedupe autotest instances by displayName ### Что изменилось - В `site/routes/main.py` сервисный список теперь склеивает записи по `displayName`. - Если cloud уже отдал `running`, он выигрывает у tracker-fallback `creating`. ### Что это чинит - Дубли одной и той же autotest-записи после CREATE, когда в списке появлялись и `running`, и `creating`. ## v1.0.69 (27.07.2026) — autotest prefix fixed in CREATE field ### Что изменилось - В `site/templates/index.html` префикс `autotest-` отображается отдельным фиксированным текстом. - Рядом с ним остаётся только редактируемый суффикс имени. - При отправке CREATE имя собирается как `autotest-` + введённый хвост. ### Что это чинит - Ситуацию, когда весь `displayName` показывался в одном редактируемом поле. - Риск случайно стереть обязательный префикс `autotest-`. ## v1.0.68 (27.07.2026) — operation name shown after OK + muted operation buttons ### Что изменилось - В `site/templates/index.html` финальный статус теперь показывает имя операции рядом со временем. - Кнопки операций получили спокойные неброские оттенки по типу операции. ### Что это чинит - Неясность после завершения операции, когда было видно только `OK` и время без указания, что именно выполнялось. - Слишком кислотный вид кнопок операций. ## v1.0.67 (27.07.2026) — autotest instances are shown by cloud prefix ### Что изменилось - В `site/routes/main.py` список инстансов сервиса больше не отфильтровывается через `/tmp/instances.json`. - Теперь в таблицу попадают все облачные инстансы с префиксом `autotest-`. - Трекер оставлен только как fallback, если новый autotest-инстанс ещё не успел появиться в ответе облака. ### Что это чинит - Ситуацию, когда autotest-инстанс уже есть в облаке, но не показывается в таблице из-за отсутствия записи в json. ## v1.0.66 (27.07.2026) — backend status resolver for operations ### Что изменилось - В `site/routes/main.py` добавлен канонический резолвер статуса инстанса для `/api/operations/`. - Backend теперь отдаёт `status` для инстансов, а UI читает именно его вместо угадывания по `explainedStatus`. - В `site/templates/index.html` убрано раннее отображение «Готово» во время выполнения операции. ### Что это чинит - Путаницу между `creating`, `running` и фактическим статусом в UI. - Ситуацию, когда фронтенд сам интерпретировал статусы и показывал не то состояние. ## v1.0.65 (27.07.2026) — cloud list pagination fix ### Что изменилось - В `site/operations/get_instances.py` пагинация списка инстансов теперь останавливается по размеру страницы, а не по `total`. - Это убирает ситуацию, когда инстанс уже создан в облаке, но приложение не дочитало следующую страницу и показывает `creating`. - В `DOCS/ARCHITECTURE.md` и `site/app.py` синхронизирована версия `1.0.65`. ### Что это чинит - Ложный `creating` для уже существующего инстанса, если он попал не на первую страницу `/instances`. ## v1.0.64 (27.07.2026) — header version + editable displayName placeholder ### Что изменилось - В `site/routes/main.py` версия теперь гарантированно попадает в `config.VERSION` даже после `load_config()`. - В `site/templates/index.html` поле `displayName` остаётся редактируемым, но автотест-имя показывается как placeholder. - При CREATE пользователь может ввести своё имя, а backend всё равно добавит `autotest-` и проверит уникальность. - В `DOCS/ARCHITECTURE.md` зафиксированы оба изменения. ### Что это чинит - Пропадающую версию в шапке. - Неправильное поведение поля `displayName`, когда оно выглядело как готовое значение вместо подсказки. ## v1.0.63 (27.07.2026) — autotest namespace for instances ### Что изменилось - В `site/templates/index.html` CREATE теперь генерирует `displayName` с префиксом `autotest-` и проверяет его на уникальность среди текущих инстансов. - В `site/routes/api_test.py` backend тоже нормализует `displayName` с этим префиксом и, если нужно, добавляет суффикс для уникальности перед созданием в облаке. - В `site/routes/main.py` список инстансов фильтруется по namespace `autotest-`, чтобы в UI попадали только тестовые инстансы приложения. - В `DOCS/ARCHITECTURE.md` зафиксирован переход на namespace-based фильтрацию. ### Что это чинит - Дубли `displayName` при CREATE. - Чужие инстансы в списке. - Зависимость от локального трекера как от основного признака принадлежности. ## v1.0.62 (27.07.2026) — immediate visual refresh after CREATE ### Что изменилось - В `site/templates/index.html` после завершения CREATE список инстансов перерисовывается полностью. - `refreshInstances()` больше не зависит от DOM-diff и сразу ставит новый инстанс в список. - `DOCS/ARCHITECTURE.md` и `site/app.py` синхронизированы на `1.0.62`. ### Что это чинит - После появления кнопки «Готово» созданный инстанс должен сразу быть виден в списке. ## v1.0.61 (27.07.2026) — immediate list rebuild after CREATE ### Что изменилось - В `site/templates/index.html` `refreshInstances()` теперь всегда полностью перерисовывает список инстансов после завершения операции. - После `OK` новый инстанс должен появляться в списке сразу, без зависимости от DOM-diff и без перезагрузки страницы. - В `DOCS/ARCHITECTURE.md` и `site/app.py` синхронизирована версия `1.0.61`. ### Что это чинит - Убрана ситуация, когда после CREATE статус уже `OK`, но в UI инстанс ещё не виден. ## v1.0.60 (27.07.2026) — full list rerender after CREATE ### Что изменилось - В `site/templates/index.html` `refreshInstances()` теперь полностью перерисовывает список инстансов, а не пытается вставить только diff. - После завершения CREATE новый инстанс должен появляться в списке сразу после `OK`. - В `DOCS/ARCHITECTURE.md` добавлен отдельный шаг про полную перерисовку списка. ### Что это чинит - Снята зависимость от частичного DOM-diff-а, из-за которого созданный инстанс мог не появляться сразу. ## v1.0.59 (27.07.2026) — restore tracked instance after reload ### Что изменилось - В `site/routes/main.py` tracked-инстансы, которых Nubes уже не отдает в ответе после reload, снова добавляются в список из `/tmp/instances.json`. - В `site/templates/index.html` статус CREATE теперь показывает имя инстанса, а не только `create`. - В `DOCS/ARCHITECTURE.md` зафиксирован новый шаг восстановления списка после F5. ### Что это чинит - После F5 инстанс не пропадает из UI, если он есть в локальном трекере. - В статусе выполнения видно, по какому displayName идет CREATE. ## v1.0.58 (27.07.2026) — version bump - Поднята версия проекта до `1.0.58`. - Синхронизированы заголовки в `site/app.py` и `DOCS/ARCHITECTURE.md`. ## v1.0.57 (27.07.2026) — UI hardening + history sync ### Что изменилось - В `site/templates/index.html` финальное состояние кнопки вынесено в `setFinishedState()`, чтобы не держать логику завершения операции в двух местах. - После завершения операции кнопка «Готово» теперь гарантированно сбрасывает обработчик через `btn.onclick = null`. - Повторный CREATE через старый обработчик больше не воспроизводится. - `displayName` больше не теряется в нормальном сценарии завершения CREATE. - В `site/app.py` версия поднята до `1.0.57`. - В `DOCS/ARCHITECTURE.md` отмечено закрытие бага с повторным CREATE и синхронизирован статус по `displayName`. ### Зачем это было сделано - Убрать хрупкость вокруг состояния кнопки после завершения операции. - Привести документацию и версию к текущему состоянию кода. ## v1.0.54 (27.07.2026) — Аудит #3: 4 бага исправлено ### Баг #1: `_client()` не автоопределял стенд (КРИТИЧЕСКИЙ) - **Где:** `api_test.py:_client()` — использовал `current_app.config["NUBES_API_ENDPOINT"]` (raw env var) - **Симптом:** main.py автоопределял стенд для главной, но POST /api/test падал с 401 если токен от другого стенда - **Исправление:** `detect_endpoint()` вынесен в `api/http_client.py`, используется в `_client()` - **Как пропустили:** анализировал main.py и api_test.py в изоляции, не сравнил ### Баг #2: `_find_uid()` возвращал не тот UUID (КРИТИЧЕСКИЙ) - **Где:** `api_test.py:_find_uid()` — итерировал по ВСЕМ значениям dict, искал 36-символьную строку - **Симптом:** `/instanceOperations` возвращает оба `instanceUid` + `instanceOperationUid`, функция брала первый попавшийся → `run` шёл на неправильный URL - **Исправление:** ищет по конкретным ключам: `instanceOperationUid` → `instanceUid` → `uid` → `Uid` - **Как пропустили:** не проверил реальный формат ответа API ### Баг #3: Сироты при ошибке params (СРЕДНИЙ) - **Где:** `api_test.py`: порядок — `POST /instances` → `POST /instanceOperations` → params loop → `tracker_add` - **Симптом:** если params падает — инстанс и операция созданы в Nubes, трекер пуст → сироты - **Исправление:** `tracker_add` вызывается ДО params loop, сразу после получения `instanceUid` - **Как пропустили:** не трассировал линейно порядок вызовов ### Баг #4: `flock` без таймаута (НИЗКИЙ) - **Где:** `tracker.py:_locked_read/_write` — `fcntl.flock(fd, LOCK_EX)` без LOCK_NB - **Симптом:** при зависшем процессе с локом все воркеры блокируются навсегда - **Исправление:** `_acquire_lock()` с `LOCK_EX | LOCK_NB` + retry до 2 секунд - **Как пропустили:** новый код flock не перечитал с нуля после добавления ### Архитектурное: `detect_endpoint` вынесен в http_client.py - Раньше был в main.py → недоступен для api_test.py - Теперь в `api/http_client.py` → оба модуля используют --- ## v1.0.53 (27.07.2026) — Файловый трекер с fcntl.flock - In-memory dict заменён на `/tmp/instances.json` с `fcntl.LOCK_EX` - Multi-worker gunicorn: все воркеры читают/пишут один файл под локом ## v1.0.52 (27.07.2026) — `_tmpl()` helper - Все переменные шаблона передаются во всех трёх return-путях index() - Исправлен UndefinedError при «Выйти» ## v1.0.51 (27.07.2026) — Автоопределение стенда + UnboundLocalError - `detect_endpoint()` в main.py: пробует токен против dev и test API - `instance_groups = {}` инициализирован до if - `_finish_op` обёрнут в полный try/except ## v1.0.50 (27.07.2026) — showStages + api_operations fix - `showStages()`: dtFinish вместо isSuccessful для ⏳/✅/❌ - `api_operations()`: не фильтровать "not created", добавлять tracked-сирот ## v1.0.49 (27.07.2026) — In-memory tracker + refreshInstances - Трекер: in-memory dict вместо файла `/tmp/instances.json` - `refreshInstances()` добавляет новые инстансы в DOM (не только бейджи) - `selectService()` заменён на `refreshInstances()` после OK ## v1.0.48 (27.07.2026) — tracker_add синхронно - `tracker_add` в `api_test()` до `threading.Thread` - Лог `is_ok` в `_finish_op` - Flexbox-кнопки горизонтально ## v1.0.47 (27.07.2026) — displayName fix - displayName захватывается до очистки формы - tracker_add до _op_results[OK] - autotest-1 в _INITIAL ## v1.0.46 (27.07.2026) — _finish_op signature - Добавлены op_name, svc_op_id в _finish_op() ## v1.0.45 и ранее - Базовый CREATE/MODIFY/SUSPEND/DELETE/RESUME/REDEPLOY - UI с этапами, поллинг, params форма - Множественные баги CREATE flow (документированы в DOCS/api-create-flow.md)