# 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-намёком только в пустом альбоме. Лимит — 100 МБ с понятной ошибкой при превышении. - **Переименование фото.** `PATCH /photos/:id` меняет `original_filename`; инлайн-редактор в правой панели, доступный автору фото и owner/admin. - **Метаданные фото (EXIF).** При загрузке система извлекает все распознаваемые EXIF-атрибуты (камера, объектив, экспозиция, ISO, дата съёмки, GPS и др.) и хранит их в `photos.exif`; они возвращаются вместе с фото и показываются в разделе «Информация». Для ранее загруженных фото есть команда бэкфилла метаданных из оригиналов. - **Просмотр.** Полноэкранный режим (кнопка и `f`) с автоскрытием верхней/нижней панелей и стрелок у кромок; зум колесом к указателю (без прокрутки, максимум 200%), `Space` возвращает из любого зума во вписанный вид, в зуме догружается оригинал изображения; удаление текущего фото с модальным подтверждением; возврат к обзору. - **Разделы и панели.** Правая панель — сворачиваемые разделы (состояние сохраняется), с разделом «Информация» (EXIF/метаданные); левая и правая панели ресайзятся перетаскиванием. Выбор фото в сетке показывается в панели (одиночный клик), двойной клик открывает просмотр. - **Настройки информации.** Раздел «Информация» получает кнопку-шестерёнку, открывающую модалку со списком EXIF-атрибутов: галочки видимости (с действиями «отметить все»/«снять все»), пользовательские подписи и сброс. Скрытые атрибуты сворачиваются под элементом «…» (клик раскрывает все). Настройки хранятся в профиле пользователя (server-side), применяются ко всем фото, а при отсутствии настроек показывается базовый набор; «Сбросить» удаляет настройки из профиля. - **Мультивыбор и операции.** Ctrl/Shift-выбор нескольких фото в сетке; в правой панели — раздел «Действия» с пунктами «Открыть (просмотр)», «Переместить», «Копировать», «Удалить»; перетаскивание выделенных фото на альбом в рейле открывает диалог перенос/копирование. Перенос и копирование меняют только метаданные (объекты S3 не трогаются). Любое удаление помещает фото в корзину; объекты S3 удаляются лишь когда на них нет ссылок в других альбомах. Корзина — последний элемент списка альбомов в левом рейле (иконка корзины); на обзоре убрана пустая правая панель. - **Счётчики.** В ответе альбома — число фото и участников. - **Темы и хром.** Существующие 4 темы сохраняются; `dark` — графит Lightroom и дефолт, `neutral` — тёплый графит; переключатель упорядочен тёмная → нейтральная → светлая → системная; добавляются токены `--chrome`/`--canvas`; скроллбары стилизованы в тон темы. Верхняя панель приложения и верхняя панель режима просмотра — компактные (минимум высоты). - **Адаптив.** На узких экранах рейл становится off-canvas drawer, правая панель — bottom-sheet, filmstrip — горизонтальным скроллом. ## Capabilities ### New Capabilities - `ui-workspace`: рабочий стол приложения — шелл, рейл альбомов, контекстная панель, режим просмотра как маршрут, адаптивное поведение и тёмный хром. ### Modified Capabilities - `albums`: отображение обложки, счётчики фото/участников и явный выбор обложки. - `photos`: автообложка только при отсутствии выбора; переименование фото; лимит размера загрузки; извлечение и хранение EXIF-метаданных; перенос/копирование и корзина. - `auth`: хранение пользовательских настроек отображения информации в профиле. ## Impact - **Backend:** миграция FK `albums.cover_photo_id -> photos(id) ON DELETE SET NULL`; `internal/albums/store.go` (LEFT JOIN `photos` → `cover_thumb_key` и счётчики `photos_count`/`members_count` в `ListForUser`/`GetByID`); `internal/albums/service.go` (presign → `CoverThumbURL`, обогащение списка); `internal/models` (`Album.CoverThumbURL`, `PhotosCount`, `MembersCount`); `internal/photos` (автообложка только при `cover_photo_id IS NULL`; `PATCH /photos/:id` для переименования; лимит загрузки 100 МБ с `413 file_too_large`; событие `photo.updated`; извлечение EXIF через `github.com/dsoprea/go-exif/v3` в `photos.exif`, миграция `000003_photo_exif`, команда `cmd/backfill-exif` и `storage.Get`); миграция `users.preferences`, `models.User.Preferences`, `internal/auth` (`Me` отдаёт настройки, `PATCH /auth/me/preferences` с валидацией). - **Frontend:** реструктуризация `+layout.svelte` в группы `(app)`/`(public)`, `AppShell` с ресайзом панелей и кнопкой полного экрана; компоненты рейла, контекстной панели со сворачиваемыми разделами и EXIF, модалки создания/пикера обложки/подтверждения, `Viewer` с полноэкранным режимом и зумом, общий стор альбомов, контрол плотности; новый маршрут `albums/[id]/photos/[photoId]`; слот действий в `PanelSection`, модалка настроек атрибутов с пользовательскими подписями, стор настроек, фильтрация и «…» в панели; новые значения токенов темы и стили скроллбаров; `types.ts` (+`cover_thumb_url`, счётчики, `photos_count`, `preferences`); новые иконки в реестре. - **Спеки:** `ui-workspace` (новая), `albums`, `photos`, `auth` (дельты). `ui-iconography` не затрагивается — иконки по-прежнему наследуют цвет темы. - **Совместимость:** API-контракты сохраняются; добавляется поле ответа и один FK. Ломающих изменений API нет.