chore(openspec): архивировать photo-color-editing и обновить photos
Дельта-спека, дизайн, предложение и задачи приведены к фактической реализации: WebGL2-предпросмотр, пипетка баланса белого, цветокоррекция по зонам. Изменение применено к основной спеке photos и перемещено в archive.
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
# Design
|
||||
|
||||
## Context
|
||||
|
||||
Неразрушающее редактирование фото уже работает: параметры хранятся в
|
||||
`photo.edit_params` (`map[string]any` JSON-блоб), сервер рендерит копию в роли
|
||||
`edit`, `edit_thumb`, `edit_medium`, `edit_preview`, оригинал не меняется.
|
||||
Исторически поддерживался только блок «Свет» (`LightParams`), живой превью шёл
|
||||
через WASM (`frontend/wasm/light/`). Теперь добавлен блок «Цвет» и GPU-превью:
|
||||
основной live-предпросмотр считает WebGL2, а CPU-путь (TypeScript/WASM) остаётся
|
||||
фолбэком и эталоном паритета. Хранение в JSON-блобе миграции не требует: фото без
|
||||
ключа `color` рендерятся как прежде.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Добавить «Цвет»: баланс белого (температура/оттенок + пипетка), сочность
|
||||
(vibrance), насыщенность, цветовой микшер по оттенкам, цветокоррекция
|
||||
(тени/средние тона/света + яркость зон, наложение, баланс), поканальная
|
||||
коррекция.
|
||||
- Показывать правки в просмотрщике сразу, не дожидаясь серверного рендера.
|
||||
- Сохранить неразрушающий серверный рендер как источник истины и обратную
|
||||
совместимость со старыми `edit_params`.
|
||||
|
||||
**Non-Goals:**
|
||||
- Синхронизация правок между устройствами и Android-клиент.
|
||||
- Изменение ролей хранения или формата объектов.
|
||||
- Миграция схемы базы данных.
|
||||
|
||||
## Decisions
|
||||
|
||||
**Цвет хранится в том же `edit_params`, рядом с `light`.**
|
||||
- Обоснование: `EditParams` расширяется полем `Color ColorParams`; JSON-блоб и
|
||||
клиентская модель принимают новый ключ без схемных изменений.
|
||||
- Альтернатива: отдельная колонка/таблица — отвергнута, потребовала бы миграцию.
|
||||
|
||||
**Порядок операций: свет, затем цвет.**
|
||||
- Обоснование: цветовые коррекции логично применять к уже скорректированной по
|
||||
тональности картинке; сервер и клиент следуют одному порядку.
|
||||
- Альтернатива: цвет до света — отвергнуто, расходится с поведением Lightroom и
|
||||
текущим конвейером.
|
||||
|
||||
**Живой предпросмотр считается на GPU (WebGL2), CPU/WASM — фолбэк.**
|
||||
- Обоснование: попиксельный CPU-фильтр на полном viewport блокировал main thread
|
||||
(замеры: десятки мс на кадр). Шейдер повторяет свет/цвет и считает кадр на
|
||||
видеокарте; текстура источника загружается один раз на смену изображения.
|
||||
- Фолбэк: если WebGL2 недоступен или шейдер не собрался, используется прежний
|
||||
CPU-путь (WASM, затем JS) с адаптивным буфером. Это медленнее, но сохраняет
|
||||
функциональность.
|
||||
- Альтернатива: вынести CPU-фильтр в Web Worker/OffscreenCanvas — отвергнуто как
|
||||
более сложное при уже готовом GPU-пути.
|
||||
|
||||
**Паритет реализаций ограничен явно.**
|
||||
- Go (сервер) — источник истины для сохранённого фото; покрыт Go-тестами.
|
||||
- TypeScript и Rust/WASM — эталонная пара для CPU-фолбэка; паритет проверяется
|
||||
`wasmMatchesReference` на пробе и больших градиентах.
|
||||
- GLSL/WebGL2 — быстрый предпросмотр; проверяется компиляцией/линковкой шейдера,
|
||||
пиксельный паритет с сервером не гарантируется. Финальное качество даёт сервер.
|
||||
|
||||
**Тональные зоны и быстрый путь.**
|
||||
- Веса зон: тени `(1-l)^4`, света `l^4`, средние тона — остаток; это не даёт
|
||||
колесу теней заметно задевать средние тона и уменьшает резкую границу на
|
||||
контрастных снимках.
|
||||
- `blending` по умолчанию 50 (диапазон 0..100), `balance` — -100..100.
|
||||
- Яркость зон применяется аддитивным сдвигом, без деления на пиксель.
|
||||
- Если микшер и насыщенность/вибрация не задействованы, цвет считается быстрым
|
||||
путём без RGB→HSL→RGB; иначе — полный HSL-путь.
|
||||
|
||||
**Пустота цветовых правок.**
|
||||
- Наложение/баланс и оттенок колеса без силы и яркости не считаются правкой:
|
||||
фото не получает цветовую версию, сброс остаётся доступным по другим полям.
|
||||
|
||||
**Пипетка баланса белого.**
|
||||
- Клиент сэмплирует пиксель из исходного (неотредактированного) превью и решает
|
||||
обратную задачу баланса белого: подбирает температуру/оттенок, при которых
|
||||
точка становится нейтральной. Пресет переходит в «Пользовательский».
|
||||
|
||||
**Поканальная коррекция — в модели и рендере, но не в UI.**
|
||||
- `ColorCorrection` (red/green/blue) принимается API и учитывается рендером, но в
|
||||
панели не выведена: в макете «Цветокоррекция» — это колёса тональных зон.
|
||||
|
||||
**UI.**
|
||||
- Раздел «Цвет»: баланс белого с пресетами и пипеткой, сочность/насыщенность,
|
||||
микшер (8 оттенков × тон/насыщенность/яркость), цветокоррекция (3 колеса,
|
||||
яркость зон, наложение, баланс).
|
||||
- Слайдеры с градиентными дорожками, цветовые колёса, двойной клик по контролу
|
||||
сбрасывает значение.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
[WebGL2 недоступен] → фолбэк на CPU/WASM с адаптивным буфером; функциональность
|
||||
сохраняется, скорость ниже.
|
||||
|
||||
[Расхождение шейдера и сервера] → серверный рендер остаётся источником истины;
|
||||
шейдер проходит проверку компиляции, а CPU-пара JS/WASM — тесты паритета.
|
||||
|
||||
[Большая текстура оригинала] → загрузка один раз на смену источника; при
|
||||
переключении зума/источника возможна разовая пауза.
|
||||
|
||||
[Резкая граница на контрастных снимках] → более узкие веса зон и аддитивная
|
||||
яркость; полностью убрать границу нельзя, если она есть в самом снимке.
|
||||
|
||||
[Обратная совместимость] → отсутствие `color` трактуется как нулевые правки.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
Миграция схемы не требуется: новый ключ `color` дополняет существующий `light`.
|
||||
Откат — удаление ключа `color` из `edit_params`.
|
||||
|
||||
## Open Questions
|
||||
|
||||
Нет.
|
||||
+21
-15
@@ -10,18 +10,20 @@
|
||||
|
||||
## What Changes
|
||||
|
||||
- Расширить `EditParams` новым блоком `Color`: баланс белого (Темп, Оттенок),
|
||||
Вибрация (Vibrance), Насыщенность, Цветовой микшер (Тон/Насыщенность/Яркость
|
||||
по оттенкам), Точечный цвет и Цветокоррекция.
|
||||
- Расширить `EditParams` новым блоком `Color`: баланс белого (температура/оттенок
|
||||
+ пипетка по нейтральной точке), сочность (vibrance), насыщенность, цветовой
|
||||
микшер (8 оттенков × тон/насыщенность/яркость), цветокоррекция (тени/средние
|
||||
тона/света + яркость зон, наложение, баланс) и поканальная коррекция.
|
||||
- Сервер (Go): рендер цветовых правок на пикселях исходного объекта, порядок
|
||||
операций — свет, затем цвет; результат записывается в те же роли `edit`,
|
||||
`edit_thumb`, `edit_medium`, `edit_preview`.
|
||||
- Клиент (TypeScript): цветовые ползунки и элементы управления в
|
||||
`PhotoEditPanel`, живой превью через `light.wasm` с тестом паритета
|
||||
(`wasmMatchesReference`).
|
||||
- Клиент (TypeScript/Svelte): раздел «Цвет» с ползунками, цветовыми колёсами и
|
||||
микшером; живой предпросмотр на WebGL2, CPU/WASM-фолбэк с тестом паритета
|
||||
(`wasmMatchesReference`); пипетка баланса белого; двойной клик по контролу
|
||||
сбрасывает значение.
|
||||
- WASM (Rust): расширение `frontend/wasm/light/` цветовыми операциями и
|
||||
пересборка `static/light.wasm`.
|
||||
- Хранение: `photo.edit_params` остаётся `map[string]any` JSON-блоба — старые
|
||||
пересборка `static/light.wasm` (фолбэк предпросмотра).
|
||||
- Хранение: `photo.edit_params` остаётся `map[string]any` JSON-блобом — старые
|
||||
фото без ключа `color` рендерятся без цветовых правок, миграций схемы не
|
||||
требуется.
|
||||
|
||||
@@ -43,13 +45,17 @@
|
||||
`Normalized`/`IsEmpty`/`JSON`.
|
||||
- `backend/internal/photos/edit_render.go` — `applyColor` / `applyColorRows`,
|
||||
`decodeAndAdjust` применяет свет и цвет.
|
||||
- `backend/internal/photos/edit_service.go` — валидация и сохранение без
|
||||
изменений логики (параметр `color` добавится в JSON).
|
||||
- `backend/internal/photos/handlers.go` — приём `color` в `PATCH /photos/:id/edit`.
|
||||
- `frontend/src/lib/edit.ts` — `ColorParams`, цветовые ползунки,
|
||||
`readEditParams`/`isEmptyEditParams`/`normalizeEditParams` с цветом,
|
||||
`applyColorToPixels`.
|
||||
`readEditParams`/`isEmptyEditParams`/`normalizeEditParams`, `applyColorToPixels`,
|
||||
`whiteBalanceFromRGB`.
|
||||
- `frontend/src/lib/light-wasm.ts` — вызов WASM для цвета, поддержка паритета.
|
||||
- `frontend/src/lib/components/PhotoEditPanel.svelte` — новый раздел «Цвет».
|
||||
- `frontend/src/lib/components/Viewer.svelte` — превью с цветом.
|
||||
- `frontend/src/lib/webgl-preview.ts` — WebGL2-шейдер и рендер превью.
|
||||
- `frontend/src/lib/stores/eyedropper.svelte.ts` — режим пипетки.
|
||||
- `frontend/src/lib/components/PhotoEditPanel.svelte` — раздел «Цвет».
|
||||
- `frontend/src/lib/components/EditSlider.svelte`, `ColorWheel.svelte` — контролы.
|
||||
- `frontend/src/lib/components/Viewer.svelte` — live-превью (WebGL/CPU) и сэмплирование пипетки.
|
||||
- `frontend/src/lib/components/PhotoPanel.svelte` — передача признака просмотрщика.
|
||||
- `frontend/wasm/light/` (Rust) + `static/light.wasm` — цветовые операции.
|
||||
- Тесты: `edit_test.go`, `edit.test.ts`, `light-wasm.test.ts`.
|
||||
- Тесты: `edit_test.go`, `edit.test.ts`, `light-wasm.test.ts`,
|
||||
`backend/internal/e2e/color_edit_test.go`.
|
||||
+29
-1
@@ -34,9 +34,37 @@
|
||||
- **THEN** система отклоняет запрос
|
||||
|
||||
#### Scenario: Цветовые правки сохраняются и рендерятся
|
||||
- **WHEN** пользователь сохраняет цветовые правки фото (баланс белого, вибрацию, насыщенность, цветовой микшер или точечный цвет)
|
||||
- **WHEN** пользователь сохраняет цветовые правки фото: баланс белого (температура/оттенок), сочность (vibrance), насыщенность, цветовой микшер по оттенкам, цветокоррекцию (тени/средние тона/света, яркость зон, наложение, баланс) или поканальную коррекцию
|
||||
- **THEN** параметры цвета сохраняются в метаданных, отредактированная версия рендерится в фоне, а после рендера фото получает URL отредактированных вариантов
|
||||
|
||||
#### Scenario: Цветовые правки применяются к пикселям исходного объекта
|
||||
- **WHEN** готовится отредактированная версия фото с цветовыми правками
|
||||
- **THEN** цветовые правки применяются к пикселям исходного объекта после световых правок, а не к его уменьшенной копии
|
||||
|
||||
#### Scenario: Пустые цветовые правки не сохраняются
|
||||
- **WHEN** в цветовых параметрах заданы только наложение/баланс или оттенок колеса без силы и яркости
|
||||
- **THEN** правки считаются пустыми и фото не получает цветовую версию
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Пипетка баланса белого
|
||||
Клиент SHALL позволять выбрать нейтральную точку на фото и SHALL устанавливать температуру и оттенок так, чтобы цвет этой точки стал нейтральным. Выборка SHALL браться из исходного (неотредактированного) превью, а пресет баланса белого SHALL переходить в «Пользовательский».
|
||||
|
||||
#### Scenario: Выбор нейтральной точки
|
||||
- **WHEN** пользователь включает пипетку и кликает по нейтральному участку фото
|
||||
- **THEN** температура и оттенок обновляются, и цвет выбранной точки становится нейтральным
|
||||
|
||||
#### Scenario: Пипетка доступна только в просмотрщике
|
||||
- **WHEN** фото не открыто в просмотрщике
|
||||
- **THEN** пипетка недоступна
|
||||
|
||||
### Requirement: Живой предпросмотр цветовых правок
|
||||
Клиент SHALL показывать результат цветовых правок в просмотрщике до завершения серверного рендера. После завершения рендера SHALL показываться серверная версия.
|
||||
|
||||
#### Scenario: Правки видны сразу
|
||||
- **WHEN** пользователь двигает цветовой контрол
|
||||
- **THEN** просмотрщик обновляет изображение без ожидания серверного рендера
|
||||
|
||||
#### Scenario: Серверная версия заменяет предпросмотр
|
||||
- **WHEN** серверный рендер цветовых правок завершён
|
||||
- **THEN** просмотрщик показывает отрендеренную версию
|
||||
@@ -0,0 +1,59 @@
|
||||
# Tasks
|
||||
|
||||
## 1. Backend: цветовая модель и рендер (Go)
|
||||
|
||||
- [x] 1.1 Добавить `ColorParams` и `EditParams.Color` в `backend/internal/photos/edit.go`, обновить `Normalized`/`IsEmpty`/`JSON` с учетом цвета — проверить `go build ./internal/photos/`
|
||||
- [x] 1.2 Реализовать `applyColor` / `applyColorRows` и включить цвет в `decodeAndAdjust` после света (`backend/internal/photos/edit_render.go`) — проверить `go test ./internal/photos/ -run TestColor -v`
|
||||
- [x] 1.3 Добавить тесты цветовых параметров (`edit_test.go`): валидация диапазонов, `IsEmpty`, рендер с цветом — проверить `go test ./internal/photos/ -v`
|
||||
|
||||
## 2. Фронтенд: цветовая модель (TypeScript)
|
||||
|
||||
- [x] 2.1 Добавить `ColorParams`, цветовые ползунки, `emptyColor`, обновить `readEditParams`/`isEmptyEditParams`/`normalizeEditParams` в `frontend/src/lib/edit.ts` — проверить `npm run check` (в `frontend`)
|
||||
- [x] 2.2 Реализовать `applyColorToPixels` в `edit.ts`, зеркальное серверной математике — проверить `npm run test` (в `frontend`, `edit.test.ts`)
|
||||
- [x] 2.3 Поддержать цвет в `light-wasm.ts` и тест паритета `wasmMatchesReference` — проверить `npm run test` (в `frontend`, `light-wasm.test.ts`)
|
||||
|
||||
## 3. WASM модуль цвета (Rust)
|
||||
|
||||
- [x] 3.1 Реализовать цветовые операции (баланс белого, вибрация, насыщенность, микшер, точечный цвет) в `frontend/wasm/light/` — проверить сборку модуля
|
||||
- [x] 3.2 Пересобрать `static/light.wasm` — проверить файл обновился
|
||||
|
||||
## 4. UI: панель и превью цвета
|
||||
|
||||
- [x] 4.1 Добавить раздел «Цвет» в `PhotoEditPanel.svelte` (баланс белого, сочность, насыщенность, микшер, цветокоррекция) — проверить открытие/сворачивание панели
|
||||
- [x] 4.2 Поддержать цвет в live-превью `Viewer.svelte` — проверить изменение превью при движении ползунков
|
||||
- [x] 4.3 Подключить сохранение цветовых параметров через `photosApi.edit` — проверить сохранение на сервере
|
||||
|
||||
## 5. Интеграция и проверка
|
||||
|
||||
- [x] 5.1 Проверить эндпоинт правки (`PATCH /api/photos/:id/edit`) с цветовыми параметрами — проверить ответ с `edit_url`
|
||||
- [x] 5.2 Проверить сброс цветовых правок — проверить возврат к оригиналу
|
||||
- [x] 5.3 Проверить обратную совместимость: фото без ключа `color` в `edit_params` рендерятся без цветовых правок — проверить `make test` (бэкенд)
|
||||
|
||||
## 6. WebGL-предпросмотр
|
||||
|
||||
- [x] 6.1 Реализовать `frontend/src/lib/webgl-preview.ts`: WebGL2-шейдер света/цвета, LUT-текстура кривых, загрузка текстуры изображения — проверить сборку `npm run build`
|
||||
- [x] 6.2 Подключить GL-first и CPU/WASM-фолбэк в `Viewer.svelte` (два канваса, `useGL`) — проверить переключение при отсутствии WebGL2
|
||||
- [x] 6.3 Проверить компиляцию и линковку шейдера в headless Firefox — зелёный экран `OK`
|
||||
- [x] 6.4 Пропускать свет, если он не менялся, и микшер, если он пуст — проверить `go test ./internal/photos/ ./internal/e2e/`
|
||||
- [x] 6.5 Снизить стоимость CPU-фолбэка: адаптивный буфер, беззвучный быстрый путь без HSL и аддитивная яркость — проверить замер WASM/визуально
|
||||
|
||||
## 7. Пипетка баланса белого
|
||||
|
||||
- [x] 7.1 Добавить `frontend/src/lib/stores/eyedropper.svelte.ts` (режим, фото, сэмпл) — проверить `npm run check`
|
||||
- [x] 7.2 Добавить `whiteBalanceFromRGB` в `edit.ts` (обратная задача баланса белого) — проверить `npm run test` (`edit.test.ts`)
|
||||
- [x] 7.3 Сэмплировать пиксель базового превью в `Viewer.svelte` по клику — проверить ручным сценарием
|
||||
- [x] 7.4 Подключить кнопку пипетки и подсказку в `PhotoEditPanel.svelte`, пресет «Пользовательский» — проверить `npm run check`
|
||||
- [x] 7.5 Покрыть расчёт нейтральной точки тестом — проверить `npm run test`
|
||||
|
||||
## 8. UI и тональные правки
|
||||
|
||||
- [x] 8.1 Добавить `EditSlider.svelte` (градиентная/заполненная дорожка, двойной клик — сброс) — проверить `npm run check`
|
||||
- [x] 8.2 Добавить `ColorWheel.svelte` (оттенок/насыщенность, двойной клик — сброс) — проверить открытие/вращение
|
||||
- [x] 8.3 Переименовать «Красивость» → «Сочность» — проверить подпись ползунка
|
||||
- [x] 8.4 Сузить веса зон теней/светов и сделать яркость аддитивной — проверить отсутствие резкой границы на контрастном снимке
|
||||
- [x] 8.5 Добавить пресеты баланса белого и «Пользовательский» — проверить переключение пресетов
|
||||
|
||||
## Workflow follow-up
|
||||
|
||||
- Архивировать изменение после удовлетворения требований ревью проекта.
|
||||
- Проверить архивированный результат.
|
||||
@@ -1,88 +0,0 @@
|
||||
# Design
|
||||
|
||||
## Context
|
||||
|
||||
Неразрушающее редактирование фото уже реализовано: параметры правок хранятся в
|
||||
`photo.edit_params` (`map[string]any` JSON-блоб), сервер рендерит отредактированную
|
||||
копию как отдельные объекты ролей `edit`, `edit_thumb`, `edit_medium`,
|
||||
`edit_preview` рядом с исходными, оригинал не меняется. На сегодня поддерживается
|
||||
только блок «Свет» (`LightParams` в `backend/internal/photos/edit.go`,
|
||||
зеркало на клиенте `frontend/src/lib/edit.ts`, живой превью через
|
||||
`frontend/wasm/light/` → `static/light.wasm` с тестом паритета
|
||||
`wasmMatchesReference`). Хранение в JSON-блобе обратноли не требует миграции:
|
||||
старые фото без ключа `color` рендерятся без цветовых правок.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Добавить блок «Цвет» к неразрушающему редактированию: баланс белого
|
||||
(Темп, Оттенок), Вибрация, Насыщенность, Цветовой микшер по оттенкам,
|
||||
Точечный цвет, Цветокоррекция.
|
||||
- Живой клиентский превью с паритетом трёх реализаций: сервер Go, клиент TypeScript,
|
||||
WASM (Rust) — как для «Света».
|
||||
- Рендер цветовых правок по пикселям исходного объекта, после световых правок.
|
||||
- Обратная совместимость: фото без ключа `color` в `edit_params` рендерятся как
|
||||
прежде.
|
||||
|
||||
**Non-Goals:**
|
||||
- Синхронизация правок между устройствами или через Android-клиент.
|
||||
- Изменение ролей хранения или формата объектов (`edit`, `edit_thumb`, … остаются).
|
||||
- Миграция схемы базы данных.
|
||||
|
||||
## Decisions
|
||||
|
||||
**Цвет хранится в том же `edit_params`, рядом с `light`.**
|
||||
- Обоснование: `EditParams` уже расширяется полем `Color ColorParams`; `map[string]any`
|
||||
на бэкенде и `EditParams` на клиенте принимают новый ключ без cambios схемы.
|
||||
- Альтернатива: отдельная колонка/таблица для цветовых правок — отвергнута, добавила бы
|
||||
миграцию и не сочетается с текущей моделью хранения.
|
||||
|
||||
**Порядок операций при рендере: свет, затем цвет.**
|
||||
- Обоснование: цветовые коррекции (баланс белого, насыщенность) логично применять
|
||||
к уже скорректированной по тональности картинке; сервер и клиент должны следовать
|
||||
одному порядку, иначе превью не совпадёт с результатом.
|
||||
- Альтернатива: цвет до света — отвергнуто, несоответствие Lightroom-поведению и
|
||||
текущему клиентскому конвейеру.
|
||||
|
||||
**Цветовая математика реализована трижды и держится в паритете: Go (сервер),
|
||||
TypeScript (клиент), Rust/WASM (живой превью).**
|
||||
- Обоснование: текущий подход со «Светом» (`applyLight` в Go, `applyLightToPixels`
|
||||
в TS, `light.wasm` в Rust, тест `wasmMatchesReference`) гарантирует, что превью
|
||||
в браузере совпадает с финальным рендером. Для цвета повторяем эту схему.
|
||||
- Альтернатива: считать цвет только на сервере и показывать превью после рендера —
|
||||
отвергнуто, пользователь ожидает мгновенного отклика при движении ползунков, как
|
||||
сейчас со светом.
|
||||
|
||||
**Цветовые параметры применяются в пространстве RGB с промежуточным HSL.**
|
||||
- Обоснование: баланс белого, вибрация, насыщенность и тонирование естественно
|
||||
выражаются через HSL; пиксели хранятся в RGBA, поэтому пересчёт RGB→HSL→RGB
|
||||
на пиксельном цикле.
|
||||
- Альтернатива: чистые операции над RGB-каналами — отвергнуто, менее точно
|
||||
соответствует цветовым инструментам Lightroom.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
[Расхождение реализаций Go / TS / Rust] → mitigation: тест паритета
|
||||
`wasmMatchesReference` расширяется на цвет, изменение любой реализации требует
|
||||
обновления остальных и теста.
|
||||
|
||||
[Сложность UI] → mitigation: цветовой микшер по 8 оттенкам и точечное тонирование
|
||||
добавляют много элементов управления в `PhotoEditPanel`; раздел «Цвет» делаем
|
||||
сворачиваемым, как «Свет».
|
||||
|
||||
[Производительность рендера] → mitigation: цвет добавляет один пиксельный проход
|
||||
(или объединяется с существующим циклом света); параллелизация по строкам
|
||||
(`applyLightRows`) остаётся.
|
||||
|
||||
[Обратная совместимость] → mitigation: отсутствие ключа `color` в `edit_params`
|
||||
трактуется как нулевые цветовые правки; старые фото не затрагиваются.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
Миграция схемы не требуется: `edit_params` — JSON-блоб, новый ключ `color`
|
||||
дополняет существующий `light`. Откат: удаление ключа `color` из `edit_params`
|
||||
возвращает фото к состоянию без цветовых правок.
|
||||
|
||||
## Open Questions
|
||||
|
||||
Нет — все проектные решения (объём цвета, живой превью с паритетом) согласованы.
|
||||
@@ -1,35 +0,0 @@
|
||||
# Tasks
|
||||
|
||||
## 1. Backend: цветовая модель и рендер (Go)
|
||||
|
||||
- [x] 1.1 Добавить `ColorParams` и `EditParams.Color` в `backend/internal/photos/edit.go`, обновить `Normalized`/`IsEmpty`/`JSON` с учетом цвета — проверить `go build ./internal/photos/`
|
||||
- [x] 1.2 Реализовать `applyColor` / `applyColorRows` и включить цвет в `decodeAndAdjust` после света (`backend/internal/photos/edit_render.go`) — проверить `go test ./internal/photos/ -run TestColor -v`
|
||||
- [x] 1.3 Добавить тесты цветовых параметров (`edit_test.go`): валидация диапазонов, `IsEmpty`, рендер с цветом — проверить `go test ./internal/photos/ -v`
|
||||
|
||||
## 2. Фронтенд: цветовая модель (TypeScript)
|
||||
|
||||
- [x] 2.1 Добавить `ColorParams`, цветовые ползунки, `emptyColor`, обновить `readEditParams`/`isEmptyEditParams`/`normalizeEditParams` в `frontend/src/lib/edit.ts` — проверить `npm run check` (в `frontend`)
|
||||
- [x] 2.2 Реализовать `applyColorToPixels` в `edit.ts`, зеркальное серверной математике — проверить `npm run test` (в `frontend`, `edit.test.ts`)
|
||||
- [x] 2.3 Поддержать цвет в `light-wasm.ts` и тест паритета `wasmMatchesReference` — проверить `npm run test` (в `frontend`, `light-wasm.test.ts`)
|
||||
|
||||
## 3. WASM модуль цвета (Rust)
|
||||
|
||||
- [x] 3.1 Реализовать цветовые операции (баланс белого, вибрация, насыщенность, микшер, точечный цвет) в `frontend/wasm/light/` — проверить сборку модуля
|
||||
- [x] 3.2 Пересобрать `static/light.wasm` — проверить файл обновился
|
||||
|
||||
## 4. UI: панель и превью цвета
|
||||
|
||||
- [x] 4.1 Добавить раздел «Цвет» в `PhotoEditPanel.svelte` (баланс белого, вибрация, насыщенность, микшер, точечный цвет) — проверить открытие/сворачивание панели
|
||||
- [x] 4.2 Поддержать цвет вライブ-превью `Viewer.svelte` через `applyLight` + `applyColor` — проверить изменение превью при движении ползунков
|
||||
- [x] 4.3 Подключить сохранение цветовых параметров через `photosApi.edit` — проверить сохранение на сервере
|
||||
|
||||
## 5. Интеграция и проверка
|
||||
|
||||
- [x] 5.1 Проверить эндпоинт правки (`POST /api/photos/:id/edit`) с цветовыми параметрами — проверить ответ с `edit_url`
|
||||
- [x] 5.2 Проверить сброс цветовых правок — проверить возврат к оригиналу
|
||||
- [x] 5.3 Проверить обратную совместимость: фото без ключа `color` в `edit_params` рендерятся без цветовых правок — проверить `make test` (бэкенд)
|
||||
|
||||
## Workflow follow-up
|
||||
|
||||
- Архивировать изменение после удовлетворения требований ревью проекта.
|
||||
- Проверить архивированный результат.
|
||||
Reference in New Issue
Block a user