# Схема БД Основная БД Crank Community — PostgreSQL. ## Основные таблицы - `workspaces` - `users` - `user_sessions` - `memberships` - `operations` - `operation_versions` - `published_operations` - `operation_samples` - `agents` - `agent_versions` - `agent_operation_bindings` - `published_agents` - `platform_api_keys` - `secrets` - `secret_versions` - `auth_profiles` - `invocation_logs` - `usage_rollups` - `product_events` - `product_event_daily_rollups` - `yaml_import_jobs` `memberships` используется как служебная привязка единственного администратора к bootstrap workspace. ## Operations `operations` хранит текущую карточку operation. `operation_versions` хранит versioned JSON contract: - version-local tool identity, display metadata, protocol и security level; - REST target; - schemas; - mappings; - execution config; - tool description; - samples metadata. Migration v4 добавляет honest snapshot provenance и PostgreSQL trigger, который запрещает UPDATE/DELETE Published payload, включая parent cascade. Единственное разрешённое изменение version row — атомарный current Draft → Published transition; дальнейшие правки всегда INSERT новой revision. Migration v5 расширяет `invocation_logs` nullable полями `operation_version`, `execution_stage`, `execution_error_code`, `retryability` и `outcome_certainty`. Новые execution записи заполняют их, legacy строки остаются неизвестными без fabricated backfill. Migration v11 добавляет nullable `platform_api_key_id` и composite foreign key `(workspace_id, agent_id, platform_api_key_id)` к key того же Agent/workspace. Это exact credential provenance только для новых verified MCP invocations; legacy и external-verifier rows честно остаются `NULL`. Partial index по workspace/Agent/key/successful tool call поддерживает bounded onboarding projection без materialization history. `published_operations` указывает на опубликованную version. Archive изменяет только `operations.status`; exact Agent bindings и invocation history продолжают ссылаться на immutable version. ## Agents `agents` хранит карточку agent. `agent_versions` хранит versioned agent contract. `agent_operation_bindings` связывает agent и published operations. `published_agents` указывает на опубликованную version. ## Secrets `secrets` хранит metadata. `secret_versions` хранит encrypted value, `key_version` и `master_key_epoch`. Во время master-key rotation дополнительные nullable поля `target_ciphertext`, `target_key_version`, `target_master_key_epoch` содержат только verified candidate ciphertext до promotion; основной ciphertext остаётся рабочим до атомарного переключения epoch. `master_key_identities` хранит non-secret identity активных/retired epochs: epoch, lowercase hex fingerprint, cipher contract, status и optional opaque `backup_ref`. Raw master key bytes и derived encryption keys в таблицах не хранятся. `master_key_rotations` хранит durable operator workflow: source/target epoch, target fingerprint, state, checkpoint, counts и safe failure code. Только одна rotation может быть active (`running|verifying|verified`) для Secret writes. `auth_profiles` хранит способ применения secrets к REST request. `platform_api_keys` хранит metadata, bounded prefix и hash для MCP client и approval keys. Raw key в таблице не хранится. `status` принимает `active|revoked|deleted`; delete endpoint выполняет terminal soft-delete, чтобы не стирать audit/provenance. Для approval keys поле `allowed_origins_json` фиксирует точные разрешённые origins. ## Observability `invocation_logs` хранит события runtime/MCP вызовов. `usage_rollups` хранит агрегированную статистику. ## Local ProductEvents `product_events` хранит workspace-scoped append-only ProductEvents: closed event name, `schema_version`, UTC `occurred_at`, bounded idempotency key и bounded JSON object properties. Unique `(workspace_id, idempotency_key)` делает replay безопасным; trigger отвергает `UPDATE` и `DELETE`. `product_event_daily_rollups` хранит только daily counters по workspace/event/day. Его primary key не допускает дубликатов, а check constraint требует неотрицательные values и `eligible_total <= events_total`. Эти таблицы не содержат raw key, credentials, raw user/object identifiers, invocation payload или telemetry endpoint.