Files
crank/docs/data-model.md
T
2026-04-06 21:27:19 +03:00

11 KiB
Raw Blame History

Модель данных

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

Этот документ фиксирует целевую формальную модель данных платформы. Его цель - определить такие структуры, которые можно без существенных изменений перенести в:

  • Rust domain types;
  • HTTP DTO;
  • структуру таблиц БД;
  • runtime-представление операций и агентов;
  • UI-формы и конфигурационные экраны.

2. Общие принципы модели

2.1. Одна операция - один интеграционный контракт

Каждая Operation соответствует одному интеграционному контракту:

  • GraphQL -> один конкретный query или mutation;
  • gRPC -> один unary method или один server-streaming method в bounded execution mode;
  • REST -> один endpoint-сценарий.

Однако MCP tool публикуется не напрямую из operation, а через AgentOperationBinding внутри конкретного Agent.

2.2. Внутренний транспортный формат - JSON

Независимо от внешнего протокола внутри системы данные представлены в JSON-ориентированном виде.

2.3. Mapping всегда явный

Даже если система умеет строить черновой mapping по примерам данных, итоговая конфигурация mapping сохраняется явно.

2.4. JSONPath как единый язык адресации

Для input и output mapping используется JSONPath.

2.5. Workspace - обязательная граница данных

Все продуктовые сущности принадлежат одному Workspace.

Минимальный набор workspace-scoped сущностей:

  • Secret
  • SecretVersion
  • Operation
  • OperationVersion
  • AuthProfile
  • Agent
  • PlatformApiKey
  • InvocationLog
  • UsageRollup

2.6. YAML как формат обмена конфигурацией

Помимо канонической JSON-модели система поддерживает импорт и экспорт конфигураций в YAML.

2.7. Streaming operation обязана быть bounded

Если операция использует upstream streaming, она должна работать в одном из execution modes:

  • window
  • session
  • async_job

Бесконечный passthrough stream не является допустимой моделью Operation.

2.8. Execution model важнее transport-specific особенностей

Каждая операция в системе определяется двумя измерениями:

  • protocol
  • execution_mode

Это позволяет описывать:

  • REST unary;
  • REST SSE window;
  • gRPC server-stream session;
  • WebSocket event feed;
  • SOAP request-response;

в рамках одной общей модели runtime и MCP publishing.

3. Корневые сущности

3.1. Workspace

Поля:

  • id
  • slug
  • display_name
  • status
  • settings
  • created_at
  • updated_at

Назначение:

  • логическая изоляция команд;
  • scoping для операций, агентов, ключей и логов;
  • основа для multi-tenant MCP endpoints.

3.2. Operation

Поля:

  • id
  • workspace_id
  • name
  • display_name
  • category
  • protocol
  • status
  • version
  • target
  • input_schema
  • output_schema
  • input_mapping
  • output_mapping
  • execution_config
  • tool_description
  • samples
  • generated_draft
  • config_export
  • streaming_config
  • created_at
  • updated_at
  • published_at

3.3. Agent

Agent - пользовательская MCP-поверхность, которая собирает ограниченный набор published operations.

Поля:

  • id
  • workspace_id
  • slug
  • display_name
  • description
  • status
  • current_draft_version
  • latest_published_version
  • created_at
  • updated_at
  • published_at

3.4. AgentVersion

Снимок конфигурации агента.

Поля:

  • agent_id
  • version
  • status
  • instructions
  • tool_selection_policy
  • bindings
  • created_at

3.5. AgentOperationBinding

Связь published operation с agent version.

Поля:

  • operation_id
  • operation_version
  • tool_name
  • tool_title
  • tool_description_override
  • enabled

3.6. Secret

Секрет для доступа к внешней системе.

Поля:

  • id
  • workspace_id
  • name
  • kind
  • status
  • current_version
  • created_at
  • updated_at

Значение:

  • plaintext не возвращается в list/get endpoints;
  • текущее значение хранится в зашифрованном виде через SecretVersion;
  • rotate создает новую версию секрета без потери ссылочной целостности.

3.7. SecretVersion

Зашифрованное значение секрета.

Поля:

  • secret_id
  • version
  • ciphertext
  • key_version
  • created_at

3.8. AuthProfile

Используется только для доступа к внешним системам.

Поля:

  • id
  • workspace_id
  • name
  • kind
  • config

Принцип:

  • AuthProfile не хранит plaintext;
  • config ссылается на secret_id или пару secret_id, если auth-схема составная;
  • runtime применяет profile к запросу только в момент вызова upstream.

3.9. PlatformApiKey

Отдельная сущность для доступа к самой платформе.

