chore(openspec): архивировать fix-album-sync-churn-and-degradation и синхронизировать спеки
В спеку phone-album-sync добавлены требования о роли локального файла, подтверждении новой версии до удаления устаревшей и разгрузке без незавершённой загрузки; уточнены синхронизация изменений, провенанс и возврат оригиналов.
This commit is contained in:
@@ -74,8 +74,9 @@
|
||||
|
||||
Для каждого отслеженного изменения приложение SHALL применить его к целевому
|
||||
серверному альбому: загрузить новое содержимое, переименовать и перенести через
|
||||
API, а изменение содержимого SHALL трактовать как новую загрузку с удалением
|
||||
устаревшей собственной загрузки.
|
||||
API. Изменение содержимого SHALL трактоваться как новая загрузка, а устаревшая
|
||||
собственная загрузка SHALL удаляться после подтверждения новой версии и SHALL NOT
|
||||
удаляться из-за смены локальной роли файла (оригинал ↔ превью).
|
||||
|
||||
#### Scenario: Новое содержимое
|
||||
|
||||
@@ -90,7 +91,36 @@ API, а изменение содержимого SHALL трактовать к
|
||||
#### Scenario: Изменение содержимого
|
||||
|
||||
- **WHEN** содержимое медиа изменено на устройстве
|
||||
- **THEN** приложение загружает новую версию, а устаревшую собственную загрузку удаляет
|
||||
- **THEN** приложение загружает новую версию и после её подтверждения удаляет устаревшую собственную загрузку
|
||||
|
||||
### Requirement: Подтверждение новой версии до удаления устаревшей
|
||||
|
||||
Устаревшая собственная загрузка элемента SHALL удаляться только после подтверждения новой
|
||||
версии: сообщённая сервером контрольная сумма принятого объекта SHALL совпадать с
|
||||
отправленной. При расхождении приложение SHALL отклонить загрузку, удалив принятую копию, и
|
||||
SHALL NOT считать элемент загруженным. Если сервер контрольную сумму не сообщил, загрузка
|
||||
SHALL считаться состоявшейся, но устаревшая копия SHALL NOT удаляться, а замена SHALL
|
||||
повториться при следующей синхронизации.
|
||||
|
||||
#### Scenario: Новая версия подтверждена
|
||||
|
||||
- **WHEN** новая версия загружена, а сообщённая сервером контрольная сумма совпала с отправленной
|
||||
- **THEN** приложение удаляет устаревшую собственную загрузку (мягко, в корзину)
|
||||
|
||||
#### Scenario: Контрольная сумма не совпала
|
||||
|
||||
- **WHEN** сервер сообщил для принятого объекта контрольную сумму, отличную от отправленной
|
||||
- **THEN** приложение удаляет принятую копию, не считает элемент загруженным и оставляет прежнюю серверную копию в альбоме
|
||||
|
||||
#### Scenario: Контрольная сумма не сообщена
|
||||
|
||||
- **WHEN** сервер не сообщил контрольную сумму принятого объекта
|
||||
- **THEN** загрузка считается состоявшейся, прежняя серверная копия остаётся в альбоме, а замена повторяется при следующей синхронизации
|
||||
|
||||
#### Scenario: Загрузка не удалась
|
||||
|
||||
- **WHEN** загрузка новой версии завершилась ошибкой
|
||||
- **THEN** прежняя серверная копия остаётся в альбоме
|
||||
|
||||
### Requirement: Идентичность по контрольной сумме
|
||||
|
||||
@@ -154,12 +184,29 @@ API, а изменение содержимого SHALL трактовать к
|
||||
- **WHEN** пользователь включает режим переноса
|
||||
- **THEN** приложение запрашивает широкий доступ к файлам, и разгрузка выполняется без системного диалога согласия
|
||||
|
||||
### Requirement: Разгрузка без незавершённой загрузки
|
||||
|
||||
Приложение SHALL NOT заменять оригинал превью, пока для этого элемента есть незавершённая
|
||||
загрузка (в очереди или выполняющаяся), чтобы загрузка не отправила превью вместо оригинала.
|
||||
|
||||
#### Scenario: Загрузка в очереди
|
||||
|
||||
- **WHEN** для элемента есть задание загрузки в очереди или выполняющееся
|
||||
- **THEN** оригинал на устройстве не заменяется превью
|
||||
|
||||
#### Scenario: Загрузка подтверждена
|
||||
|
||||
- **WHEN** загрузка элемента подтверждена сервером
|
||||
- **THEN** приложение выполняет обычную разгрузку в режиме переноса
|
||||
|
||||
### Requirement: Провенанс разгруженных превью
|
||||
|
||||
Разгруженные превью, постеры видео и скачанные с сервера элементы SHALL содержать
|
||||
метаданные провенанса, включая признак происхождения (загружено клиентом или скачано с
|
||||
сервера), достаточные для восстановления связи с серверным альбомом и принадлежности
|
||||
загрузок после переустановки приложения.
|
||||
загрузок после переустановки приложения. Метка SHALL также служить признаком того, что
|
||||
локальный файл является созданным приложением превью: элемент с такой меткой SHALL NOT
|
||||
считаться содержащим оригинал, даже если состояние локального индекса утверждает обратное.
|
||||
|
||||
#### Scenario: Восстановление после переустановки
|
||||
|
||||
@@ -176,6 +223,39 @@ API, а изменение содержимого SHALL трактовать к
|
||||
- **WHEN** метаданные провенанса недоступны (например, файл перезаписан сторонним редактором)
|
||||
- **THEN** элемент считается неопознанным, не удаляется и не загружается повторно
|
||||
|
||||
#### Scenario: Метка против состояния индекса
|
||||
|
||||
- **WHEN** файл несёт метку созданного приложением превью, а состояние индекса указывает оригинал
|
||||
- **THEN** элемент считается разгруженным, а не новым оригиналом
|
||||
|
||||
### Requirement: Роль локального файла не является содержимым
|
||||
|
||||
Приложение SHALL отличать превью, созданное им самим при разгрузке (в том числе по метке
|
||||
провенанса), от новой версии оригинала: разгруженный элемент SHALL NOT загружаться повторно
|
||||
и SHALL NOT вызывать удаление серверной копии, а расхождение состояния в локальном индексе
|
||||
SHALL выправляться. Это SHALL относиться и к постеру, которым в режиме переноса заменяется
|
||||
видео.
|
||||
|
||||
#### Scenario: Разгруженный элемент не создаёт новую версию
|
||||
|
||||
- **WHEN** серверная копия элемента есть в целевом альбоме, а на устройстве лежит созданное приложением превью, в том числе если состояние локального индекса ошибочно указывает оригинал
|
||||
- **THEN** приложение не ставит загрузку и не удаляет серверную копию
|
||||
|
||||
#### Scenario: Состояние выправляется
|
||||
|
||||
- **WHEN** файл на устройстве является созданным приложением превью, а индекс считает его оригиналом
|
||||
- **THEN** приложение помечает элемент как разгруженный и последующие проходы не создают загрузок
|
||||
|
||||
#### Scenario: Постер разгруженного видео
|
||||
|
||||
- **WHEN** видео разгружено (заменено постером под новым элементом MediaStore), а его метка указывает на исходное видео
|
||||
- **THEN** приложение связывает элемент с серверным фото видео и не удаляет это фото на сервере, а постер не загружается как новое фото
|
||||
|
||||
#### Scenario: Настоящее изменение содержимого
|
||||
|
||||
- **WHEN** содержимое медиа заменено содержимым, не созданным приложением при разгрузке
|
||||
- **THEN** приложение загружает новую версию элемента
|
||||
|
||||
### Requirement: Возврат оригиналов и отвязка
|
||||
|
||||
При выходе из режима C приложение SHALL предложить вернуть оригиналы на устройство
|
||||
@@ -215,6 +295,11 @@ API, а изменение содержимого SHALL трактовать к
|
||||
- **WHEN** пользователь снова включает синхронизацию после выключения
|
||||
- **THEN** связь создаётся заново, а восстановление происхождения снова действует по обычным правилам
|
||||
|
||||
#### Scenario: Возврат устойчив
|
||||
|
||||
- **WHEN** оригиналы возвращены на устройство после выхода из режима переноса
|
||||
- **THEN** приложение не разгружает их повторно, пока альбом не переведён в режим переноса снова
|
||||
|
||||
### Requirement: Автоматическая фоновая синхронизация
|
||||
|
||||
Синхронизация SHALL выполняться автоматически в обе стороны: при открытом приложении —
|
||||
|
||||
Reference in New Issue
Block a user