chore(openspec): archive add-phone-album-sync and sync main specs
Sync the deltas into phpne...
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
# 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; синхронизация на уровне сервера (устройства/сессии на
|
||||
бэкенде); многопользовательские конфликты владения; редактирование изображений.
|
||||
Reference in New Issue
Block a user