chore(openspec): archive add-user-avatar and sync main specs

This commit is contained in:
iu
2026-10-12 16:17:40 +03:00
parent 04617d1cdb
commit 43f5520236
8 changed files with 109 additions and 2 deletions
+23 -2
View File
@@ -56,8 +56,8 @@ MIME-типом, размером, габаритами и состоянием;
- **THEN** изменяется только привязка к альбому, объекты хранилища не меняются - **THEN** изменяется только привязка к альбому, объекты хранилища не меняются
### Requirement: Сборка мусора по ссылкам ### Requirement: Сборка мусора по ссылкам
Объект хранилища SHALL удаляться только когда на него не ссылается ни одно фото; Объект хранилища SHALL удаляться только когда на него не ссылается ни одно фото и ни один
удаление альбома и попадание фото в корзину SHALL сохранять объекты. аватар пользователя; удаление альбома и попадание фото в корзину SHALL сохранять объекты.
#### Scenario: Последняя ссылка удалена #### Scenario: Последняя ссылка удалена
- **WHEN** фото удаляется навсегда и больше ни одно фото не ссылается на его объекты - **WHEN** фото удаляется навсегда и больше ни одно фото не ссылается на его объекты
@@ -71,6 +71,10 @@ MIME-типом, размером, габаритами и состоянием;
- **WHEN** владелец удаляет альбом - **WHEN** владелец удаляет альбом
- **THEN** объекты хранилища не удаляются - **THEN** объекты хранилища не удаляются
#### Scenario: Ссылка аватара
- **WHEN** на объект ссылается аватар пользователя
- **THEN** объект сохраняется в хранилище, пока ссылка существует
### Requirement: Устойчивость жизненного цикла объекта ### Requirement: Устойчивость жизненного цикла объекта
Объект SHALL иметь состояние жизненного цикла, и незавершённые операции SHALL Объект SHALL иметь состояние жизненного цикла, и незавершённые операции SHALL
самовосстанавливаться: неудачная загрузка не оставляет осиротевших объектов, а самовосстанавливаться: неудачная загрузка не оставляет осиротевших объектов, а
@@ -110,3 +114,20 @@ SHALL различать короткие задания изображений
#### Scenario: Длительное задание видео #### Scenario: Длительное задание видео
- **WHEN** выполняется длительная подготовка видео - **WHEN** выполняется длительная подготовка видео
- **THEN** задание удерживается на весь срок выполнения и не вытесняет генерацию вариантов изображений - **THEN** задание удерживается на весь срок выполнения и не вытесняет генерацию вариантов изображений
### Requirement: Аватар пользователя как объект журнала
Аватар пользователя SHALL храниться как объект журнала, привязанный к пользователю по ролям,
соответствующим нарезкам аватара. Замена и удаление аватара SHALL менять привязку, а объекты
без ссылок SHALL освобождаться сборкой мусора.
#### Scenario: Привязка аватара
- **WHEN** пользователь устанавливает аватар
- **THEN** объекты нарезок привязываются к пользователю по своим ролям
#### Scenario: Замена аватара
- **WHEN** пользователь заменяет аватар
- **THEN** привязка указывает на новые объекты, а старые освобождаются сборкой мусора
#### Scenario: Удаление аватара
- **WHEN** пользователь удаляет аватар
- **THEN** привязка снимается, и объекты аватара освобождаются сборкой мусора
+86
View File
@@ -118,3 +118,89 @@ Android-приложение SHALL предоставлять отдельный
#### Scenario: Возврат после удаления #### Scenario: Возврат после удаления
- **WHEN** удаление аккаунта завершилось успешно - **WHEN** удаление аккаунта завершилось успешно
- **THEN** приложение очищает токены и возвращает на экран входа - **THEN** приложение очищает токены и возвращает на экран входа
### Requirement: Загрузка фото профиля с выбором области
Пользователь SHALL загружать собственное фото в профиль, выбирая видимую квадратную область.
Сохранённый аватар SHALL соответствовать выбранной области. Загрузка SHALL быть доступна только
владельцу профиля.
#### Scenario: Успешная загрузка
- **WHEN** пользователь выбирает изображение и подтверждает квадратную область
- **THEN** аватар обновляется и возвращается в профиле
#### Scenario: Выбранная область учтена
- **WHEN** пользователь сдвигает или масштабирует область перед подтверждением
- **THEN** сохранённый аватар показывает именно выбранную область
#### Scenario: Не изображение
- **WHEN** загруженный файл не является декодируемым изображением
- **THEN** система отклоняет запрос и не меняет аватар
### Requirement: Нормализация аватара и снятие метаданных
Система SHALL сохранять аватар в виде квадратных изображений фиксированных размеров и SHALL NOT
сохранять EXIF-метаданные загруженного файла.
#### Scenario: Метаданные не сохраняются
- **WHEN** загружено изображение с EXIF, включая GPS-координаты
- **THEN** сохранённый аватар не содержит EXIF и GPS
#### Scenario: Слишком большой файл
- **WHEN** размер загруженного файла превышает допустимый предел
- **THEN** система отклоняет запрос и не меняет аватар
### Requirement: Отдача аватара по стабильному URL
Профиль и публичные представления пользователя SHALL содержать URL аватара, когда он задан.
URL SHALL быть стабильным и SHALL изменяться при обновлении аватара, чтобы клиентские кэши
инвалидировались. Изображение SHALL отдаваться по публичной ссылке без аутентификации, чтобы
его могли загружать теги изображений и клиентские загрузчики.
#### Scenario: Ссылка в представлениях пользователя
- **WHEN** аутентифицированный клиент запрашивает профиль, участников альбома, комментарии или автора фото
- **THEN** представления содержат URL аватара, если он задан
#### Scenario: Кэш инвалидируется при замене
- **WHEN** пользователь заменяет аватар
- **THEN** URL аватара изменяется
#### Scenario: Загрузка изображения без заголовка авторизации
- **WHEN** браузер или клиентский загрузчик изображений запрашивает изображение аватара по URL без заголовка авторизации
- **THEN** система отдаёт изображение
### Requirement: Круглое отображение аватара в веб-интерфейсе
Веб-приложение SHALL отображать аватар пользователя круглым в шапке, на странице профиля, у
участников альбома, в комментариях и у автора фото.
#### Scenario: Аватар в шапке
- **WHEN** аутентифицированный пользователь открывает любое место приложения
- **THEN** в шапке отображается его круглый аватар
#### Scenario: Аватар рядом с другими пользователями
- **WHEN** пользователь просматривает участников, комментарии или автора фото
- **THEN** аватары этих пользователей отображаются круглыми
### Requirement: Круглое отображение аватара в Android-клиенте
Android-приложение SHALL отображать аватар пользователя круглым на экране профиля и в шапке
списка альбомов.
#### Scenario: Аватар на экране профиля
- **WHEN** пользователь открывает экран профиля
- **THEN** отображается его круглый аватар
#### Scenario: Аватар в шапке списка альбомов
- **WHEN** пользователь открывает список альбомов
- **THEN** в шапке отображается его круглый аватар
### Requirement: Заглушка при отсутствии аватара
Когда аватар не задан, система SHALL показывать нейтральную заглушку-силуэт вместо изображения.
#### Scenario: Аватар не задан
- **WHEN** у пользователя нет аватара и его представление отображается в вебе или Android
- **THEN** вместо изображения показывается нейтральная круглая заглушка-силуэт
### Requirement: Удаление аватара
Пользователь SHALL удалять свой аватар; после удаления SHALL показываться заглушка, а связанные
объекты хранилища SHALL освобождаться.
#### Scenario: Сброс аватара
- **WHEN** пользователь удаляет аватар
- **THEN** представления возвращаются к заглушке, а объекты старого аватара освобождаются