Skip to content

SpaceManager

Файл: backend/src/spaces/manager.rs

Управление пространствами (spaces) — логическими контейнерами для файлов, предназначенных для синхронизации и расшаривания. Включает CRUD пространств, управление файлами, обработку полученных пространств, конфликтов и tombstones.

SpaceName

Имя пространства валидируется на границе через newtype SpaceName (файл: commands/spaces.rs):

rust
#[derive(Debug, Clone, Serialize, Deserialize, Type)]
#[serde(try_from = "String")]
pub struct SpaceName(String);

impl SpaceName {
    pub fn new(name: &str) -> Result<Self, String> {
        // trim, non-empty, ≤255 символов
    }
}
  • При десериализации из JSON автоматически вызывается TryFrom<String>, валидируя данные на входе
  • create_space принимает &SpaceName вместо &str

Структура

ПолеТипОписание
dbArc<Mutex<Connection>>SQLite соединение

Методы

МетодСигнатураОписание
CRUD
create_spacefn(&self, identity_id, name: &SpaceName, ...) -> Result<Space>Создать пространство
get_spacefn(&self, space_id) -> Result<Option<Space>>Получить по ID
list_spacesfn(&self, identity_id) -> Result<Vec<Space>>Список по identity
list_all_spacesfn(&self) -> Result<Vec<Space>>Все пространства
update_spacefn(&self, space_id, ...) -> Result<()>Обновить поля
delete_spacefn(&self, space_id) -> Result<()>Удалить + каскад
Files
add_filesfn(&self, space_id, paths) -> Result<Vec<SpaceFile>>Добавить файлы
remove_filefn(&self, file_id) -> Result<()>Удалить файл
list_filesfn(&self, space_id) -> Result<Vec<SpaceFile>>Список файлов
Received
save_received_spacefn(&self, space, files, ...) -> Result<()>Сохранить полученное
accept_received_spacefn(&self, space_id) -> Result<()>Принять
reject_received_spacefn(&self, space_id) -> Result<()>Отклонить
list_received_spacesfn(&self) -> Result<Vec<ReceivedSpace>>Список полученных
Conflicts
add_conflictfn(&self, ...) -> Result<String>Добавить конфликт
list_conflictsfn(&self) -> Result<Vec<FileConflict>>Список конфликтов
resolve_conflictfn(&self, id, resolution) -> Result<()>Разрешить конфликт
Tombstones
add_tombstonefn(&self, type, id, device_id) -> Result<()>Пометить удалённым
list_tombstonesfn(&self) -> Result<Vec<Tombstone>>Список tombstones
has_tombstonefn(&self, type, id) -> Result<bool>Проверить наличие
delete_space_authorizedfn(&self, space_id, proof: &IdentityProof) -> Result<()>Удалить с проверкой владельца
update_space_authorizedfn(&self, space_id, proof: &IdentityProof, ...) -> Result<()>Обновить с проверкой владельца
store_tombstonesfn(&self, tombstones) -> Result<()>Batch insert
gc_tombstonesfn(&self) -> Result<u64>Удалить expired

Зависимости

  • SQLite — таблицы spaces, space_files, received_spaces, sync_tombstones, sync_conflicts
  • blake3 — хеширование файлов и генерация ID

create_space

fn create_space(&self, identity_id: &str, name: &SpaceName, ...) -> Result<Space>

Создаёт новое пространство с опциональными настройками. Имя валидируется через SpaceName на границе сервиса.

Параметры

ИмяТипОписание
identity_id&strID владельца
name&SpaceNameИмя пространства (валидированное)
descriptionOption<&str>Описание
iconOption<&str>Иконка
colorOption<&str>Цвет
sync_modeOption<&str>Режим синхронизации
encryptionOption<bool>Шифрование
versioningOption<bool>Версионирование
notificationsOption<bool>Уведомления

Логика

  1. Генерирует UUID v4 для space_id
  2. INSERT INTO spaces со всеми полями
plantuml Diagram

Используется в: create_space_svc


add_files

fn add_files(&self, space_id: &str, file_paths: &[String]) -> Result<Vec<SpaceFile>>

Добавляет файлы в пространство. Для каждого файла вычисляется blake3 hash.

Логика

  1. Для каждого файла:
    • Читает метаданные (size, name)
    • Вычисляет blake3 hash содержимого
    • file_id = blake3(space_id + file_path)
    • INSERT OR REPLACE INTO space_files
plantuml Diagram

Используется в: add_files_to_space_svc


save_received_space

fn save_received_space(&self, space: Space, files: Vec<SpaceFile>, from_identity_id: &str, from_identity_name: &str, share_type: &str) -> Result<()>

Сохраняет пространство, полученное от другого пользователя через P2P sharing.

Логика

  1. Проверяет тип: «shared» имеет приоритет над «published»
  2. INSERT OR REPLACE INTO spaces (обновляет если space_id уже существует)
  3. INSERT OR REPLACE файлы
  4. INSERT OR REPLACE INTO received_spaces (метаданные получения)
plantuml Diagram

Используется в: внутренне в SharingManager при получении Publish/Share сообщений


list_spaces / list_all_spaces / get_space

Запросы пространств:

  • list_spaces(identity_id) — SELECT WHERE identity_id = ?
  • list_all_spaces() — SELECT * FROM spaces
  • get_space(space_id) — SELECT WHERE id = ?

Используется в: list_user_spaces_svc, get_user_space_svc, publish_space_svc


accept_received_space / reject_received_space

  • accept_received_space — UPDATE received_spaces SET accepted = 1
  • reject_received_space — DELETE FROM spaces + space_files + received_spaces (каскад)

Используется в: accept_space_svc, reject_space_svc


Conflict Management

add_conflict

Создаёт запись о конфликте при синхронизации (разные версии одного файла на разных устройствах).

resolve_conflict

Разрешает конфликт: UPDATE SET resolved = 1, resolution = ?, resolved_at = now

Используется в: внутренне в SharingManager при синхронизации


Tombstone Management

Tombstones — маркеры удалённых сущностей для корректной синхронизации между устройствами.

  • add_tombstone(entity_type, entity_id, device_id) — INSERT OR IGNORE
  • has_tombstone(entity_type, entity_id) -> Result<bool> — проверка перед применением remote операций (пропагирует ошибки БД вместо тихого unwrap_or(false))
  • store_tombstones(tombstones) — batch insert из snapshot синхронизации
  • gc_tombstones() — удаление tombstones старше TTL (предотвращает неограниченный рост)
plantuml Diagram

Используется в: внутренне в SharingManager при синхронизации


Авторизованные операции (Capability-Based Security)

Деструктивные операции с пространствами защищены через IdentityProof — capability token, доступный только при наличии активной identity.

delete_space_authorized

fn delete_space_authorized(&self, space_id: &str, proof: &IdentityProof) -> Result<()>

Удаляет пространство с проверкой владельца. Если space.identity_id != proof.identity_id() — возвращает ошибку авторизации.

update_space_authorized

fn update_space_authorized(&self, space_id: &str, proof: &IdentityProof, ...) -> Result<()>

Обновляет пространство с проверкой владельца. Аналогичная проверка identity.

Используется в: delete_space_svc, publish_space_svc, share_space_svc