chore(openspec): archive shared-album and sync main specs
Move the completed shared-album change to openspec/changes/archive/2026-10-10-shared-album/ and create the 8 main specs (albums, auth, members, notifications, photos, realtime, share-links, social) from the delta ADDED requirements.
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# Spec Delta
|
||||
|
||||
## Purpose
|
||||
|
||||
Управление фотоальбомами: создание, просмотр, редактирование, удаление и владение.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Создание альбома
|
||||
Зарегистрированный пользователь SHALL иметь возможность создать альбом и стать его владельцем.
|
||||
|
||||
#### Scenario: Создание альбома
|
||||
- **WHEN** пользователь создаёт альбом с названием
|
||||
- **THEN** система создаёт альбом и назначает пользователя владельцем
|
||||
|
||||
### Requirement: Список альбомов пользователя
|
||||
Пользователь SHALL иметь возможность получить список альбомов, к которым у него есть доступ.
|
||||
|
||||
#### Scenario: Список альбомов
|
||||
- **WHEN** пользователь запрашивает список альбомов
|
||||
- **THEN** система возвращает альбомы, где он владелец или участник
|
||||
|
||||
### Requirement: Получение альбома
|
||||
Участник SHALL иметь возможность получить данные альбома по id.
|
||||
|
||||
#### Scenario: Просмотр альбома
|
||||
- **WHEN** участник запрашивает альбом по id
|
||||
- **THEN** система возвращает данные альбома
|
||||
|
||||
### Requirement: Редактирование альбома
|
||||
Владелец и админ SHALL иметь возможность редактировать название, описание и обложку альбома.
|
||||
|
||||
#### Scenario: Редактирование альбома
|
||||
- **WHEN** админ изменяет описание альбома
|
||||
- **THEN** система сохраняет изменения
|
||||
|
||||
### Requirement: Удаление альбома
|
||||
Владелец SHALL иметь возможность удалить альбом вместе с содержимым.
|
||||
|
||||
#### Scenario: Удаление альбома
|
||||
- **WHEN** владелец удаляет альбом
|
||||
- **THEN** система удаляет альбом, его фото, участников и share-ссылки
|
||||
@@ -0,0 +1,47 @@
|
||||
# Spec Delta
|
||||
|
||||
## Purpose
|
||||
|
||||
Регистрация и аутентификация пользователей по email и паролю с выдачей краткоживущих и долгоживущих JWT-токенов.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Регистрация пользователя
|
||||
Пользователь SHALL иметь возможность зарегистрироваться, указав email, пароль и имя. Пароль SHALL храниться в виде bcrypt-хэша.
|
||||
|
||||
#### Scenario: Успешная регистрация
|
||||
- **WHEN** пользователь отправляет уникальный email, пароль и имя
|
||||
- **THEN** система создаёт учётную запись и возвращает access- и refresh-токены
|
||||
|
||||
#### Scenario: Повторный email
|
||||
- **WHEN** пользователь регистрируется с уже занятым email
|
||||
- **THEN** система возвращает ошибку конфликта и не создаёт вторую запись
|
||||
|
||||
### Requirement: Вход по email и паролю
|
||||
Пользователь SHALL иметь возможность войти, указав email и пароль.
|
||||
|
||||
#### Scenario: Успешный вход
|
||||
- **WHEN** пользователь вводит верные email и пароль
|
||||
- **THEN** система возвращает access- и refresh-токены
|
||||
|
||||
#### Scenario: Неверные учётные данные
|
||||
- **WHEN** пользователь вводит неверный email или пароль
|
||||
- **THEN** система возвращает 401, не раскрывая, какое именно поле неверно
|
||||
|
||||
### Requirement: Обновление access-токена
|
||||
Пользователь SHALL иметь возможность обменять refresh-токен на новую пару токенов. Access-токен живёт 15 минут, refresh-токен — 30 дней.
|
||||
|
||||
#### Scenario: Валидный refresh-токен
|
||||
- **WHEN** пользователь предоставляет действующий refresh-токен
|
||||
- **THEN** система выдаёт новый access-токен и ротирует refresh-токен
|
||||
|
||||
#### Scenario: Недействительный refresh-токен
|
||||
- **WHEN** пользователь предоставляет истёкший или отозванный refresh-токен
|
||||
- **THEN** система возвращает 401
|
||||
|
||||
### Requirement: Выход из системы
|
||||
Пользователь SHALL иметь возможность выйти, отозвав refresh-токен.
|
||||
|
||||
#### Scenario: Выход
|
||||
- **WHEN** пользователь вызывает logout с действующим refresh-токеном
|
||||
- **THEN** система отзывает refresh-токен, и его дальнейшее использование отклоняется
|
||||
@@ -0,0 +1,65 @@
|
||||
# Spec Delta
|
||||
|
||||
## Purpose
|
||||
|
||||
Управление составом альбома, ролями и правами доступа, включая приглашения по токену.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Роли участников
|
||||
Участник альбома SHALL иметь одну из ролей: admin, editor, member, viewer. Владелец выводится из albums.owner_id и не хранится как роль участника.
|
||||
|
||||
#### Scenario: Создатель становится владельцем
|
||||
- **WHEN** пользователь создаёт альбом
|
||||
- **THEN** система делает его владельцем альбома
|
||||
|
||||
### Requirement: Матрица прав
|
||||
Система SHALL ограничивать действия по ролям: загружать фото могут owner/admin/editor/member; удалять чужие фото — owner/admin; удалять свои — owner/admin/editor/member; комментировать — owner/admin/editor/member; скачивать одиночное фото и просматривать — все участники, включая viewer.
|
||||
|
||||
#### Scenario: Наблюдатель не может загружать
|
||||
- **WHEN** участник с ролью viewer пытается загрузить фото
|
||||
- **THEN** система отклоняет запрос
|
||||
|
||||
#### Scenario: Участник не может удалять чужие фото
|
||||
- **WHEN** участник с ролью member пытается удалить фото другого автора
|
||||
- **THEN** система отклоняет запрос
|
||||
|
||||
### Requirement: Приглашение участников
|
||||
Владелец и админ SHALL иметь возможность создавать инвайт-ссылку с токеном. Редактор SHALL иметь возможность приглашать только на роли member и viewer. Никто не может приглашать на роль выше своей.
|
||||
|
||||
#### Scenario: Админ приглашает участника
|
||||
- **WHEN** админ создаёт инвайт на роль member
|
||||
- **THEN** система создаёт инвайт с токеном и сроком действия
|
||||
|
||||
#### Scenario: Редактор не может приглашать админа
|
||||
- **WHEN** редактор пытается создать инвайт на роль admin или editor
|
||||
- **THEN** система отклоняет запрос
|
||||
|
||||
### Requirement: Принятие инвайта
|
||||
Пользователь SHALL иметь возможность стать участником, перейдя по токену инвайта.
|
||||
|
||||
#### Scenario: Принятие действующего инвайта
|
||||
- **WHEN** пользователь принимает неистёкший инвайт с неисчерпанным лимитом использования
|
||||
- **THEN** система добавляет его в состав альбома с ролью из инвайта
|
||||
|
||||
#### Scenario: Принятие истёкшего инвайта
|
||||
- **WHEN** пользователь принимает истёкший инвайт
|
||||
- **THEN** система отклоняет запрос
|
||||
|
||||
### Requirement: Смена ролей
|
||||
Админ SHALL иметь возможность менять роли editor/member/viewer. Владелец SHALL управлять ролями админов. Никто не может менять роль выше своей и не может трогать владельца.
|
||||
|
||||
#### Scenario: Админ меняет роль участника
|
||||
- **WHEN** админ повышает участника до editor
|
||||
- **THEN** система обновляет роль
|
||||
|
||||
#### Scenario: Админ не может назначить админа
|
||||
- **WHEN** админ пытается назначить другому участнику роль admin
|
||||
- **THEN** система отклоняет запрос
|
||||
|
||||
### Requirement: Удаление участника
|
||||
Владелец и админ SHALL иметь возможность удалять участников, кроме владельца и других админов.
|
||||
|
||||
#### Scenario: Удаление участника
|
||||
- **WHEN** админ удаляет участника с ролью member/viewer/editor
|
||||
- **THEN** система убирает его из состава альбома
|
||||
@@ -0,0 +1,28 @@
|
||||
# Spec Delta
|
||||
|
||||
## Purpose
|
||||
|
||||
Персональные уведомления пользователя о событиях (комментарии, лайки, участники) и их статус прочитано.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Создание уведомления
|
||||
Система SHALL создавать уведомление пользователю при наступлении события (комментарий к его фото, лайк, добавление в альбом).
|
||||
|
||||
#### Scenario: Комментарий к моему фото
|
||||
- **WHEN** другой пользователь комментирует фото пользователя
|
||||
- **THEN** система создаёт уведомление этому пользователю
|
||||
|
||||
### Requirement: Список уведомлений
|
||||
Пользователь SHALL иметь возможность получить свои уведомления.
|
||||
|
||||
#### Scenario: Получение уведомлений
|
||||
- **WHEN** пользователь запрашивает уведомления
|
||||
- **THEN** система возвращает список с признаком прочитано
|
||||
|
||||
### Requirement: Отметка прочитанным
|
||||
Пользователь SHALL иметь возможность отметить уведомление прочитанным.
|
||||
|
||||
#### Scenario: Отметить прочитанным
|
||||
- **WHEN** пользователь отмечает уведомление прочитанным
|
||||
- **THEN** система фиксирует время прочтения
|
||||
@@ -0,0 +1,57 @@
|
||||
# Spec Delta
|
||||
|
||||
## Purpose
|
||||
|
||||
Загрузка, хранение в S3 и просмотр фотографий с генерацией вариантов и извлечением EXIF.
|
||||
|
||||
## ADDED 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** система отклоняет запрос
|
||||
@@ -0,0 +1,49 @@
|
||||
# Spec Delta
|
||||
|
||||
## Purpose
|
||||
|
||||
Поток событий альбома и персональный поток через Server-Sent Events.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Подписка на события альбома
|
||||
Клиент SHALL иметь возможность подписаться на события конкретного альбома через SSE.
|
||||
|
||||
#### Scenario: Подписка на альбом
|
||||
- **WHEN** участник подключается к SSE-потоку альбома
|
||||
- **THEN** система устанавливает text/event-stream и отправляет heartbeat
|
||||
|
||||
### Requirement: События альбома
|
||||
Система SHALL публиковать события photo.created, photo.deleted, comment.created, like.added, like.removed, member.joined, member.left, album.updated.
|
||||
|
||||
#### Scenario: Новое фото
|
||||
- **WHEN** в альбоме появляется фото
|
||||
- **THEN** подписчики получают событие photo.created с метаданными и URL превью
|
||||
|
||||
### Requirement: Персональный поток
|
||||
Клиент SHALL иметь возможность подписаться на персональный поток (приглашения, уведомления).
|
||||
|
||||
#### Scenario: Подписка на персональный поток
|
||||
- **WHEN** пользователь подключается к персональному потоку
|
||||
- **THEN** система отправляет ему персональные события
|
||||
|
||||
### Requirement: Авторизация и область доступа
|
||||
Клиент SHALL подписываться только на доступные ему альбомы; токен передаётся в query-параметре.
|
||||
|
||||
#### Scenario: Подписка на недоступный альбом
|
||||
- **WHEN** пользователь подписывается на альбом, к которому нет доступа
|
||||
- **THEN** система отклоняет подключение
|
||||
|
||||
### Requirement: Устойчивость соединения
|
||||
Система SHALL отправлять heartbeat каждые 25 секунд и отключать медленных клиентов при переполнении буфера.
|
||||
|
||||
#### Scenario: Переполнение буфера клиента
|
||||
- **WHEN** буфер клиента переполняется
|
||||
- **THEN** система отключает клиента
|
||||
|
||||
### Requirement: Догон пропущенного
|
||||
Клиент SHALL иметь возможность догнать пропущенные события через REST.
|
||||
|
||||
#### Scenario: Переподключение
|
||||
- **WHEN** клиент переподключается после разрыва
|
||||
- **THEN** клиент догоняет события через запрос фото с параметром since
|
||||
@@ -0,0 +1,46 @@
|
||||
# Spec Delta
|
||||
|
||||
## Purpose
|
||||
|
||||
View-only доступ к альбому по ссылке без авторизации, с несколькими ссылками, сроком действия и отзывом.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Создание ссылки для просмотра
|
||||
Владелец и админ SHALL иметь возможность создать ссылку для просмотра альбома с заданным сроком действия.
|
||||
|
||||
#### Scenario: Создание ссылки
|
||||
- **WHEN** админ создаёт share-ссылку со сроком действия
|
||||
- **THEN** система создаёт токен и возвращает URL для просмотра
|
||||
|
||||
### Requirement: Несколько ссылок
|
||||
Альбом SHALL поддерживать несколько независимых share-ссылок.
|
||||
|
||||
#### Scenario: Отзыв одной ссылки не затрагивает другие
|
||||
- **WHEN** владелец отзывает одну ссылку
|
||||
- **THEN** остальные ссылки остаются действующими
|
||||
|
||||
### Requirement: Просмотр альбома по ссылке
|
||||
Пользователь без авторизации SHALL иметь возможность просматривать альбом по действующему токену (сетка, лайтбокс, скачивание одиночного фото).
|
||||
|
||||
#### Scenario: Просмотр по действующей ссылке
|
||||
- **WHEN** аноним открывает ссылку с действующим токеном
|
||||
- **THEN** система возвращает фото альбома со свежими presigned URL
|
||||
|
||||
#### Scenario: Истёкшая или отозванная ссылка
|
||||
- **WHEN** аноним открывает ссылку с истёкшим или отозванным токеном
|
||||
- **THEN** система отклоняет доступ
|
||||
|
||||
### Requirement: Ограничения по ссылке
|
||||
Доступ по ссылке SHALL быть только на просмотр: без комментариев, лайков, загрузки и управления участниками.
|
||||
|
||||
#### Scenario: Аноним не может комментировать
|
||||
- **WHEN** аноним по ссылке пытается добавить комментарий
|
||||
- **THEN** система отклоняет запрос
|
||||
|
||||
### Requirement: Отзыв ссылки
|
||||
Владелец и админ SHALL иметь возможность отозвать ссылку.
|
||||
|
||||
#### Scenario: Отзыв ссылки
|
||||
- **WHEN** владелец отзывает share-ссылку
|
||||
- **THEN** система прекращает доступ по этому токену
|
||||
@@ -0,0 +1,39 @@
|
||||
# Spec Delta
|
||||
|
||||
## Purpose
|
||||
|
||||
Лайки и комментарии к фотографиям.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Лайк фото
|
||||
Пользователь с правом комментирования SHALL иметь возможность поставить и убрать лайк.
|
||||
|
||||
#### Scenario: Поставить лайк
|
||||
- **WHEN** участник ставит лайк фото
|
||||
- **THEN** система фиксирует лайк и публикует событие like.added
|
||||
|
||||
#### Scenario: Убрать лайк
|
||||
- **WHEN** участник убирает лайк
|
||||
- **THEN** система удаляет лайк и публикует событие like.removed
|
||||
|
||||
### Requirement: Комментарий к фото
|
||||
Пользователь с правом комментирования SHALL иметь возможность добавить комментарий.
|
||||
|
||||
#### Scenario: Добавить комментарий
|
||||
- **WHEN** участник добавляет комментарий
|
||||
- **THEN** система сохраняет комментарий и публикует событие comment.created
|
||||
|
||||
### Requirement: Список комментариев
|
||||
Система SHALL возвращать комментарии фото.
|
||||
|
||||
#### Scenario: Получение комментариев
|
||||
- **WHEN** клиент запрашивает комментарии фото
|
||||
- **THEN** система возвращает список комментариев с авторами
|
||||
|
||||
### Requirement: Удаление комментария
|
||||
Автор комментария (или владелец/админ) SHALL иметь возможность удалить комментарий.
|
||||
|
||||
#### Scenario: Удаление своего комментария
|
||||
- **WHEN** автор удаляет свой комментарий
|
||||
- **THEN** система удаляет комментарий
|
||||
Reference in New Issue
Block a user