# Admin API

## 1. Назначение документа

Этот документ фиксирует целевые HTTP-контракты административного API, через которое UI управляет workspace, operations, agents, machine access и observability.

Для потоковой модели детальные HTTP DTO вынесены отдельно в:

- `docs/streaming-admin-api.md`

## 2. Общие правила API

- все payload по умолчанию в `JSON`;
- import/export конфигурации используют `YAML`;
- все основные ресурсы являются `workspace-scoped`;
- версии operation и agent адресуются явно;
- published operation и published agent - ссылки на конкретные version;
- ошибки валидации возвращаются отдельно от transport errors.

Базовый префикс:

```text
/api/admin
```

## 3. Основные ресурсы

- `workspaces`
- `auth`
- `memberships`
- `invitations`
- `operations`
- `secrets`
- `auth-profiles`
- `agents`
- `agent-keys`
- `logs`
- `usage`
- `samples`
- `descriptors`
- `config import/export`

## 4. Workspace-scoped routing

Канонический префикс для UI-driven сценариев:

```text
/api/admin/workspaces/{workspace_id}
```

## 5. Группы endpoints

### 5.0. Build capabilities

- `GET /api/admin/capabilities`
- `GET /api/admin/workspaces/{workspace_id}/protocol-capabilities`

Контракт:

- endpoint возвращает capability payload текущей сборки;
- payload описывает:
  - `edition`
  - `supported_protocols`
  - `supported_security_levels`
  - `machine_access_modes`
  - `limits`
- UI использует этот ответ для edition-aware gating и честного product copy.
- `GET /protocol-capabilities` возвращает только те протоколы и execution capabilities, которые реально доступны в текущей редакции;
- для `Community` это означает только:
  - `REST`
  - `GraphQL`
  - `gRPC`

### 5.1. Workspaces and members

- `GET /api/admin/workspaces`
- `POST /api/admin/workspaces`
- `GET /api/admin/workspaces/{workspace_id}`
- `PATCH /api/admin/workspaces/{workspace_id}`
- `DELETE /api/admin/workspaces/{workspace_id}`
- `GET /api/admin/workspaces/{workspace_id}/members`
- `PATCH /api/admin/workspaces/{workspace_id}/members/{user_id}`
- `DELETE /api/admin/workspaces/{workspace_id}/members/{user_id}`
- `GET /api/admin/workspaces/{workspace_id}/invitations`
- `POST /api/admin/workspaces/{workspace_id}/invitations`
- `DELETE /api/admin/workspaces/{workspace_id}/invitations/{invitation_id}`
- `GET /api/admin/workspaces/{workspace_id}/export`

Контракт:

- `POST /invitations` возвращает metadata invitation и одноразовый `invite_token`;
- `invite_token` доступен только в create-response и не возвращается повторно в list endpoints;
- `PATCH /members/{user_id}` меняет роль участника;
- `DELETE /members/{user_id}` удаляет участника из workspace;
- `GET /export` возвращает JSON snapshot workspace lifecycle-данных;
- `DELETE /workspaces/{workspace_id}` разрешен только `owner`.

### 5.2. Auth and session

- `POST /api/auth/login`
- `POST /api/auth/logout`
- `GET /api/auth/session`
- `GET /api/auth/profile`
- `PATCH /api/auth/profile`
- `POST /api/auth/current-workspace`
- `POST /api/auth/password`

Контракт:

- `POST /login` принимает `email` и `password`;
- при успешном логине backend выставляет `HttpOnly` session cookie;
- `GET /session` возвращает текущего пользователя, memberships и `current_workspace_id`;
- `GET /profile` возвращает текущего пользователя, memberships и `current_workspace_id` для settings UI;
- `PATCH /profile` обновляет `display_name` и `email` текущего пользователя;
- `POST /current-workspace` переключает текущий workspace внутри текущей authenticated session;
- `POST /password` меняет пароль текущего пользователя после проверки `current_password`;
- `POST /logout` инвалидирует текущую session.

### 5.3. Operations

- `GET /api/admin/workspaces/{workspace_id}/operations`
- `POST /api/admin/workspaces/{workspace_id}/operations`
- `GET /api/admin/workspaces/{workspace_id}/operations/{operation_id}`
- `PATCH /api/admin/workspaces/{workspace_id}/operations/{operation_id}`
- `DELETE /api/admin/workspaces/{workspace_id}/operations/{operation_id}`
- `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/versions`
- `GET /api/admin/workspaces/{workspace_id}/operations/{operation_id}/versions/{version}`
- `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/publish`
- `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/archive`
- `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/test-runs`
- `GET /api/admin/workspaces/{workspace_id}/operations/{operation_id}/export`
- `POST /api/admin/workspaces/{workspace_id}/operations/import`

Контракт дополнительно включает:

- у операции задается обязательный `security_level`;
- допустимые значения: `standard`, `elevated`, `strict`;
- этот параметр определяет минимально допустимый режим машинного доступа при вызове через MCP.
- если поле не передано, используется `standard` для обратной совместимости с уже существующим YAML и draft payload;
- в `Community` backend принимает только:
  - `REST`
  - `GraphQL`
  - `gRPC`
  - `security_level = standard`
- попытка создать, обновить или импортировать операцию с неподдерживаемым `protocol` или `security_level` должна завершаться `validation_error` еще на стороне `admin-api`, а не только скрываться в UI.

### 5.4. Samples and descriptors

- `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/samples/input-json`
- `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/samples/output-json`
- `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/drafts/generate`
- `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/descriptors/proto`
- `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/descriptors/descriptor-set`
- `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/descriptors/wsdl`
- `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/descriptors/xsd`
- `GET /api/admin/workspaces/{workspace_id}/operations/{operation_id}/grpc/services`
- `GET /api/admin/workspaces/{workspace_id}/operations/{operation_id}/soap/services`

Контракт:

- `POST /descriptors/wsdl` принимает raw WSDL payload и сохраняет inspection metadata для SOAP;
- `POST /descriptors/xsd` принимает supporting XSD artifacts для SOAP operation;
- `GET /soap/services` возвращает нормализованный список `service -> port -> operation` из последнего WSDL текущего draft version.
- `POST /operations/{operation_id}/test-runs` остается единым test-run endpoint для `unary`, `window`, `session` и `async_job` execution modes;
- test-run response всегда возвращает `mode`, `request_preview`, `response_preview`, `errors`, а для streaming modes дополняется:
  - `window` с `window_complete`, `truncated`, `has_more`, `cursor`;
  - `stream_session` с `session_id`, `status`, `expires_at`, `poll_after_ms`, `preview`;
  - `async_job` с `job_id`, `status`, `progress`.

### 5.5. Upstream auth profiles

- `GET /api/admin/workspaces/{workspace_id}/secrets`
- `POST /api/admin/workspaces/{workspace_id}/secrets`
- `GET /api/admin/workspaces/{workspace_id}/secrets/{secret_id}`
- `POST /api/admin/workspaces/{workspace_id}/secrets/{secret_id}/rotate`
- `DELETE /api/admin/workspaces/{workspace_id}/secrets/{secret_id}`

- `GET /api/admin/workspaces/{workspace_id}/auth-profiles`
- `POST /api/admin/workspaces/{workspace_id}/auth-profiles`
- `GET /api/admin/workspaces/{workspace_id}/auth-profiles/{auth_profile_id}`
- `PATCH /api/admin/workspaces/{workspace_id}/auth-profiles/{auth_profile_id}`
- `DELETE /api/admin/workspaces/{workspace_id}/auth-profiles/{auth_profile_id}`

Контракт:

- `POST /secrets` принимает metadata и plaintext value, но create-response возвращает только metadata;
- `GET /secrets` и `GET /secrets/{secret_id}` возвращают только metadata, `kind`, `status`, `current_version`, `created_at`, `updated_at`, `last_used_at` при наличии;
- `POST /secrets/{secret_id}/rotate` создает новую secret version;
- `DELETE /secrets/{secret_id}` отклоняется, если secret все еще используется `AuthProfile`;
- `AuthProfile.config` хранит ссылки на `secret_id`, а не placeholder-строки `${secrets.*}`.

### 5.6. Agents

- `GET /api/admin/workspaces/{workspace_id}/agents`
- `POST /api/admin/workspaces/{workspace_id}/agents`
- `GET /api/admin/workspaces/{workspace_id}/agents/{agent_id}`
- `PATCH /api/admin/workspaces/{workspace_id}/agents/{agent_id}`
- `DELETE /api/admin/workspaces/{workspace_id}/agents/{agent_id}`
- `POST /api/admin/workspaces/{workspace_id}/agents/{agent_id}/versions`
- `GET /api/admin/workspaces/{workspace_id}/agents/{agent_id}/versions/{version}`
- `POST /api/admin/workspaces/{workspace_id}/agents/{agent_id}/publish`
- `POST /api/admin/workspaces/{workspace_id}/agents/{agent_id}/unpublish`
- `POST /api/admin/workspaces/{workspace_id}/agents/{agent_id}/archive`
- `POST /api/admin/workspaces/{workspace_id}/agents/{agent_id}/bindings`
- `DELETE /api/admin/workspaces/{workspace_id}/agents/{agent_id}/bindings/{operation_id}`
- `GET /api/admin/workspaces/{workspace_id}/agents/{agent_id}/platform-api-keys`
- `POST /api/admin/workspaces/{workspace_id}/agents/{agent_id}/platform-api-keys`
- `POST /api/admin/workspaces/{workspace_id}/agents/{agent_id}/platform-api-keys/{key_id}/revoke`
- `DELETE /api/admin/workspaces/{workspace_id}/agents/{agent_id}/platform-api-keys/{key_id}`

Контракт:

- `POST /agents/{agent_id}/platform-api-keys` возвращает metadata ключа и одноразовый `secret`;
- полное значение ключа доступно только в create-response;
- list endpoints возвращают только metadata, `prefix`, `status`, `scopes`, `expires_at` и `last_used_at`;
- в `Community` ключ агента является основным машинным credential;
- в коммерческих редакциях этот же ключ используется как исходный credential для более строгих токенных режимов.

### 5.7. Token issuance

Для расширенных редакций платформы:

- `POST /mcp-auth/v1/token`
- `POST /mcp-auth/v1/token/one-time`

Контракт:

- `POST /mcp-auth/v1/token` выдает короткоживущий токен доступа для операций уровня `elevated`;
- `POST /mcp-auth/v1/token/one-time` выдает одноразовый токен для операций уровня `strict`;
- открытая редакция работает только со статическим ключом агента и не обязана реализовывать эти конечные точки;
- детальная схема уровней и режимов доступа зафиксирована в `docs/agent-auth-model.md`.

JSON payloads:

- `POST /mcp-auth/v1/token`
  - request:
    - `grant_type`: `agent_key | refresh_token`
    - `agent_key?`
    - `refresh_token?`
    - `scope[]`
  - response:
    - `access_token`
    - `token_type`
    - `expires_in`
    - `refresh_token?`
    - `machine_access_mode`
    - `security_level`
    - `agent_id`

- `POST /mcp-auth/v1/token/one-time`
  - request:
    - `agent_key`
    - `operation_id`
    - `scope[]`
  - response:
    - `access_token`
    - `token_type`
    - `expires_in`
    - `machine_access_mode`
    - `security_level`
    - `agent_id`

Community behavior:

- открытая редакция публикует эти конечные точки как stable public contract;
- в Community вызовы возвращают `403 forbidden` с structured `error.context`, где явно указаны:
  - `edition`
  - `machine_access_mode`
  - `upgrade_required`
- private реализация short-lived и one-time token service подключается без изменения публичного HTTP surface.

### 5.8. Observability

- `GET /api/admin/workspaces/{workspace_id}/logs`
- `GET /api/admin/workspaces/{workspace_id}/logs/{log_id}`
- `GET /api/admin/workspaces/{workspace_id}/usage`
- `GET /api/admin/workspaces/{workspace_id}/usage/operations/{operation_id}`
- `GET /api/admin/workspaces/{workspace_id}/usage/agents/{agent_id}`

Контракт:

- `GET /logs` поддерживает `level`, `search`, `source`, `operation_id`, `agent_id`, `period`, `limit`;
- `period` использует UI-friendly значения `30m`, `1h`, `6h`, `24h`, `7d`, `30d`, `90d`, `this_month`;
- `source` различает `admin_test_run` и `agent_tool_call`;
- `GET /usage` возвращает `summary`, `timeline`, `operations`, `agents` одним ответом;
- detail endpoints по operation и agent возвращают rollup для выбранного периода.

## 6. Page-to-endpoint mapping

### Operations catalog

Нужны:

- список операций;
- удаление операции;
- edit/open operation;
- publish/archive;
- usage summary для карточек и фильтров.

### Wizard

Нужны:

- create/update version;
- test run;
- samples;
- draft generation;
- gRPC descriptor upload и discovery.
- upstream auth selector;
- quick-create secret / auth profile modal.
- execution mode selector;
- streaming config blocks, stream test-runs и tool family preview только там, где это разрешает capability model редакции;

Детальные DTO и response shapes для экранов `Operations` и `Wizard` зафиксированы отдельно в:

- `docs/operations-workspace-contracts.md`

### Agents

Нужны:

- CRUD агентов;
- bindings к operations;
- publish agent;
- выдача MCP endpoint metadata.

### API Keys

Нужны:

- list/create/revoke/delete agent keys;
- one-time reveal значения ключа при создании;
- для расширенных редакций — выдача короткоживущих и одноразовых токенов.

### Secrets

Нужны:

- list/create/rotate/delete upstream secrets;
- metadata-only retrieval после создания;
- связь с auth profiles;
- usage references, чтобы оператор видел, где секрет используется.

### Logs

Нужны:

- list logs с фильтрами;
- log detail;
- polling или live refresh strategy.

### Usage

Нужны:

- агрегаты по периодам;
- breakdown по operation;
- breakdown по agent;
- CSV export.

Текущая реализация:

- summary и breakdown считаются по `invocation_logs`;
- materialized `usage_rollups` остаются совместимым storage-слоем для дальнейшей оптимизации, но не являются единственным source of truth в MVP.

## 7. Принцип совместимости

Если UI расходится с текущим backend, приоритет отдается целевой продуктовой модели, но конфликт должен быть явно разобран в `docs/as-is-to-be.md` до начала реализации.
