Backend (Go/Gin/pgx): env config, pgx pool with retries, Garage S3 client (path-style, region garage), embedded golang-migrate migrations, JWT auth with refresh rotation, albums CRUD, members/roles/invites with no-escalation matrix, photo upload + async imaging/goexif WebP variants, cursor pagination, presigned URLs, likes/comments, SSE hub (album + personal), notifications, share links. Frontend (SvelteKit 2 + Svelte 5 + Tailwind v4): API wrapper with 401 refresh, auth store, all screens, Uploader/PhotoGrid/Lightbox/Comments, SSE client with reconnect + REST catch-up, three themes + system via data-theme. Deploy without Docker: Makefile builds the frontend into backend/static and embeds it (go:embed) into a single statically linked binary; systemd unit and nginx SSE example included. Use gen2brain/webp (-tags nodynamic) instead of cgo kolesa-team/go-webp to keep CGO_ENABLED=0 static builds; design.md/proposal.md updated accordingly.
7.5 KiB
7.5 KiB
Tasks
1. Скелет проекта и подключения
- 1.1 Создать структуру
backend/(cmd/server, internal/*) иfrontend/(SvelteKit 2 + Svelte 5 + adapter-static + Tailwind), Makefile,.env.example,deploy/shared-album.service; проверить наличие ожидаемых файлов и чтоmake frontendсобирает статику - 1.2 Реализовать
internal/config— чтение всех env (PG_, S3_, JWT_, HTTP_, SSE_*); проверить парсинг запуском бинарника с.env.example - 1.3 Подключение к
pg.localnetчерез pgx с ретраями; проверитьGET /api/healthвозвращает 200 при доступной БД - 1.4 Клиент S3 к Garage (AWS SDK v2,
region=garage,UsePathStyle=true, BaseEndpoint) и создание бакета при отсутствии; проверить health-check пингует S3
2. Миграции и репозитории
- 2.1 Добавить golang-migrate и миграции для таблиц: users, albums, album_members, invites, photos, comments, likes, notifications, share_links, refresh_tokens; проверить
make migrateприменяет схему к pg.localnet - 2.2 Реализовать базовые репозитории на pgx (users, albums); проверить юнит-тесты CRUD на тестовой БД
- 2.3 Репозитории album_members, invites, share_links, refresh_tokens; проверить тесты на инвайт-токены и роли
3. Аутентификация
- 3.1
POST /api/auth/registerи/loginс bcrypt и выдачей access (15 мин) + refresh (30 дней, хэш в refresh_tokens); проверить curl-сценарии регистрации/входа - 3.2
POST /api/auth/refreshс ротацией refresh-токена иPOST /api/auth/logoutс отзывом; проверить повторный refresh отозванным токеном возвращает 401 - 3.3 JWT-middleware для защиты эндпоинтов, кроме
/api/auth/*и share; проверить доступ без/с токеном
4. Альбомы и участники
- 4.1 CRUD альбомов (
GET/POST /api/albums,GET/PATCH/DELETE /api/albums/:id) с владельцем из owner_id; проверить сценарии создания и удаления альбома - 4.2 Инвайты (
POST /api/albums/:id/invites,POST /api/invites/:token/accept) с ролями и лимитом использований; проверить принятие и истечение инвайта - 4.3 Роли и права на уровне сервиса (матрица прав, правило «нет эскалации»,
PATCH/DELETE /api/albums/:id/members/:user_id); проверить отклонение эскалации прав тестами
5. Загрузка и просмотр фото
- 5.1 Загрузка фото в Garage (single + batch) со стримингом и генерацией thumb/preview/original; проверить загрузку одного и пачки файлов
- 5.2 Конвейер изображений: imaging (resize) + go-webp (WebP-энкод) + goexif (EXIF); проверить создание thumb 200px и preview 1200px с EXIF-полями
- 5.3 Листинг
GET /api/albums/:id/photos?cursor=&limit=иGET /api/photos/:idс presigned URL (1 час); проверить cursor-пагинацию и выдачу свежих URL - 5.4 Скачивание
GET /api/photos/:id/downloadи удалениеDELETE /api/photos/:id; проверить права на удаление (своё/чужое)
6. Лайки и комментарии
- 6.1 Лайки (
POST/DELETE /api/photos/:id/likes); проверить поставить/убрать лайк - 6.2 Комментарии (
GET/POST /api/photos/:id/comments,DELETE /api/comments/:id); проверить добавление, список и удаление комментария
7. SSE real-time
- 7.1 SSE-хаб на каналах (map по album_id, неблокирующая публикация, backpressure) и
GET /api/sse/albums/:id; проверить подключение и heartbeat 25 сек - 7.2 Публикация событий photo.created/photo.deleted/comment.created/like.added/like.removed/member.joined/member.left/album.updated из сервисов; проверить получение события при новом фото
- 7.3 Авторизация SSE через
?token=и проверка доступа к альбому; проверить отклонение подписки на чужой альбом
8. Уведомления
- 8.1 Создание уведомлений при комментариях/лайках/добавлении в альбом; проверить запись в таблицу notifications
- 8.2
GET /api/sse/me(персональный поток) и отметка уведомлений прочитанными; проверить получение персонального события и смену статуса read_at
9. Ссылки для просмотра
- 9.1 Создание/отзыв share-ссылок (
POST/DELETE /api/albums/:id/share) с expires_at и несколькими ссылками; проверить создание и точечный отзыв - 9.2 Публичные эндпоинты
/api/share/:token(просмотр, листинг, скачивание одиночного) без авторизации; проверить доступ по действующему и отклонение по истёкшему/отозванному токену
10. Frontend SvelteKit
- 10.1 API-обёртка (fetch) и auth-store с автообновлением при 401; проверить логин/регистрацию в браузере
- 10.2 Экраны: список альбомов, страница альбома, участники, настройки, принятие инвайта; проверить навигацию по альбомам
- 10.3 Uploader (drag&drop, прогресс), PhotoGrid (ленивая загрузка), Lightbox (свайпы); проверить загрузку и просмотр фото
- 10.4 SSE-клиент (EventSource + reconnect/backoff + догон по REST) и live-обновление сетки/комментариев; проверить live-появление фото
- 10.5 Три темы (light/dark/neutral) + system через data-theme, store на runes, ThemeSwitcher; проверить переключение без вспышки
11. Сборка и деплой
- 11.1 Сборка frontend в статику, копирование в
backend/static,go:embed, сборка одного бинарника (CGO_ENABLED=0); проверитьmake buildдаёт один артефакт - 11.2 systemd-юнит с EnvironmentFile и харденингом, пример nginx для SSE (
proxy_buffering off); проверить запуск бинарника и подключение к нему - 11.3 README с инструкцией сборки, деплоя и запуска через systemd; проверить команды из README выполняются