# Spec Delta ## MODIFIED Requirements ### Requirement: Персональный поток Клиент SHALL иметь возможность подписаться на персональный поток (приглашения, уведомления, изменения его альбомов). #### Scenario: Подписка на персональный поток - **WHEN** пользователь подключается к персональному потоку - **THEN** система отправляет ему персональные события #### Scenario: Изменение списка альбомов - **WHEN** альбом, доступный пользователю, создан, изменён или удалён - **THEN** пользователь получает соответствующее событие в персональном потоке ## ADDED Requirements ### 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** клиент убирает альбом из списка ### Requirement: Догон состояния альбомов при переподключении Клиент SHALL после восстановления персонального потока синхронизировать список альбомов через REST, чтобы отразить изменения, пропущенные во время разрыва соединения. #### Scenario: Переподключение персонального потока - **WHEN** персональный поток восстанавливается после разрыва - **THEN** клиент перезапрашивает список альбомов и приводит локальное состояние к серверному ### Requirement: Потеря доступа к альбому Клиент SHALL переставать отображать альбом, который удалён или к которому потерян доступ, при получении соответствующего персонального события, в том числе на открытой странице альбома. #### Scenario: Альбом удалён во время просмотра - **WHEN** владелец удаляет альбом, пока участник просматривает его страницу - **THEN** участник получает событие и страница перестаёт отображать удалённый альбом #### Scenario: Участник исключён из альбома - **WHEN** участника исключают из альбома - **THEN** исключённый получает событие, и альбом убирается из его списка ### Requirement: Обновление альбома при изменении состава фото Система SHALL публиковать `album.updated` с актуальным объектом альбома в персональные потоки владельца и участников, когда состав фото альбома меняется: загрузка, копирование, перемещение, восстановление, перевод в корзину и окончательное удаление. При загрузке система также SHALL публиковать `photo.created` в поток альбома (см. способность `realtime`, требование «События альбома»), чтобы открытая страница добавляла новое фото. #### 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`