# Proposal ## Why Клиент узнаёт о готовности серверного рендера правок только по появлению `edit_url`/`edit_preview_url` в объекте фото, а признака «рендер сохранённых правок ещё идёт» в API нет. Из-за этого в просмотрщике: - после отложенного сохранения (дебаунс 10 с) при появлении полного рендера клиентский предпросмотр выключается раньше, чем новое изображение загружено, и в зуме на время загрузки виден оригинал (мигание «оригинал → правка»); - повторная правка, у которой уже есть предыдущий рендер, после сохранения показывает старую отрендеренную версию, пока не завершится новый рендер; - сброс, сделанный возвратом контролов в значения по умолчанию, не виден до срабатывания дебаунса: локальные параметры уже пусты, предпросмотр выключен, и просмотрщик показывает старую серверную версию — «сброс срабатывает через 10 с». ## What Changes - Фото получает аддитивный признак незавершённого рендера правок — булево поле `edit_pending` в ответах API и в событиях `photo.updated`: `true`, пока в `edit_jobs` есть задание на рендер; `false`, когда рендера нет или он завершён. - Клиент перестаёт угадывать готовность по наличию URL и опирается на признак: пока есть несохранённые локальные правки или серверный рендер не завершён, просмотрщик показывает клиентский предпросмотр поверх исходной версии. - Замена предпросмотра серверной версией выполняется только после загрузки и декодирования нового изображения — без промежуточного показа оригинала или предыдущей отрендеренной версии. - Сброс правок (кнопкой и возвратом контролов в значения по умолчанию) виден в просмотрщике сразу, не дожидаясь отложенного сохранения. - Viewer перестаёт предпочитать устаревшую локальную копию фото: URL для показа берутся из актуального объекта, обновляемого SSE-событиями. - Индикатор «Рендерим правки на сервере…» в панели редактора опирается на `edit_pending`, а не на отсутствие URL. - Без изменений: отложенное сохранение (10 с), неразрушающий рендер, роли объектов, формат `edit_params`, схема БД, Android-клиент (поле аддитивное, отсутствие трактуется как `false`). ## Capabilities ### New Capabilities Нет — изменение уточняет существующие способности. ### Modified Capabilities - `photos`: новый признак незавершённого рендера правок; уточняются «Живой предпросмотр цветовых правок», «Живой предпросмотр эффектов» (бесшовная подмена) и добавляется требование о мгновенном показе сброса. - `realtime`: `photo.updated` отражает жизненный цикл рендера правок — сохранение (`edit_pending=true`), готовность (`edit_pending=false` + URL отредактированных вариантов), сброс (без URL отредактированных вариантов). ## Impact - `backend/internal/models/models.go` — поле `EditPending` в `Photo`. - `backend/internal/photos/store.go`, `sqlite_store.go` — `EXISTS` по `edit_jobs` в общем списке колонок; сканирование поля. Миграции не нужны: таблица уже есть. - `backend/internal/photos/edit_service.go`, `worker.go`, `handlers.go` — признак попадает в ответы сохранения/сброса и в события (через общие запросы фото). - `frontend/src/lib/types.ts` — поле в типе `Photo`. - `frontend/src/lib/components/Viewer.svelte` — выбор источника изображения по состоянию (локальные правки / `edit_pending` / загруженность нового кадра), предзагрузка и декодирование, единый актуальный источник URL. - `frontend/src/lib/components/PhotoEditPanel.svelte` — статус рендера. - Новый чистый модуль выбора источника предпросмотра + vitest. - Тесты: контрактные (репозитории, SQLite и Postgres), e2e рендера правок, frontend-модульные тесты, проверка `svelte-check`. - API: аддитивное поле `edit_pending`; старые клиенты (Android) его игнорируют.