diff --git a/openspec/changes/fix-edit-preview-handoff/.openspec.yaml b/openspec/changes/archive/2026-10-25-fix-edit-preview-handoff/.openspec.yaml similarity index 100% rename from openspec/changes/fix-edit-preview-handoff/.openspec.yaml rename to openspec/changes/archive/2026-10-25-fix-edit-preview-handoff/.openspec.yaml diff --git a/openspec/changes/fix-edit-preview-handoff/design.md b/openspec/changes/archive/2026-10-25-fix-edit-preview-handoff/design.md similarity index 100% rename from openspec/changes/fix-edit-preview-handoff/design.md rename to openspec/changes/archive/2026-10-25-fix-edit-preview-handoff/design.md diff --git a/openspec/changes/fix-edit-preview-handoff/proposal.md b/openspec/changes/archive/2026-10-25-fix-edit-preview-handoff/proposal.md similarity index 100% rename from openspec/changes/fix-edit-preview-handoff/proposal.md rename to openspec/changes/archive/2026-10-25-fix-edit-preview-handoff/proposal.md diff --git a/openspec/changes/fix-edit-preview-handoff/specs/photos/spec.md b/openspec/changes/archive/2026-10-25-fix-edit-preview-handoff/specs/photos/spec.md similarity index 100% rename from openspec/changes/fix-edit-preview-handoff/specs/photos/spec.md rename to openspec/changes/archive/2026-10-25-fix-edit-preview-handoff/specs/photos/spec.md diff --git a/openspec/changes/fix-edit-preview-handoff/specs/realtime/spec.md b/openspec/changes/archive/2026-10-25-fix-edit-preview-handoff/specs/realtime/spec.md similarity index 100% rename from openspec/changes/fix-edit-preview-handoff/specs/realtime/spec.md rename to openspec/changes/archive/2026-10-25-fix-edit-preview-handoff/specs/realtime/spec.md diff --git a/openspec/changes/fix-edit-preview-handoff/tasks.md b/openspec/changes/archive/2026-10-25-fix-edit-preview-handoff/tasks.md similarity index 100% rename from openspec/changes/fix-edit-preview-handoff/tasks.md rename to openspec/changes/archive/2026-10-25-fix-edit-preview-handoff/tasks.md diff --git a/openspec/specs/photos/spec.md b/openspec/specs/photos/spec.md index 31e05b2..d78cee2 100644 --- a/openspec/specs/photos/spec.md +++ b/openspec/specs/photos/spec.md @@ -329,6 +329,25 @@ SHALL быть доступно и для фото без альбома (нап - **WHEN** во всех эффектах заданы только значения по умолчанию (сила эффекта, виньетки и зерна равна нулю) - **THEN** правки считаются пустыми и фото не получает новую отредактированную версию +### Requirement: Признак незавершённого рендера правок +Фото в ответах API и в событиях `photo.updated` SHALL содержать булево поле `edit_pending`. Оно SHALL быть `true`, пока серверный рендер сохранённых правок не завершён, и `false`, когда рендера нет или он завершён. Пока `edit_pending` равно `true`, URL отредактированных вариантов SHALL NOT считаться актуальными, даже если они присутствуют. Поле SHALL быть аддитивным: клиент, который его не читает, продолжает работать как раньше. + +#### Scenario: Сохранение правок +- **WHEN** правки фото сохранены, а серверный рендер ещё не завершён +- **THEN** ответ на сохранение и событие `photo.updated` содержат `edit_pending=true` + +#### Scenario: Предыдущий рендер устарел +- **WHEN** у фото уже есть отрендеренная версия, а для новых сохранённых правок рендер ещё не завершён +- **THEN** фото содержит `edit_pending=true`, а URL отредактированных вариантов не выдаются за актуальные + +#### Scenario: Готовность рендера +- **WHEN** серверный рендер сохранённых правок завершён +- **THEN** `edit_pending=false`, а URL отредактированных вариантов соответствуют сохранённым правкам + +#### Scenario: Сброс правок +- **WHEN** правки фото сброшены +- **THEN** `edit_pending=false` и URL отредактированных вариантов отсутствуют + ### Requirement: Пипетка баланса белого Клиент SHALL позволять выбрать нейтральную точку на фото и SHALL устанавливать температуру и оттенок так, чтобы цвет этой точки стал нейтральным. Выборка SHALL браться из исходного (неотредактированного) превью, а пресет баланса белого SHALL переходить в «Пользовательский». @@ -341,7 +360,7 @@ SHALL быть доступно и для фото без альбома (нап - **THEN** пипетка недоступна ### Requirement: Живой предпросмотр цветовых правок -Клиент SHALL показывать результат цветовых правок в просмотрщике до завершения серверного рендера. После завершения рендера SHALL показываться серверная версия. +Клиент SHALL показывать результат цветовых правок в просмотрщике до завершения серверного рендера. Пока серверный рендер сохранённых правок не завершён (`edit_pending`) или пока локальные правки не сохранены, клиент SHALL показывать клиентский предпросмотр поверх исходной версии. После завершения рендера SHALL показываться серверная версия. #### Scenario: Правки видны сразу - **WHEN** пользователь двигает цветовой контрол @@ -351,6 +370,10 @@ SHALL быть доступно и для фото без альбома (нап - **WHEN** серверный рендер цветовых правок завершён - **THEN** просмотрщик показывает отрендеренную версию +#### Scenario: Бесшовная подмена предпросмотра +- **WHEN** серверный рендер завершён, но новое изображение ещё загружается +- **THEN** просмотрщик продолжает показывать предпросмотр и не показывает оригинал или предыдущую отрендеренную версию + ### Requirement: Тоновая кривая Тоновая кривая SHALL задаваться контрольными точками для каналов RGB, R, G и B. Крайние точки SHALL существовать по умолчанию, SHALL двигаться по обеим осям и SHALL задавать плоские участки вне себя. Кривая SHALL быть плавной и монотонной между точками; первый клик по полю SHALL добавлять точку между крайними. Сброс SHALL возвращать линейную кривую. @@ -516,7 +539,7 @@ SHALL быть доступно и для фото без альбома (нап - **THEN** зерно не влияет на изображение ### Requirement: Живой предпросмотр эффектов -Клиент SHALL показывать эффекты в просмотрщике до завершения серверного рендера. После готовности серверной версии клиент SHALL показывать её. Предпросмотр пространственных эффектов (текстура, чёткость, дымка) MAY отличаться от серверного рендера деталями, но SHALL передавать характер эффекта. +Клиент SHALL показывать эффекты в просмотрщике до завершения серверного рендера. Пока серверный рендер сохранённых правок не завершён (`edit_pending`) или локальные правки не сохранены, клиент SHALL показывать клиентский предпросмотр поверх исходной версии. После готовности клиент SHALL показывать серверную версию, не показывая в промежутке оригинал или предыдущую версию. Предпросмотр пространственных эффектов MAY отличаться от серверного рендера деталями, но SHALL передавать характер эффекта. #### Scenario: Эффекты видны сразу - **WHEN** пользователь двигает ползунок эффекта @@ -526,10 +549,29 @@ SHALL быть доступно и для фото без альбома (нап - **WHEN** серверный рендер эффектов завершён - **THEN** просмотрщик показывает серверную версию +#### Scenario: Бесшовная подмена предпросмотра +- **WHEN** серверный рендер эффектов завершён, но новое изображение ещё загружается +- **THEN** просмотрщик продолжает показывать предпросмотр и не показывает оригинал или предыдущую отрендеренную версию + #### Scenario: Предпросмотр без WebGL - **WHEN** аппаратное ускорение недоступно - **THEN** клиент показывает эффекты доступным способом или показывает их после серверного рендера, не блокируя интерфейс +### Requirement: Мгновенный показ сброса правок +Клиент SHALL показывать исходный вид фото сразу после возврата контролов редактора в значения по умолчанию или нажатия сброса, не дожидаясь отложенного сохранения на сервер. Пока сброс, выполненный возвратом контролов, ещё не отправлен, просмотрщик SHALL NOT показывать отредактированную версию фото. + +#### Scenario: Сброс возвратом контролов +- **WHEN** пользователь возвращает контролы редактора в значения по умолчанию (двойной клик по ползунку, шкала в нуле) +- **THEN** просмотрщик сразу показывает исходный вид, не дожидаясь срабатывания отложенного сохранения + +#### Scenario: Сброс кнопкой +- **WHEN** пользователь нажимает «Сброс» +- **THEN** просмотрщик показывает исходный вид не позже ответа на запрос сброса + +#### Scenario: Сброс при готовом рендере +- **WHEN** сброс выполнен, а отредактированная версия ещё существует на сервере +- **THEN** просмотрщик показывает исходный вид, а не отредактированную версию + ### Requirement: Свёрнутые секции редактора Редактор SHALL показывать все сворачиваемые секции инструментов свёрнутыми по умолчанию. Клиент SHALL сохранять состояние каждой секции (свёрнута или развёрнута) в браузере пользователя и восстанавливать его при повторном открытии редактора и перезагрузке страницы. Состояние SHALL NOT зависеть от выбранного фото. diff --git a/openspec/specs/realtime/spec.md b/openspec/specs/realtime/spec.md index 509317f..5bc9309 100644 --- a/openspec/specs/realtime/spec.md +++ b/openspec/specs/realtime/spec.md @@ -17,7 +17,9 @@ Система SHALL публиковать события photo.created, photo.updated, photo.deleted, comment.created, like.added, like.removed, member.joined, member.left, album.updated. Событие photo.created SHALL обозначать появление фото в альбоме, а готовность вариантов -существующего фото SHALL публиковаться как photo.updated. +существующего фото SHALL публиковаться как photo.updated. Сохранение, готовность и сброс +правок фото SHALL также публиковаться как photo.updated с признаком незавершённого +рендера правок (`edit_pending`). #### Scenario: Новое фото - **WHEN** в альбоме появляется фото @@ -27,6 +29,18 @@ comment.created, like.added, like.removed, member.joined, member.left, album.upd - **WHEN** для существующего фото сгенерированы thumb и preview - **THEN** подписчики получают событие photo.updated с этим фото +#### Scenario: Сохранены правки фото +- **WHEN** пользователь сохраняет правки фото, а рендер ещё не завершён +- **THEN** подписчики получают событие photo.updated с `edit_pending=true` + +#### Scenario: Рендер правок готов +- **WHEN** серверный рендер сохранённых правок завершён +- **THEN** подписчики получают событие photo.updated с `edit_pending=false` и URL отредактированных вариантов + +#### Scenario: Правки фото сброшены +- **WHEN** правки фото сброшены +- **THEN** подписчики получают событие photo.updated с `edit_pending=false` и без URL отредактированных вариантов + ### Requirement: Персональный поток Клиент SHALL иметь возможность подписаться на персональный поток (приглашения, уведомления, изменения его альбомов).