Files
ds-galo/openspec/specs/realtime/spec.md
T
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

14 KiB
Raw Blame History

realtime Specification

Purpose

Поток событий альбома и персональный поток через Server-Sent Events.

Requirements

Requirement: Подписка на события альбома

Клиент SHALL иметь возможность подписаться на события конкретного альбома через SSE.

Scenario: Подписка на альбом

  • WHEN участник подключается к SSE-потоку альбома
  • THEN система устанавливает text/event-stream и отправляет heartbeat

Requirement: События альбома

Система SHALL публиковать события photo.created, photo.updated, photo.deleted, comment.created, like.added, like.removed, member.joined, member.left, album.updated. Событие photo.created SHALL обозначать появление фото в альбоме, а готовность вариантов существующего фото SHALL публиковаться как photo.updated.

Scenario: Новое фото

  • WHEN в альбоме появляется фото
  • THEN подписчики получают событие photo.created с метаданными и URL превью

Scenario: Готовы варианты

  • WHEN для существующего фото сгенерированы thumb и preview
  • THEN подписчики получают событие photo.updated с этим фото

Requirement: Персональный поток

Клиент SHALL иметь возможность подписаться на персональный поток (приглашения, уведомления, изменения его альбомов).

Scenario: Подписка на персональный поток

  • WHEN пользователь подключается к персональному потоку
  • THEN система отправляет ему персональные события

Scenario: Изменение списка альбомов

  • WHEN альбом, доступный пользователю, создан, изменён или удалён
  • THEN пользователь получает соответствующее событие в персональном потоке

Requirement: Авторизация и область доступа

Клиент SHALL подписываться только на доступные ему альбомы; токен передаётся в query-параметре.

Scenario: Подписка на недоступный альбом

  • WHEN пользователь подписывается на альбом, к которому нет доступа
  • THEN система отклоняет подключение

Requirement: Устойчивость соединения

Система SHALL отправлять heartbeat каждые 25 секунд и отключать медленных клиентов при переполнении буфера.

Scenario: Переполнение буфера клиента

  • WHEN буфер клиента переполняется
  • THEN система отключает клиента

Requirement: Догон пропущенного

Клиент SHALL иметь возможность догнать пропущенные события через REST.

Scenario: Переподключение

  • WHEN клиент переподключается после разрыва
  • THEN клиент догоняет события через запрос фото с параметром since

Requirement: Различение добавления и обновления фото

Клиент SHALL различать добавление нового фото в альбом и обновление уже показанного: обновление SHALL изменять фото на месте, не меняя порядок сетки.

Scenario: Обновление отображаемого фото

  • WHEN приходит событие обновления для фото, которое уже показано
  • THEN клиент обновляет его на месте, порядок сетки не меняется

Scenario: Обновление отсутствующего фото

  • WHEN приходит событие обновления для фото, которого нет в текущем списке
  • THEN клиент не добавляет его в сетку

Requirement: События жизненного цикла альбома

Система SHALL публиковать в персональные потоки события album.created и album.updated с объектом альбома и album.deleted с идентификатором альбома.

Scenario: Создание альбома

  • WHEN пользователь создаёт альбом
  • THEN владелец получает событие album.created с объектом альбома

Scenario: Изменение метаданных альбома

  • WHEN участник с правом редактирования меняет название, описание или обложку
  • THEN владелец и участники получают событие album.updated с актуальным объектом

Scenario: Удаление альбома

  • WHEN владелец удаляет альбом
  • THEN владелец и участники получают событие album.deleted с идентификатором

Requirement: Получатели событий об альбоме

Система SHALL доставлять события жизненного цикла альбома владельцу и всем участникам альбома, для которых он доступен.

Scenario: Веер по участникам

  • WHEN альбом изменён
  • THEN событие получает владелец и каждый участник альбома, включая инициатора изменения

