Files
ds-galo/openspec/changes/shared-album/specs/photos/spec.md
T
iu 2b2b342492 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.
2026-10-10 12:50:33 +03:00

3.3 KiB

Spec Delta

Purpose

Загрузка, хранение в S3 и просмотр фотографий с генерацией вариантов и извлечением EXIF.

ADDED Requirements

Requirement: Загрузка фото

Пользователь с правом загрузки SHALL иметь возможность загружать фото по одному и массово.

Scenario: Успешная загрузка

  • WHEN участник с правом загрузки отправляет файл изображения
  • THEN система сохраняет оригинал и создаёт запись фото с метаданными

Scenario: Загрузка без права

  • WHEN наблюдатель пытается загрузить фото
  • THEN система отклоняет запрос

Requirement: Варианты изображений

Система SHALL генерировать три варианта: thumb (200px), preview (1200px) и оригинал, с WebP для превью, и извлекать EXIF (дата, координаты, размеры).

Scenario: Генерация вариантов

  • WHEN фото загружено
  • THEN система асинхронно генерирует thumb и preview и заполняет EXIF-поля

Requirement: Листинг фото с пагинацией

Система SHALL возвращать фото альбома с cursor-пагинацией.

Scenario: Пагинация по курсору

  • WHEN клиент запрашивает список с курсором и лимитом
  • THEN система возвращает не более лимита фото и курсор следующей страницы

Requirement: Получение фото по требованию

Клиент SHALL иметь возможность получить актуальные данные фото с presigned URL.

Scenario: Выдача свежего URL

  • WHEN клиент запрашивает фото по id
  • THEN система возвращает свежий presigned URL (срок до 1 часа) для просмотра

Requirement: Скачивание одиночного фото

Любой участник, включая viewer, SHALL иметь возможность скачать одиночное фото.

Scenario: Скачивание фото

  • WHEN участник запрашивает скачивание фото
  • THEN система возвращает presigned URL оригинала

Requirement: Удаление фото

Автор SHALL иметь возможность удалить своё фото; владелец и админ SHALL иметь возможность удалить любое фото.

Scenario: Удаление своего фото

  • WHEN автор удаляет своё фото
  • THEN система удаляет запись и файлы в S3

Scenario: Удаление чужого фото участником

  • WHEN участник с ролью member пытается удалить чужое фото
  • THEN система отклоняет запрос