Поля:

  • id
  • workspace_id
  • name
  • prefix
  • scopes
  • status
  • created_at
  • last_used_at

Секрет:

  • полный secret показывается только один раз при создании;
  • в persistent storage сохраняется только secret_hash.

3.10. User

Поля:

  • id
  • email
  • display_name
  • password_hash
  • status
  • created_at

Пароль:

  • хранится только как Argon2id hash;
  • plaintext пароль не сохраняется;
  • верификация использует password_pepper из env.

3.11. UserSession

Поля:

  • id
  • user_id
  • secret_hash
  • status
  • expires_at
  • last_seen_at
  • created_at

Секрет:

  • браузеру выдается только opaque session token;
  • в persistent storage сохраняется только secret_hash;
  • подпись и верификация используют session_secret из env.

3.12. Membership

Поля:

  • workspace_id
  • user_id
  • role
  • created_at

3.13. InvitationToken

Поля:

  • id
  • workspace_id
  • email
  • role
  • status
  • expires_at
  • created_at

Токен:

  • полный invite token показывается только один раз при создании;
  • в persistent storage сохраняется только token_hash.

3.14. InvocationLog

Продуктовая запись о вызове tool.

Поля:

  • id
  • workspace_id
  • agent_id
  • operation_id
  • request_id
  • level
  • status
  • duration_ms
  • error_kind
  • request_preview
  • response_preview
  • created_at

3.15. UsageRollup

Агрегированная статистика по периоду.

Поля:

  • workspace_id
  • agent_id
  • operation_id
  • period_kind
  • period_start
  • calls_total
  • calls_ok
  • calls_error
  • p50_ms
  • p95_ms
  • p99_ms

3.16. StreamSession

Поля:

  • id
  • workspace_id
  • agent_id
  • operation_id
  • mode
  • status
  • cursor
  • state
  • expires_at
  • last_poll_at
  • created_at
  • closed_at

Назначение:

  • хранение bounded session state для streaming tools;
  • поддержка start/poll/stop;
  • cleanup orphaned и expired sessions.

3.17. AsyncJobHandle

Поля:

  • id
  • workspace_id
  • agent_id
  • operation_id
  • status
  • progress
  • result
  • error
  • expires_at
  • created_at
  • updated_at
  • finished_at

Назначение:

  • поддержка start/status/result/cancel для long-running upstream actions.

4. Target

Target описывает конкретный внешний вызов. Это discriminated union по протоколу.

4.1. RestTarget

  • kind
  • base_url
  • method
  • path_template
  • static_headers

4.2. GraphqlTarget

  • kind
  • endpoint
  • operation_type
  • operation_name
  • query_template
  • response_path

4.3. GrpcTarget

  • kind
  • server_addr
  • package
  • service
  • method
  • descriptor_ref
  • descriptor_set_b64

4.4. WebSocketTarget

  • kind
  • url
  • subprotocols
  • subscribe_message_template
  • unsubscribe_message_template
  • static_headers

4.5. SoapTarget

  • kind
  • wsdl_ref
  • service_name
  • port_name
  • operation_name
  • endpoint_override
  • soap_version
  • soap_action
  • binding_style
  • headers
  • fault_contract
  • metadata

5. ProtocolOptions

ProtocolOptions хранит protocol-specific runtime tuning, который не должен смешиваться с общей ExecutionConfig.

5.1. GrpcProtocolOptions

  • use_tls

5.2. WebsocketProtocolOptions

  • heartbeat_interval_ms
  • reconnect_max_attempts
  • reconnect_backoff_ms

5.3. SoapProtocolOptions

  • use_tls
  • validate_certificate
  • ws_security_profile

6. XML normalization model

Для SOAP/XSD-пайплайна crank-schema теперь фиксирует XML-origin metadata отдельными code-level types:

  • XmlNodeKind
  • XmlQualifiedName
  • XmlSchemaBinding

Они описывают:

  • является ли узел element / attribute / text;
  • локальное имя и namespace;
  • repeated / nillable semantics.

7. Schema

Schema - нормализованное описание входа или выхода.

Поддерживаются:

  • скалярные поля;
  • вложенные объекты;
  • массивы;
  • enum;
  • nullable-поля;
  • oneof для protobuf.

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

Если UI требует сущность, которой нет в текущем backend, эта сущность должна быть сначала явно добавлена в эту модель данных, а уже потом в код и БД.

Для upstream credentials это означает:

  • placeholder-строки вида ${secrets.API_KEY} не считаются реальной моделью данных;
  • рабочая продуктовая модель строится только через Secret + AuthProfile.

Для Operations и Wizard дополнительный уровень контрактной детализации закреплен в:

  • docs/operations-workspace-contracts.md