diff --git a/polygon-docs/sonnet-integration-prompt.md b/polygon-docs/sonnet-integration-prompt.md new file mode 100644 index 0000000..f6568b7 --- /dev/null +++ b/polygon-docs/sonnet-integration-prompt.md @@ -0,0 +1,139 @@ +# Консультация: интеграция polygon ↔ app-autotest + +> Адресат: Claude Sonnet 4.6 (новый чат) +> Дата: 2026-07-31 +> ⛔ ОТВЕТ — ТОЛЬКО В ЧАТ. Не редактировать файлы. + +--- + +## Контекст + +**Polygon** (v0.2.4) — эмулятор Nubes API. Задеплоен на `polygon.pythonk8s.dev.nubes.ru`, +17 эндпоинтов с префиксом `/api/v1/svc`, 37 сервисов, все в памяти. +Принимает те же запросы что реальный Nubes API: POST /instances → 201 + Location, +POST /instanceOperations → 201 + Location, GET /instanceOperations/default/{id} → cfsParams, +POST /run → sleep + apply_effect + dtFinish. + +**app-autotest** (v1.2.23) — Flask-приложение для ручного/сценарного тестирования Nubes. +Делает реальные HTTP-запросы к Nubes API через `HttpClient` (обёртка над `requests.Session`). +Сейчас ходит только в реальные dev/test стенды. + +**Задача:** сделать так чтобы app-autotest мог ходить в polygon вместо реального API. + +## Как app-autotest подключается к API (сейчас) + +Файл `api/auth.py`: + +```python +def get_client(): + token = get_token() + endpoint = detect_endpoint(token) or current_app.config["NUBES_API_ENDPOINT"] + return HttpClient(endpoint, token) + +def get_stand(): + token = get_token() + endpoint = detect_endpoint(token) or current_app.config["NUBES_API_ENDPOINT"] + return stand_name(endpoint) +``` + +`detect_endpoint(token)` — пробует dev/test стенды, возвращает URL первого ответившего. +Хардкод: `["https://lk-api-gateway-dev...", "https://lk-api-gateway-test..."]`. + +`stand_name(endpoint)` — "dev" или "test" по URL. + +`HttpClient(endpoint, token)` — обёртка `requests.Session`: +- `get(path)` — GET, `.json()` +- `post(path, body)` — POST, извлекает UUID из заголовка `Location` + +## Проблема + +`detect_endpoint(token)` ВСЕГДА находит реальный стенд (токен валиден). +До fallback на `NUBES_API_ENDPOINT` дело НЕ доходит. +Даже при `NUBES_API_ENDPOINT=http://localhost:5000` app-autotest долбится в облако. + +## Предлагаемое решение + +Добавить проверку localhost в `get_client()` и `get_stand()`: + +```python +def _is_localhost(url): + return (url or "").startswith(("http://localhost", "http://127.0.0.1")) + +def get_client(): + token = get_token() + endpoint = current_app.config["NUBES_API_ENDPOINT"] + if not _is_localhost(endpoint): + endpoint = detect_endpoint(token) or endpoint + return HttpClient(endpoint, token) + +def get_stand(): + token = get_token() + endpoint = current_app.config["NUBES_API_ENDPOINT"] + if _is_localhost(endpoint): + return "mock" + endpoint = detect_endpoint(token) or endpoint + return stand_name(endpoint) +``` + +Логика: +- Если `NUBES_API_ENDPOINT` указывает на localhost → пропустить detect_endpoint, сразу использовать его +- `get_stand()` для localhost → "mock" (вместо "?" которое вернёт stand_name для неизвестного URL) +- Ноль новых env-переменных, `NUBES_API_ENDPOINT` уже есть в конфиге + +## Вопросы к Соннету + +### Q1. Достаточно ли проверки localhost? + +Сейчас: `startswith(("http://localhost", "http://127.0.0.1"))`. + +Что насчёт: +- `https://polygon.pythonk8s.dev.nubes.ru` — удалённый polygon, НЕ localhost. `detect_endpoint` попытается dev/test и упадёт (потому что polygon не вернёт реальный токен-челлендж). Нужна ли более широкая проверка — например «любой не-deck URL»? +- IPv6 localhost `[::1]`? +- Docker-сети `http://host.docker.internal`? + +### Q2. stand_name для polygon + +Сейчас `stand_name("http://localhost:5000")` вернёт `"?"` потому что там нет "dev"/"test". +Мы предлагаем "mock" для localhost. Но что насчёт: +- `https://polygon.pythonk8s.dev.nubes.ru` — stand_name вернёт `"?"` потому что в URL нет "dev"/"test". Нужно ли добавить "polygon" в stand_name? +- Трекер инстансов (`/tmp/instances-{clientId}-{stand}.json`) использует stand для имени файла. "?" или "mock" — ок, но для удалённого polygon тоже будет "?". + +### Q3. HttpClient — нужны ли изменения? + +Polygon отдаёт ровно те же форматы что реальный API: +- `Location: ./{uuid}` на POST /instances и POST /instanceOperations +- `{"results": [...]}` на GET /instances +- `{"svcOperation": {"cfsParams": [...]}}` на GET /instanceOperations/default/{id} +- Пустое тело 200 на validate-cfs + +Нужно ли что-то менять в `HttpClient.post()` или `http_client.py`? + +### Q4. Токен для polygon + +Polygon НЕ проверяет токен (все `_mock/*` открыты, основные эндпоинты тоже без auth). +app-autotest ВСЕГДА шлёт `Authorization: Bearer ` через HttpClient. + +Это ок? Или polygon должен проверять токен (хотя бы непустой)? + +### Q5. Порядок запуска для тестов + +При локальном тестировании: +```bash +# Терминал 1: polygon +cd polygon/site && python app.py # порт 5000 + +# Терминал 2: app-autotest → polygon +cd app-autotest/site && \ + NUBES_API_ENDPOINT=http://localhost:5000/api/v1/svc \ + python app.py # порт 5001 или другой +``` + +Нет ли коллизий портов? app-autotest по умолчанию на 5000, polygon тоже на 5000. + +### Q6. Альтернативный подход + +Вместо проверки localhost, может лучше: +- Новая env-переменная `NUBES_MOCK=1` — явное переключение в режим мока? +- Или `NUBES_API_ENDPOINT` как единственный источник, а detect_endpoint вызывать только если endpoint НЕ задан явно? + +Какой подход надёжнее?