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)
This commit is contained in:
iu
2026-10-10 18:15:13 +03:00
parent b90e6b0267
commit 304cfedb75
47 changed files with 1942 additions and 601 deletions
@@ -0,0 +1,31 @@
# Spec Delta
## ADDED Requirements
### Requirement: Отображение обложки альбома
Данные альбома SHALL включать URL миниатюры обложки, когда обложка задана, чтобы клиенты
могли показать её в списке, рейле и карточке.
#### Scenario: Обложка задана
- **WHEN** клиент запрашивает список альбомов или альбом по id, и у альбома есть обложка
- **THEN** ответ содержит URL миниатюры обложки
#### Scenario: Обложка отсутствует
- **WHEN** у альбома нет обложки или фото обложки удалено
- **THEN** ответ не содержит URL обложки, и клиент показывает плейсхолдер
### Requirement: Выбор обложки
Владелец и админ SHALL иметь возможность назначить обложкой любое фото альбома или сбросить
обложку; после сброса обложка определяется заново по умолчанию.
#### Scenario: Назначение обложки
- **WHEN** владелец выбирает фото альбома как обложку
- **THEN** система сохраняет выбор и отражает его в списке и карточках
#### Scenario: Сброс обложки
- **WHEN** админ сбрасывает обложку
- **THEN** система удаляет явный выбор, и обложка возвращается к значению по умолчанию
#### Scenario: Нет прав на смену обложки
- **WHEN** участник без права редактирования пытается сменить обложку
- **THEN** система отклоняет запрос