Scenario: Принятие приглашения

  • WHEN пользователь принимает приглашение в альбом
  • THEN приглашённый получает событие о появлении альбома в своём списке, а владелец — обновлённый объект альбома с новым числом участников

Requirement: Единая форма объекта альбома в событиях

Объект альбома в событиях SHALL совпадать по форме с элементом ответа списка альбомов, включая URL обложки и счётчики, чтобы клиент применял событие без дополнительных запросов.

Scenario: Объект события совпадает со списком

  • WHEN клиент получает album.created или album.updated
  • THEN объект содержит те же поля, что элемент ответа GET /api/albums

Requirement: Применение события без повторного запроса

Клиент SHALL обновлять локальный список альбомов из payload'а события: создавать или заменять альбом по полученному объекту и удалять его по идентификатору, не выполняя дополнительный запрос списка.

Scenario: Обновление альбома из списка

  • WHEN приходит событие обновления для альбома, который уже есть в списке клиента
  • THEN клиент заменяет альбом по полученному объекту без дополнительного запроса списка

Scenario: Удаление альбома из списка

  • WHEN приходит событие удаления для альбома, который есть в списке клиента
  • THEN клиент убирает альбом из списка

Scenario: Порядок списка

  • WHEN клиент применяет событие к списку альбомов
  • THEN порядок элементов списка определяется правилами отображения этого клиента

Requirement: Догон состояния альбомов при переподключении

Клиент SHALL после восстановления персонального потока синхронизировать список альбомов через REST, чтобы отразить изменения, пропущенные во время разрыва соединения.

Scenario: Переподключение персонального потока

  • WHEN персональный поток восстанавливается после разрыва
  • THEN клиент перезапрашивает список альбомов и приводит локальное состояние к серверному

Requirement: Потеря доступа к альбому

Клиент SHALL переставать отображать альбом, который удалён или к которому потерян доступ, при получении соответствующего персонального события, в том числе на открытой странице альбома.

Scenario: Альбом удалён во время просмотра

  • WHEN владелец удаляет альбом, пока участник просматривает его страницу
  • THEN участник получает событие и страница перестаёт отображать удалённый альбом

Scenario: Участник исключён из альбома

  • WHEN участника исключают из альбома
  • THEN исключённый получает событие, и альбом убирается из его списка

Requirement: Обновление альбома при изменении состава фото

Система SHALL публиковать album.updated с актуальным объектом альбома в персональные потоки владельца и участников, когда состав фото альбома меняется: загрузка, копирование, перемещение, восстановление, перевод в корзину и окончательное удаление. При загрузке система также SHALL публиковать photo.created в поток альбома, чтобы открытая страница добавляла новое фото.

Scenario: Загрузка фото

  • WHEN пользователь загружает фото в альбом
  • THEN владелец и участники получают album.updated с увеличенным photos_count

Scenario: Перемещение фото

  • WHEN фото перемещается из одного альбома в другой
  • THEN владелец и участники обоих альбомов получают album.updated с актуальными счётчиками

Scenario: Фото в корзине

  • WHEN фото переводится в корзину или восстанавливается
  • THEN владелец и участники получают album.updated с обновлённым photos_count

Scenario: Окончательное удаление фото

  • WHEN фото удаляется окончательно
  • THEN владелец и участники получают album.updated с уменьшенным photos_count

Requirement: Обновление альбома при готовности вариантов обложки

Когда для фото, являющегося обложкой альбома, сгенерированы варианты, система SHALL публиковать album.updated с актуальным объектом альбома в персональные потоки владельца и участников: только тогда объект получает ссылку на обложку. Готовность вариантов прочих фото событий не порождает.

Scenario: Варианты обложки готовы

  • WHEN для фото, которое является обложкой альбома, сгенерированы thumb и medium
  • THEN владелец и участники получают album.updated с непустой ссылкой на обложку

Scenario: Варианты обычного фото готовы

  • WHEN варианты готовы для фото, которое не является обложкой альбома
  • THEN персональные потоки не получают album.updated