Files
ds-galo/openspec/changes/lightroom-workspace-ui/proposal.md
T
iu 304cfedb75 feat: lightroom-style workspace UI with album covers
Backend:
- expose cover thumbnail URL on album responses (LEFT JOIN + presign)
- auto-assign cover only when empty; FK cover_photo_id -> photos ON DELETE SET NULL
- add photos_count / members_count to album responses; cover repo test

Frontend:
- split layouts into (app) shell (resizable rail + contextual panel) and (public)
- album rail + create-album dialog; album panel with cover picker / make-cover
- photo viewer route with filmstrip, replacing lightbox; share reuses it
- grid density slider, toolbar + drag-and-drop upload, dark graphite default

OpenSpec: add lightroom-workspace-ui change (proposal, design, specs, tasks)
2026-10-10 18:15:13 +03:00

5.2 KiB

Proposal

Why

Сейчас интерфейс — это центрированный «маркетинговый» лейаут: список альбомов с инлайн-формой создания, серая заглушка вместо обложек, отдельные страницы «Участники» и «Настройки», лайтбокс-оверлей. Обложки в бэкенде уже есть (albums.cover_photo_id, PATCH /albums/:id), но до UI не доходят. Пользователь хочет полноценный «рабочий стол» в духе Adobe Lightroom: постоянный рейл альбомов, контекстная панель, плотная сетка, режим просмотра как часть рабочего стола, обложки с явным выбором и единый тёмный графитовый хром.

What Changes

  • Рабочий стол (шелл). Группа (app) с постоянным левым рейлом альбомов, топбаром и контекстной правой панелью. Публичные маршруты (/login, /invites/[token], /share/[token]) остаются вне шелла, но в тех же токенах.
  • Создание альбома. Инлайн-форма заменяется иконочной кнопкой с хинтом, открывающей модалку ввода названия.
  • Обложки. Album получает cover_thumb_url; карточки и рейл показывают реальную миниатюру. Выбор обложки: пикер в правой панели и действие «сделать обложкой» в просмотре. Автообложка пишется только когда обложка ещё не задана; FK albums.cover_photo_id -> photos(id) ON DELETE SET NULL чинит висячие ссылки.
  • Просмотр как маршрут. Lightbox-оверлей заменяется маршрутом /albums/:id/photos/:photoId внутри шелла: крупное фото, filmstrip снизу, панель метаданных/комментариев. share/[token] переиспользует тот же компонент.
  • Плотность сетки. Слайдер размера миниатюр в тулбаре (состояние в localStorage). Мультивыбор и массовые действия — вне объёма.
  • Загрузка. Крупный dropzone заменяется кнопкой в тулбаре, полноэкранным drag-overlay и dropzone-намёком только в пустом альбоме.
  • Тёмная тема. Существующие 4 темы сохраняются; dark переодевается в графит Lightroom и становится дефолтом; добавляются токены --chrome и --canvas.
  • Адаптив. На узких экранах рейл становится off-canvas drawer, правая панель — bottom-sheet, filmstrip — горизонтальным скроллом.

Capabilities

New Capabilities

  • ui-workspace: рабочий стол приложения — шелл, рейл альбомов, контекстная панель, режим просмотра как маршрут, адаптивное поведение и тёмный хром.

Modified Capabilities

  • albums: отображение обложки в списке/карточках и явный выбор обложки; поведение обложки при отсутствии выбора.
  • photos: автоустановка обложки первым загруженным фото выполняется только если обложка ещё не задана.

Impact

  • Backend: миграция FK albums.cover_photo_id -> photos(id) ON DELETE SET NULL; internal/albums/store.go (LEFT JOIN photos → cover_thumb_key в ListForUser и GetByID); internal/albums/service.go (presign → CoverThumbURL, обогащение списка); internal/models (Album.CoverThumbURL); internal/photos/service.go (SetCover только при cover_photo_id IS NULL).
  • Frontend: реструктуризация +layout.svelte в группы (app)/(public); новые компоненты шелла, рейла, панели, модалки создания, пикера обложки, filmstrip и просмотра; новый маршрут albums/[id]/photos/[photoId]; новые значения токенов темы; types.ts (+cover_thumb_url); новые иконки в реестре.
  • Спеки: ui-workspace (новая), albums, photos (дельты). ui-iconography не затрагивается — иконки по-прежнему наследуют цвет темы.
  • Совместимость: API-контракты сохраняются; добавляется поле ответа и один FK. Ломающих изменений API нет.