diff --git a/polygon-docs/sonnet-swagger-analysis-verified.md b/polygon-docs/sonnet-swagger-analysis-verified.md new file mode 100644 index 0000000..afd9a28 --- /dev/null +++ b/polygon-docs/sonnet-swagger-analysis-verified.md @@ -0,0 +1,152 @@ +# Соннет: проверь наш анализ Swagger/OpenAPI в Polygon + +> Адресат: Claude Sonnet 4.6 (новый чат) +> ⛔ ОТВЕТ — ТОЛЬКО В ЧАТ. Не редактировать файлы. +> ⛔ НЕ предлагать переписывать всё. Только точечные правки. + +--- + +## Контекст + +**Polygon** (v0.4.0) — эмулятор REST API облачной платформы Nubes. +Задеплоен на `polygon.pythonk8s.dev.nubes.ru`. 17 эндпоинтов, 37 сервисов. + +Swagger UI (`/swagger`) + OpenAPI 3.1.0 спека (`/api/v1/svc/openapi.json`). + +Основные файлы: +- `polygon/site/routes/openapi.py` — ~500 строк, динамическая спека +- `polygon/site/templates/swagger.html` — Swagger UI 5 с CDN +- `polygon/site/app.py` — Flask, 7 blueprint'ов +- `polygon/site/mock_state.py` — синглтон состояния +- `polygon/site/routes/mock_routes.py` — `_mock/*` эндпоинты +- `polygon/site/routes/run.py` — `POST /run` + +## Что мы уже нашли + +Ниже — наш анализ. Проверь каждую находку: подтверждаешь? Есть что добавить? Что-то упустили? + +--- + +### 🔴 Баг 1 (критичный): Глобальная Bearer-авторизация не реализована + +**Спека врёт.** В `openapi.py` глобально: +```json +"security": [{"bearerAuth": []}] +``` +Но в `app.py` **нет** `before_request` с проверкой `Authorization: Bearer`. +Единственная auth — в `mock_routes.py` через `@bp.before_request`, и та проверяет **`X-Mock-Auth`**, не `Authorization`. + +Более того, комментарий в `mock_routes.py:39` прямо врёт: +```python +# Примечание: app.before_request уже проверяет Authorization: Bearer; +``` +Такого `before_request` не существует. + +**Последствия**: пользователь в Swagger UI нажимает Authorize, вводит токен, убеждён что защищён. На деле токен нигде не проверяется. `_mock/*` требует другой заголовок. + +--- + +### 🔴 Баг 2: dtStart, isSuccessful не nullable + +`mock_state.py` `create_operation()`: +```python +"dtStart": None, +"dtFinish": None, +"isSuccessful": None, +``` + +В схеме `Operation`: +- `dtFinish` — `"nullable": True` (но это синтаксис OAS 3.0, не 3.1.0) +- `dtStart` — без nullable +- `isSuccessful` — без nullable + +До `run` операция возвращает `{"dtStart": null, "dtFinish": null, "isSuccessful": null}`. Кодогенератор упадёт. + +--- + +### 🔴 Баг 3: RunResponse не включает поле error + +`run.py:73` при `fail_next`: +```python +return jsonify({"ok": False, "error": op["errorLog"]}) +``` + +Схема `RunResponse`: +```python +"RunResponse": {"type": "object", "properties": {"ok": {"type": "boolean"}}} +``` + +Поля `error` нет. + +--- + +### 🔴 Баг 4: pageSize — нет 400, тихое срезание + +Спека: `"maximum": 200` → подразумевает 400 при превышении. +Код `mock_state.py:72`: `page_size = min(page_size, 200)` — тихо срезает. + +--- + +### 🔴 Баг 5: nullable — синтаксис OAS 3.0 + +`"nullable": True` в `dtFinish` — валидно в OAS 3.0, но спека заявлена как **3.1.0**. В 3.1.0 нужно: `"type": ["string", "null"]`. + +--- + +### 🟡 Удобство 1: Нет описания lifecycle операций + +Пользователь видит 5 эндпоинтов в теге "operations" и не понимает порядок: +1. `GET /default/{svcOperationId}` +2. `POST /instanceOperations` +3. `POST /instanceOperationCfsParams` × N +4. `GET /{opUid}/validate-cfs` +5. `POST /{opUid}/run` + +--- + +### 🟡 Удобство 2: fields — нет enum и примера + +Описан как `"cs-список полей"` — пользователь не знает что писать в Try it out. + +--- + +### 🟡 Удобство 3: status/kind/action без enum + +`status: "creating | running | modifying | deleting | suspended"` — только в description. Try it out не подсказывает. + +--- + +### 🟡 Удобство 4: _mock/* смешаны с production + +Тег "mock" наравне с services/instances. Новичок не отличает тестовые эндпоинты от рабочих. + +--- + +### 🟡 Удобство 5: displayName — нет default + +Реально `body.get("displayName", "unnamed")`. В спеке default не указан. + +--- + +### 🔵 Косметика + +1. `bearerFormat: "token"` → нестандартное значение +2. `ServiceDetail` схема обрывается (operations описаны частично) +3. Тег "health" не нужен пользователям в документации +4. Нет `example` в схемах (Instance, CfsParam, Operation) + +--- + +## Что от тебя нужно + +1. **Подтверди или оспорь** каждую находку +2. **Что мы пропустили?** — есть баги/неудобства которые мы не заметили? +3. **Приоритеты** — что чинить в первую очередь? +4. **Best practices** — как ПРАВИЛЬНО сделать, чтобы Swagger был «кошерным»: + - Группировка тегов + - Описание схем для Try it out + - Скрытие служебных эндпоинтов + - Русские summary/description + - Авторизация в Swagger UI + +В конце — **3-5 правок с максимальным эффектом при минимуме кода**. diff --git a/polygon-docs/sonnet-swagger-review-prompt.md b/polygon-docs/sonnet-swagger-review-prompt.md index 372c248..a65b34c 100644 --- a/polygon-docs/sonnet-swagger-review-prompt.md +++ b/polygon-docs/sonnet-swagger-review-prompt.md @@ -54,33 +54,6 @@ - Не усложнять — полигон это мок, не прод - Не предлагать автогенерацию из кода через декораторы -## Дополнительные вопросы - -### requestInterceptor и X-Mock-Auth - -Сейчас `swagger.html` добавляет только `Authorization: Bearer` через `requestInterceptor`. -Но `_mock/*` эндпоинты проверяют заголовок `X-Mock-Auth`, а не `Authorization`. -Как правильно дописать `requestInterceptor` чтобы оба механизма работали: -- `Authorization: Bearer ` — для всех эндпоинтов (если включена глобальная auth) -- `X-Mock-Auth: ` — только для `_mock/*` - -### docExpansion - -Какое значение `docExpansion` оптимально для Swagger UI 5? -- `"list"` — раскрыты только названия тегов (средний вариант) -- `"none"` — всё свёрнуто (минимализм) -- `"full"` — все эндпоинты раскрыты (но может быть перегружено) - -Учитывая что есть 5 тегов (services, instances, operations, health, mock) и ~17 эндпоинтов. - -### Примеры ответов (examples) - -В каких схемах стоит добавить `example` чтобы Try it out был максимально полезен? -Например: -- `Instance` с реальными данными (instanceUid, serviceId, status, state.params, state.out) -- `CfsParam` с valueList (чтобы было видно как выглядят enum-параметры) -- `Operation` до run (dtStart=null, dtFinish=null) и после run (всё заполнено) - ## Формат ответа Сгруппируй находки так: