15 KiB
Operations Workspace Contracts
1. Назначение документа
Этот документ задает точные workspace-scoped контракты для экранов:
OperationsWizard
Документ нужен как промежуточный слой между:
- текущим Alpine UI в
apps/ui; docs/backend-gap-plan.md;- реализацией
admin-api.
2. Общие правила
Базовый префикс:
/api/admin/workspaces/{workspace_id}
Общие принципы:
- все operation принадлежат одному workspace;
- каталог операций отдается целиком с сервера и не требует client-side merge поверх локального mock state;
- wizard работает только через backend и не опирается на
localStorageилиsessionStorage; - versioning остается явным;
- текущий draft lifecycle отделен от published lifecycle;
PATCH /operations/{operation_id}обновляет текущий draft;POST /operations/{operation_id}/versionsсоздает новый explicit snapshot;- опубликованная operation не удаляется hard delete, если на нее есть published agent bindings.
3. Канонические представления
3.1. OperationSummary
Используется в каталоге операций.
{
"id": "op_01hr9f7q4b0w1svxv5a6j8k2np",
"workspace_id": "ws_01hr9dzv4s5ec1f1v3y8t1n7gr",
"name": "crm_create_lead",
"display_name": "Create Lead",
"protocol": "rest",
"status": "draft",
"category": "sales",
"current_draft_version": 3,
"latest_published_version": 2,
"updated_at": "2026-03-29T12:00:00Z",
"usage_summary": {
"calls_today": 4821,
"error_rate_pct": 1.8,
"avg_latency_ms": 187
},
"agent_refs": [
{
"agent_id": "agent_01hr9g3kgznn57d8s1q0h0g7qn",
"agent_slug": "sales-assistant",
"display_name": "Sales Assistant"
}
]
}
3.2. OperationDetail
Используется на detail page и как источник для edit-mode wizard.
{
"id": "op_01hr9f7q4b0w1svxv5a6j8k2np",
"workspace_id": "ws_01hr9dzv4s5ec1f1v3y8t1n7gr",
"name": "crm_create_lead",
"display_name": "Create Lead",
"protocol": "rest",
"status": "draft",
"category": "sales",
"current_draft_version": 3,
"latest_published_version": 2,
"published_at": "2026-03-28T18:10:00Z",
"draft_version_ref": {
"version": 3,
"status": "draft"
},
"published_version_ref": {
"version": 2,
"status": "published"
},
"agent_refs": [
{
"agent_id": "agent_01hr9g3kgznn57d8s1q0h0g7qn",
"agent_slug": "sales-assistant",
"display_name": "Sales Assistant"
}
],
"created_at": "2026-03-27T09:15:00Z",
"updated_at": "2026-03-29T12:00:00Z"
}
3.3. OperationVersionDocument
Полная конфигурация версии. Используется wizard и detail page.
{
"operation_id": "op_01hr9f7q4b0w1svxv5a6j8k2np",
"workspace_id": "ws_01hr9dzv4s5ec1f1v3y8t1n7gr",
"version": 3,
"status": "draft",
"target": {},
"input_schema": {},
"output_schema": {},
"input_mapping": {},
"output_mapping": {},
"execution_config": {},
"tool_description": {},
"samples": {
"input_json": {},
"output_json": {}
},
"generated_draft": {
"input_schema": {},
"output_schema": {},
"input_mapping": {},
"output_mapping": {}
},
"config_export": {
"format_version": "1",
"export_mode": "portable"
},
"change_note": "update request mapping",
"created_at": "2026-03-29T12:00:00Z",
"updated_at": "2026-03-29T12:45:00Z"
}
3.4. OperationMutationResult
Используется как ответ на create, patch, explicit version, archive и delete.
{
"operation_id": "op_01hr9f7q4b0w1svxv5a6j8k2np",
"workspace_id": "ws_01hr9dzv4s5ec1f1v3y8t1n7gr",
"version": 3,
"status": "draft",
"updated_at": "2026-03-29T12:45:00Z"
}
4. Catalog endpoints
GET /api/admin/workspaces/{workspace_id}/operations
Назначение:
- отдать каталог операций для списка.
Query params:
protocolstatussearchcategoryagent_idpagepage_size
Ответ:
{
"items": [
{
"id": "op_01hr9f7q4b0w1svxv5a6j8k2np",
"workspace_id": "ws_01hr9dzv4s5ec1f1v3y8t1n7gr",
"name": "crm_create_lead",
"display_name": "Create Lead",
"protocol": "rest",
"status": "draft",
"category": "sales",
"target_url": "https://api.example.com/v1/leads",
"target_action": "POST",
"current_draft_version": 3,
"latest_published_version": 2,
"updated_at": "2026-03-29T12:00:00Z",
"usage_summary": {
"calls_today": 4821,
"error_rate_pct": 1.8,
"avg_latency_ms": 187
},
"agent_refs": []
}
],
"page": 1,
"page_size": 20,
"total": 48
}
GET /api/admin/workspaces/{workspace_id}/operations/{operation_id}
Назначение:
- отдать
OperationDetail.
GET /api/admin/workspaces/{workspace_id}/operations/{operation_id}/versions/{version}
Назначение:
- отдать
OperationVersionDocument.
5. Create and update contracts
POST /api/admin/workspaces/{workspace_id}/operations
Назначение:
- создать operation и draft version
1.
Тело:
{
"name": "crm_create_lead",
"display_name": "Create Lead",
"protocol": "rest",
"category": "sales",
"target": {},
"input_schema": {},
"output_schema": {},
"input_mapping": {},
"output_mapping": {},
"execution_config": {},
"tool_description": {}
}
Ответ:
{
"operation_id": "op_01hr9f7q4b0w1svxv5a6j8k2np",
"workspace_id": "ws_01hr9dzv4s5ec1f1v3y8t1n7gr",
"version": 1,
"status": "draft",
"updated_at": "2026-03-29T12:00:00Z"
}
PATCH /api/admin/workspaces/{workspace_id}/operations/{operation_id}
Назначение:
- обновить identity metadata;
- обновить текущий draft document без создания новой версии вручную со стороны UI.
Это endpoint для обычного wizard edit-mode.
Тело:
{
"display_name": "Create Lead",
"category": "sales",
"draft_document": {
"target": {},
"input_schema": {},
"output_schema": {},
"input_mapping": {},
"output_mapping": {},
"execution_config": {},
"tool_description": {}
}
}
Ответ:
{
"operation_id": "op_01hr9f7q4b0w1svxv5a6j8k2np",
"workspace_id": "ws_01hr9dzv4s5ec1f1v3y8t1n7gr",
"version": 3,
"status": "draft",
"updated_at": "2026-03-29T12:45:00Z"
}
POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/versions
Назначение:
- создать новую explicit draft-version snapshot.
Этот endpoint нужен для сценариев:
Save as new version;- controlled version history;
- YAML import с
mode=upsert.
Тело:
{
"source_version": 3,
"change_note": "prepare release candidate",
"document": {
"target": {},
"input_schema": {},
"output_schema": {},
"input_mapping": {},
"output_mapping": {},
"execution_config": {},
"tool_description": {}
}
}
Ответ:
{
"operation_id": "op_01hr9f7q4b0w1svxv5a6j8k2np",
"workspace_id": "ws_01hr9dzv4s5ec1f1v3y8t1n7gr",
"version": 4,
"status": "draft",
"updated_at": "2026-03-29T13:05:00Z"
}
6. Lifecycle endpoints
POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/publish
Назначение:
- опубликовать конкретную версию операции.
Тело:
{
"version": 3
}
Ответ:
{
"operation_id": "op_01hr9f7q4b0w1svxv5a6j8k2np",
"workspace_id": "ws_01hr9dzv4s5ec1f1v3y8t1n7gr",
"version": 3,
"status": "published",
"updated_at": "2026-03-29T13:10:00Z"
}
POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/archive
Назначение:
- перевести operation в archived lifecycle state без hard delete.
Тело:
{
"reason": "deprecated by crm_create_lead_v2"
}
Ответ:
{
"operation_id": "op_01hr9f7q4b0w1svxv5a6j8k2np",
"workspace_id": "ws_01hr9dzv4s5ec1f1v3y8t1n7gr",
"version": 3,
"status": "archived",
"updated_at": "2026-03-29T13:15:00Z"
}
DELETE /api/admin/workspaces/{workspace_id}/operations/{operation_id}
Назначение:
- hard delete для еще не опубликованной operation.
Правила:
- hard delete допустим только для draft/unpublished operation;
- если operation уже публиковалась, UI должен использовать archive;
- если operation используется published agent-ами, endpoint возвращает
409 Conflict.
Ответ:
{
"operation_id": "op_01hr9f7q4b0w1svxv5a6j8k2np",
"workspace_id": "ws_01hr9dzv4s5ec1f1v3y8t1n7gr",
"deleted": true
}
7. Wizard-specific endpoints
POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/test-runs
Тело:
{
"version": 3,
"input": {}
}
Ответ:
{
"status": "ok",
"request_preview": {},
"response_preview": {},
"output": {},
"runtime_labels": {
"workspace_id": "ws_01hr9dzv4s5ec1f1v3y8t1n7gr",
"operation_id": "op_01hr9f7q4b0w1svxv5a6j8k2np"
}
}
POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/samples/input-json
Тело:
{
"version": 3,
"sample": {}
}
Ответ:
{
"operation_id": "op_01hr9f7q4b0w1svxv5a6j8k2np",
"version": 3,
"stored": true
}
POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/samples/output-json
Тело:
{
"version": 3,
"sample": {}
}
Ответ:
{
"operation_id": "op_01hr9f7q4b0w1svxv5a6j8k2np",
"version": 3,
"stored": true
}
POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/drafts/generate
Назначение:
- сгенерировать черновую схему и draft mappings по samples/descriptors.
Тело:
{
"version": 3
}
Ответ должен возвращать полный draft payload, пригодный для прямой подстановки в wizard:
{
"generated_draft": {
"input_schema": {},
"output_schema": {},
"input_mapping": {},
"output_mapping": {}
},
"input_schema": {},
"output_schema": {},
"input_mapping": {},
"output_mapping": {}
}
POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/descriptors/proto
Тело:
{
"version": 3,
"file_name": "crm.proto",
"content_b64": "..."
}
Ответ:
{
"descriptor_ref": "desc_01hr9n0m2yzdb8f8xv1gvztm2b",
"stored": true
}
POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/descriptors/descriptor-set
Тело:
{
"version": 3,
"file_name": "crm-descriptor-set.bin",
"content_b64": "..."
}
Ответ:
{
"descriptor_ref": "desc_01hr9n0m2yzdb8f8xv1gvztm2b",
"stored": true
}
GET /api/admin/workspaces/{workspace_id}/operations/{operation_id}/grpc/services?version=3
Ответ:
{
"services": [
{
"package": "crm.v1",
"service": "LeadService",
"methods": [
{
"name": "CreateLead",
"kind": "unary",
"input_schema": {},
"output_schema": {}
}
]
}
]
}
8. YAML contracts
GET /api/admin/workspaces/{workspace_id}/operations/{operation_id}/export
Query:
mode=portable|bundleversion=<optional>
Ответ:
application/yaml
POST /api/admin/workspaces/{workspace_id}/operations/import
Query:
mode=create|upsert
Body:
- raw YAML document
Ответ:
{
"workspace_id": "ws_01hr9dzv4s5ec1f1v3y8t1n7gr",
"operation_id": "op_01hr9f7q4b0w1svxv5a6j8k2np",
"version": 4,
"status": "draft",
"result": "upserted"
}
9. Wizard lifecycle semantics
Текущее редактирование
Wizard всегда открывается на current draft version и использует:
GET /operations/{operation_id}GET /operations/{operation_id}/versions/{current_draft_version}PATCH /operations/{operation_id}
Это основной сценарий редактирования.
Явное создание новой версии
Если UI вводит действие Save as new version, оно должно использовать:
POST /operations/{operation_id}/versions
Это уже отдельный snapshot, а не обычное сохранение формы.
Публикация
Публикуется конкретная version, а не “текущее состояние формы”.
Поэтому UI всегда должен передавать:
version
в POST /publish.
10. Конфликты, которые закрывает этот документ
Конфликт 1. PATCH против explicit version snapshots
Решение:
- wizard использует
PATCHдля текущего draft; - controlled snapshots остаются на
POST /versions.
Конфликт 2. Delete semantics
Решение:
- hard delete только для unpublished drafts;
- для опубликованных операций использовать archive.
Конфликт 3. Category source of truth
Решение:
categoryпризнается частью operation identity metadata и хранится на стороне backend.
Конфликт 4. Catalog data merge
Решение:
- каталог должен возвращать все нужные поля для UI с сервера;
- локальные overlays и tombstones в целевой реализации не используются.
11. Следующий шаг
После этого документа следующая реализация должна идти в таком порядке:
- обновить
admin-apihandlers и service contracts под workspace prefix; - добавить
category,workspace_idи update/delete/archive lifecycle в storage model; - перевести wizard на create/patch/version semantics из этого документа;
- только после этого подключать
OperationsиWizardк реальному UI.