# Proposal ## Why Android-клиент работает только с серверными альбомами и ручной загрузкой через системный Photo Picker: он не видит альбомы самого телефона, не следит за их изменениями и не освобождает место. Основной мобильный сценарий — «снимаю на телефон и не думаю о переносе» — не покрыт. Нужна синхронизация альбомов устройства с серверным альбомом в трёх режимах, с отслеживанием изменений. ## What Changes - Смешанный список альбомов: альбомы устройства (MediaStore bucket'ы) и серверные альбомы в одном списке; связанная пара «телефонный → серверный» показывается одной карточкой устройства с указателем связи и меткой режима, а связанный серверный альбом из списка скрывается. - Экран альбома устройства с настройками по свайпу вправо: только выбор режима синхронизации; целевой серверный альбом выбирается (или создаётся) при включении, допускается n:1. - Три режима синхронизации альбома: - **A — выключена**: оригиналы на телефоне, превью генерируются и хранятся на телефоне; сервера не касается. - **B — копии оригиналов**: оригиналы остаются на телефоне, копии загружаются на сервер. - **C — перенос оригиналов**: оригиналы уходят на сервер, на телефоне вместо них остаются превью; замена файла в галерее выполняется автоматически (широкий доступ к файлам запрашивается при включении режима, без системного диалога); видео заменяется постером. - Отслеживание и синхронизация изменений (добавление, удаление, переименование, перенос между альбомами, правка контента как «новый + удалить старый») автоматически в фоне (`MediaStore.getGeneration`/`ContentObserver` + периодический WorkManager) и при открытом приложении (SSE + `?since=`). - Идентичность и дедупликация по content-hash (sha256) относительно контрольной суммы объекта на сервере; удаление на сервере — только для «наших» загрузок. - Провенанс, переживающий переустановку: в EXIF разгруженных в C превью пишется метка (серверный альбом/фото, hash оригинала), по которой связь и провенанс восстанавливаются. - Возврат оригиналов из C («вернуть оригиналы»); отвязка и выключение синхронизации никогда не удаляют фотографии с сервера. - Сервер начинает отдавать контрольную сумму оригинала в данных фото (малая правка API, без миграции БД — `checksum` уже хранится). - **BREAKING**: нет (добавляемое поле ответа; существующие клиенты не ломаются). ## Capabilities ### New Capabilities - `phone-album-sync`: синхронизация альбома устройства с существующим серверным альбомом — режимы A/B/C, отслеживание изменений, идентичность и дедуп по content-hash, политика удалений, разгрузка места и провенанс. ### Modified Capabilities - `android-client`: смешанный список альбомов устройства и сервера, экран и настройки синхронизации телефонного альбома, широкий доступ к медиа (`READ_MEDIA_*`) и фоновая работа синхронизации. - `photos`: данные фото включают контрольную сумму оригинала, чтобы клиент мог сопоставлять локальный ассет с серверным фото и не загружать дубли. ## Impact - `android/`: новый источник MediaStore (bucket'ы и ассеты), движок синхронизации и очередь на существующем `UploadRepository`/`UploadWorker`, локальный индекс и провенанс в Room, кэш превью, EXIF-метка, чтение/запись превью (широкий доступ к файлам `MANAGE_EXTERNAL_STORAGE`), правки навигации (`GaloNavHost`), манифеста (права) и `AppContainer`. - `backend/`: отдать `checksum` в моделях/запросах/ответах фото. Миграции БД не требуются. - Зависимости клиента: MediaStore, ExifInterface, MediaMetadataRetriever, WorkManager, Room, Coil — большинство уже подключено. - Платформенные ограничения: согласие ОС на изменение/удаление чужого медиа; фоновая работа ограничена WorkManager; Google Play ограничивает `READ_MEDIA_*`. - **Предпосылка (побочно, вне объёма этой правки)**: `.gitignore` содержит правило `data/`, из-за которого весь Kotlin-слой `android/.../com/galo/android/data/` не отслеживается git и отсутствует в git-истории. До реализации это нужно устранить, иначе новые файлы синхронизации тоже не попадут в коммит. - Вне объёма: iOS; синхронизация на уровне сервера (устройства/сессии на бэкенде); многопользовательские конфликты владения; редактирование изображений.