Files
ds-galo/openspec/specs/phone-album-sync/spec.md
T
iu 19309e2ac0 chore(openspec): архивировать android-album-restore-progress и синхронизировать спеки
Дельта перенесена в основные спеки: android-client («Прогресс восстановления
оригиналов») и phone-album-sync («Ход и устойчивость восстановления оригиналов»).
Изменение перемещено в openspec/changes/archive/2026-10-16-android-album-restore-progress.
2026-10-16 20:15:57 +03:00

327 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# phone-album-sync Specification
## Purpose
Синхронизация альбома устройства с существующим серверным альбомом: режимы A/B/C,
отслеживание изменений, идентичность и дедупликация, политика удалений, разгрузка
места и провенанс разгруженных превью.
## Requirements
### Requirement: Режимы синхронизации альбома устройства
Альбом устройства SHALL иметь выбираемый режим синхронизации: выключена (A — только
локально), копии оригиналов на сервере (B), перенос оригиналов на сервер (C). Пока
режим A, приложение SHALL показывать альбом локально и SHALL NOT обращаться к
серверу по этому альбому.
#### Scenario: Выключенная синхронизация
- **WHEN** у альбома устройства выбран режим A
- **THEN** приложение показывает альбом из локальных файлов и не отправляет запросы на сервер по этому альбому
#### Scenario: Копии оригиналов
- **WHEN** у альбома устройства выбран режим B
- **THEN** оригиналы остаются на устройстве, а их копии загружаются в целевой серверный альбом
#### Scenario: Перенос оригиналов
- **WHEN** у альбома устройства выбран режим C
- **THEN** оригиналы загружаются на сервер, а на устройстве вместо них остаются превью
### Requirement: Выбор целевого серверного альбома
При включении синхронизации пользователь SHALL выбрать серверный альбом назначения —
существующий или созданный на месте, с именем, предзаполненным именем альбома
устройства. Несколько альбомов устройства SHALL иметь возможность указывать на один
серверный альбом.
#### Scenario: Выбор цели
- **WHEN** пользователь включает синхронизацию альбома устройства
- **THEN** приложение предлагает выбрать существующий серверный альбом или создать новый с предзаполненным именем и сохраняет выбор
#### Scenario: Несколько источников в одну цель
- **WHEN** два альбома устройства указывают на один серверный альбом
- **THEN** оба синхронизируются в него, а связь каждого отражается отдельно
### Requirement: Отслеживание изменений на устройстве
Приложение SHALL отслеживать изменения содержимого синхронизируемого альбома
устройства — добавление, удаление, переименование, перенос между альбомами и
изменение содержимого — и SHALL хранить локальный индекс, позволяющий обнаружить
удаления, произошедшие вне приложения.
#### Scenario: Добавление
- **WHEN** в альбоме устройства появляется новое медиа
- **THEN** приложение фиксирует его как новое и ставит в очередь синхронизации
#### Scenario: Удаление вне приложения
- **WHEN** медиа удалено из альбома устройства другим приложением или системной галереей
- **THEN** приложение обнаруживает отсутствие по локальному индексу
#### Scenario: Переименование и перенос
- **WHEN** медиа переименовано или перемещено между альбомами устройства
- **THEN** приложение фиксирует изменение имени или принадлежности альбому
### Requirement: Синхронизация изменений с сервером
Для каждого отслеженного изменения приложение SHALL применить его к целевому
серверному альбому: загрузить новое содержимое, переименовать и перенести через
API, а изменение содержимого SHALL трактовать как новую загрузку с удалением
устаревшей собственной загрузки.
#### Scenario: Новое содержимое
- **WHEN** в альбоме устройства появилось медиа, которого нет на сервере
- **THEN** приложение загружает его в целевой серверный альбом
#### Scenario: Переименование доходит до сервера
- **WHEN** медиа переименовано на устройстве и уже синхронизировано
- **THEN** приложение переименовывает соответствующее серверное фото
#### Scenario: Изменение содержимого
- **WHEN** содержимое медиа изменено на устройстве
- **THEN** приложение загружает новую версию, а устаревшую собственную загрузку удаляет
### Requirement: Идентичность по контрольной сумме
Приложение SHALL сопоставлять локальный ассет с серверным фото по контрольной сумме
содержимого и SHALL NOT повторно загружать содержимое, уже присутствующее на
сервере.
#### Scenario: Повторная синхронизация
- **WHEN** синхронизация запускается повторно без изменений содержимого
- **THEN** приложение не создаёт новых загрузок
#### Scenario: Уже загруженное содержимое
- **WHEN** содержимое ассета уже присутствует на сервере (в том числе загружено ранее)
- **THEN** приложение связывает ассет с существующим серверным фото без загрузки
### Requirement: Удаление только собственных загрузок
При удалении содержимого на устройстве приложение SHALL удалять на сервере только
фото, загруженные этим клиентом, и SHALL сохранять остальные фото целевого альбома,
в том числе загруженные из других источников.
#### Scenario: Собственная загрузка
- **WHEN** удалено содержимое, которое загрузил этот клиент, и его контрольная сумма отсутствует во всех локальных альбомах, льющихся в этот серверный
- **THEN** приложение удаляет соответствующее серверное фото
#### Scenario: Чужие фото
- **WHEN** в целевом серверном альбоме есть фото, загруженные из других источников
- **THEN** приложение не удаляет их
### Requirement: Отражение серверных изменений на устройстве
Приложение SHALL отражать изменения целевого серверного альбома — новые фото,
переименования, теги, подписи и удаления — в локальном представлении, SHALL NOT
изменять или удалять оригиналы на устройстве.
#### Scenario: Новое с другого устройства
- **WHEN** другое устройство добавляет фото в целевой серверный альбом
- **THEN** приложение показывает его в серверном представлении альбома
#### Scenario: Удалено на сервере
- **WHEN** серверное фото удалено на сервере
- **THEN** приложение убирает его из локального представления, не трогая оригинал на устройстве
### Requirement: Разгрузка оригиналов в режиме переноса
В режиме C после успешной загрузки приложение SHALL автоматически заменять оригинал
на устройстве превью, без отдельного действия на экране; видео SHALL заменяться
постером-кадром. При включении режима C приложение SHALL запрашивать широкий доступ
к файлам, чтобы замена выполнялась без системного диалога согласия.
#### Scenario: Разгрузка фото
- **WHEN** оригинал фото успешно загружен
- **THEN** файл в галерее автоматически заменяется превью с сохранением даты съёмки и места в альбоме
#### Scenario: Разгрузка видео
- **WHEN** оригинал видео успешно загружен
- **THEN** видео в галерее автоматически заменяется статичным постером-кадром, а элемент в приложении остаётся видео с оригиналом на сервере
#### Scenario: Доступ к файлам для разгрузки
- **WHEN** пользователь включает режим переноса
- **THEN** приложение запрашивает широкий доступ к файлам, и разгрузка выполняется без системного диалога согласия
### Requirement: Провенанс разгруженных превью
Разгруженные превью и постеры видео SHALL содержать метаданные провенанса,
достаточные для восстановления связи с серверным альбомом и принадлежности
загрузок после переустановки приложения.
#### Scenario: Восстановление после переустановки
- **WHEN** приложение переустановлено или его данные очищены, а альбом устройства содержит разгруженные превью
- **THEN** приложение восстанавливает связь с серверным альбомом и принадлежность своих загрузок из метаданных превью
#### Scenario: Метка утрачена
- **WHEN** метаданные провенанса недоступны (например, файл перезаписан сторонним редактором)
- **THEN** элемент считается неопознанным, не удаляется и не загружается повторно
### Requirement: Возврат оригиналов и отвязка
При выходе из режима C приложение SHALL предложить вернуть оригиналы на устройство
и SHALL предупредить, если пользователь отказывается. Отвязка альбома и выключение
синхронизации SHALL NOT удалять фото с сервера.
#### Scenario: Возврат оригиналов
- **WHEN** пользователь выходит из режима C и соглашается вернуть оригиналы
- **THEN** приложение возвращает оригиналы на устройство вместо превью
#### Scenario: Отказ от возврата
- **WHEN** пользователь выходит из режима C и отказывается возвращать оригиналы
- **THEN** приложение предупреждает, что на устройстве останутся только превью
#### Scenario: Отвязка
- **WHEN** пользователь отвязывает альбом устройства от серверного
- **THEN** фото на сервере сохраняются
#### Scenario: Выключение синхронизации
- **WHEN** пользователь выключает синхронизацию альбома устройства
- **THEN** связь с серверным альбомом снимается, а фото на сервере сохраняются
### Requirement: Автоматическая фоновая синхронизация
Синхронизация SHALL выполняться автоматически: при открытом приложении — по
событиям изменения, в фоне — периодически, с учётом ограничений сети, выбранных
пользователем. В режиме C разгрузка оригиналов SHALL выполняться автоматически
после успешной загрузки.
#### Scenario: Фоновая синхронизация
- **WHEN** приложение не открыто, а в альбоме устройства появились изменения
- **THEN** синхронизация выполняется в фоне при ближайшей возможности
#### Scenario: Ограничение сети
- **WHEN** включено ограничение «только Wi-Fi», а доступна только сотовая сеть
- **THEN** синхронизация не начинается до появления Wi-Fi
#### Scenario: Автоматическая разгрузка
- **WHEN** оригиналы загружены в режиме C
- **THEN** замена оригиналов превью выполняется автоматически, без отдельного подтверждения
### Requirement: Локальные превью
Приложение SHALL генерировать превью на устройстве и хранить их локально; при
просмотре элемента без локального оригинала приложение SHALL подгружать оригинал с
сервера.
#### Scenario: Сетка из превью
- **WHEN** открыт альбом устройства
- **THEN** сетка показывает локальные превью
#### Scenario: Просмотр без локального оригинала
- **WHEN** пользователь открывает элемент, чей оригинал разгружен на сервер
- **THEN** приложение подгружает оригинал с сервера для полноэкранного просмотра
### Requirement: Обнаружение потери серверной копии превью
При проверке синхронизации приложение SHALL сопоставлять серверное фото каждого
разгруженного превью с фото целевого альбома и при его отсутствии SHALL помечать
элемент как потерявший серверную копию, сохраняя превью и провенанс.
#### Scenario: Копии больше нет
- **WHEN** серверное фото разгруженного превью отсутствует в целевом альбоме
- **THEN** приложение помечает элемент как потерявший серверную копию
#### Scenario: Превью не трогается
- **WHEN** элемент помечен как потерявший серверную копию
- **THEN** превью-файл на устройстве сохраняется и не загружается повторно как оригинал
### Requirement: Восстановление связи при возврате серверного фото
При проверке синхронизации приложение SHALL снимать пометку с элемента, если его
серверное фото снова присутствует в целевом альбоме.
#### Scenario: Фото вернулось на сервер
- **WHEN** серверное фото помеченного элемента снова присутствует в целевом альбоме
- **THEN** элемент возвращается к обычному разгруженному состоянию с серверной копией
### Requirement: Удаление потерянного превью с устройства
Приложение SHALL позволять удалить потерявшее серверную копию превью с устройства;
удаление SHALL удалять превью-файл и запись локального индекса и SHALL NOT
обращаться к серверу, поскольку копии там уже нет.
#### Scenario: Удаление с устройства
- **WHEN** пользователь удаляет потерявшее серверную копию превью с устройства
- **THEN** превью-файл и запись локального индекса удаляются, а сервер не затрагивается
#### Scenario: Согласие системы
- **WHEN** превью-файл не принадлежит приложению
- **THEN** удаление выполняется после системного согласия на удаление
### Requirement: Повторная заливка вернувшегося оригинала
Если содержимое с исходной контрольной суммой потерявшего копию элемента снова
присутствует на устройстве, приложение SHALL загрузить его на сервер как новую
загрузку этого элемента.
#### Scenario: Вернулся в тот же альбом
- **WHEN** оригинал с исходной контрольной суммой снова появился в альбоме устройства
- **THEN** приложение загружает его в целевой серверный альбом
#### Scenario: Вернулся в другой альбом
- **WHEN** содержимое с исходной контрольной суммой присутствует в другом альбоме устройства
- **THEN** приложение загружает его в целевой серверный альбом
#### Scenario: Режим переноса
- **WHEN** загрузка вернувшегося оригинала завершена в режиме переноса
- **THEN** элемент снова проходит обычную разгрузку в превью
### Requirement: Ход и устойчивость восстановления оригиналов
При возврате оригиналов на устройство приложение SHALL выполнять операцию до конца
независимо от того, остаётся ли открыт экран альбома устройства, и SHALL сообщать ход:
сколько элементов восстановлено из скольких намечено.
#### Scenario: Уход с экрана
- **WHEN** восстановление оригиналов запущено и пользователь покидает экран альбома устройства
- **THEN** восстановление продолжается и завершается
#### Scenario: Ход операции
- **WHEN** восстановление оригиналов идёт
- **THEN** приложение знает и сообщает, сколько элементов уже восстановлено из намеченных
#### Scenario: Нечего восстанавливать
- **WHEN** среди элементов альбома нет превью с серверной копией
- **THEN** операция не запускается и ход не показывается