103 lines
8.6 KiB
Typst
103 lines
8.6 KiB
Typst
#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 и заделом под синхронизацию без передачи ключей. Диаграммы зафиксированы в приложении Г.
|