Files
iu 14db79632a chore(openspec): архивировать android-live-albums и fix-album-cover-readiness
Дельта android-live-albums: android-client (+3 требования: живое обновление
списка, догон при переподключении, потеря доступа) и realtime (порядок списка
теперь правило отображения клиента).

Дельта fix-album-cover-readiness: realtime (+1 требование: album.updated при
готовности вариантов фото-обложки).
2026-10-16 12:48:32 +03:00

6.2 KiB

Proposal

Why

Список альбомов в Android-клиенте обновляется только REST-снимком при открытии экрана, поэтому изменения, сделанные с другого устройства или в веб-клиенте (создание, переименование, смена обложки, изменение состава участников, удаление альбома, изменение состава фото), не доходят до открытого приложения до ручного обновления. На вебе это уже решено персональным потоком GET /api/sse/me, и сервер события публикует, но Android к этому потоку не подключён.

Отдельно открытый экран альбома не обрабатывает потерю доступа: при удалении альбома владельцем или исключении участника экран продолжает отображать устаревшие данные (или пустую сетку с заголовком-заглушкой), а карточка остаётся в списке.

What Changes

  • Android подписывается на персональный поток GET /api/sse/me и применяет album.created, album.updated и album.deleted к локальному кэшу (Room) без дополнительного запроса списка.
  • Подписка привязана к сессии: создаётся при входе на главный экран и завершается при выходе из аккаунта, не пересоздаётся при навигации между экранами.
  • Применение события — это мутация кэша: upsert объекта альбома или удаление альбома и связанных с ним фото. Список и открытый экран альбома наблюдают Room и обновляются сами, дополнительных запросов на каждое событие нет.
  • album.deleted (удаление владельцем или исключение участника) убирает альбом из кэша; открытый экран этого альбома перестаёт его показывать и возвращается к списку.
  • При переподключении персонального потока клиент догоняет состояние REST-снимком списка альбомов, поэтому изменения, пропущенные во время разрыва, не теряются.
  • Порядок элементов списка — правило отображения клиента: событие, применённое к локальному кэшу, может изменить позицию альбома (Android упорядочивает серверные альбомы по времени изменения).
  • События notification в персональном потоке игнорируются: в Android нет экрана уведомлений и приглашений.
  • BREAKING: нет. Изменение аддитивное: пер-альбомный контракт событий и REST остаются прежними, неизвестные клиенту события он уже сейчас игнорирует.

Capabilities

New Capabilities

Нет — поведение расширяет существующие способности android-client и realtime.

Modified Capabilities

  • android-client: добавляется живое обновление списка альбомов из персонального потока (применение событий к кэшу без запроса списка, догон при переподключении) и обработка потери доступа к альбому (удаление из кэша, уход открытого экрана).
  • realtime: сценарий «Обновление альбома из списка» больше не требует сохранять порядок списка от всех клиентов — порядок становится правилом отображения клиента.

Impact

  • Код (Android): новый клиент персонального потока (data/network), парсер событий жизненного цикла альбома, применение событий в data/repo (Room), подписка в ui/albums/AlbumsViewModel, обработка потери доступа в ui/album/AlbumViewModel и ui/album/AlbumScreen, di/AppContainer.
  • Схема Room: без изменений (новых колонок и миграций не требуется).
  • API: новых эндпоинтов нет; существующий GET /api/sse/me начинает использоваться мобильным клиентом. Для авторизации используется заголовок Authorization (у Android есть интерцептор), поэтому query-параметр token не нужен.
  • Не затрагивается: веб-клиент, бэкенд (события и веер уже реализованы), схема БД, пер-альбомный поток, загрузка и синхронизация медиа.
  • Известное ограничение (фиксируется, не закрывается здесь): пер-альбомный SSE проверяет доступ только при подключении, поэтому исключённый участник продолжает получать события альбома до разрыва соединения. Персональный поток закрывает список и открытый экран, но не отменяет установленное соединение.