6.3 KiB
6.3 KiB
2026-08-03-session — Полигон: интеграция, баг с сервисами
Контекст
Сессия началась с чтения двух файлов AI-агентом:
AGENT_BRIEFING.md— контекст app-autotest (v1.2.28)polygon-docs/POLYGON-FULL.md— полное описание полигона (v0.5.9)
jsonEnv автотеста на проде:
{
"POLYGON_ENDPOINT": "https://polygon.pythonk8s.dev.nubes.ru/api/v1/svc",
"NUBES_API_ENDPOINT": "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc"
}
Архитектурное решение: разделение сервисы/инстансы
Зафиксировано (2026-08-03):
| Режим | Сервисы (метаданные) | Инстансы |
|---|---|---|
| Без полигона | Реальный API | Реальное облако |
| С полигоном | Реальный API | Виртуальные (полигон) |
POLYGON_ENDPOINT подменяет ТОЛЬКО инстансы/операции. Сервисы — это «справочник», всегда из реального API.
Где это в коде
auth.py:_make_client(use_polygon):
use_polygon=True→get_client(): еслиPOLYGON_ENDPOINTзадан → полигон, иначе →NUBES_API_ENDPOINTuse_polygon=False→get_real_client(): всегдаNUBES_API_ENDPOINT
Баг: «нет сервисов» при POLYGON_ENDPOINT
Причина
Цепочка:
get_stand()→"polygon"(auth.py:141, POLYGON_ENDPOINT задан)load_service_ids("polygon")→services_polygon.txtне существует → пустойsetsorted(пустой_set)→[]- Шаблон
index.html:81:{% if svc.svcId in config.service_ids %}→svc.svcId in []→ всегда False → ни один сервис не показывается
Хотя get_real_client() корректно получает сервисы из реального API, фильтр в шаблоне убивает весь список.
Исправление (v1.2.29)
Шаблон index.html:81: добавить or not config.service_ids:
{# Было #}
{% if svc.svcId in config.service_ids %}
{# Стало #}
{% if not config.service_ids or svc.svcId in config.service_ids %}
Это соответствует изначальному замыслу load_service_ids: «пустой set → показываем все».
Фаза 2: селектор режима и стенда (v1.2.30)
Требования
- Селектор режима над версией: 🎭 Эмуляция / ☁️ Облако (только если POLYGON_ENDPOINT задан)
- Селектор стенда (DEV/TEST/PROD) — только в режиме эмуляции
- По умолчанию: эмуляция + TEST
- В эмуляции: токен дезактивирован
- В облаке: стенд автоопределяется по токену (как раньше)
- При смене режима/стенда → сервисы обновляются
Новая архитектура
| Режим | Сервисы | Инстансы | Стенд |
|---|---|---|---|
| Эмуляция | Полигон (/{stand}/api/v1/svc) | Полигон | Выбор (dev/test/prod) |
| Облако | Реальный API | Реальный API | Авто (токен→dev/test) |
В эмуляции всё идёт в полигон — и сервисы, и инстансы. Полигон имеет полный набор эндпоинтов (/services, /instances, /instanceOperations).
get_real_client() упраздняется — становится алиасом get_client().
Cookie
mode—"polygon"(по умолчанию) или"cloud"polygon_stand—"test"(по умолчанию),"dev","prod"
Изменённые файлы
auth.py— новые функцииget_mode(),get_polygon_stand();get_token()в режиме полигона только env-токен;get_client()строит URL с префиксом стенда;get_real_client()→ алиасmain.py—action=set_mode(cookie), singleget_client()вместо real_client/inst_client, переменныеmode/polygon_stand/polygon_enabledindex.html— селекторы над версией, disable токена в эмуляцииservice_list.py— обрезатьpolygon_префиксapi_test.py—get_real_client()→get_client()
Фаза 3: Код-ревью Соннета 4.6 (v1.2.39)
Промпт
Ты — senior backend-разработчик, делаешь код-ревью веб-приложения app-autotest.
Flask 3.1 + vanilla JS + PostgreSQL. Два режима: эмуляция (Polygon) / облако.
Проверь внимательно: безопасность, URL, гонки, целостность данных, ошибки, архитектуру, JS.
Для каждой находки: 🔴 критическое / 🟡 важное / 🟢 рекомендация.
Если неясно — спроси, устроим диалог.
Результаты
| # | Файл | Проблема | Серьёзность |
|---|---|---|---|
| 1 | static/js/instances.js |
o.operation в innerHTML без _esc() |
🔴 |
| 2 | api/auth.py |
Двойной detect_endpoint() на запрос |
🟡 |
| 3 | routes/main.py |
mode/polygon_stand без whitelist-валидации |
🟡 |
| 4 | api/auth.py |
Общий client_id в polygon-режиме (env-токен) |
🟡 |
| 5 | routes/api_test.py |
api_history без finally для conn |
🟡 |
| 6 | api/http_client.py |
stand_name() substring match |
🟡 |
| 7 | operations/scenario.py |
Двойной отступ в for-цикле | 🟢 |
| 8 | api/auth.py |
get_real_client() мёртвый алиас |
🟢 |
| 9 | db/init_db.py |
Нет UNIQUE индекса на runs.op_uid |
🟢 |
| 10 | routes/api_test.py |
flock(LOCK_UN) перед flush в ротации лога |
🟢 |