Files
crank/docs/database-schema.md
T
2026-05-03 10:38:12 +00:00

478 lines
9.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Схема БД
## 1. Назначение документа
Этот документ фиксирует целевую структуру хранения workspace-scoped конфигураций, агентов, ключей доступа и observability-данных. Базовая СУБД - `PostgreSQL`.
## 2. Общие принципы хранения
### 2.1. Версионирование обязательно
Конфигурация operation и agent не хранится только в одной "живой" записи. Каждое существенное изменение создает новую версию.
### 2.2. Published и draft разделяются логически
- `draft` может меняться;
- `published` всегда указывает на конкретную version;
- runtime читает только опубликованные представления.
### 2.3. Workspace scoping обязателен
Все продуктовые таблицы должны ссылаться на `workspaces`.
### 2.4. Артефакты и конфигурация не смешиваются
`.proto`, descriptor set, sample JSON и YAML payload не хранятся в тех же строках, что runtime-ready configuration.
### 2.5. Секреты не хранятся в открытом виде
- upstream secrets живут в отдельных таблицах и шифруются;
- agent keys и credentials доверенных клиентов хранятся как hash;
- короткоживущие токены хранятся в форме, пригодной для отзыва и учета использования.
## 3. Основные таблицы
- `workspaces`
- `users`
- `user_sessions`
- `memberships`
- `invitation_tokens`
- `secrets`
- `secret_versions`
- `operations`
- `operation_versions`
- `published_operations`
- `operation_samples`
- `descriptors`
- `auth_profiles`
- `agents`
- `agent_versions`
- `agent_operation_bindings`
- `published_agents`
- `agent_keys`
- `issued_agent_tokens`
- `platform_client_credentials`
- `stream_sessions`
- `async_jobs`
- `invocation_logs`
- `usage_rollups`
- `yaml_import_jobs`
## 4. Operations
### `operations`
- `id`
- `workspace_id`
- `name`
- `display_name`
- `protocol`
- `status`
- `security_level`
- `current_draft_version`
- `latest_published_version`
- `created_at`
- `updated_at`
- `published_at`
Ограничение:
- `unique (workspace_id, name)`
### `operation_versions`
- `operation_id`
- `version`
- `status`
- `target_json`
- `input_schema_json`
- `output_schema_json`
- `input_mapping_json`
- `output_mapping_json`
- `execution_config_json`
- `tool_description_json`
- `samples_json`
- `generated_draft_json`
- `config_export_json`
- `change_note`
- `created_at`
- `created_by`
### `published_operations`
- `operation_id`
- `version`
- `published_at`
- `published_by`
## 5. Operation artifacts
### `operation_samples`
- `id`
- `operation_id`
- `version`
- `sample_kind`
- `storage_ref`
- `content_type`
- `file_name`
- `created_at`
### `descriptors`
- `id`
- `operation_id`
- `version`
- `descriptor_kind`
- `storage_ref`
- `source_name`
- `package_index_json`
- `created_at`
`descriptor_kind` дополнительно поддерживает:
- `wsdl_upload`
- `xsd_upload`
`package_index_json` для `wsdl_upload` хранит нормализованный inspection result:
- `service_name`
- `port_name`
- `binding_name`
- `endpoint`
- `soap_version`
- `operations[]`
### `yaml_import_jobs`
- `id`
- `source_sample_id`
- `status`
- `format_version`
- `mode`
- `result_operation_id`
- `result_version`
- `error_text`
- `created_at`
- `finished_at`
## 6. Upstream secrets and auth
### `secrets`
- `id`
- `workspace_id`
- `name`
- `kind`
- `status`
- `current_version`
- `created_at`
- `updated_at`
Ограничение:
- `unique (workspace_id, name)`
### `secret_versions`
- `secret_id`
- `version`
- `ciphertext`
- `key_version`
- `created_at`
### `auth_profiles`
- `id`
- `workspace_id`
- `name`
- `kind`
- `config_json`
- `created_at`
- `updated_at`
Назначение:
- `config_json` хранит ссылки на `secret_id`, а не plaintext значения;
- допустимы bearer, basic, api-key-header, api-key-query профили.
Ограничение:
- `unique (workspace_id, name)`
### `agent_keys`
- `id`
- `workspace_id`
- `agent_id`
- `name`
- `prefix`
- `secret_hash`
- `scopes_json`
- `status`
- `expires_at`
- `created_at`
- `last_used_at`
Ограничения:
- `unique (agent_id, name)`
- `prefix` уникален глобально
Назначение:
- длинноживущий ключ принадлежит одному агенту;
- ключ используется как исходное основание для выпуска короткоживущего токена;
- прямой вызов MCP по такому ключу допускается только в переходном режиме.
### `issued_agent_tokens`
- `id`
- `workspace_id`
- `agent_id`
- `agent_key_id`
- `token_kind`
- `status`
- `scopes_json`
- `max_uses`
- `used_count`
- `cnf_jkt`
- `expires_at`
- `created_at`
- `used_at`
Индексы:
- `(agent_id, status, expires_at)`
- `(workspace_id, status, expires_at)`
- `(cnf_jkt)` при включенной привязке токена к ключевой паре клиента
Назначение:
- учет выданных короткоживущих токенов;
- поддержка одноразовых токенов;
- поддержка отзыва и проверки повторного использования.
### `stream_sessions`
- `id`
- `workspace_id`
- `agent_id`
- `operation_id`
- `mode`
- `status`
- `cursor_json`
- `state_json`
- `expires_at`
- `last_poll_at`
- `created_at`
- `closed_at`
Индексы:
- `(workspace_id, status, expires_at)`
- `(operation_id, status)`
### `async_jobs`
- `id`
- `workspace_id`
- `agent_id`
- `operation_id`
- `status`
- `progress_json`
- `result_json`
- `error_json`
- `expires_at`
- `created_at`
- `updated_at`
- `finished_at`
Индексы:
- `(workspace_id, status, expires_at)`
- `(operation_id, status)`
## 7. Workspaces and access layer
### `workspaces`
- `id`
- `slug`
- `display_name`
- `status`
- `settings_json`
- `created_at`
- `updated_at`
### `users`
- `id`
- `email`
- `display_name`
- `password_hash`
- `status`
- `created_at`
### `user_sessions`
- `id`
- `user_id`
- `secret_hash`
- `status`
- `expires_at`
- `last_seen_at`
- `created_at`
Ограничения:
- `unique (user_id, id)`
### `memberships`
- `workspace_id`
- `user_id`
- `role`
- `created_at`
### `invitation_tokens`
- `id`
- `workspace_id`
- `email`
- `role`
- `status`
- `token_hash`
- `expires_at`
- `created_at`
## 8. Agents
### `agents`
- `id`
- `workspace_id`
- `slug`
- `display_name`
- `description`
- `status`
- `current_draft_version`
- `latest_published_version`
- `created_at`
- `updated_at`
- `published_at`
Ограничение:
- `unique (workspace_id, slug)`
### `agent_versions`
- `agent_id`
- `version`
- `status`
- `instructions_json`
- `tool_selection_policy_json`
- `created_at`
### `agent_operation_bindings`
- `agent_id`
- `agent_version`
- `operation_id`
- `operation_version`
- `tool_name`
- `tool_title`
- `tool_description_override`
- `enabled`
### `published_agents`
- `agent_id`
- `version`
- `published_at`
- `published_by`
## 9. Machine access and observability
### `agent_keys`
- `id`
- `workspace_id`
- `agent_id`
- `name`
- `prefix`
- `secret_hash`
- `scopes_json`
- `status`
- `expires_at`
- `created_at`
- `last_used_at`
### `issued_agent_tokens`
- `id`
- `workspace_id`
- `agent_id`
- `agent_key_id`
- `token_kind`
- `status`
- `scopes_json`
- `max_uses`
- `used_count`
- `cnf_jkt`
- `expires_at`
- `created_at`
- `used_at`
### `invocation_logs`
- `id`
- `workspace_id`
- `agent_id`
- `operation_id`
- `source`
- `request_id`
- `level`
- `status`
- `tool_name`
- `message`
- `status_code`
- `duration_ms`
- `error_kind`
- `request_preview_json`
- `response_preview_json`
- `created_at`
### `usage_rollups`
- `workspace_id`
- `agent_id`
- `operation_id`
- `period_kind`
- `period_start`
- `calls_total`
- `calls_ok`
- `calls_error`
- `p50_ms`
- `p95_ms`
- `p99_ms`
Замечание:
- в MVP usage read-model может вычисляться напрямую из `invocation_logs`;
- `usage_rollups` сохраняется как совместимая таблица под materialized aggregates и дальнейшую оптимизацию.
## 10. Migration strategy
Переход от текущей схемы к целевой идет так:
1. добавить `workspaces` и заполнить default workspace;
2. добавить `workspace_id` в `operations` и `auth_profiles`;
3. добавить `secrets` и `secret_versions`;
4. перевести `auth_profiles` на secret-backed config;
5. добавить `agents` и `published_agents`;
6. внедрить `agent_keys`, `platform_client_credentials` и `issued_agent_tokens`;
7. добавить `invocation_logs` и `usage_rollups`;
8. перевести MCP runtime на `published_agents`, а не на глобальный список operations.