Files
ds-galo/openspec/specs/media-objects/spec.md
T
iu 748143c9d7 docs(openspec): описать правки редактора, сделанные без спецификаций
Дополнены спеки ui-workspace (сворачивание кривой, живая гистограмма,
точки кривой, навигация в зуме, Space к центру), media-objects (роли edit*,
привязка отредактированной версии, отдельная очередь рендера правок),
photos (рендер по оригиналу) и dev-make-workflow (сборка WASM-модуля).
2026-10-21 20:21:59 +03:00

159 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# media-objects Specification
## Purpose
Физическое объектное хранилище с непрозрачными ключами и журналом объектов:
привязка объектов к фото по ролям, совместное использование объектов несколькими
фото и сборка мусора по отсутствию ссылок.
## Requirements
### Requirement: Непрозрачные ключи хранилища
Слой хранения SHALL адресоваться непрозрачными ключами объектов, не содержащими
идентификаторов сущностей метаданных (таких как альбом или фото); сопоставление
ключей и сущностей SHALL храниться только в слое метаданных.
#### Scenario: Ключ без альбома
- **WHEN** система сохраняет объект в хранилище
- **THEN** ключ объекта не содержит идентификатора альбома
#### Scenario: Перенос не трогает ключи
- **WHEN** фото переносится в другой альбом
- **THEN** ключи его объектов остаются неизменными
### Requirement: Журнал объектов
Каждый физический объект SHALL иметь ровно одну запись в слое метаданных с ключом,
MIME-типом, размером, габаритами и состоянием; фото SHALL ссылаться на объекты по
ролям original, thumb, medium, preview, playback, edit, edit_thumb, edit_medium и
edit_preview.
#### Scenario: Привязка ролей
- **WHEN** фото загружено и обработано
- **THEN** фото ссылается на объект-оригинал и, когда они готовы, на объекты thumb, medium и preview
#### Scenario: Оригинал без вариантов
- **WHEN** варианты ещё не сгенерированы
- **THEN** фото доступно с оригиналом, а thumb, medium и preview отсутствуют
#### Scenario: Привязка роли воспроизведения
- **WHEN** видео обработано
- **THEN** медиа ссылается на объект playback наряду с оригиналом и постером
#### Scenario: Привязка отредактированной версии
- **WHEN** фото отредактировано и отредактированная версия отрендерена
- **THEN** фото ссылается на объекты edit, edit_thumb, edit_medium и edit_preview рядом с
исходными вариантами
### Requirement: Совместные объекты
Несколько фото SHALL иметь возможность ссылаться на один и тот же физический
объект; перенос и копирование SHALL изменять только ссылки и SHALL не изменять
объекты хранилища. Отредактированная версия SHALL создаваться и привязываться только
к тому фото, чьи правки её породили, в отличие от обычных вариантов, которые
разделяются копиями того же оригинала.
#### Scenario: Копирование
- **WHEN** пользователь копирует фото в другой альбом
- **THEN** создаётся новая запись, ссылающаяся на те же объекты, без операций с хранилищем
#### Scenario: Перенос
- **WHEN** пользователь переносит фото в другой альбом
- **THEN** изменяется только привязка к альбому, объекты хранилища не меняются
#### Scenario: Правка не распространяется на копии
- **WHEN** фото скопировали в другой альбом, а затем отредактировали исходное фото
- **THEN** отредактированные объекты привязаны только к отредактированному фото, а копия
остаётся в исходном виде
#### Scenario: Копия отредактированного фото
- **WHEN** фото с уже отрендеренной отредактированной версией копируют в другой альбом
- **THEN** копия разделяет те же объекты, включая отредактированные, но не наследует
параметры правок
### Requirement: Сборка мусора по ссылкам
Объект хранилища SHALL удаляться только когда на него не ссылается ни одно фото и ни один
аватар пользователя; удаление альбома и попадание фото в корзину SHALL сохранять объекты.
#### Scenario: Последняя ссылка удалена
- **WHEN** фото удаляется навсегда и больше ни одно фото не ссылается на его объекты
- **THEN** объекты удаляются из хранилища
#### 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 различать короткие задания изображений и длительные задания видео. Рендер
отредактированных версий SHALL использовать отдельную очередь, чтобы правки не
блокировали генерацию обычных вариантов.
#### Scenario: Повтор после рестарта
- **WHEN** процесс перезапускается с незавершёнными заданиями
- **THEN** генерация вариантов продолжается
#### Scenario: Событие после генерации
- **WHEN** варианты фото готовы
- **THEN** подписчикам альбома публикуется событие обновления этого фото
#### Scenario: Приоритет свежих фото
- **WHEN** в очереди есть готовые к обработке задания разного возраста
- **THEN** система обрабатывает более свежие фото раньше
#### Scenario: Настраиваемая пропускная способность
- **WHEN** задан уровень параллелизма генерации
- **THEN** система обрабатывает варианты с этим уровнем параллелизма
#### Scenario: Длительное задание видео
- **WHEN** выполняется длительная подготовка видео
- **THEN** задание удерживается на весь срок выполнения и не вытесняет генерацию вариантов изображений
#### Scenario: Рендер правок не блокирует варианты
- **WHEN** в фоне выполняется рендер отредактированной версии
- **THEN** генерация обычных вариантов продолжается независимо от него
### Requirement: Аватар пользователя как объект журнала
Аватар пользователя SHALL храниться как объект журнала, привязанный к пользователю по ролям,
соответствующим нарезкам аватара. Замена и удаление аватара SHALL менять привязку, а объекты
без ссылок SHALL освобождаться сборкой мусора.
#### Scenario: Привязка аватара
- **WHEN** пользователь устанавливает аватар
- **THEN** объекты нарезок привязываются к пользователю по своим ролям
#### Scenario: Замена аватара
- **WHEN** пользователь заменяет аватар
- **THEN** привязка указывает на новые объекты, а старые освобождаются сборкой мусора
#### Scenario: Удаление аватара
- **WHEN** пользователь удаляет аватар
- **THEN** привязка снимается, и объекты аватара освобождаются сборкой мусора