feat: implement shared-album multi-user photo album
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.
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
# Proposal
|
||||
|
||||
## Why
|
||||
|
||||
Фото участников разбросаны по мессенджерам и галереям — теряется авторство, контекст
|
||||
и разграничение прав. Нужно единое многопользовательское пространство (семьи и друзья,
|
||||
рабочие команды, фотограф ↔ клиент) с понятными ролями, live-обновлениями и self-hosted
|
||||
хранением поверх уже существующих Garage (S3) и PostgreSQL, без контейнеров.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Новый backend на Go 1.22+ (Gin, pgx, AWS SDK v2, нативный SSE) — один статичный
|
||||
бинарник (`CGO_ENABLED=0`) со вшитой статикой SvelteKit через `go:embed`.
|
||||
- Новый frontend на SvelteKit 2 + Svelte 5 (adapter-static, TypeScript, TailwindCSS).
|
||||
- Аутентификация: регистрация, вход, JWT (access 15 мин + refresh 30 дней), logout.
|
||||
- Альбомы: создание / редактирование / удаление / список, владение альбомом.
|
||||
- Участники и роли: инвайт по токену, роли `admin` / `editor` / `member` / `viewer`,
|
||||
владелец выводится из `albums.owner_id`, правило «нет эскалации прав».
|
||||
- Фото: загрузка (одиночно и массово), три варианта (thumb 200px / preview 1200px /
|
||||
original), WebP-превью, EXIF, cursor-пагинация, просмотр, скачивание одиночного фото.
|
||||
- Социальное: лайки и комментарии к фото.
|
||||
- Real-time через SSE: события фото / комментариев / лайков / участников.
|
||||
- Уведомления: персональный поток в приложении (in-app через SSE).
|
||||
- Ссылки для просмотра: view-only доступ к альбому без аккаунта (несколько ссылок,
|
||||
срок действия, отзыв).
|
||||
- Деплой без Docker: systemd-юнит, статика вшита в бинарник, один артефакт.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `auth`: регистрация и вход по email/паролю, JWT-токены, refresh, logout.
|
||||
- `albums`: жизненный цикл альбома (создание, просмотр, редактирование, удаление,
|
||||
список) и владение им.
|
||||
- `members`: состав альбома, роли и права доступа, инвайт по токену, смена ролей.
|
||||
- `photos`: загрузка и хранение фото в S3, генерация вариантов и EXIF, листинг с
|
||||
пагинацией, просмотр, скачивание одиночного фото.
|
||||
- `social`: лайки и комментарии к фотографиям.
|
||||
- `realtime`: поток событий альбома через SSE (фото, комментарии, лайки, участники).
|
||||
- `notifications`: персональные уведомления пользователя и их статус прочитано.
|
||||
- `share-links`: view-only доступ к альбому по ссылке без авторизации.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
_Нет — проект новый, существующих спец нет._
|
||||
|
||||
## Impact
|
||||
|
||||
- **Код:** новый `backend/` (Go) и `frontend/` (SvelteKit), `deploy/` (systemd, nginx),
|
||||
`Makefile`, `.env.example`.
|
||||
- **Зависимости:** `gin`, `pgx`, `aws-sdk-go-v2`, `golang-migrate`, `imaging`,
|
||||
`gen2brain/webp` (чистый Go), `rwcarlsen/goexif`, `golang-jwt`, `bcrypt`.
|
||||
- **Системы:** подключение к существующим `pg.localnet:5432` (PostgreSQL) и
|
||||
Garage на `s3.localnet` (path-style, регион `garage`, ключ `GK...`).
|
||||
- **Права:** все эндпоинты за JWT, кроме `/api/auth/*` и публичных share-эндпоинтов;
|
||||
проверка прав на уровне сервиса, не только UI.
|
||||
- **Не входит в MVP (осознанно отложено):** web push (браузерные push-уведомления),
|
||||
распознавание лиц/ML-теги, мобильные приложения, биллинг, публичный API, печать.
|
||||
Reference in New Issue
Block a user