#import "common.typ": pz-fig = Программная реализация == Разработка программных модулей Архитектура реализации следует принятой на этапе проектирования схеме MVVM + Clean Architecture. Модули Gradle разделены по ответственности: контракты vault, доменная логика, сценарии use case, Android-инфраструктура (Room, OAuth, файловые адаптеры), UI и точка входа `:app`. Такое разбиение позволило параллельно развивать локальный и удалённый контуры и изолировать криптографию от представления данных. === Модуль криптографической защиты данных Класс `Encryptor` формирует `StorageEncryptionInfo`, проверяет ключ и выполняет шифрование/дешифрование на клиенте. Unit-тесты подтверждают корректность для верного и неверного ключа (гл. 5). === Модуль управления vault и шифрованием Use case `ManageStoragesEncryptionUseCase` инкапсулирует проверку `canEncrypt`, включение шифрования и открытие хранилища. ViewModel предотвращает повторный запуск шифрования для занятого vault. Фрагмент логики включения шифрования: ```kotlin fun enableEncryption(storage: IStorageInfo, password: String, encryptPath: Boolean) { val key = EncryptKey(password) viewModelScope.launch { when (manageStoragesEncryptionUseCase.canEncrypt(storage)) { ManageStoragesEncryptionUseCase.CanEncryptResult.Allowed -> { manageStoragesEncryptionUseCase.enableEncryption(storage, key, encryptPath) manageStoragesEncryptionUseCase.openStorage(storage, key, true) } ManageStoragesEncryptionUseCase.CanEncryptResult.AlreadyEncrypted -> { /* сообщение */ } else -> { /* неподдерживаемая операция */ } } } } ``` Блок-схема сценария — рис. @fig-21. #pz-fig("fig_21_encrypt_flow.png", [Блок-схема: enableEncryption → checkKey → openStorage], "fig-21") === Модуль адаптеров хранилищ Адаптеры реализуют единый контракт доступа к локальным и удалённым хранилищам; регистрация vault выполняется через модуль `:vault-contracts`. === Проект модуля синхронизации В Room добавлена сущность `DbStorageSyncGroup`; спроектирован `SyncWorker` и очередь UUID для фонового сравнения историй коммитов (рис. @fig-01–@fig-03). Реализация синхронизации находится в стадии развития. Модель синхронизации опирается на аналогию с распределённой системой контроля версий: для каждого `Storage` ведётся история коммитов; сервис по таймеру или через `WorkManager` сравнивает локальную и удалённую истории и приводит зашифрованное содержимое к согласованному состоянию. Ключи шифрования в этот обмен не включаются — провайдер видит только зашифрованные объекты. Модуль `:task-runtime` зарезервирован для фоновых задач длительного шифрования и синхронизации без блокировки UI. == Разработка мобильного приложения на Kotlin (Android) === Слой domain Модуль `:domain` содержит интерфейсы хранилищ и use case. Модуль `:usecases` связывает сценарии приложения. === Слой data Модуль `:infrastructure-android` реализует Room `AppDb` (версия 5) с сущностями `DbStorageKeyMap`, `DbStorageMetaInfo`, `DbYandexAccount`, `DbStorageSyncGroup`: ```kotlin @Database( entities = [ DbStorageKeyMap::class, DbStorageMetaInfo::class, DbYandexAccount::class, DbStorageSyncGroup::class, ], version = 5, exportSchema = false, ) abstract class AppDb : IAppDb, RoomDatabase() ``` === Слой presentation Модуль `:ui` и `:app` содержат Compose-экраны, ViewModel и навигацию. OAuth Яндекс запускается из UI удалённых vault: ```kotlin viewModel.yandexSignIn.launch { outcome -> when (outcome) { is RemoteYandexAuthResult.Success -> viewModel.onYandexAuthSuccess(outcome.accessToken) is RemoteYandexAuthResult.Failure -> { /* ошибка */ } RemoteYandexAuthResult.Cancelled -> { } } } ``` == Взаимодействие подсистем и итоговая архитектура Зависимости модулей Gradle показаны на рисунке @fig-23. Полный исходный код всех модулей сборки приведён в *приложении А* (307 файлов, сгенерировано скриптом `gen_listings.py`). #pz-fig("fig_23_module_deps.png", [Зависимости модулей Gradle], "fig-23") В основном тексте приведены показательные фрагменты; листинги по модулям `:domain`, `:infrastructure-android`, `:app` — в приложении А, разделы «Модуль :domain» и др. #include "ch04-expand.typ" #include "ch04-modules.typ"