# Spec Delta ## ADDED Requirements ### 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** представления возвращаются к заглушке, а объекты старого аватара освобождаются