Clone переносил все привязки photo_objects, включая роли edit*, хотя
правка принадлежит фото, чьи правки её породили. Теперь копия делит
только обычные варианты и показывается в исходном виде.
- EditRoles() и IsEditRole() в edit_render.go — единый список ролей;
- фильтр edit-ролей в Store.Clone и SQLiteStore.Clone;
- миграции 000016 (Postgres) и 000008 (SQLite) убирают привязки у
копий, созданных до фикса;
- контрактная проверка копирования, сервисные и e2e-тесты.
В правой панели фото появилась вкладка «Редактирование» с инструментом «Свет»:
ползунки экспозиции, контраста, светов, теней, белых и чёрных и точечная кривая
с выбором канала. Правки сохраняются автоматически, переключатель «Сброс»
удаляет параметры правок и отредактированную версию фото.
Редактирование неразрушающее: параметры хранятся в метаданных фото, а
отредактированная версия рендерится в фоне отдельным объектом (edit, edit_thumb,
edit_medium, edit_preview) рядом с исходными вариантами. Оригинал не меняется,
скачивание отдаёт исходный файл. Сетка, просмотр и обложки альбомов показывают
отредактированную версию, когда она отрендерена.
Add video as a media kind in photos: streaming upload with per-kind
limits, ffprobe metadata, poster frame reusing the image variant
pipeline, and a playback object (remux when web-compatible, else
h264/yuv420p/aac transcode). Video jobs run on a separate pool with a
long lease. Frontend gains a video viewer, grid badge/duration and
video upload.
- app_settings table (PostgreSQL migration 000010, SQLite 000002)
- internal/settings repository (Get/Set/Ensure) wired into store.Repos
- secret generated with crypto/rand on first start and persisted; reused on restart
- drop required JWT_SECRET from env/config; app.New takes a TokenManager and
storage.Open takes the resolved secret (URL_SECRET still overrides)
- docs updated