DOCS+HISTORY: Opus architecture prompt, Q&A, implementation plan, session logs

This commit is contained in:
2026-07-31 08:39:19 +04:00
parent 6e2418b157
commit bcacb1fb33
5 changed files with 586 additions and 0 deletions
+103
View File
@@ -0,0 +1,103 @@
# 2026-07-30 — Сессия (v1.1.51 → v1.1.55)
## Контекст
Сценарий `dummy_test` падает на шаге CREATE: `no instanceUid in response`. Ручное создание Болванки через UI работает.
## Найденные и исправленные баги
### Баг #1 — no instanceUid in response (ЛОЖНАЯ ТРЕВОГА)
**Где:** `scenario.py:122``resp.get("instanceUid")` возвращал None.
**Причина:** сценарий НЕ перезапускался после деплоя v1.1.52. UI показывал старый результат из БД от v1.1.51 (баг #3).
**Проверка curl:** API отвечает корректно — 201, `Location: ./UUID`, тело `""`. `http_client.py` правильно парсит.
**Добавлено в v1.1.52:** `_status` (HTTP-код) в результат `http_client.post()` для отладки.
### Баг #2 — лишний svcOperationId для create (ИСПРАВЛЕН в v1.1.52)
**Где:** `scenario.py:127`
Для `create` операция `/instanceOperations` не должна содержать `svcOperationId` (по спецификации Terraform). Было одинаково для всех операций, стало:
```python
if op_name == "create":
op_payload = {"instanceUid": instance_uid, "operation": op_name}
else:
op_payload = {"instanceUid": instance_uid, "svcOperationId": svc_op_id, "operation": op_name}
```
### Баг #3 — старые результаты сценариев после редеплоя (ИСПРАВЛЕН в v1.1.53)
**Где:** `api_scenario.py` + `app.js`
**Симптом:** после редеплоя UI показывал результат сценария от СТАРОЙ версии (из БД), пользователь думал что новый код не работает.
**Причина:** `/api/scenario/status` не возвращал `app_version`, фронтенд не фильтровал по версии.
**Исправление:**
- `api_scenario.py`: добавлен `app_version` в SELECT обоих эндпоинтов
- `app.js`: `loadScenarios()` фильтрует историю по `window.APP.version` — показывает только запуски текущей версии
### Баг #4 — нельзя удалять без suspend (ОБНАРУЖЕН)
DELETE после CREATE падает: «Невозможно выполнить операцию удаления услуги. Услуга не остановлена».
Нужно сначала suspend + 15 мин ожидания. **Вывод:** не использовать delete в сценариях.
## Хронология
### v1.1.52 — fix scenario create + http_client _status debug
- `scenario.py`: убран `svcOperationId` из create payload
- `http_client.py`: добавлен `{"_status": r.status_code}` в результат для отладки
### v1.1.53 — filter scenario history by app_version
- `api_scenario.py`: `app_version` в SELECT
- `app.js`: фильтр `verHistory = srHistory.filter(r => r.app_version === curVer)`
### v1.1.55 — split large files + CRUD scenario editor
**Backend (5→7 файлов):**
- `api_test.py`: 622→479 строк, terraform-функции → `operations/terraform.py` (142)
- `api_scenario.py``api_scenario_run.py` (153) + `api_scenario_defs.py` (108)
- `db/scenario_defs.py`: + `client_id`, `stand`, `is_seed` в `list_definitions`
- `api_scenario_defs.py`: `_validate_steps()` — валидация шагов перед create/update
- `scenario.py`: импорт `send_params_terraform` из `operations/terraform.py` (вместо кросс-импорта из routes)
**Frontend (1→10 файлов):**
- `app.js`: 554→16 (загрузчик)
- `utils.js` (45), `instances.js` (89), `operations.js` (249)
- `history.js` (35), `scenario-list.js` (90)
- CRUD: `scenario-form.js` (128), `scenario-create.js` (25, +clone), `scenario-edit.js` (12), `scenario-delete.js` (13)
- Кнопки [▶][✏][⎘][🗑], seed-сценарии только [▶][⎘]
- Inline-редактор: имя, шаги (service_id, operation, params), 409 conflict
**Максимальный размер файла:** JS 249 строк, Python 479 строк.
## Agent consultations
### Вопрос к Sonnet: план CRUD-редактирования сценариев
**Суть:** сейчас сценарии правятся только через `scenario_seed.yaml` → редеплой. Нужно редактирование через UI без редеплоя.
**Ответ Sonnet (ключевые выводы):**
1. **CRUD-эндпоинты УЖЕ реализованы** в `api_scenario.py` (я ошибался, они есть):
- `GET/POST /api/scenario/definitions`
- `GET/PUT/DELETE /api/scenario/definitions/<id>`
- DB-функции в `scenario_defs.py` полностью готовы
2. **Нужны только 3 мелкие правки бэкенда:**
- `list_definitions`: добавить `client_id`, `stand`, `is_seed` в SELECT
- `api_scenario.py`: `_validate_steps()` с проверкой service_id, operation, params
- `index.html`: `window.APP.services` (список сервисов для фронтенда)
3. **Фронтенд — ~200 строк JS:**
- Кнопки [▶][✏][⎘][🗑] у каждого сценария
- Inline-редактор: имя, шаги (сервис▾, операция▾, параметры)
- Автоподгрузка операций при смене сервиса (`GET /api/operations/{svcId}`)
- Автозаполнение параметров при смене операции (`GET /api/params/{svcOpId}`)
- Оптимистичная блокировка (version → 409)
4. **Безопасность:** изоляция по client_id+stand, seed-сценарии только [▶][⎘]
## Отладка через kubectl
- SSH: `naeel@5.172.178.213` (ключ `secrets/id_ed25519.txt`)
- Неймспейс autotest: `01a2d5b2-4df4-4cfe-b98e-8dd3534a3bb5`
- Код в поде: `/var/www/site/`
- Проверка версии: `kubectl exec -n $NS deploy/pythonk8s -c app -- grep VERSION /var/www/site/app.py`
+71
View File
@@ -0,0 +1,71 @@
# 2026-07-31 — Сессия (v1.1.57 → ...)
## Контекст
Обсуждение архитектуры: унификация ручного и сценарного режимов, гибкие ссылки на инстансы, новый UI редактора сценариев.
## Agent consultations
### Промпт для Opus
Составлен `DOCS/opus-architecture-prompt.md` — полное описание проекта, дублирование CREATE-флоу, ограничение instance_map, вопросы по архитектуре.
### Ответ Opus — 19 уточняющих вопросов
**A. Единый executor (operations/executor.py)**
1. Граница ответственности: executor делает всё до /run, поллинг — снаружи?
2. Обработка ошибок: исключения с типом или dict {ok, error, failed_step}?
3. Трекер: вызывать tracker_add внутри executor для create? Нужны ли сценарные инстансы в трекере?
4. _finish_op: остаётся в api_test.py или выносим в общий модуль поллинга?
**B. Гибкие ссылки на инстансы**
5. Приоритет резолвинга: instance_uid > instance_ref > (для create — новый)
6. Где хранить output→uid: в памяти (instance_map) или в scenario_runs.instance_bindings?
7. Валидация _validate_steps: проверять ссылки на output, уникальность, обязательность
8. Обратная совместимость: поддерживать старый формат (service_id) или мигрировать?
**C. Схема БД**
9. Формат в steps JSONB без изменений схемы? (подтверждено)
10. Использовать существующую колонку scenario_runs.instance_bindings?
**D. UI редактора**
11. Модал vs inline — рекомендация: модал на весь экран
12. Переиспользовать renderParamRow из operations.js в общем модуле?
13. Pre-fill параметров: авто или по кнопке?
14. Формат параметров: символические имена в БД (как сейчас) или иное?
**E. Оптимизация**
15. Вынести _find_uid/_uid_from_location в общий utils
16. Механизм восстановления зависших scenario_runs?
17. Ограничение lock_check: только один RUNNING сценарий — осознанное?
18. _op_results в памяти → мигрировать в БД/Redis?
19. Приоритет: бэкенд или UI редактора в первую очередь?
## Ключевые решения (отвечено DeepSeek)
**A. Executor:**
- A1. Граница: до /run включительно, без поллинга. Возвращает {instance_uid, op_uid, display_name}
- A2. Ошибки: dict {ok, error, failed_step}, не исключения
- A3. Трекер: да, tracker_add внутри executor для всех create
- A4. _finish_op: оставить в api_test.py, цикл поллинга → operations/poll.py
**B. Ссылки:**
- B5. Приоритет: instance_uid > instance_ref > новый create
- B6. Хранение: память + scenario_runs.instance_bindings
- B7. Валидация: проверять ссылки, уникальность, обязательность
- B8. Совместимость: оба формата, без миграции, fallback на service_id
**C. БД:**
- C9. Без изменений схемы
- C10. Использовать instance_bindings
**D. UI:**
- D11. Модал на весь экран
- D12. Общий модуль params-render.js
- D13. Авто pre-fill, все параметры с defaults
- D14. Символические имена в БД
**E. Оптимизация:**
- E15. _find_uid → api/utils.py
- E16. Startup check: TIMEOUT для зависших >1ч
- E17. lock_check оставить
- E18. _op_results не в scope
- E19. Порядок: executor → формат → api_test/scenario → UI