Files
ds-galo/openspec/specs/photos/spec.md
T
iu 384f126d8a chore(openspec): archive lightroom-workspace-ui and sync main specs
- synced delta specs into main specs: albums (+3 reqs, MODIFIED deleting album -> photos to trash), auth (+1), photos (+8), and created new ui-workspace spec (29 reqs)
- moved the change to openspec/changes/archive/2026-10-10-lightroom-workspace-ui/
2026-10-10 22:47:33 +03:00

11 KiB

photos Specification

Purpose

Загрузка, хранение в S3 и просмотр фотографий с генерацией вариантов и извлечением EXIF.

Requirements

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

Пользователь с правом загрузки SHALL иметь возможность загружать фото по одному и массово.

Scenario: Успешная загрузка

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

Scenario: Загрузка без права

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

Requirement: Варианты изображений

Система SHALL генерировать три варианта: thumb (200px), preview (1200px) и оригинал, с WebP для превью, и извлекать EXIF (дата, координаты, размеры).

Scenario: Генерация вариантов

  • WHEN фото загружено
  • THEN система асинхронно генерирует thumb и preview и заполняет EXIF-поля

Requirement: Листинг фото с пагинацией

Система SHALL возвращать фото альбома с cursor-пагинацией.

Scenario: Пагинация по курсору

  • WHEN клиент запрашивает список с курсором и лимитом
  • THEN система возвращает не более лимита фото и курсор следующей страницы

Requirement: Получение фото по требованию

Клиент SHALL иметь возможность получить актуальные данные фото с presigned URL.

Scenario: Выдача свежего URL

  • WHEN клиент запрашивает фото по id
  • THEN система возвращает свежий presigned URL (срок до 1 часа) для просмотра

Requirement: Скачивание одиночного фото

Любой участник, включая viewer, SHALL иметь возможность скачать одиночное фото.

Scenario: Скачивание фото

  • WHEN участник запрашивает скачивание фото
  • THEN система возвращает presigned URL оригинала

Requirement: Удаление фото

Автор SHALL иметь возможность удалить своё фото; владелец и админ SHALL иметь возможность удалить любое фото.

Scenario: Удаление своего фото

  • WHEN автор удаляет своё фото
  • THEN система удаляет запись и файлы в S3

Scenario: Удаление чужого фото участником

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

Requirement: Обложка по умолчанию

При обработке загруженного фото система SHALL назначать его обложкой альбома только если обложка ещё не задана.

Scenario: Первое фото

  • WHEN фото обработано, и у альбома нет обложки
  • THEN система назначает это фото обложкой

Scenario: Обложка уже задана

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

Requirement: Переименование фото

Автор фото, владелец и админ альбома SHALL иметь возможность изменить имя файла фото; остальные SHALL получать отказ, а пустое имя SHALL отклоняться.

Scenario: Переименование автором

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

Scenario: Пустое имя

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

Scenario: Нет прав

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

Requirement: Ограничение размера загрузки

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

Scenario: Превышение лимита

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

Scenario: Файл в пределах лимита

  • WHEN файл не превышает лимит
  • THEN система принимает multipart-загрузку и обрабатывает фото

Requirement: Метаданные фото (EXIF)

При загрузке фото система SHALL извлекать распознаваемые EXIF-атрибуты и SHALL возвращать их вместе с данными фото; при отсутствии метаданных SHALL возвращать пустой набор.

Scenario: Фото с метаданными

  • WHEN загружается фото с EXIF
  • THEN данные фото содержат извлечённые атрибуты (камера, экспозиция, ISO, дата съёмки и др.)

Scenario: Фото без метаданных

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

Requirement: Перенос и копирование фото между альбомами

Пользователь с правом удаления в исходном альбоме и правом загрузки в целевом SHALL иметь возможность перенести или скопировать фото в другой альбом. Операции SHALL изменять только метаданные и SHALL не изменять объекты хранилища.

Scenario: Перенос

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

Scenario: Копирование

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

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 система предлагает выбрать альбом или создать новый и восстанавливает фото в него

Requirement: Метки фото

Пользователь SHALL присваивать фото свои метки (область — пользователь): создавать новые и выбирать из списка с поиском; метки SHALL отдаваться вместе с фото и сниматься.

Scenario: Создание метки

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

Scenario: Выбор из списка с поиском

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

Scenario: Снятие метки

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