Skip to content

Схема базы данных

Файлы: backend/src/identity/manager.rs, vault/manager.rs, spaces/manager.rs, clouds/manager.rs

10 таблиц SQLite в 3 файлах БД. Без миграционного фреймворка — таблицы создаются через CREATE TABLE IF NOT EXISTS, миграции через ALTER TABLE ADD COLUMN.

Typed ID Newtypes

ID всех основных сущностей обёрнуты в newtype-обёртки (файл: backend/src/types/mod.rs):

ТипГенерацияSQL-тип
IdentityIdblake3(public_key)TEXT
DeviceIdblake3(device_public_key)TEXT
SpaceIdUuid::new_v4()TEXT
CloudIdUuid::new_v4()TEXT

Все newtypes реализуют ToSql/FromSql для прозрачной работы с rusqlite, Serialize/Deserialize через #[serde(transparent)], и кросс-типовые сравнения (PartialEq<String>, PartialEq<str>).

Idempotency (INSERT OR IGNORE)

Все основные INSERT-операции используют INSERT OR IGNORE для идемпотентности при повторном выполнении (replay-safe):

ТаблицаМенеджер
identityIdentityManager
devicesDeviceManager
spacesSpaceManager
cloudsCloudManager
vault_configVaultManager

Это предотвращает ошибки при повторной обработке P2P-сообщений или перезапуске операций.

Организация

База данныхМенеджерыТаблицыНазначение
identity.dbIdentityManager, DeviceManageridentity, devicesПользователь и устройства
vault.dbVaultManagervault_config, encrypted_secrets, vault_pin_state, vault_settingsШифрованные секреты
spaces.dbSpaceManager, CloudManagerspaces, space_files, received_spaces, space_device_sync, sync_tombstones, sync_conflicts, cloudsПространства и синхронизация

Общие настройки:

  • PRAGMA busy_timeout=5000 — ожидание при блокировке до 5 сек
  • PRAGMA foreign_keys = ON — для spaces.db
  • Arc<Mutex<Connection>> — потокобезопасный доступ
  • identity.db разделяется между IdentityManager и DeviceManager
  • spaces.db разделяется между SpaceManager и CloudManager

ER-диаграмма

plantuml Diagram

identity.db

identity

Управляется: IdentityManager

sql
CREATE TABLE IF NOT EXISTS identity (
    id TEXT PRIMARY KEY,
    display_name TEXT NOT NULL,
    public_key BLOB NOT NULL,
    created_at INTEGER NOT NULL
)
КолонкаТипОписание
idTEXT, PKblake3 hash публичного ключа (IdentityId newtype)
display_nameTEXTИмя пользователя
public_keyBLOBEd25519 public key (32 bytes)
created_atINTEGERUnix timestamp

Одна identity на БД (одна строка, обновляется при паринге).

devices

Управляется: DeviceManager

sql
CREATE TABLE IF NOT EXISTS devices (
    id TEXT PRIMARY KEY,
    name TEXT NOT NULL,
    device_type TEXT NOT NULL,
    identity_id TEXT NOT NULL,
    public_key BLOB NOT NULL,
    private_key BLOB,
    peer_id TEXT,
    last_seen INTEGER NOT NULL,
    is_current INTEGER DEFAULT 0,
    os TEXT,
    ip TEXT,
    storage_used INTEGER,
    storage_total INTEGER,
    storage_unit TEXT,
    added_via TEXT
)
КолонкаТипОписание
idTEXT, PKblake3 hash публичного ключа устройства (DeviceId newtype)
nameTEXTИмя устройства
device_typeTEXTlaptop, phone, tablet, desktop, nas, server
identity_idTEXTID владельца
public_keyBLOBEd25519 public key (32 bytes)
private_keyBLOBEd25519 private key (только для текущего устройства)
peer_idTEXTlibp2p PeerId (base58)
last_seenINTEGERПоследняя активность (Unix timestamp)
is_currentINTEGER1 = текущее устройство
osTEXTОперационная система
ipTEXTIP-адрес
storage_*INTEGER/TEXTИнформация о хранилище
added_viaTEXTСпособ добавления (QR, PIN)

Миграции:

