chore(openspec): предложить phone-album-two-way-sync и обновить спеку phone-album-sync
Новое изменение: двусторонний миррор альбома устройства и серверного альбома (материализация серверных фото, признак происхождения, двусторонние удаления с явным намерением, устойчивое выключение, первый проход, n:1). Purpose основной спеки phone-album-sync обновлён под двустороннюю синхронизацию. Change проходит `openspec validate --strict`.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# Proposal
|
||||
|
||||
## Why
|
||||
|
||||
Синхронизация альбома устройства сегодня односторонняя по содержимому: устройство отдаёт
|
||||
байты, сервер возвращает только метаданные. Фото, добавленное в целевой серверный альбом из
|
||||
веба или с другого устройства, на телефон не приезжает, а связанный серверный альбом ещё и
|
||||
скрыт из списка — увидеть его в приложении нельзя. Пользователь ожидает, что
|
||||
синхронизированный альбом — один и тот же набор медиа на телефоне и на сервере.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Связанная пара «альбом устройства → серверный альбом» становится **двусторонним миррором**:
|
||||
состав медиа совпадает, добавление и удаление ходят в обе стороны.
|
||||
- **Материализация серверных фото на устройстве**: в режиме копий (B) скачивается оригинал, в
|
||||
режиме переноса (C) — превью (для видео — постер). Файлы пишутся в галерею (MediaStore)
|
||||
бакета альбома устройства и видны системной галерее.
|
||||
- Вводится явный **признак происхождения** элемента (`own` — загружено этим клиентом,
|
||||
`mirror` — скачано с сервера). Политика удалений, разгрузка и восстановление после
|
||||
переустановки опираются на него, а не на наличие `serverPhotoId`.
|
||||
- **Удаление в обе стороны**: удаление элемента на устройстве удаляет соответствующее фото на
|
||||
сервере (мягко, в корзину); серверное удаление убирает локальный элемент. Удаление
|
||||
принадлежащего иному источнику элемента на устройстве подчиняется правам сервера.
|
||||
- **Журнал удалений (надгробия)**: локально удалённый элемент не скачивается заново, пока
|
||||
серверное удаление не подтверждено; серверные события не дают эха.
|
||||
- Восстановление серверного фото из корзины заново материализует элемент на устройстве.
|
||||
- **Отвязка и выключение синхронизации** остаются неразрушающими: фото на сервере сохраняются,
|
||||
уже скачанные файлы остаются в галерее как обычные.
|
||||
- **Выключение синхронизации устойчиво**: восстановление происхождения по меткам превью не
|
||||
возобновляет связь, пока пользователь не включит синхронизацию снова.
|
||||
- **Первый проход**: выбор «скачать всё содержимое альбома» или «только новое с этого момента»;
|
||||
ограничение «только Wi-Fi» распространяется и на скачивание.
|
||||
- **BREAKING**: нет — поведение аддитивное, существующие связи продолжают работать.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
Нет — поведение относится к существующей способности синхронизации альбома устройства.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `phone-album-sync`: двусторонний миррор — материализация серверных фото по режимам, признак
|
||||
происхождения, надгробия, политика удалений в обе стороны, восстановление из корзины,
|
||||
поведение при отвязке.
|
||||
- `android-client`: сетка альбома устройства включает скачанные (серверные) элементы, а
|
||||
связанный альбом читается как один двусторонний альбом.
|
||||
|
||||
## Impact
|
||||
|
||||
- `android/`: движок синхронизации (`data/sync/*` — `SyncPlan`, `SyncCoordinator`, `SyncCheck`,
|
||||
`SyncRecovery`, `ProvenanceStamp`, `OffloadManager`, `RestoreManager`, `LocalAssetProvider`),
|
||||
новый загрузчик серверных фото, запись в MediaStore без диалога согласия (файлы приложения),
|
||||
Room-схема (признак происхождения, надгробия, watermark первого прохода), UI
|
||||
(`DeviceAlbumScreen`/`DeviceAlbumViewModel`, `AlbumsScreen`/`AlbumListBuilder`,
|
||||
`SyncRepository`).
|
||||
- `backend/`: изменений API не требуется — `preview_url`/`medium_url`/`original_url`, `?since=`,
|
||||
мягкое удаление и восстановление из корзины уже есть.
|
||||
- Спеки: `phone-album-sync`, `android-client`.
|
||||
Reference in New Issue
Block a user