Разбор 21 коммита диапазона 45a953f..eb2d478: что было описано, что осталось без спек и почему, найденное расхождение по копированию фото с правками.
134 lines
12 KiB
Markdown
134 lines
12 KiB
Markdown
# Отчёт: изменения, сделанные без спецификаций
|
|
|
|
- **Дата:** 2026-10-21
|
|
- **Диапазон:** `45a953f^..eb2d478` — 21 коммит, 2026-10-20 — 2026-10-21
|
|
- **Ветка:** `develop`
|
|
- **Предмет:** правки веб-интерфейса просмотра и нового инструмента «Свет» (редактирование фото), сделанные без обновления спецификаций OpenSpec
|
|
- **Результат:** спеки дописаны (`748143c`), заведено изменение `fix-copy-edit-variant-sharing`
|
|
|
|
## 1. Метод
|
|
|
|
1. Разобран диапазон коммитов `45a953f^..eb2d478`: для каждого проверено, затронул ли
|
|
он `openspec/specs`.
|
|
2. Для коммитов без спек — прочитаны затронутые участки кода
|
|
(`frontend/src/lib/components/Viewer.svelte`, `PhotoEditPanel.svelte`,
|
|
`PhotoPanel.svelte`, `frontend/src/lib/edit.ts`, `backend/internal/photos/worker.go`,
|
|
`store.go`, `sqlite_store.go`).
|
|
3. Сопоставлено фактическое поведение с текстом существующих требований
|
|
`ui-workspace`, `media-objects`, `photos`, `dev-make-workflow`.
|
|
4. Каждое найденное расхождение зафиксировано как требование (SHALL) со сценариями
|
|
WHEN/THEN; после правок спеки проверены `openspec validate --specs`.
|
|
|
|
## 2. Сводка
|
|
|
|
| Показатель | Значение |
|
|
| --- | --- |
|
|
| Коммитов в диапазоне | 21 |
|
|
| Из них со спеками | 11 |
|
|
| Из них без спек | 10 |
|
|
| Затронутых спецификаций | 4 (`ui-workspace`, `media-objects`, `photos`, `dev-make-workflow`) |
|
|
| Новых требований | 3 («График тональной кривой», «Навигация в зуме», «Сборка WASM-модуля фильтров») |
|
|
| Уточнённых требований | 6 |
|
|
| Новых сценариев | 12 |
|
|
| Ошибок валидации | 0 (`23 passed, 0 failed`) |
|
|
|
|
## 3. Покрытие по коммитам
|
|
|
|
| Коммит | Изменение | Где описано |
|
|
| --- | --- | --- |
|
|
| `45a953f` | скрытие боковых панелей, хоткеи размера миниатюр | `ui-workspace` → «Скрытие боковых панелей» (уже было) |
|
|
| `50b9983` | размер миниатюр не меняется при скрытых панелях | там же, сценарий «Размер миниатюр при скрытых панелях» |
|
|
| `35f8439` | зум клавишами `+` / `-` | `ui-workspace` → «Зум в просмотре» (уже было) |
|
|
| `0a9e527` | лента миниатюр следует за текущим фото | уже было |
|
|
| `961dff1` | `Ctrl+F` — полноэкранный режим приложения | уже было |
|
|
| `afaaaab` | офлайн-режим с кешем эскизов и превью | `ui-workspace` → «Офлайн-режим веб-приложения» (уже было) |
|
|
| `0548b1a` | вкладка «Редактирование», инструмент «Свет» | `ui-workspace` → «Вкладка «Редактирование»» (уточнено) |
|
|
| `cd3d17c` | правки применяются сразу; вкладка не сбрасывается при обновлении фото | уточнено: «Обновление фото SHALL сохранять открытую вкладку панели» |
|
|
| `6d3d7cb` | ускорение рендера правок в 9 раз | сознательно не специфицировано (внутренняя оптимизация) |
|
|
| `4d2069d`, `520886a` | клиентский рендер правок, WASM-фильтры | «Фильтры считаются в браузере» (уже было) |
|
|
| `2adcb13` | предпросмотр правок работает и без зума | уточнено: «Правки видны сразу — и во вписанном виде, и в зуме» |
|
|
| `500ec10`, `f8ee937` | починка зума, центрирование | «Зум в просмотре»: `Space` = 100% **от оригинала по центру кадра** |
|
|
| `b2a509f` | в зуме стрелки панорамируют фото | **новое** требование «Навигация в зуме» |
|
|
| `2668d87` | искажение цветов в предпросмотре | уже было (сценарий про сверку с эталоном) |
|
|
| `d904b2f` | невидимая линия тональной кривой | сознательно не специфицировано (багфикс) |
|
|
| `b64574b` | гистограммы каналов в редакторе кривой | **новое** требование «График тональной кривой» |
|
|
| `48ed0bb` | гистограмма пересчитывается при правке | там же, сценарий «Живая гистограмма» |
|
|
| `332f35b`, `eb2d478` | сворачивание блока «Кривая», свёрнут по умолчанию | там же, сценарий «Сворачивание кривой» |
|
|
| `520886a` | сборка WASM-модуля фильтров (`npm run wasm`, cargo) | `dev-make-workflow` → **новое** требование «Сборка WASM-модуля фильтров» |
|
|
| `520886a`, `worker.go` | роли объектов `edit`, `edit_thumb`, `edit_medium`, `edit_preview` | `media-objects` → «Журнал объектов» + сценарий «Привязка отредактированной версии» |
|
|
| `worker.go` | отдельная очередь рендера правок (`edit_jobs`) | `media-objects` → «Генерация вариантов» + «Рендер правок не блокирует варианты» |
|
|
| `worker.go` | рендер правок по исходному объекту | `photos` → «Неразрушающее редактирование фотографии» + «Рендер по оригиналу» |
|
|
|
|
## 4. Новые и уточнённые требования
|
|
|
|
**Новые требования:**
|
|
|
|
- `ui-workspace` → «График тональной кривой»: гистограмма каналов, живой пересчёт,
|
|
добавление и перетаскивание точек, сворачиваемый блок «Кривая» (по умолчанию свёрнут,
|
|
кнопки выбора канала остаются доступными).
|
|
- `ui-workspace` → «Навигация в зуме»: клавиши-стрелки панорамируют фото и не
|
|
переключают соседние снимки, переключение остаётся за мышью и кнопками у краёв.
|
|
- `dev-make-workflow` → «Сборка WASM-модуля фильтров»: Rust-исходники в
|
|
`frontend/wasm/light`, обновление модуля перед сборкой статики, откат на готовый
|
|
модуль из репозитория, если cargo недоступен.
|
|
|
|
**Уточнённые требования:**
|
|
|
|
- `ui-workspace` → «Вкладка «Редактирование»»: добавлено сохранение вкладки при
|
|
обновлении фото; предпросмотр правок работает в любом режиме просмотра.
|
|
- `ui-workspace` → «Зум в просмотре»: `Space` показывает 100% **от оригинала** по
|
|
центру кадра.
|
|
- `media-objects` → «Журнал объектов»: перечислены роли `edit`, `edit_thumb`,
|
|
`edit_medium`, `edit_preview`.
|
|
- `media-objects` → «Совместные объекты»: уточнено, что отредактированная версия
|
|
создаётся и привязывается только к фото, чьи правки её породили.
|
|
- `media-objects` → «Генерация вариантов»: рендер правок идёт в отдельной очереди.
|
|
- `photos` → «Неразрушающее редактирование фотографии»: рендер идёт по исходному
|
|
объекту, а не по уменьшенной копии.
|
|
|
|
## 5. Что сознательно осталось без спецификаций
|
|
|
|
| Изменение | Почему |
|
|
| --- | --- |
|
|
| `6d3d7cb` — ускорение рендера в 9 раз | внутренняя оптимизация, внешнее поведение не изменилось |
|
|
| `d904b2f` — видимость линии кривой | багфикс: требование «кривая показывается» уже было |
|
|
| `500ec10` — контейнер прокрутки зума | деталь вёрстки, покрыта требованием «Панорамирование» |
|
|
| правки переноса/центрирования внутри `f8ee937` | описаны пользовательские последствия, а не механизм |
|
|
|
|
## 6. Найденное расхождение кода и замысла
|
|
|
|
`Store.Clone` и `SQLiteStore.Clone` копируют **все** привязки `photo_objects`,
|
|
включая роли `edit*`, хотя воркер создаёт edit-объекты с владельцем
|
|
`[]string{photoID}` и комментирует это так: «The edit belongs to this photo only, so
|
|
the variants are not shared with the copies of the same original».
|
|
|
|
Последствия:
|
|
|
|
| Сценарий | Фактическое поведение | Ожидаемое |
|
|
| --- | --- | --- |
|
|
| Копия **до** правки | копия в исходном виде | так и должно быть |
|
|
| Копия **после** рендера | копия показывает отредактированную картинку, но `edit_params` пусты: в панели правок параметров нет, первая же новая правка перезаписывает обработку с нуля | копия в исходном виде |
|
|
|
|
Оформлено как изменение `fix-copy-edit-variant-sharing`
|
|
(`openspec/changes/fix-copy-edit-variant-sharing/`):
|
|
|
|
- `proposal.md` — зачем;
|
|
- `design.md` — фильтр ролей в `Clone` вместо правки выдачи URL, единый список
|
|
edit-ролей, разовая чистка существующих копий миграцией в обоих диалектах;
|
|
- `specs/media-objects/spec.md` — дельта требования «Совместные объекты»;
|
|
- `tasks.md` — 4 группы задач (список ролей → копирование → миграции → проверки).
|
|
|
|
## 7. Проверка
|
|
|
|
```
|
|
openspec validate --specs → 23 passed, 0 failed
|
|
openspec validate fix-copy-edit-variant-sharing --type change → valid
|
|
```
|
|
|
|
## 8. Что дальше
|
|
|
|
- Реализация правки копирования — из `/opsx-apply` для изменённого
|
|
`fix-copy-edit-variant-sharing`.
|
|
- После реализации и архивации изменений дельта `media-objects` будет перенесена в
|
|
основную спеку.
|