Files
iu 1eb1177273 feat(android): статус синхронизации на карточке и безопасная разгрузка
Карточка альбома устройства получает третью строку: метку режима («Копии»/
«Перенос») и ход загрузки. Процент считается как (uploaded + running) / total
для обоих синхронизируемых режимов, пульсирует только при активной загрузке,
показывает очередь, ожидание Wi-Fi и ошибку. В режиме переноса карточка
показывает и карту памяти, и облако — режимы различает метка, а не значки.

Разгрузка оригиналов теперь требует подтверждённой серверной копии в текущем
целевом альбоме: устаревший serverPhotoId перепроверяется по альбому, смена
цели переносит уже загруженные фото и отклоняется, если перенести нельзя.
Потеря серверной копии видна на карточке и на экране альбома, автозатирания
превью нет.

Изменения OpenSpec: android-album-card-sync-status, safe-album-offload.
2026-10-16 18:36:51 +03:00

4.6 KiB

Tasks

1. Агрегаты данных для карточки

  • 1.1 Добавить в UploadDao/UploadRepository поток sync-загрузок с полями deviceAlbumId, status, progress, wifiOnly (джобы ручной загрузки с deviceAlbumId = null исключены) и доменную модель для него; проверить тестом в data/repo, что выборка не смешивает альбомы и отбрасывает ручные загрузки (cd android && ./gradlew test --tests "*SyncUpload*").
  • 1.2 Добавить в SyncDao групповой запрос числа ассетов с непустым serverPhotoId по deviceAlbumId и метод в SyncRepository; проверить тестом, что альбом без серверных фото даёт 0, а альбом с провенансом — фактическое число (cd android && ./gradlew test --tests "*SyncRepository*").

2. Модель статуса синхронизации карточки

  • 2.1 Добавить доменный тип AlbumSyncProgress и чистую функцию сборки из (режим, список sync-загрузок альбома, число загруженных, itemCount); покрыть юнит-тестами пульсацию при RUNNING, «в очереди» без активных, «ждёт Wi‑Fi» для QUEUED + wifiOnly, ошибку при ERROR, простой без загрузок, кламп процента и случай total == 0 (cd android && ./gradlew test --tests "*AlbumSyncProgress*").
  • 2.2 Покрыть тестами монотонность формулы: при завершении одного файла из нескольких показанный процент не уменьшается (cd android && ./gradlew test --tests "*AlbumSyncProgress*").

3. Сборка списка

  • 3.1 Расширить AlbumListItem.DeviceAlbumItem статусом и принимать карту «deviceAlbumId → AlbumSyncProgress» в AlbumListBuilder.build; проверить в AlbumListBuilderTest, что статус попадает в нужную карточку, а серверные карточки остаются без него (cd android && ./gradlew test --tests "*AlbumListBuilderTest").
  • 3.2 Связать агрегаты (задачи 1.1–1.2) с существующей combine в AlbumsViewModel и покрыть AlbumsViewModelTest случаем, когда очередь и индекс дают ожидаемый статус для альбома устройства (cd android && ./gradlew test --tests "*AlbumsViewModelTest").

4. Карточка альбома

  • 4.1 Изменить placementOf так, чтобы режим переноса давал DEVICE_AND_CLOUD (карта памяти + облако); обновить/добавить проверку в AlbumsContentTest для трёх режимов (cd android && ./gradlew test --tests "*AlbumsContentTest").

  • 4.2 Добавить третью строку карточки: метка режима («Копии»/«Перенос») и текст статуса копий (процент, «в очереди», «ждёт Wi‑Fi», «ошибка»); процент пульсирует через rememberInfiniteTransition только при RUNNING; покрыть AlbumsContentTest и завести тест-теги для строки статуса (cd android && ./gradlew test --tests "*AlbumsContentTest").

  • 4.3 Показывать процент операции и в режиме переноса: загрузка оригиналов идёт и в C, поэтому процент считается по общей формуле для B и C, а метка даёт «Перенос <процент>%»; покрыть AlbumSyncProgressTest и AlbumsContentTest (cd android && ./gradlew :app:testDebugUnitTest --tests "*AlbumSyncProgressTest" --tests "*AlbumsContentTest").

5. Интеграционная проверка

  • 5.1 Прогнать весь Android-набор и убедиться, что он зелёный, затем собрать debug-APK (cd android && ./gradlew test && ./gradlew :app:assembleDebug).

Workflow follow-up

  • Заархивировать изменение после прохождения ревью проекта.
  • Проверить результат архивации.