sql
ALTER TABLE devices ADD COLUMN os TEXT;
ALTER TABLE devices ADD COLUMN ip TEXT;
ALTER TABLE devices ADD COLUMN storage_used INTEGER;
ALTER TABLE devices ADD COLUMN storage_total INTEGER;
ALTER TABLE devices ADD COLUMN storage_unit TEXT;
ALTER TABLE devices ADD COLUMN added_via TEXT;

vault.db

vault_config

Управляется: VaultManager

sql
CREATE TABLE IF NOT EXISTS vault_config (
    id INTEGER PRIMARY KEY CHECK (id = 1),
    salt BLOB NOT NULL,
    nonce BLOB NOT NULL,
    wrapped_master_key BLOB NOT NULL,
    created_at INTEGER NOT NULL,
    updated_at INTEGER NOT NULL
)

Singleton-таблица (CHECK (id = 1)). Хранит master key, обёрнутый PIN'ом.

КолонкаТипОписание
saltBLOBArgon2 salt для derive PIN key (32 bytes)
nonceBLOBNonce для ChaCha20Poly1305 (12 bytes)
wrapped_master_keyBLOBMaster key, зашифрованный PIN key'ом
encrypted_recovery_phraseBLOBBIP39 фраза, зашифрованная master key'ом
recovery_phrase_nonceBLOBNonce для шифрования recovery phrase

Миграции:

sql
ALTER TABLE vault_config ADD COLUMN encrypted_recovery_phrase BLOB;
ALTER TABLE vault_config ADD COLUMN recovery_phrase_nonce BLOB;

encrypted_secrets

Управляется: VaultManager

sql
CREATE TABLE IF NOT EXISTS encrypted_secrets (
    secret_id TEXT PRIMARY KEY,
    salt BLOB NOT NULL,
    nonce BLOB NOT NULL,
    encrypted_data BLOB NOT NULL,
    created_at INTEGER NOT NULL,
    updated_at INTEGER NOT NULL
)

Зашифрованные секреты. Каждый секрет имеет индивидуальные salt и nonce.

Типичные secret_id:

  • identity_signing_key:{identity_id} — Ed25519 private key для подписи
  • device_private_key:{device_id} — приватный ключ устройства
  • s3_access_key:{cloud_id} — S3 access key
  • s3_secret_key:{cloud_id} — S3 secret key

vault_pin_state

Управляется: VaultManager

sql
CREATE TABLE IF NOT EXISTS vault_pin_state (
    id INTEGER PRIMARY KEY CHECK (id = 1),
    failed_attempts INTEGER NOT NULL DEFAULT 0,
    last_failed_attempt INTEGER,
    is_locked INTEGER NOT NULL DEFAULT 0,
    lockout_until INTEGER,
    total_attempts INTEGER NOT NULL DEFAULT 0
)

Singleton-таблица. Отслеживает попытки ввода PIN и lockout. Подробнее: PIN Rate Limiting.

vault_settings

Управляется: VaultManager

sql
CREATE TABLE IF NOT EXISTS vault_settings (
    id INTEGER PRIMARY KEY CHECK (id = 1),
    auto_lock_timeout INTEGER NOT NULL DEFAULT 300,
    background_operation_mode TEXT NOT NULL DEFAULT 'continue'
)

Singleton-таблица. Хранит персистентные настройки vault: таймаут auto-lock и режим фоновых операций.

КолонкаТипОписание
auto_lock_timeoutINTEGERТаймаут автоблокировки в секундах (0 = отключено, default = 300)
background_operation_modeTEXTcontinue (default) или pause

Настройки загружаются при создании VaultManager и применяются к SessionState. Обновляются через set_auto_lock_timeout() и set_background_operation_mode().

spaces.db

spaces

Управляется: SpaceManager

sql
CREATE TABLE IF NOT EXISTS spaces (
    id TEXT PRIMARY KEY,
    name TEXT NOT NULL,
    description TEXT,
    identity_id TEXT NOT NULL,
    space_type TEXT NOT NULL DEFAULT 'own',
    created_at INTEGER NOT NULL,
    updated_at INTEGER NOT NULL
)
КолонкаТипОписание
space_typeTEXTown (создано), published (broadcast), shared (зашифровано)
sync_modeTEXTauto или manual
encryptionINTEGER1 = шифрование включено
cloud_idTEXTПривязка к облачному хранилищу

