# AGENT BRIEFING — app-autotest (2026-07-31, v1.2.23) > **Контекст для нового агента.** Прочитай этот файл полностью — он заменит тебе чтение 4166 строк истории чата. Здесь всё что нужно знать чтобы продолжить работу. --- ## 1. Что такое app-autotest Flask 3.1 + vanilla JS + PostgreSQL (psycopg2). Веб-приложение для автоматического тестирования сервисов облачной платформы Nubes через REST API. **Ручной режим:** выбрать сервис → выбрать операцию (create/modify/delete/suspend/resume/redeploy) → заполнить параметры → запустить → поллинг статуса. **Сценарный режим:** последовательность операций с передачей контекста между шагами. Сценарии редактируются через модальный UI, хранятся в БД. **Деплой:** Nubes pythonk8s managed service, gunicorn --workers 2. **URL:** `https://atest.pythonk8s.dev.nubes.ru` **Репозиторий:** `https://gitea.services.ngcloud.ru/forcloud/app-autotest.git` (ветка `master`) ### Файлы которые надо прочитать (обязательно) - [DOCS/ARCHITECTURE.md](DOCS/ARCHITECTURE.md) — архитектура, эндпоинты, безопасность - [DOCS/polygon-plan.md](DOCS/polygon-plan.md) — полный план мок-полигона - [HISTORY/2026-07-31-session.md](HISTORY/2026-07-31-session.md) — хронология всего что сделано сегодня - [TASKS/mock-architecture-prompt.md](TASKS/mock-architecture-prompt.md) — исходный промпт для Опуса - [TASKS/universal-mock-generator-prompt.md](TASKS/universal-mock-generator-prompt.md) — промпт про STANDS YAML ### Структура кода ``` app-autotest/site/ ├── app.py # точка входа (VERSION = "1.2.23") ├── api/ │ ├── auth.py # токен/clientId/stand из JWT cookie │ ├── http_client.py # HttpClient (requests.Session) + автостенд │ └── utils.py # find_uid(), uid_from_location() ├── operations/ │ ├── executor.py # ЕДИНЫЙ запуск (create→instanceOperations→params→run) │ ├── poll.py # poll_until_done() — поллинг до dtFinish │ ├── scenario.py # run_scenario() — шаги с резолвингом instance_ref │ ├── terraform.py # send_params_terraform() — нормализация + refSvc + validate-cfs │ ├── tracker.py # JSON-файловый кеш /tmp/instances-*.json (flock) │ ├── get_instances.py # GET /instances с пагинацией │ ├── get_params.py # параметры с ТЕКУЩИМИ значениями из state.params │ ├── get_services.py # GET /services │ └── service_list.py # services_{stand}.txt фильтр ├── db/ │ ├── pool.py # ThreadedConnectionPool(1,5) │ ├── init_db.py # CREATE TABLE + миграции + idx_one_running + seed │ ├── save_run.py # INSERT в runs + instance_meta JSONB │ └── scenario_defs.py # CRUD scenario_definitions + lock_check (трёхсостояночный) ├── routes/ │ ├── main.py # GET/POST / — главная страница │ ├── api_test.py # /api/test, /api/params, /api/log (основная логика) │ ├── api_scenario_run.py # /api/scenario/run, /api/scenario/status │ ├── api_scenario_defs.py # CRUD /api/scenario/definitions │ ├── api_scenario.py # ДУБЛИКАТ? (241 строка) │ └── api.py # LEGACY /api/run ├── static/ │ ├── app.js, style.css │ └── js/ (12 файлов: utils, icons, snackbar, views, instances, operations, │ params-render, history, scenario-list, scenario-form, │ scenario-create, scenario-edit, scenario-delete) └── templates/ └── index.html ``` --- ## 2. Что было сделано сегодня (2026-07-31) ### Версии - v1.2.16 → v1.2.23 (8 версий) - 23 коммита в app-autotest, 9 в root autotest ### Комментарии ко ВСЕМУ коду 29 файлов, ~6000 строк. Подробные комментарии к каждой функции, каждому if-ветвлению, каждому архитектурному решению. Python + JS. ### Аудит безопасности (GPT-5.3-Codex, 3 раунда) **Раунд 1 (11 находок):** - v1.2.19: XSS params, JS injection onclick, polling timeout, has_target, tracker atomic update - v1.2.20: _op_results lock (threading.Lock), advisory lock (pg_try_advisory_lock), _ensure_schema logging, stale async generation token, validate-cfs JSONDecodeError **Раунд 2 (Codex нашёл 2 критических ошибки в моих фиксах):** - ❌ Advisory lock сломан: брал lock на conn1, unlock на conn2 (другая сессия из пула) - ❌ escName без `"` escape: HTML-атрибут onclick="..." разрывается - v1.2.21: advisory lock → partial unique index `idx_one_running`, escName + `"` **Раунд 3 (3 находки):** - v1.2.22: UniqueViolation→409, escName + `&`, lock_check fallback - v1.2.23: трёхсостояночный lock_check (True/False/None→503) после дискуссии **Тесты:** `app-autotest/tests/` — 5 файлов от Codex (conftest, test_api_scenario_run, test_db_scenario_defs, test_static_regressions, README). Покрывают критические фиксы. НЕ запускались. ### Архитектура мок-полигона (Опус) **Концепция:** отдельный managed-сервис `https://nubes_polygon.pythonk8s.dev.nubes.ru`, притворяющийся Nubes API для всех 37 сервисов. **10 архитектурных решений** (см. [DOCS/polygon-plan.md](DOCS/polygon-plan.md)): - Отдельный процесс :5001 (не blueprint) - Data-driven: сервисы из STANDS YAML, не хардкод - Ленивый dtFinish (без потоков) - Единая стейт-машина (create→running→suspended→deleted) - Реальный мерж params при modify - `/_mock/reset` для тестов **Универсальный конвертер STANDS YAML** — Опус подтвердил: `polygon/from_stands.py` читает 37 YAML из `STANDS/test/resources_yaml/` и генерит конфиги для всех сервисов. Маппинг почти 1:1 (см. HISTORY). **Subresource-операции** — `create_user`/`create_database` через обычный `apply_effect` с флагом `subresource`. Универсально, без сервис-специфичного кода. --- ## 3. Что надо делать дальше ### 🔴 Срочно (сегодня) **Реализовать мок-полигон** по плану в [DOCS/polygon-plan.md](DOCS/polygon-plan.md): Фаза 1 — MVP: 1. `polygon/defaults.py` — `default_for(dataType)` 2. `polygon/from_stands.py` — конвертер STANDS YAML → polygon config 3. `polygon/state.py` — `MockState` (instances, operations, ленивый dtFinish, apply_effect, reset) 4. `polygon/server.py` — Flask на порту 5001, префикс `/api/v1/svc`, Location-заголовки 5. `polygon/services/` — НЕ создавать вручную! Генерится из STANDS 6. Интеграция в `auth.py` — short-circuit localhost (см. §3.3 в polygon-plan.md) Фаза 2 — полный CRUD: 7. GET /instances, GET /instances/{uid}, GET /services, GET /services/{id} 8. GET /instanceOperations/default/{id} (cfsParams шаблон) 9. apply_effect для всех операций + subresource 10. `/_mock/reset` Фаза 3 — тесты: 11. `tests/conftest.py` — фикстура поднятия мока 12. `tests/test_mock_integration.py` — 5 сценариев через app_client ### 🟡 В планах - Прогнать конвертер на ВСЕХ 37 YAML, найти аномалии - Исправить `instances.js:78` — instanceUid в onclick (низкий риск) - Вынести `_op_results` в Redis/БД (архитектурное ограничение) - Context snapshot всех инстансов пользователя (идея из HISTORY) --- ## 4. Ключевые файлы документации | Файл | Содержание | |------|-----------| | [DOCS/ARCHITECTURE.md](DOCS/ARCHITECTURE.md) | Полная архитектура, эндпоинты Nubes API, безопасность (§8) | | [DOCS/polygon-plan.md](DOCS/polygon-plan.md) | План мок-полигона: 3 фазы, 12 шагов, YAML-спецификация | | [DOCS/architecture-final.md](DOCS/architecture-final.md) | Финальная архитектура | | [HISTORY/2026-07-31-session.md](HISTORY/2026-07-31-session.md) | Хронология: все версии, аудит, ошибки, дискуссии | | [TASKS/mock-architecture-prompt.md](TASKS/mock-architecture-prompt.md) | Исходный промпт для Опуса | | [TASKS/universal-mock-generator-prompt.md](TASKS/universal-mock-generator-prompt.md) | Промпт про STANDS YAML + ответы | | [STANDS/test/resources_yaml/](STANDS/test/resources_yaml/) | 37 YAML — источник для конвертера | --- ## 5. Что НЕ надо делать - ❌ Не деплоить app-autotest без повышения версии - ❌ Не править код без явного «делай» - ❌ Не использовать sed для правки файлов - ❌ Не удалять файлы/БД/контейнеры без разрешения --- ## 6. Как запускать ```bash # app-autotest (основное) cd app-autotest/site && python app.py # порт 5000 # Мок-полигон (когда будет готов) cd app-autotest && STANDS_DIR=../STANDS/test/resources_yaml python polygon/server.py # порт 5001 # Тесты (когда будут готовы) NUBES_API_ENDPOINT=http://localhost:5001/api/v1/svc pytest tests/ -v ```