Commit Graph
263 Commits
Author SHA1 Message Date
Repinoid e0130a2baf feat: add in-app user help 2026-10-25 18:01:55 +03:00
Repinoid 1f8e00e4f9 feat: configure cloud API endpoints by stand 2026-10-25 17:43:42 +03:00
Repinoid 5b19094a4d feat: support configured production API endpoint 2026-10-25 16:51:27 +03:00
Repinoid 4203e5674c fix: adapt autotest to updated service APIs 2026-10-25 16:30:25 +03:00
“Naeel” 8d956c8063 Docs: исправление ссылки на api-operation-stages.html в README 2026-08-09 14:50:09 +04:00
“Naeel” 802f527fb5 fix: нельзя сохранить сценарий — валидация + svcId для instance_ref (v1.2.47)
Баг 1: collectFormSteps не вычислял svcId для instance_ref
  (output-ссылка не резолвилась в service_id)
Баг 2: валидация требовала service_id для ВСЕХ шагов,
  включая не-create с instance_ref/instance_uid
2026-08-04 15:22:57 +04:00
“Naeel” 5c102387b3 fix: параметры не грузились в редакторе сценариев (v1.2.46)
Причина: select сервиса и instance_ref не имели onchange —
  step.service_id и step.instance_ref никогда не обновлялись.
  loadStepParams() падал на if (!svcId) return null.

Исправлено: onchange на select сервиса, select instance_ref, input output.
2026-08-04 14:52:41 +04:00
“Naeel” 862be69267 fix: история LIMIT 50->25 — ответ не влазил в 20KB (v1.2.45) 2026-08-04 14:50:07 +04:00
“Naeel” fe31b0579c fix: история — столбцы шире, дата в 1 строку, text-overflow (v1.2.44)
Время: 130->145px, Операция: 90->115px
Все ячейки: white-space:nowrap
Инстанс/Операция: overflow:hidden + text-overflow:ellipsis
2026-08-04 13:28:48 +04:00
“Naeel” 40f8321cf7 test: +PostgreSQL сценарий — create_user, create_database (тесты 9, 10) 2026-08-04 13:25:42 +04:00
“Naeel” c8a1471908 test: полная симуляция пользователя — 38 проверок, 8 сценариев
ТЕСТ 1: загрузка страницы, сервисы, инстансы
ТЕСТ 2: create 9 сервисов (Болванка, PostgreSQL, Redis, ...)
ТЕСТ 3: переключение DEV/TEST/PROD
ТЕСТ 4: Облако/Эмуляция туда-обратно
ТЕСТ 5: CRUD сценария + запуск + повтор + seed
ТЕСТ 6: история + проверка дубликатов
ТЕСТ 7: логи
ТЕСТ 8: валидация входных данных
2026-08-04 09:10:19 +04:00
“Naeel” 7e8f3b25b9 test: дымовой тест АВТОТЕСТА (не полигона) — create + история 2026-08-04 09:05:26 +04:00
“Naeel” e373fb7e2e test: дымовой create->modify->delete для всех сервисов полигона
test_smoke_all_services.py — прогоняет все 3 стенда (dev/test/prod),
для каждого сервиса: create -> modify -> delete, с поллингом.
2026-08-04 08:54:33 +04:00
“Naeel” c36656d591 test: +13 тестов — save_run UPSERT, auth режимы/URL, сценарии
test_db_save_run.py (4 теста): INSERT/UPDATE/UPSERT/без БД
test_auth.py (9 тестов): URL полигона, get_stand, whitelist, режимы
test_scenario_full.py (8 тестов): CRUD + запуск (требует polygon + БД)

Итого: 35 тестов (22 старых + 13 новых)
2026-08-04 08:48:36 +04:00
“Naeel” 7ec191c752 fix: код-ревью #5 #6 #8 #9 #10 — 5 исправлений (v1.2.43)
#5 api_history: try/finally для conn/cur (как везде)
#6 stand_name: точное сравнение URL вместо substring
#8 get_real_client: удалён мёртвый алиас
#9 UNIQUE индекс idx_runs_op_uid для предотвращения гонок
#10 flock flush: f.flush() перед LOCK_UN в ротации лога
#7 (отступ scenario.py) пропущен — только косметика, риск сломать else:
2026-08-04 08:02:08 +04:00
“Naeel” 97964fe64e fix: whitelist mode/polygon_stand — защита от мусора в cookie (v1.2.42)
Результат код-ревью #3:
  mode/polygon_stand принимали любые значения из формы.
  Добавлена валидация в main.py (set_mode) и auth.py (get_mode, get_polygon_stand):
  mode ∈ {polygon, cloud}, stand ∈ {dev, test, prod}.
2026-08-04 07:32:06 +04:00
“Naeel” a0d60c3c3d perf: кеширование detect_endpoint в flask.g — минус 2 HTTP-запроса (v1.2.41)
Результат код-ревью #2:
  get_client() и get_stand() вызывали detect_endpoint() независимо
  → двойной HTTP-запрос к Nubes API на каждый рендер страницы.

  _cached_detect(token) кеширует результат в flask.g на время запроса.
