# media-objects Specification ## Purpose Физическое объектное хранилище с непрозрачными ключами и журналом объектов: привязка объектов к фото по ролям, совместное использование объектов несколькими фото и сборка мусора по отсутствию ссылок. ## Requirements ### Requirement: Непрозрачные ключи хранилища Слой хранения SHALL адресоваться непрозрачными ключами объектов, не содержащими идентификаторов сущностей метаданных (таких как альбом или фото); сопоставление ключей и сущностей SHALL храниться только в слое метаданных. #### Scenario: Ключ без альбома - **WHEN** система сохраняет объект в хранилище - **THEN** ключ объекта не содержит идентификатора альбома #### Scenario: Перенос не трогает ключи - **WHEN** фото переносится в другой альбом - **THEN** ключи его объектов остаются неизменными ### Requirement: Журнал объектов Каждый физический объект SHALL иметь ровно одну запись в слое метаданных с ключом, MIME-типом, размером, габаритами и состоянием; фото SHALL ссылаться на объекты по ролям original, thumb, medium, preview и playback. #### Scenario: Привязка ролей - **WHEN** фото загружено и обработано - **THEN** фото ссылается на объект-оригинал и, когда они готовы, на объекты thumb, medium и preview #### Scenario: Оригинал без вариантов - **WHEN** варианты ещё не сгенерированы - **THEN** фото доступно с оригиналом, а thumb, medium и preview отсутствуют #### Scenario: Привязка роли воспроизведения - **WHEN** видео обработано - **THEN** медиа ссылается на объект playback наряду с оригиналом и постером ### Requirement: Совместные объекты Несколько фото SHALL иметь возможность ссылаться на один и тот же физический объект; перенос и копирование SHALL изменять только ссылки и SHALL не изменять объекты хранилища. #### Scenario: Копирование - **WHEN** пользователь копирует фото в другой альбом - **THEN** создаётся новая запись, ссылающаяся на те же объекты, без операций с хранилищем #### Scenario: Перенос - **WHEN** пользователь переносит фото в другой альбом - **THEN** изменяется только привязка к альбому, объекты хранилища не меняются ### Requirement: Сборка мусора по ссылкам Объект хранилища SHALL удаляться только когда на него не ссылается ни одно фото; удаление альбома и попадание фото в корзину SHALL сохранять объекты. #### Scenario: Последняя ссылка удалена - **WHEN** фото удаляется навсегда и больше ни одно фото не ссылается на его объекты - **THEN** объекты удаляются из хранилища #### Scenario: Остались ссылки - **WHEN** на объект ссылается другое фото - **THEN** объект сохраняется в хранилище #### Scenario: Удаление альбома - **WHEN** владелец удаляет альбом - **THEN** объекты хранилища не удаляются ### Requirement: Устойчивость жизненного цикла объекта Объект SHALL иметь состояние жизненного цикла, и незавершённые операции SHALL самовосстанавливаться: неудачная загрузка не оставляет осиротевших объектов, а удаление объекта SHALL доводиться до конца после сбоя. #### Scenario: Сбой загрузки - **WHEN** запись объекта создана, но загрузка в хранилище не завершилась - **THEN** объект очищается без ручного вмешательства #### Scenario: Сбой удаления - **WHEN** удаление объекта из хранилища не удалось - **THEN** попытка повторяется до успешного удаления ### Requirement: Генерация вариантов Генерация вариантов SHALL выполняться через надёжную очередь заданий с однократным выполнением и повтором при сбое; готовый результат SHALL транслироваться подписчикам альбома. Очередь SHALL поддерживать настраиваемую пропускную способность, SHALL обрабатывать более свежие фото раньше остальных и SHALL различать короткие задания изображений и длительные задания видео. #### Scenario: Повтор после рестарта - **WHEN** процесс перезапускается с незавершёнными заданиями - **THEN** генерация вариантов продолжается #### Scenario: Событие после генерации - **WHEN** варианты фото готовы - **THEN** подписчикам альбома публикуется событие обновления этого фото #### Scenario: Приоритет свежих фото - **WHEN** в очереди есть готовые к обработке задания разного возраста - **THEN** система обрабатывает более свежие фото раньше #### Scenario: Настраиваемая пропускная способность - **WHEN** задан уровень параллелизма генерации - **THEN** система обрабатывает варианты с этим уровнем параллелизма #### Scenario: Длительное задание видео - **WHEN** выполняется длительная подготовка видео - **THEN** задание удерживается на весь срок выполнения и не вытесняет генерацию вариантов изображений