doc: новый промпт Соннету с подтверждённым анализом багов; revert лишних вопросов
This commit is contained in:
@@ -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 правок с максимальным эффектом при минимуме кода**.
|
||||||
@@ -54,33 +54,6 @@
|
|||||||
- Не усложнять — полигон это мок, не прод
|
- Не усложнять — полигон это мок, не прод
|
||||||
- Не предлагать автогенерацию из кода через декораторы
|
- Не предлагать автогенерацию из кода через декораторы
|
||||||
|
|
||||||
## Дополнительные вопросы
|
|
||||||
|
|
||||||
### requestInterceptor и X-Mock-Auth
|
|
||||||
|
|
||||||
Сейчас `swagger.html` добавляет только `Authorization: Bearer` через `requestInterceptor`.
|
|
||||||
Но `_mock/*` эндпоинты проверяют заголовок `X-Mock-Auth`, а не `Authorization`.
|
|
||||||
Как правильно дописать `requestInterceptor` чтобы оба механизма работали:
|
|
||||||
- `Authorization: Bearer <token>` — для всех эндпоинтов (если включена глобальная auth)
|
|
||||||
- `X-Mock-Auth: <token>` — только для `_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 (всё заполнено)
|
|
||||||
|
|
||||||
## Формат ответа
|
## Формат ответа
|
||||||
|
|
||||||
Сгруппируй находки так:
|
Сгруппируй находки так:
|
||||||
|
|||||||
Reference in New Issue
Block a user