7.1 KiB
7.1 KiB
Tasks
1. Модель данных и сборка мусора
- 1.1 Добавить миграцию Postgres
000014_user_avatar_objects.up.sql/.down.sqlи SQLite000006_user_avatar_objects.up.sql/.down.sql: таблицаuser_avatar_objects(user_id, object_id, role)с FK наusersиobjectsи уникальностью(user_id, role); проверить, что тесты миграций (go test ./internal/db/...) проходят иmake migrateприменяет и откатывает. - 1.2 Расширить
ClaimGarbageв Postgres-сторе (internal/photos/objects.go): не считать мусором объекты, на которые ссылаетсяuser_avatar_objects; проверить тестом, что привязанный объект аватара переживает сборку, а после снятия привязки освобождается. - 1.3 Расширить
ClaimGarbageв SQLite-сторе (internal/photos/sqlite_objects.go) тем же исключением; проверить аналогичным тестом на SQLite. - 1.4 Добавить методы стора для аватара (привязать/заменить/снять по ролям
avatar/avatar_small, получить текущие объекты) на обоих бэкендах; проверить контрактным тестом, покрывающим оба бэкенда.
2. Backend: нормализация и жизненный цикл объекта аватара
- 2.1 Реализовать нормализацию аватара: декодировать, отклонить не-изображение,
imaging.Fillв 512 и 128, перекодировать в WebP (снятие EXIF/GPS); проверить юнит-тестом на JPEG с EXIF/GPS — результат квадратный 512 и 128 без EXIF. - 2.2 Реализовать сервис установки/замены/удаления аватара через журнал объектов (pending → Put → ready → привязка, откат при ошибке); проверить тестом, что сбой не оставляет объектов, а успех привязывает обе роли.
- 2.3 Применить предел размера файла (10 MB) и отклонение не-изображений на границе сервиса; проверить тестами на превышение размера и на не-изображение.
3. Backend: API и отдача
- 3.1 Добавить хендлеры
POST /api/auth/me/avatar(multipartfile) иDELETE /api/auth/me/avatar, возвращающие обновлённый self-профиль; проверить тестами: без аутентификации — отказ, после загрузкиavatar_urlзадан, после удаления — пуст. - 3.2 Добавить отдачу
GET /api/avatars/:userID/:version(малая нарезка,?size=large— крупная) под авторизацией; проверить тестами: без аутентификации — отказ, версия меняется при замене, отсутствующий пользователь/аватар — корректная ошибка. - 3.3 Зарегистрировать маршруты в
internal/app/app.go; проверить тестом маршрутизации, что новые пути доступны и защищены middleware.
4. Аватар в представлениях пользователей
- 4.1 Убедиться, что
auth/me, участники, комментарии и автор фото отдают заполненныйavatar_url(запросы уже выбирают колонку) и чтоPublicUser/SelfUserсериализуют поле; проверить тестами: у пользователя с аватаромavatar_urlприсутствует, без аватара — пуст.
5. Веб-интерфейс
- 5.1 Добавить в
lib/api.tsметоды загрузки и удаления аватара и сохранятьavatar_urlв auth-стор; проверитьnpm run check(типы) без ошибок. - 5.2 Добавить иконку
personвlib/icons/registry.tsи компонент круглого аватара с заглушкой-силуэтом; проверить, что компонент показывает изображение при заданном URL и силуэт при пустом. - 5.3 На странице
routes/(app)/profileдобавить выбор файла, канвас-кроппер и кнопки загрузки/удаления; проверить вручную: загрузка меняет аватар, удаление возвращает заглушку. - 5.4 Показывать круглый аватар в
AppShell(шапка), у участников, вComments.svelteи у автора вPhotoPanel.svelte; проверить визуально, что заглушка и реальный аватар отображаются круглыми.
6. Android-клиент
- 6.1 Добавить в
ProfileApi/GaloApiзагрузку (multipart) и удаление аватара, аProfileViewModel—avatarUrlи действия; проверить юнит-тестами ViewModel (успех, ошибка, обновление состояния). - 6.2 На
ProfileScreenпоказать круглый аватар, выбор изображения и Compose-кроппер, кнопку удаления; проверить Compose-тестом и вручную, что аватар обновляется и сбрасывается. - 6.3 Показать круглый аватар в шапке
AlbumsScreen; проверить Compose-тестом, что при заданномavatarUrlрисуется изображение, иначе — силуэт.
7. Интеграция
- 7.1 Прогнать сквозной сценарий: загрузка аватара отражается в шапке, у участников и в комментариях; замена освобождает старый объект (проверить сборкой мусора); удаление возвращает заглушку — тест проходит на обоих бэкендах метаданных.
- 7.2 Обновить документацию проекта (README/project.md), где перечислены эндпоинты и схема; проверить, что новые маршруты и таблица упомянуты.
Workflow follow-up
- Архивировать изменение после прохождения ревью.
- Проверить результат в архивированных спеках
user-profileиmedia-objects.