Files
Wallenc/Report/includes/ch02.typ

103 lines
8.6 KiB
Typst
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.
#import "common.typ": pz-fig, pz-table
= Проектирование архитектуры системы
== Схема бизнес-процессов предметной области
=== Организационная структура
Участники процесса: *пользователь*, *мобильное приложение Wallenc*, *внешний провайдер хранения* (облачный API). Сервер приложения отсутствует.
=== Карта процессов
Основные процессы: создание storage в vault опциональное шифрование storage открытие storage работа с файлами закрытие; для удалённых vault OAuth привязка учётной записи листинг storage провайдера проектная синхронизация.
=== Диаграмма BPMN
На рисунке @fig-15 представлена диаграмма BPMN основного процесса работы со storage внутри vault.
#pz-fig("fig_15_bpmn_vault.png", [BPMN: storage создание, шифрование, открытие, содержимое], "fig-15")
=== Карта систем
Wallenc выступает посредником между пользователем и файловыми API провайдера, дополняя взаимодействие локальной БД Room и криптографическим модулем.
== Диаграмма DFD
DFD уровня 0 (рис. @fig-16) отражает потоки между UI, доменной логикой, криптографией, адаптерами хранилищ, Room и внешним API.
#pz-fig("fig_16_dfd_level0.png", [DFD уровень 0: потоки данных в Wallenc], "fig-16")
== Объектно-ориентированный анализ и проектирование (UML)
=== Диаграмма прецедентов
Прецеденты включают управление storage, подключение удалённых vault (OAuth), шифрование и открытие storage, работу с файлами и синхронизацию групп storage (рис. @fig-17).
#pz-fig("fig_17_use_case.png", [Диаграмма прецедентов Wallenc], "fig-17")
=== Диаграмма классов
Доменная модель модуля `:domain` (интерфейсы хранилищ, use case, сущности шифрования) приведена на рисунке @fig-04.
#pz-fig("fig_04_domain_class.png", [Диаграмма классов модуля domain], "fig-04")
=== Доменная иерархия хранения данных
Модель данных приложения строится на трёх уровнях (см. `IVaultsManager`, `IVault`, `IStorage` на рис. @fig-04):
- *VaultsManager* единая точка доступа: реактивный список всех vault (`vaults`), агрегированный список storage (`allStorages`) и `IUnlockManager` для открытых storage;
- *IVault* контейнер, объединяющий набор storage. *LocalVault* в приложении один (корень на устройстве); удалённые vault (например, `YandexVault`) добавляются по одному на привязанную учётную запись OAuth;
- *IStorage* хранилище, которое пользователь создаёт, переименовывает и удаляет в интерфейсе; внутри файлы и каталоги, доступные через `IStorageAccessor` (с опциональным клиентским шифрованием).
Пользовательские сценарии «создать локальный vault» в UI соответствуют созданию нового *storage* внутри единственного `LocalVault`, а не появлению второго локального vault.
Служебные сущности Room показаны на рисунке @fig-11.
#pz-fig("fig_11_room_schema.png", [Схема служебных сущностей Room], "fig-11")
=== Диаграмма развёртывания
Компоненты развёртывания: устройство Android (приложение, Room), облачный API Яндекса (рис. @fig-18).
#pz-fig("fig_18_deployment.png", [Диаграмма развёртывания], "fig-18")
Архитектурные слои MVVM + Clean Architecture @martin-clean-architecture и соответствие модулям Gradle на рисунке @fig-19.
#pz-fig("fig_19_clean_architecture.png", [Слои Clean Architecture и модули проекта], "fig-19")
== Проектирование локальной базы данных
Служебная БД Room хранит ключи шифрования для пар «исходный storage зашифрованное представление» (`DbStorageKeyMap`), сериализованные метаданные storage (`DbStorageMetaInfo`), учётные записи Яндекс (`DbYandexAccount`) и группы синхронизации (`DbStorageSyncGroup`). Пользовательский контент в открытом виде в БД не сохраняется только параметры, необходимые для восстановления состояния приложения при следующем запуске. Доступ инкапсулирован в DAO и репозиториях модуля `:infrastructure-android`.
#pz-table(
[Сущности Room и назначение],
3,
table.header([Сущность], [Назначение], [Связь с тестами]),
[`DbStorageKeyMap`], [Ключ для `sourceUuid` storage (связь с зашифрованной копией)], [Интеграция],
[`DbStorageMetaInfo`], [Сериализованные метаданные `IStorage` (имя, путь, шифрование)], [Интеграция],
[`DbYandexAccount`], [OAuth access token, идентификатор аккаунта], [`YandexAccountRepositoryTest`],
[`DbStorageSyncGroup`], [Группа UUID для синхронизации], [`StorageSyncEngineTest`],
) <tbl-room-entities>
== Проектирование подсистемы синхронизации
Подсистема синхронизации спроектирована как набор независимых операций над журналом изменений каждого `Storage`. Алгоритм выбирает «победителя» по ревизии, копирует или удаляет файлы на целевом хранилище, не расшифровывая данные на сервере. Блокировки предотвращают одновременную синхронизацию одной группы; при отмене задачи блокировки снимаются (покрыто unit-тестами `syncGroupCooperativeCancellationReleasesLocks` и др., гл. 5). Подробное описание реализации и выбора источника для каждого пути в гл. 4 алгоритм согласования журналов, рис. @fig-35).
== Нефункциональные архитектурные решения
#pz-table(
[Нефункциональные решения],
2,
table.header([Атрибут], [Решение]),
[Производительность], [Потоковое шифрование, фоновые задачи в `:task-runtime`],
[Безопасность], [AES, проверка ключа без полного decrypt, скрытие служебных путей],
[Расширяемость], [`vault-contracts`, регистрация провайдеров],
[Сопровождаемость], [Модульные тесты 68 + листинги в приложении А],
[Надёжность], [Room-транзакции, восстановление журнала после сбоя записи],
) <tbl-nfr-arch>
== Вывод
Спроектирована клиентская архитектура с разделением domain, infrastructure и presentation, единым интерфейсом vault и заделом под синхронизацию без передачи ключей. Диаграммы зафиксированы в приложении Г.