440 lines
9.2 KiB
Markdown
440 lines
9.2 KiB
Markdown
# Admin API
|
||
|
||
## 1. Назначение документа
|
||
|
||
Этот документ фиксирует HTTP-контракты административного API, через которое UI управляет операциями, загружает артефакты, тестирует вызовы и выполняет YAML import/export.
|
||
|
||
Документ задает логический контракт. Конкретные детали `axum` handlers, auth middleware и response envelope могут уточняться при реализации.
|
||
|
||
## 2. Общие правила API
|
||
|
||
- все payload по умолчанию в `JSON`;
|
||
- import/export конфигурации используют `YAML` как payload или файл;
|
||
- версии operation адресуются явно;
|
||
- published операция - это ссылка на конкретную version;
|
||
- ошибки валидации возвращаются отдельно от transport errors.
|
||
|
||
Базовый префикс:
|
||
|
||
```text
|
||
/api/admin
|
||
```
|
||
|
||
## 3. Основные ресурсы
|
||
|
||
- `operations`
|
||
- `versions`
|
||
- `samples`
|
||
- `descriptors`
|
||
- `auth-profiles`
|
||
- `test-runs`
|
||
- `config import/export`
|
||
|
||
## 4. CRUD операций
|
||
|
||
### `GET /api/admin/operations`
|
||
|
||
Назначение:
|
||
|
||
- список операций для UI.
|
||
|
||
Параметры:
|
||
|
||
- `protocol`
|
||
- `status`
|
||
- `search`
|
||
|
||
Ответ:
|
||
|
||
```json
|
||
{
|
||
"items": [
|
||
{
|
||
"id": "op_01",
|
||
"name": "crm_create_lead",
|
||
"display_name": "Create Lead",
|
||
"protocol": "rest",
|
||
"status": "draft",
|
||
"current_draft_version": 3,
|
||
"latest_published_version": 2,
|
||
"updated_at": "2026-03-25T09:00:00Z"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### `POST /api/admin/operations`
|
||
|
||
Назначение:
|
||
|
||
- создание новой операции и версии `1`.
|
||
|
||
Тело:
|
||
|
||
```json
|
||
{
|
||
"name": "crm_create_lead",
|
||
"display_name": "Create Lead",
|
||
"protocol": "rest",
|
||
"target": {
|
||
"kind": "rest",
|
||
"base_url": "https://api.example.com",
|
||
"method": "POST",
|
||
"path_template": "/v1/leads"
|
||
},
|
||
"input_schema": { "type": "object", "fields": {} },
|
||
"output_schema": { "type": "object", "fields": {} },
|
||
"input_mapping": { "rules": [] },
|
||
"output_mapping": { "rules": [] },
|
||
"execution_config": {
|
||
"timeout_ms": 10000
|
||
},
|
||
"tool_description": {
|
||
"title": "Create CRM lead",
|
||
"description": "Creates a new lead."
|
||
}
|
||
}
|
||
```
|
||
|
||
Ответ:
|
||
|
||
```json
|
||
{
|
||
"operation_id": "op_01",
|
||
"version": 1,
|
||
"status": "draft"
|
||
}
|
||
```
|
||
|
||
### `GET /api/admin/operations/{operation_id}`
|
||
|
||
Назначение:
|
||
|
||
- получить метаданные operation и ссылки на draft/published версии.
|
||
|
||
### `GET /api/admin/operations/{operation_id}/versions/{version}`
|
||
|
||
Назначение:
|
||
|
||
- получить полную конфигурацию конкретной версии.
|
||
|
||
### `POST /api/admin/operations/{operation_id}/versions`
|
||
|
||
Назначение:
|
||
|
||
- создать новую draft-версию на основе текущего payload.
|
||
|
||
Тело:
|
||
|
||
- полная конфигурация operation;
|
||
- опционально `change_note`.
|
||
|
||
Ответ:
|
||
|
||
```json
|
||
{
|
||
"operation_id": "op_01",
|
||
"version": 4,
|
||
"status": "draft"
|
||
}
|
||
```
|
||
|
||
## 5. Публикация
|
||
|
||
### `POST /api/admin/operations/{operation_id}/publish`
|
||
|
||
Назначение:
|
||
|
||
- опубликовать текущую draft-версию.
|
||
|
||
Тело:
|
||
|
||
```json
|
||
{
|
||
"version": 4
|
||
}
|
||
```
|
||
|
||
Ответ:
|
||
|
||
```json
|
||
{
|
||
"operation_id": "op_01",
|
||
"published_version": 4,
|
||
"published_at": "2026-03-25T10:00:00Z"
|
||
}
|
||
```
|
||
|
||
### `POST /api/admin/operations/{operation_id}/archive`
|
||
|
||
Назначение:
|
||
|
||
- перевести operation в archived status.
|
||
|
||
## 6. Samples и schema artifacts
|
||
|
||
### `POST /api/admin/operations/{operation_id}/samples/input-json`
|
||
|
||
Назначение:
|
||
|
||
- загрузить sample входного JSON.
|
||
|
||
Тип:
|
||
|
||
- `multipart/form-data` или raw `application/json`.
|
||
|
||
Ответ:
|
||
|
||
```json
|
||
{
|
||
"sample_id": "file_01",
|
||
"sample_kind": "input_json"
|
||
}
|
||
```
|
||
|
||
### `POST /api/admin/operations/{operation_id}/samples/output-json`
|
||
|
||
Назначение:
|
||
|
||
- загрузить sample выходного JSON.
|
||
|
||
`admin-api v1` реализует именно JSON samples, потому что они нужны для REST сценария и draft generation уже на первом этапе.
|
||
|
||
### `POST /api/admin/operations/{operation_id}/drafts/generate`
|
||
|
||
Назначение:
|
||
|
||
- построить черновую схему и mappings из сохраненных JSON samples.
|
||
|
||
В `admin-api v1` endpoint возвращает:
|
||
|
||
- `generated_draft`
|
||
- сгенерированные `input_schema`
|
||
- сгенерированные `output_schema`
|
||
- сгенерированные `input_mapping`
|
||
- сгенерированные `output_mapping`
|
||
|
||
## 7. gRPC descriptor endpoints
|
||
|
||
Следующие endpoints относятся к фазе `grpc-support` и не входят в `admin-api v1`:
|
||
|
||
### `POST /api/admin/operations/{operation_id}/descriptors/proto`
|
||
|
||
Назначение:
|
||
|
||
- загрузить `.proto`.
|
||
|
||
### `POST /api/admin/operations/{operation_id}/descriptors/descriptor-set`
|
||
|
||
Назначение:
|
||
|
||
- загрузить `descriptor set`.
|
||
|
||
### `GET /api/admin/operations/{operation_id}/grpc/services`
|
||
|
||
Назначение:
|
||
|
||
- получить discovery summary по services и methods.
|
||
|
||
Ответ:
|
||
|
||
```json
|
||
{
|
||
"services": [
|
||
{
|
||
"package": "crm.v1",
|
||
"service": "LeadService",
|
||
"methods": [
|
||
{
|
||
"name": "CreateLead",
|
||
"kind": "unary"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
## 8. Тестовый запуск
|
||
|
||
### `POST /api/admin/operations/{operation_id}/test-runs`
|
||
|
||
Назначение:
|
||
|
||
- выполнить тестовый вызов draft-конфигурации.
|
||
|
||
Тело:
|
||
|
||
```json
|
||
{
|
||
"version": 4,
|
||
"input": {
|
||
"name": "Alice",
|
||
"email": "alice@example.com"
|
||
}
|
||
}
|
||
```
|
||
|
||
Ответ:
|
||
|
||
```json
|
||
{
|
||
"ok": true,
|
||
"request_preview": {
|
||
"body": {
|
||
"name": "Alice",
|
||
"email": "alice@example.com"
|
||
}
|
||
},
|
||
"response_preview": {
|
||
"id": "lead_123",
|
||
"status": "created"
|
||
},
|
||
"errors": []
|
||
}
|
||
```
|
||
|
||
## 9. Auth profiles
|
||
|
||
### `GET /api/admin/auth-profiles`
|
||
|
||
Назначение:
|
||
|
||
- список доступных профилей аутентификации.
|
||
|
||
### `POST /api/admin/auth-profiles`
|
||
|
||
Назначение:
|
||
|
||
- создать новый auth profile.
|
||
|
||
Тело:
|
||
|
||
```json
|
||
{
|
||
"name": "crm-prod-bearer",
|
||
"kind": "bearer",
|
||
"config": {
|
||
"header_name": "Authorization",
|
||
"secret_ref": "secret://auth/crm-prod-token"
|
||
}
|
||
}
|
||
```
|
||
|
||
### `GET /api/admin/auth-profiles/{auth_profile_id}`
|
||
|
||
Назначение:
|
||
|
||
- получить metadata auth profile без раскрытия секрета.
|
||
|
||
## 10. YAML export
|
||
|
||
### `GET /api/admin/operations/{operation_id}/export`
|
||
|
||
Назначение:
|
||
|
||
- экспортировать конфигурацию операции в `YAML`.
|
||
|
||
Параметры:
|
||
|
||
- `version` - опционально, если нужно экспортировать не current draft;
|
||
- `mode=portable|bundle`
|
||
|
||
Ответ:
|
||
|
||
- `Content-Type: application/yaml`
|
||
- тело ответа - YAML document
|
||
|
||
### Пример YAML response
|
||
|
||
```yaml
|
||
format_version: "1"
|
||
kind: operation
|
||
operation:
|
||
name: crm_create_lead
|
||
protocol: rest
|
||
status: draft
|
||
```
|
||
|
||
## 11. YAML import
|
||
|
||
### `POST /api/admin/operations/import`
|
||
|
||
Назначение:
|
||
|
||
- импортировать operation из YAML.
|
||
|
||
Тип:
|
||
|
||
- `application/yaml`
|
||
- или `multipart/form-data` с YAML файлом
|
||
|
||
Параметры:
|
||
|
||
- `mode=create|upsert`
|
||
|
||
Ответ:
|
||
|
||
```json
|
||
{
|
||
"operation_id": "op_01",
|
||
"version": 5,
|
||
"import_mode": "upsert",
|
||
"warnings": []
|
||
}
|
||
```
|
||
|
||
## 12. Ошибки
|
||
|
||
Рекомендуемые классы ошибок:
|
||
|
||
- `validation_error`
|
||
- `mapping_error`
|
||
- `schema_error`
|
||
- `descriptor_error`
|
||
- `auth_profile_error`
|
||
- `yaml_import_error`
|
||
- `runtime_test_error`
|
||
- `not_found`
|
||
- `conflict`
|
||
|
||
Пример:
|
||
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": "validation_error",
|
||
"message": "Invalid JSONPath in input_mapping rule 2",
|
||
"details": {
|
||
"field": "input_mapping.rules[1].source"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 13. Что важно не допустить
|
||
|
||
- смешивание CRUD и publish semantics в одном endpoint;
|
||
- обновление draft "поверх" существующей версии без создания новой version;
|
||
- YAML import как скрытый апдейт без явного режима `create|upsert`;
|
||
- возврат открытых секретов из auth-profile endpoints;
|
||
- привязку runtime к admin DTO;
|
||
- endpoints, возвращающие разные формы одной и той же сущности без причины.
|
||
|
||
## 14. Практический итог
|
||
|
||
Минимальный рабочий набор admin API для MVP:
|
||
|
||
- список и чтение operations;
|
||
- создание новой version;
|
||
- publish;
|
||
- upload JSON samples;
|
||
- auth profiles;
|
||
- generate draft;
|
||
- test run;
|
||
- YAML import/export.
|
||
|
||
Этого достаточно, чтобы UI полностью управлял жизненным циклом operation без ручного редактирования кода backend.
|
||
|
||
`gRPC descriptor` endpoints добавляются отдельным этапом вместе с `grpc-support`.
|