feat(openapi): complete upload preview and UI evidence

This commit is contained in:
2026-08-28 15:38:14 +03:00
parent d2849ea3fe
commit 2c94af6791
35 changed files with 3655 additions and 537 deletions
+4
View File
@@ -164,6 +164,10 @@ Mutation contract revision 2 требует `If-Match` для `PATCH`, create-ve
Portable export использует закрытый `format_version: "2"` contract из [`schemas/operation-export-v2.schema.json`](schemas/operation-export-v2.schema.json). Он исключает persistence IDs, lifecycle metadata, samples, wizard state и credentials. Legacy v1 принимается только при импорте и нормализуется в v2; exporter v1 не выдаёт. YAML import ограничен 256 KiB и возвращает только bounded codes `operation_yaml_too_large|operation_yaml_invalid|operation_yaml_unsupported` без raw parser text.
### OpenAPI preview upload
`POST /api/admin/workspaces/{workspace_id}/imports/openapi/preview` принимает только `multipart/form-data` с ровно одним полем `file`. Допускаются UTF-8 `.yaml`, `.yml` и `.json` размером 1..256 KiB с MIME, согласованным с расширением (для YAML/JSON также допустим `application/octet-stream`). JSON `{document}` не является production contract. Ответы об ошибках локализуются через `Accept-Language`, не раскрывают source/digest/path и могут содержать только canonical `X-Request-ID` и `X-Trace-ID` для восстановления.
`analyze-quality` принимает payload операции и возвращает рекомендации:
```json
+7 -1
View File
@@ -6,7 +6,7 @@ Crank умеет импортировать REST API из OpenAPI 3.x и Swagger
1. Откройте раздел **Операции**.
2. Нажмите **Импорт OpenAPI** рядом с кнопкой **Новая операция**.
3. Загрузите `.yaml`, `.yml`, `.json` файл или вставьте текст спецификации.
3. Загрузите ровно один UTF-8 `.yaml`, `.yml` или `.json` файл размером от 1 B до 256 KiB. Вставка текста не поддерживается.
4. Нажмите **Разобрать документ**.
5. Проверьте preview: для каждого метода показываются поля `Path`, `Query`, `Header`, `Body` и поля ответа.
6. Выберите нужные группы и методы.
@@ -16,6 +16,12 @@ Crank умеет импортировать REST API из OpenAPI 3.x и Swagger
- **Пропустить** — существующие операции не будут изменены.
9. Нажмите **Создать черновики**.
## Загрузка и восстановление
Браузер отправляет выбранный файл как `multipart/form-data`; границу multipart формирует сам браузер. Файл остаётся только в памяти текущего окна импорта. При замене файла, сбросе, закрытии окна, смене workspace/языка или уходе со страницы текущий запрос отменяется, а поздний ответ игнорируется. При `pagehide` (включая BFCache) выбранный файл и Base URL очищаются: после возврата нужно выбрать файл заново, повтор старой загрузки не предлагается.
Для ошибки можно выбрать файл заново или нажать **Повторить**. Диагностика показывает только ограниченные имя/размер файла и, если backend их вернул, `Request ID`/`Trace ID`; содержимое спецификации, digest, source ID и внутренние пути не выводятся. Повторное нажатие **Создать черновики** во время выполнения не создаёт вторую мутацию.
## Что создается
Для каждого выбранного метода Crank создает отдельную операцию в статусе черновика:
+6
View File
@@ -49,6 +49,12 @@
- Удаляйте или отзывайте ключи, которые больше не используются.
- Используйте secrets/auth profiles для токенов внешних API.
- Не вставляйте реальные токены в статические заголовки операции.
## OpenAPI import и release evidence
- Проверяйте реальный multipart upload из UI: один файл `.yaml|.yml|.json`, 1..256 KiB, preview и создание Draft.
- При сбое используйте только `Request ID`/`Trace ID`; не прикладывайте исходный OpenAPI-файл, digest, source ID, путь, Playwright trace/video или raw report к release evidence.
- Сохраняйте только JSON, сформированный `scripts/collect-capability-baseline.py`: он содержит revision, разрешённые flow IDs и агрегированные counts. Backup/retention исходных файлов OpenAPI координируются artifact lifecycle/reconciliation, а не UI или release-job.
- Не меняйте `CRANK_MASTER_KEY` напрямую. Для смены ключа выполняйте
`crank-migrate master-key preflight → rotate → verify → promote`, затем
перезапускайте secret-using процессы с target key.