Миграции:

sql
ALTER TABLE spaces ADD COLUMN icon TEXT;
ALTER TABLE spaces ADD COLUMN color TEXT;
ALTER TABLE spaces ADD COLUMN sync_mode TEXT DEFAULT 'auto';
ALTER TABLE spaces ADD COLUMN encryption INTEGER NOT NULL DEFAULT 1;
ALTER TABLE spaces ADD COLUMN versioning INTEGER NOT NULL DEFAULT 0;
ALTER TABLE spaces ADD COLUMN notifications INTEGER NOT NULL DEFAULT 1;
ALTER TABLE spaces ADD COLUMN cloud_id TEXT;

space_files

Управляется: SpaceManager

sql
CREATE TABLE IF NOT EXISTS space_files (
    id TEXT PRIMARY KEY,
    space_id TEXT NOT NULL REFERENCES spaces(id) ON DELETE CASCADE,
    file_name TEXT NOT NULL,
    file_path TEXT NOT NULL,
    relative_path TEXT NOT NULL,
    file_size INTEGER NOT NULL,
    file_hash TEXT NOT NULL,
    added_at INTEGER NOT NULL,
    updated_at INTEGER NOT NULL
)

file_hash — blake3 hash содержимого файла, используется для детекции конфликтов и файлового трансфера.

received_spaces

Управляется: SpaceManager

sql
CREATE TABLE IF NOT EXISTS received_spaces (
    space_id TEXT PRIMARY KEY REFERENCES spaces(id) ON DELETE CASCADE,
    from_identity_id TEXT NOT NULL,
    from_identity_name TEXT NOT NULL,
    share_type TEXT NOT NULL,
    received_at INTEGER NOT NULL,
    accepted INTEGER NOT NULL DEFAULT 0,
    accepted_at INTEGER
)

Метаданные полученных пространств: кто отправил, тип шаринга, статус принятия.

space_device_sync

Управляется: SpaceManager

sql
CREATE TABLE IF NOT EXISTS space_device_sync (
    space_id TEXT NOT NULL,
    device_id TEXT NOT NULL,
    last_synced_at INTEGER NOT NULL,
    PRIMARY KEY (space_id, device_id)
)

Composite PK. Отслеживает, когда каждое устройство последний раз синхронизировало каждое пространство.

sync_tombstones

Управляется: SpaceManager, GC в SharingManager

sql
CREATE TABLE IF NOT EXISTS sync_tombstones (
    entity_type TEXT NOT NULL,
    entity_id TEXT NOT NULL,
    deleted_at INTEGER NOT NULL,
    deleted_by_device_id TEXT NOT NULL,
    PRIMARY KEY (entity_type, entity_id)
)

Soft delete для state sync. TTL 30 дней — после этого tombstone удаляется garbage collector'ом.

sync_conflicts

Управляется: SpaceManager

sql
CREATE TABLE IF NOT EXISTS sync_conflicts (
    id TEXT PRIMARY KEY,
    space_id TEXT NOT NULL,
    file_id TEXT NOT NULL,
    local_file_hash TEXT NOT NULL,
    remote_file_hash TEXT NOT NULL,
    local_device_id TEXT NOT NULL,
    remote_device_id TEXT NOT NULL,
    created_at INTEGER NOT NULL,
    resolved INTEGER NOT NULL DEFAULT 0,
    resolution TEXT,
    resolved_at INTEGER
)

Конфликты синхронизации — разные версии одного файла на разных устройствах.

clouds

Управляется: CloudManager

sql
CREATE TABLE IF NOT EXISTS clouds (
    id TEXT PRIMARY KEY,
    identity_id TEXT NOT NULL,
    name TEXT NOT NULL,
    provider TEXT NOT NULL,
    endpoint TEXT NOT NULL,
    region TEXT NOT NULL,
    bucket_name TEXT,
    access_key_encrypted BLOB,
    secret_key_encrypted BLOB,
    created_at INTEGER NOT NULL,
    updated_at INTEGER NOT NULL
)

Конфигурации S3-совместимых облачных хранилищ. Credentials зашифрованы vault master key'ом.