# Архитектура

## 1. Назначение проекта

Crank - платформа для публикации внешних API в виде MCP tools без написания отдельного backend-кода под каждую интеграцию. Пользователь конфигурирует интеграции через UI, а система:

- хранит и версионирует операции;
- группирует их по workspace;
- публикует их в составе конкретных agents;
- выдает LLM не глобальный каталог tools, а curated toolset на один agent;
- собирает продуктовые логи и usage по workspace, agent и operation.

## 2. Переход `As Is -> To Be`

### 2.1. As Is

Текущее ядро системы построено вокруг:

- глобальной сущности `Operation`;
- registry версий операций;
- runtime adapters `REST / GraphQL / unary gRPC`;
- `admin-api` для CRUD и тестовых вызовов;
- `mcp-server`, который публикует tools из published operations.

### 2.2. To Be

Целевая архитектура расширяет текущее ядро до модели:

- `Workspace` - tenant boundary;
- `Operation` - интеграционный контракт;
- `Agent` - curated MCP surface;
- `Agent key`, `Agent token` и `Membership` - доступ к самой платформе;
- `Invocation log` и `Usage rollup` - observability слой.

`Operation` остается фундаментом интеграции, но tools больше не публикуются глобально. MCP публикует tools в контексте конкретного `workspace` и конкретного `agent`.

## 3. Ключевые сущности и их роль

### `Workspace`

Изолирует:

- операции;
- secrets;
- auth profiles;
- agents;
- agent keys;
- short-lived agent tokens;
- logs и usage;
- пользователей и роли.

### `Operation`

Описывает один вызываемый элемент независимо от протокола:

- `name`
- `display_name`
- `protocol`
- `target`
- `input_schema`
- `input_mapping`
- `execution_config`
- `security_level`
- `output_mapping`
- `tool_description`
- `status`

Принцип:

- уровень защиты определяется самой операцией;
- агент не может ослабить обязательный режим доступа;
- для более чувствительных данных требуется более строгий вид машинного credential.

### `Agent`

Является пользовательской MCP-поверхностью для LLM.

`Agent`:

- принадлежит одному workspace;
- имеет `slug`, `display_name`, `description`, `status`;
- ссылается на ограниченный набор published operations;
- формирует отдельный MCP endpoint;
- решает проблему "одному агенту нельзя отдавать 100 tools сразу".

При этом `Agent` не определяет чувствительность операции, а только публикует ее в составе MCP-поверхности.

### `Platform access`

Отдельный слой, не связанный с upstream auth:

- `User`
- `UserSession`
- `Membership`
- `Invitation`
- `AgentKey`
- `IssuedAgentToken`

Принцип:

- пользовательская аутентификация и машинная аутентификация разделены;
- длинноживущий доступ для вызова MCP tools привязан к конкретному агенту, а не к рабочей области целиком;
- в открытой редакции базовый режим строится на статическом ключе агента;
- в более защищенных редакциях используются короткоживущие и одноразовые токены;
- промежуточная схема с workspace-scoped ключами рассматривается как переходная и подлежит замене.

### `Upstream secrets`

Отдельный слой для доступа к внешним системам:

- `Secret`
- `SecretVersion`
- `AuthProfile`

Принцип:

- секреты принадлежат workspace;
- plaintext не хранится в открытом виде;
- `AuthProfile` описывает способ применения секрета к upstream request;
- runtime резолвит `auth_profile_ref` в реальный header/query/basic auth только в момент вызова.

### `Observability`

Отдельный продуктовый слой:

- `InvocationLog`
- `InvocationEvent`
- `UsageRollup`
- `LatencyStats`

## 4. Главный принцип проектирования

Система строится в три слоя:

1. `Operation` как низкоуровневый интеграционный контракт.
2. `Agent` как curated набор published operations.
3. `Workspace` как граница данных, доступа и observability.

Это позволяет:

- переиспользовать одну operation в нескольких agents;
- ограничивать tool catalog для конкретного LLM-сценария;
- изолировать данные команд;
- строить logs и usage не глобально, а по tenant boundary.

## 5. Границы целевого продукта

### Входит

- `Workspace` как tenant boundary.
- Операции `REST`, `GraphQL`, `gRPC`, `WebSocket`, `SOAP`.
- Controlled streaming operations поверх `Streamable HTTP`, REST SSE, gRPC server-streaming и WebSocket upstream.
- `Agent` и привязка операций к агенту.
- Agent-scoped MCP endpoints.
- Agent-scoped machine credentials.
- Short-lived MCP access tokens.
- Workspace-scoped encrypted secrets для upstream access.
- Workspace-scoped auth profiles для upstream access.
- Product logs и usage aggregates.
- Импорт и экспорт operation-конфигураций в `YAML`.
- Hot reload опубликованных agents и operations.

### Отложено

