# Схема БД

## 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 живут за `secret_ref`;
- platform API keys хранятся как hash.

## 3. Основные таблицы

- `workspaces`
- `users`
- `user_sessions`
- `memberships`
- `invitation_tokens`
- `operations`
- `operation_versions`
- `published_operations`
- `operation_samples`
- `descriptors`
- `auth_profiles`
- `agents`
- `agent_versions`
- `agent_operation_bindings`
- `published_agents`
- `platform_api_keys`
- `invocation_logs`
- `usage_rollups`
- `yaml_import_jobs`

## 4. Operations

### `operations`

- `id`
- `workspace_id`
- `name`
- `display_name`
- `protocol`
- `status`
- `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`

### `yaml_import_jobs`

- `id`
- `source_sample_id`
- `status`
- `format_version`
- `mode`
- `result_operation_id`
- `result_version`
- `error_text`
- `created_at`
- `finished_at`

## 6. Upstream auth

### `auth_profiles`

- `id`
- `workspace_id`
- `name`
- `kind`
- `config_json`
- `created_at`
- `updated_at`

Ограничение:

- `unique (workspace_id, name)`

## 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. Platform access and observability

### `platform_api_keys`

- `id`
- `workspace_id`
- `name`
- `prefix`
- `secret_hash`
- `scopes_json`
- `status`
- `created_at`
- `last_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. добавить `agents` и `published_agents`;
4. внедрить `platform_api_keys`;
5. добавить `invocation_logs` и `usage_rollups`;
6. перевести MCP runtime на `published_agents`, а не на глобальный список operations.
