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

33 lines
4.6 KiB
Markdown

# Tasks
## 1. Агрегаты данных для карточки
- [x] 1.1 Добавить в `UploadDao`/`UploadRepository` поток sync-загрузок с полями `deviceAlbumId`, `status`, `progress`, `wifiOnly` (джобы ручной загрузки с `deviceAlbumId = null` исключены) и доменную модель для него; проверить тестом в `data/repo`, что выборка не смешивает альбомы и отбрасывает ручные загрузки (`cd android && ./gradlew test --tests "*SyncUpload*"`).
- [x] 1.2 Добавить в `SyncDao` групповой запрос числа ассетов с непустым `serverPhotoId` по `deviceAlbumId` и метод в `SyncRepository`; проверить тестом, что альбом без серверных фото даёт 0, а альбом с провенансом — фактическое число (`cd android && ./gradlew test --tests "*SyncRepository*"`).
## 2. Модель статуса синхронизации карточки
- [x] 2.1 Добавить доменный тип `AlbumSyncProgress` и чистую функцию сборки из (режим, список sync-загрузок альбома, число загруженных, `itemCount`); покрыть юнит-тестами пульсацию при `RUNNING`, «в очереди» без активных, «ждёт Wi‑Fi» для `QUEUED` + `wifiOnly`, ошибку при `ERROR`, простой без загрузок, кламп процента и случай `total == 0` (`cd android && ./gradlew test --tests "*AlbumSyncProgress*"`).
- [x] 2.2 Покрыть тестами монотонность формулы: при завершении одного файла из нескольких показанный процент не уменьшается (`cd android && ./gradlew test --tests "*AlbumSyncProgress*"`).
## 3. Сборка списка
- [x] 3.1 Расширить `AlbumListItem.DeviceAlbumItem` статусом и принимать карту «deviceAlbumId → AlbumSyncProgress» в `AlbumListBuilder.build`; проверить в `AlbumListBuilderTest`, что статус попадает в нужную карточку, а серверные карточки остаются без него (`cd android && ./gradlew test --tests "*AlbumListBuilderTest"`).
- [x] 3.2 Связать агрегаты (задачи 1.1–1.2) с существующей `combine` в `AlbumsViewModel` и покрыть `AlbumsViewModelTest` случаем, когда очередь и индекс дают ожидаемый статус для альбома устройства (`cd android && ./gradlew test --tests "*AlbumsViewModelTest"`).
## 4. Карточка альбома
- [x] 4.1 Изменить `placementOf` так, чтобы режим переноса давал `DEVICE_AND_CLOUD` (карта памяти + облако); обновить/добавить проверку в `AlbumsContentTest` для трёх режимов (`cd android && ./gradlew test --tests "*AlbumsContentTest"`).
- [x] 4.2 Добавить третью строку карточки: метка режима («Копии»/«Перенос») и текст статуса копий (процент, «в очереди», «ждёт Wi‑Fi», «ошибка»); процент пульсирует через `rememberInfiniteTransition` только при `RUNNING`; покрыть `AlbumsContentTest` и завести тест-теги для строки статуса (`cd android && ./gradlew test --tests "*AlbumsContentTest"`).
- [x] 4.3 Показывать процент операции и в режиме переноса: загрузка оригиналов идёт и в C, поэтому процент считается по общей формуле для B и C, а метка даёт «Перенос <процент>%»; покрыть `AlbumSyncProgressTest` и `AlbumsContentTest` (`cd android && ./gradlew :app:testDebugUnitTest --tests "*AlbumSyncProgressTest" --tests "*AlbumsContentTest"`).
## 5. Интеграционная проверка
- [x] 5.1 Прогнать весь Android-набор и убедиться, что он зелёный, затем собрать debug-APK (`cd android && ./gradlew test && ./gradlew :app:assembleDebug`).
## Workflow follow-up
- Заархивировать изменение после прохождения ревью проекта.
- Проверить результат архивации.