- GraphQL `subscription`.
- gRPC client-streaming и bidirectional streaming.
- raw infinite stream passthrough.
- полный стек WS-* расширений.
- Оркестрация workflow.
- Биллинг.
- Full RBAC policy engine.
- Traffic splitting и deployment orchestration.

## 6. Пользовательские сценарии

### Оператор операций

1. Выбирает workspace.
2. Создает или редактирует operation.
3. При необходимости выбирает или создает upstream secret / auth profile.
4. Выполняет test run.
5. Публикует operation version.
6. Привязывает operation к одному или нескольким agents.

### Оператор агентов

1. Создает agent.
2. Выбирает набор published operations.
3. Публикует agent.
4. Получает MCP endpoint вида `/mcp/v1/{workspace}/{agent}`.

### Администратор workspace

1. Управляет ключами AI-агентов и доверенных клиентов платформы.
2. Управляет пользователями и ролями.
3. Смотрит logs и usage.

## 7. Стратегия по протоколам

### REST

- `GET`
- `POST`
- `PUT`
- `PATCH`
- `DELETE`
- path parameters
- query parameters
- headers
- JSON request body
- JSON response body

### GraphQL

- `query`
- `mutation`
- endpoint URL
- request headers
- operation template
- variables mapping

## 8. Open-core граница

Crank развивается как open-core продукт.

Это означает:

- `Community` должна полностью собираться из этого репозитория;
- коммерческие возможности не должны храниться здесь как рабочий private code;
- различия между редакциями должны отражаться в capability model, API, UI и delivery pipeline.

Ключевые продуктовые различия зафиксированы в `docs/product-editions.md`.

## 9. Коммерческий контур

Коммерческий контур не должен защищаться "скрытием" уже опубликованного исходного кода. Правильная архитектурная граница выглядит так:

- в public repo остается Community runtime и extension seams;
- коммерческие реализации поставляются из private repositories или private artifacts;
- критичные правила лицензирования, metering и token issuance исполняются на серверной стороне.

Практические правила зафиксированы в `docs/commercial-boundaries.md`.
- извлечение результата из `data`

GraphQL в MCP публикуется как фиксированная операция с предсказуемой структурой ответа.

### gRPC

- unary RPC;
- bounded server-streaming через `window`, `session` и `async_job` execution modes;
- `.proto` и `descriptor set`;
- JSON-oriented schema model поверх protobuf;
- без client-streaming и bidi.

### WebSocket

- upstream-only adapter;
- bounded `window`, `session` и `async_job`;
- subscribe/unsubscribe messages;
- heartbeat и reconnect policy;
- не используется как downstream MCP transport.

### SOAP

- WSDL-driven request-response integration;
- service/port/operation selection;
- SOAP envelope и fault normalization;
- request-response first;
- long-running workflows через `async_job`, если upstream это поддерживает.

### Streaming

Платформа поддерживает controlled streaming model:

- downstream transport: `Streamable HTTP` с optional SSE;
- upstream streaming: REST SSE, gRPC server-streaming и WebSocket;
- execution modes: `unary`, `window`, `session`, `async_job`;
- никакого raw infinite stream passthrough в MCP client.

## 8. Работа с файлами и автогенерация черновика

Поддерживаемые источники:

- пример входного `JSON`;
- пример выходного `JSON`;
- `.proto`;
- `descriptor set`.

Ожидаемый сценарий:

1. оператор загружает артефакты;
2. система строит черновую схему и mapping;
3. оператор вручную корректирует результат;
4. готовую конфигурацию можно экспортировать в `YAML`.

## 9. Внутренняя модель данных

Базовые сущности:

- `Workspace`
- `Secret`
- `SecretVersion`
- `Operation`
- `OperationVersion`
- `Agent`
- `AgentVersion`
- `AgentOperationBinding`
- `StreamSession`
- `AsyncJobHandle`
- `AuthProfile`
- `AgentKey`
- `IssuedAgentToken`
- `UserSession`
- `InvocationLog`
- `UsageRollup`

## 10. MCP publishing model

Публикация tools строится так:

1. `Operation` проходит versioning и publish.
2. `Agent` собирает curated набор published operations.
3. `MCP server` читает published view конкретного agent.
4. `tools/list` и `tools/call` работают в контексте `workspace + agent`.

## 11. Observability

На каждый вызов tool сохраняются:

- `workspace_id`
- `agent_id`
- `operation_id`
- `request_id`
- `timestamp`
- `status`
- `duration_ms`
- `error_kind`
- `request_preview`
- `response_preview`

Сверху строятся:

- logs page;
- usage page;
- периодические rollups;
- latency and error aggregates.

## 12. Модель маппинга

Платформе нужен отдельный слой маппинга:

- сопоставление поле-в-поле по `JSONPath`;
- константы;
- значения по умолчанию;
- извлечение вложенных полей из ответа.