2026-08-04 07:26:26 +04:00
“Naeel” 809be65108 fix: XSS — _esc() для o.operation в instances.js (v1.2.40)
Результат код-ревью #1 (критическое):
  o.operation вставлялся в onclick и innerHTML без экранирования.
  Исправлено: JS-escape для onclick (\\, \'), HTML-escape для текста.
2026-08-03 10:51:02 +04:00
“Naeel” 1e0861d869 fix: ручной UPSERT вместо ON CONFLICT — не требует индекса (v1.2.39)
ON CONFLICT требовал уникальный индекс idx_runs_op_uid,
который не всегда создавался (мультистейтмент SQL в psycopg2).
→ save_run падал молча → история пустая.

Новый подход: UPDATE по op_uid, если rowcount==0 → INSERT.
Не зависит от индексов, работает всегда.
2026-08-03 10:18:10 +04:00
“Naeel” 403aa87150 fix: сценарии — перерендер после поллинга + индекс отдельно (v1.2.38)
Баг 1: страница сценариев зависала после завершения
  — scenario-list.js: добавлен loadScenarios() после поллинга

Баг 2: история могла быть пустой (ON CONFLICT без индекса)
  — init_db.py: CREATE UNIQUE INDEX отдельным cur.execute()
    (мультистейтмент SQL в psycopg2 ненадёжен)
2026-08-03 10:09:17 +04:00
“Naeel” bebdf28a14 fix: дубликаты RUNNING/OK в истории — UPSERT по op_uid (v1.2.37)
Причина: save_run всегда делал INSERT, сценарий вызывал его дважды
(до поллинга RUNNING, после OK) → две строки в БД.

Исправление:
- init_db.py: частичный уникальный индекс idx_runs_op_uid
- save_run.py: INSERT ... ON CONFLICT (op_uid) DO UPDATE
  (статус, длительность, ошибка, этапы, meta — обновляются)
2026-08-03 10:00:29 +04:00
“Naeel” 283e999b8f fix: tracker_remove в сценариях + прямая загрузка логов (v1.2.36)
Баг 1: удалённые сценарием инстансы показывались как 'creating'
  — run_scenario() не вызывал tracker_remove после delete
  — фикс: tracker_remove после успешного delete-шага

Баг 2: чёрный экран на вкладке Логи
  — views.js копировал пустую log-panel
  — фикс: прямая загрузка fetch('/api/log')
2026-08-03 09:48:03 +04:00
“Naeel” 7f248ba60c fix: радиокнопки — по центру сайдбара (sidebar-nav flex:0, form margin:auto) (v1.2.35) 2026-08-03 09:29:28 +04:00
“Naeel” 6ae8edf898 fix: радиокнопки — по центру по вертикали (v1.2.34) 2026-08-03 09:26:58 +04:00
“Naeel” c3d9a42aae feat: радиокнопки вместо select для режима/стенда (v1.2.32)
- index.html: radio buttons (🎭/☁️ для режима, DEV/TEST/PROD для стенда)
- main.py: set_mode сохраняет polygon_stand из cookie если не в форме
  (нужно при Облако→Эмуляция — радио стенда нет в DOM)
2026-08-03 09:13:57 +04:00
“Naeel” d53697f36c fix: URL полигона — стенд перед /api/v1/svc, а не после (v1.2.31)
Было:  https://polygon.../api/v1/svc/test/instances → 404
Стало: https://polygon.../test/api/v1/svc/instances → OK

Замена /api/v1/svc → /{stand}/api/v1/svc.
2026-08-03 08:56:29 +04:00
“Naeel” a8816a1f23 feat: селектор режима и стенда (v1.2.30)
Новое:
- Селектор режима (🎭 Эмуляция / ☁️ Облако) над версией
- Селектор стенда (DEV/TEST/PROD) в режиме эмуляции
- В эмуляции — всё в полигон (/stand/api/v1/svc)
- В эмуляции — токен дезактивирован
- По умолчанию: эмуляция + TEST

Изменено:
- auth.py: get_mode(), get_polygon_stand(), get_client() с префиксом стенда
- main.py: action=set_mode, единый get_client() вместо real_client/inst_client
- index.html: селекторы, disable токена
- service_list.py: обрезка polygon_ префикса
- api_test.py: get_real_client → get_client

Задокументировано в HISTORY/2026-08-03-session.md.
2026-08-03 08:50:14 +04:00
“Naeel” 0271f00683 fix: сервисы не показывались при POLYGON_ENDPOINT (v1.2.29)
Причина: load_service_ids('polygon') возвращал пустой set (нет services_polygon.txt),
config.service_ids = [], и шаблонный фильтр svc.svcId in [] убивал весь список.

Исправление: в index.html добавлено not config.service_ids — если список пуст,
показываем все сервисы (как и задумано в load_service_ids).
2026-08-03 08:29:46 +04:00
“Naeel” 44e6d8e92f fix: разделение клиентов — сервисы из real API, инстансы/операции из polygon (v1.2.28) 2026-08-01 09:22:02 +04:00
“Naeel” 654f2af9d9 fix: create_client → get_client — POLYGON_ENDPOINT в main/api/runner (v1.2.27) 2026-08-01 09:00:45 +04:00
“Naeel” 676fecb03e feat: POLYGON_ENDPOINT — отдельная переменная, не трогает NUBES_API_TOKEN (v1.2.26) 2026-07-31 23:42:41 +04:00
“Naeel” d23cdb6307 test: 15 интеграционных тестов polygon + bump v1.2.25 2026-07-31 23:02:34 +04:00
“Naeel” cc57e4f14a feat: интеграция с polygon — STANDS-check в get_client/get_stand (v1.2.24) 2026-07-31 22:45:27 +04:00
“Naeel” 1a0940a2a0 Добавлены тесты для критических фиксов (lock_check, UniqueViolation, escName, idx_one_running) 2026-07-31 18:28:49 +04:00
“Naeel” 973a303d5e v1.2.23: lock_check three-state return (True/False/None), None→503 DB unavailable 2026-07-31 18:22:58 +04:00
“Naeel” b77f84403b v1.2.22: 3rd audit fixes — UniqueViolation→409, lock_check no-db→False, escName add & escape 2026-07-31 18:20:33 +04:00
“Naeel” 5b0bfeba3f v1.2.21: fix broken advisory lock (→ partial unique index), escName add " escape, lock_check fallback False 2026-07-31 18:17:09 +04:00
“Naeel” deec15f44a v1.2.20: remaining Codex fixes — _op_results lock, advisory lock for scenarios, _ensure_schema logging, stale async generation token, validate-cfs explicit JSONDecodeError 2026-07-31 18:07:24 +04:00
“Naeel” 713601aba0 v1.2.19: fixes from Codex audit — XSS in params, JS injection in onclick, scenario polling timeout, has_target validation, tracker atomic update 2026-07-31 17:58:57 +04:00
“Naeel” ba4f68ab9f v1.2.18: fix onOpChange — сохранять выбранную операцию в step.operation, авто-показ облачных инстансов для не-create 2026-07-31 17:40:33 +04:00
“Naeel” 62ed6b62d8 v1.2.17 2026-07-31 17:26:32 +04:00
“Naeel” cd0fd9c2d8 Подробные комментарии ко всем JS-файлам фронтенда 2026-07-31 17:25:44 +04:00
“Naeel” 2ba881e27a Рефакторинг API-слоя, операций и БД 2026-07-31 17:13:54 +04:00
“Naeel” ea64d897a8 v1.2.16: save full instance metadata (instance_meta JSONB)
init_db.py: ALTER TABLE runs ADD instance_meta JSONB
save_run.py: +instance_meta parameter → JSONB insert
api_test.py: _finish_op fetches GET /instances/{uid} after poll, saves all fields
scenario.py: run_scenario same — per-step instance metadata
Excludes: instanceUid, displayName, svc, serviceId, explainedStatus (already in other columns)
2026-07-31 14:19:29 +04:00
“Naeel” 266765bf9d v1.2.15: aligned table columns everywhere
- Overview cards: .overview-table with table-layout:fixed, status column 70px
- History table: table-layout:fixed, Time 130px, Op 90px, Status 50px, Duration 55px
- All tables now have consistent column widths across cards
2026-07-31 14:14:04 +04:00
“Naeel” fe1aaa0cb5 v1.2.14: expandable history rows with execution stages
Backend: /api/history now returns stages (JSONB)
Frontend: click on history row → expand to show execution stages:
  ✅ stage_name  start → finish (duration)
  ❌ stage_name  start → finish (duration)
  ⏳ stage_name  start → ... (—)
RUNNING rows: yellow background, FAIL rows: red background
2026-07-31 14:07:35 +04:00
“Naeel” 5d18c47711 v1.2.13: Organization card — same style as infra items + UUID
- Collapsible header like other infra cards
- Table row with displayName + instanceUid + status badge
- ClientID shown in header
2026-07-31 14:04:02 +04:00
“Naeel” fdfe305928 v1.2.12: scenario list — clean header row + action buttons in expanded view
- Header: name | step count | seed badge (no CRUD buttons)
- Expanded view: ▶ Запустить ✏ Редактировать 📋 Копировать 🗑 Удалить
  (same size, aligned, with labels)
- Delete hidden for seed scenarios
2026-07-31 14:02:50 +04:00
“Naeel” 5028de2b74 v1.2.11: scenario list — expandable steps + run confirmation
- Click on scenario name → expands to show step details:
  operation → service_id (output/ref/uid) (params)
- ▶ Запустить button inside expanded view
- confirm('Запустить сценарий?') before running
- CRUD buttons (✏📋🗑) with event.stopPropagation()
- toggleScenarioSteps(defId): single-expand (closes others)
2026-07-31 13:55:11 +04:00
“Naeel” 0d5c3cbbbf v1.2.10: rename Верстак→Консоль, fix logs view
- Sidebar: Верстак → 🖥 Консоль
- View header: Верстак → Консоль
- Log view: show real log content (synced with log panel)
- Dark bottom log panel: hidden on all non-log views, left offset 192px (sidebar width)
- views.js: switchView handles log view sync
2026-07-31 13:33:05 +04:00