-
0.1-alpha Pre-Release
released this
2026-10-21 18:29:36 +00:00 | 14 commits to develop since this releaseОписание релиза Galo — 21 октября 2026
База релиза:
main(84ce4d1, 10 октября 2026) →develop(afe85f7, 21 октября 2026)
Объём: 138 коммитов, 4 спецификации обновлены, 1 изменение реализовано
Коротко о главном
- Локальный режим без внешних сервисов. Слой метаданных переключается на
встроенный SQLite, хранилище блобов — на локальную файловую систему. По умолчанию
приложение работает полностью на одной машине: без Postgres и без S3. - Редактирование фотографий в браузере. Вкладка «Редактирование» с инструментом
«Свет»: экспозиция, контраст, света, тени, белые и чёрные, тональная кривая по
каналам с живой гистограммой. Правки видны сразу, без ожидания сервера. - Новый интерфейс рабочего пространства. Альбомы с обложками, тёмная, светлая и
нейтральная темы, единая система векторных иконок, гало-эмблема и фавикон. - Нативный Android-клиент. Отдельное приложение: просмотр альбомов, загрузка с
устройства, двусторонняя синхронизация с сервером, безопасная разгрузка превью. - Видео и офлайн. Видео в общих альбомах с фоновой подготовкой и перемоткой;
офлайн-кеш оболочки, списков и превью.
Новые возможности
Локальный режим: SQLite и файловая система
- Слой метаданных выбирается конфигурацией: внешний PostgreSQL или встроенный
SQLite с тем же поведением для одного экземпляра приложения. - Хранилище блобов выбирается отдельно: S3-совместимое (Garage) или локальная
файловая система. Клиент никогда не видит хранилище — блобы всегда отдаются через
бэкенд по подписанному URL. - По умолчанию (
DB_BACKEND=sqlite,STORAGE_BACKEND=fs) приложение поднимается без
Postgres и S3: данные лежат вgalo.dbи каталогеdata/. - Секрет подписи JWT и URL объектов генерируются при первом старте и хранятся в
слое метаданных — переживают перезапуск и рестарт SQLite. - Реконсиляция хранилища с журналом объектов:
make reconcile(отчёт),
make reconcile-delete(удаление осиротевших блобов). Сборку мусора ведёт журнал,
хранилище не сканируется.
Слой объектов
- Физическое объектное хранилище с непрозрачными ключами: идентификаторы альбомов и
фото в ключах не участвуют, сопоставление живёт только в метаданных. - Журнал объектов: у каждого объекта ровно одна запись с ключом, MIME-типом,
размером, габаритами и состоянием; фото ссылается на объекты по ролям
(original,thumb,medium,preview,playback,edit,edit_thumb,
edit_medium,edit_preview). - Один физический объект может разделяться несколькими фото: перенос и копирование
меняют только ссылки, хранилище не трогается. - Сборка мусора по ссылкам: объект удаляется, когда на него не ссылается ни одно фото
и ни один аватар.
Редактирование фотографий
- Вкладка «Редактирование» в правой панели фото, инструмент «Свет»: экспозиция,
контраст, света, тени, белые, чёрные. - Тональная кривая: выбор канала (R/G/B/мастер), точки добавляются кликом по
полю графика, перетаскиваются и двигаются стрелками с клавиатуры. - Гистограмма каналов пересчитывается на лету с учётом текущих правок.
- Блок «Кривая» сворачивается (по умолчанию свёрнут), кнопки выбора канала остаются
доступными. - Предпросмотр правок рисуется в браузере — WASM-модулем на Rust, с резервной
JS-реализацией, если модуль недоступен или считает иначе. - Правки применяются сразу; на сервер уходят через 10 секунд без изменений или при
переключении фото. Сервер рендерит отредактированную версию в фоне отдельной
очередью и сообщает о готовности. - Переключатель «Сброс» удаляет и параметры правок, и отредактированную версию.
- Редактирование неразрушающее: оригинал остаётся неизменным, скачивание отдаёт
исходник. Рендер идёт по исходному объекту, а не по уменьшенной копии.
Интерфейс рабочего пространства
- Альбомы с обложками, «лайтрумовская» компоновка: рельс альбомов, сетка, единая
панель фотографии. - Три темы — тёмная, светлая, нейтральная — с семантическими токенами; переключатель
тем переехал в шапку, нейтральная тема затемнена. - Единая система иконок: встроенная векторная графика (Material Symbols) вместо
эмодзи и символов системного шрифта — иконки наследуют цвет темы и не тянут
внешние ресурсы. - Гало-эмблема (диск солнца в отделённом кольце) и фирменный фавикон: отдаются
самим приложением, наследуют тему, читаются в размере 16–24 px. - Панель сведений о фото со сворачиваемыми секциями и настраиваемым набором
атрибутов: состав EXIF хранится в профиле пользователя. - Полноэкранный просмотр: своя панель, кнопка «на весь экран», возврат по
Esc.
Просмотр и навигация
- Зум колесом мыши (с привязкой к курсору, до 200%), клавишами
+и-;
Spaceвозвращает во вписанный вид, а из вписанного — в 100% от оригинала по
центру кадра. - В зуме стрелки клавиатуры панорамируют фото, переключение соседних снимков
остаётся за мышью и кнопками у краёв. - Скрытие боковых панелей альбома: кнопка в панели сетки и хоткей
Tab. Панели
уезжают за края, содержимое занимает всю ширину, панели возвращаются при наведении
на кромку окна. Размер миниатюр при этом сохраняется — в строке помещается больше
фото. - Лента миниатюр в просмотре следует за текущим фото; на превью работает наведение-
зум. - Полноэкранный режим приложения по
Ctrl+F, навигация с клавиатуры в сетке с
возвратом фокуса, открытие фото тапом на тач-экранах. - Просмотр 360-панорам по тегу
pano360, корректное направление перетаскивания. - Пока грузится оригинал для зума — спиннер; на Android — щипок-зум.
Работа с фотографиями
- Мультивыбор в сетке, контекстные меню, перенос и копирование снимков, корзина
на уровне альбома и общие счётчики. - Теги фото: правки расходятся по сетке и просмотру.
- Переименование фото и удаление из просмотра с подтверждением.
- EXIF извлекается полностью при загрузке; для старых снимков — дозаполнение
(cmd/backfill-exif).
Офлайн-режим
- Service worker кеширует оболочку приложения, списки и эскизы/превью фотографий:
открытые альбомы и ранее загруженные снимки доступны без сети. - Модуль фильтров в офлайне не кешируется — он всегда подтягивается свежим.
Видео
- Загрузка видео в те же альбомы, что и фото (
kind=video). - Фоновая подготовка: постер (кадр кадра → обычные варианты сетки) и web-совместимый
вариант для воспроизведения (ремукс без перекодирования либо транскод в
h264/yuv420p/aac с+faststart), с поддержкой перемотки (Range). - Транскод идёт в отдельном малом пуле и не вытесняет генерацию вариантов
изображений; готовность транслируется подписчикам альбома. - Без
ffmpeg/ffprobeприём видео отклоняется,/api/healthсообщает
"video": "unavailable", изображения работают как прежде.
Android-клиент
- Отдельный Gradle-модуль, работает с существующим HTTP API, сервер и веб не
трогает. Kotlin + Jetpack Compose,minSdk 28,targetSdk 35. - Двусторонняя синхронизация альбома устройства с серверным альбомом: загрузки,
изменения состава, удаления. - Безопасная разгрузка: с устройства уходит превью, оригинал остаётся на сервере;
потеря серверной копии распознаётся и показывается в интерфейсе. - Статус синхронизации на карточке альбома, ход восстановления оригиналов,
сортировка списка, обновление списка альбомов в реальном времени. - Установка на устройство одной командой:
make install-android-app(с выбором
серийного номера при нескольких подключённых устройствах).
Профиль и учётная запись
- Профиль пользователя: круглый аватар с загрузкой и кадрированием, публичная отдача
аватара по версионированной ссылке. - Вход и регистрация по телефону (E.164) в дополнение к email, управление
идентификаторами, удаление аккаунта. - Предпочтения пользователя (в том числе состав панели сведений) хранятся на сервере.
Альбомы и живое обновление
- Обложки альбомов: отдельный жизненный цикл, обложка доводится до готовности и
доставляется подписчикам. - Живое обновление: события жизненного цикла альбома и изменения состава фото через
SSE, подписчики видят изменения без перезагрузки. - Квадратный вариант
medium— резкие миниатюры в сетке; шаг переключения размера
миниатюр и направление ползунка приведены в порядок. - Быстрая загрузка больших альбомов.
Наблюдаемость и эксплуатация
- Настраиваемое логирование:
LOG_LEVEL(debugвключает access-логи и ожидаемые
4xx),LOG_FORMAT(json/text), request id в ответах и логах. scripts/seed.pyиmake testdata— наполнение запущенного инстанса тестовыми
данными через публичный API.- Release-сборка:
make build-release— статичный бинарник с вшитой версией и
UPX-сжатием, если он установлен.
Исправления
- Копия фото больше не наследует отредактированную версию. Раньше копирование
переносило все привязки объектов, включаяedit*: копия показывала
отредактированную картинку, но не наследовала параметры правок, и первая же новая
правка перезаписывала обработку с нуля. Теперь правка принадлежит своему фото, а
копия показывает исходник. Разовая миграция убирает привязки у копий, созданных до
фикса. - Предпросмотр правок работает и без зума, а не только в увеличенном виде.
- Устранено искажение цветов в предпросмотре (WASM-фильтры считались по
преобразованным каналам). - Гистограмма пересчитывается при правке, а не остаётся от исходного снимка.
- Линия тональной кривой видима в тёмной теме.
- Починен зум в просмотре: контейнер прокрутки и центрирование.
- Android: разгруженное превью больше не считается новой версией элемента.
- Сервер отдаёт контрольную сумму оригинала в ответе на загрузку — клиент может
сверить файл. - Счётчик корзины и правки тегов синхронизируются с сеткой и просмотром.
- Ошибка загрузки крупного файла показывается явно, лимит поднят.
make runпересобирает фронтенд, если он изменился.
Технические изменения
API
Новые эндпоинты:
PATCH /api/photos/:id/edit— сохранить параметры правок (тело:{"light": {...}}).DELETE /api/photos/:id/edit— сбросить правки вместе с отредактированной
версией.GET|PATCH|DELETE /api/auth/me,POST /api/auth/me/password,
POST /api/auth/me/identifiers,PATCH /api/auth/me/preferences,
POST|DELETE /api/auth/me/avatar,GET /api/avatars/:userID/:version?size=large.POST /api/photo-batch/copy,POST /api/photo-batch/move— пакетные операции над
снимками.
Изменившиеся ответы: у фото появились поля
edit_params,edit_url,
edit_thumb_url,edit_medium_url,edit_preview_url; у видео —playback_url.Схема данных и миграции
- Postgres: миграции до
000016; SQLite: до000008(нумерация диалектов
независимая, миграции вшиты в бинарник и применяются автоматически при старте;
make migrateприменяет только Postgres). - Новые роли объектов
edit,edit_thumb,edit_medium,edit_preview— рядом с
обычнымиoriginal,thumb,medium,preview,playback. - Новая колонка
photos.edit_params— параметры неразрушающих правок.
Сборка
- Фильтры правок считает WASM-модуль из
frontend/wasm/light(Rust,no_std).
Пересборка нужна только при правке самого модуля; в репозитории лежит готовый
light.wasm, поэтому фронтенд собирается без Rust-инструментов. npm run wasm— отдельная пересборка модуля; обычная сборка фронтенда обновляет
его сама.
Как обновиться
- Собрать бинарник:
make build(фронтенд →backend/static→go:embed→bin/galo)
илиmake build-release— с вшитой версией. - Остановить сервис, заменить бинарник. Фронтенк вшит в бинарник, отдельно
выкладывать нечего. - Запустить: миграции применятся автоматически при старте для выбранного бэкенда.
Для Postgres можно отдельно прогнатьmake migrate. - Для видео нужен
ffmpeg/ffprobeна хосте; без них приём видео отключается. - Android-клиент ставится отдельно:
make install-android-app.
Откат: бинарник возвращается предыдущей версии; миграции
downне восстанавливают
удалённые привязки копий — это безопасно, отредактированные версии исходных фото
остаются на месте.
Ограничения
- Редактирование — только для изображений; видео не редактируется.
- Правки не порождают отдельной записи в истории: параметры хранятся в метаданных
фото, отредактированная версия — как отдельный объект. - Офлайн-кеш ограничен оболочкой, списками и эскизами/превью: оригиналы для зума и
скачивания требуют сети. - Android-клиент требует JDK 17 и Android SDK (
platforms;android-35,
build-tools;35.0.0). - Номер версии берётся из
git describe --tags; в репозитории пока нет тегов, поэтому
версия в сборке — короткий SHA илиdev. Для осмысленной нумерации нужен тег.
Для разработчиков
- Спецификации OpenSpec синхронизированы с поведением: обновлены
ui-workspace
(редактирование, кривая, зум и навигация),media-objects(ролиedit*, раздельное
владение правками, отдельная очередь рендера),photos(рендер по оригиналу),
dev-make-workflow(сборка WASM-модуля). - Изменение
fix-copy-edit-variant-sharingреализовано (9/9 задач) и ждёт ревью и
архивации:openspec listпоказывает его какcomplete. - Контрактные тесты репозиториев (
internal/repo/contract) гоняют один набор
проверок на SQLite и Postgres — новый кейсCloneпроверяет, что копия не
наследует отредактированную версию, в обоих хранилищах. - Интеграционные тесты Postgres требуют
TEST_DATABASE_URL; без них они
пропускаются. Тесты e2e поднимают SQLite вt.TempDir()и внешних сервисов не
требуют. - Сервис переименован в
galo, бренд — «гало»; сборкаmake build-releaseпишет
bin/galo-$(VERSION).
Downloads
- Локальный режим без внешних сервисов. Слой метаданных переключается на