From 271024b8d8ac058df5ee86d874ad263d20371cb9 Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Wed, 7 Oct 2026 14:01:23 +0300 Subject: [PATCH] spec: add reduce-screen-sync-polling change OpenSpec change: screen sync status polling and observe reads run every five seconds during active sync; terminal state observes resources immediately. --- .../reduce-screen-sync-polling/.openspec.yaml | 2 + .../reduce-screen-sync-polling/design.md | 104 ++++++++++++++++++ .../reduce-screen-sync-polling/proposal.md | 50 +++++++++ .../specs/frontend-data-resilience/spec.md | 85 ++++++++++++++ .../reduce-screen-sync-polling/tasks.md | 30 +++++ 5 files changed, 271 insertions(+) create mode 100644 openspec/changes/reduce-screen-sync-polling/.openspec.yaml create mode 100644 openspec/changes/reduce-screen-sync-polling/design.md create mode 100644 openspec/changes/reduce-screen-sync-polling/proposal.md create mode 100644 openspec/changes/reduce-screen-sync-polling/specs/frontend-data-resilience/spec.md create mode 100644 openspec/changes/reduce-screen-sync-polling/tasks.md diff --git a/openspec/changes/reduce-screen-sync-polling/.openspec.yaml b/openspec/changes/reduce-screen-sync-polling/.openspec.yaml new file mode 100644 index 0000000..9123314 --- /dev/null +++ b/openspec/changes/reduce-screen-sync-polling/.openspec.yaml @@ -0,0 +1,2 @@ +schema: wealth-ledger-sdd +created: 2026-10-07 diff --git a/openspec/changes/reduce-screen-sync-polling/design.md b/openspec/changes/reduce-screen-sync-polling/design.md new file mode 100644 index 0000000..acf4c40 --- /dev/null +++ b/openspec/changes/reduce-screen-sync-polling/design.md @@ -0,0 +1,104 @@ +## Context + +`useScreenSync` уже является общим module для экранной синхронизации. Его +interface принимает scope и набор resource queries; реализация опрашивает +статусы выполняющейся работы и вызывает `observe()` для ресурсов того же +экрана. Один интервал в 1 секунду управляет обоими видами запросов, поэтому +страницы с несколькими ресурсами умножают фоновый трафик. + +Нужна меньшая частота обновления при сохранении текущей cache identity, +автоматического восстановления, защиты доступа и итогового обновления сразу +после завершения работы. + +## Goals / Non-Goals + +**Goals:** + +- Сократить периодический HTTP-трафик выполняющейся экранной синхронизации + примерно в пять раз. +- Сохранить небольшую и прежнюю interface `useScreenSync` для всех page VMs. +- Сразу обновлять ресурсы после terminal state синхронизации. +- Проверять поведение на HTTP seam, а не детали реализации TanStack Query. + +**Non-Goals:** + +- Изменять backend status contract, resource endpoints или модель синхронизации. +- Вводить отдельный polling module, второй cache или push-канал. +- Менять пользовательское представление загрузки и ошибок. + +## Decisions + +### Preserve one screen-sync module and lengthen its interval + +`useScreenSync` остаётся единственным module, который владеет связью между +статусом экранной синхронизации и observe reads. Его implementation заменяет +интервал status polling с одной секунды на пять секунд. Поскольку effect уже +наблюдает ресурсы после нового status response, это одним изменением +ограничивает оба потока запросов без расширения interface для callers. + +Alternative: добавить второй timer только для observe reads при status polling +раз в секунду. Отклонено: status traffic останется частым, а два независимых +ритма увеличат implementation и риск дублирующих наблюдений без требуемой +пользы. + +Alternative: читать ресурсы только после terminal state. Отклонено: это +устранит промежуточную публикацию уже готовых данных и изменит существующее +поведение сильнее, чем требуется. + +### Keep completion observation driven by the terminal status response + +Текущий effect уже distinguishes running и completed status: для terminal state +он observes every resource, включая тот, который был fetching. Этот путь +сохраняется. Terminal response не ждёт отдельного timer, поэтому итоговый +результат появляется в обработке того же status response; максимальная +задержка возникает только до следующей пятиисекундной проверки. + +### Test the public HTTP outcome at the screen-sync seam + +Colocated tests `screen-sync` будут использовать MSW и fake timers, чтобы +проверить отсутствие повторного status/read traffic до пяти секунд, следующий +цикл после интервала и одно итоговое observe read при terminal status. Existing +tests продолжат доказывать, что уход с экрана останавливает polling и что +observe reads не создают новую импортирующую работу. + +## UI/UX Applicability and Package + +**Applicability and scope:** N/A. Изменяется только частота невидимых фоновых +запросов; экраны, состояния, interactions и responsive behavior не меняются. + +## Delivery Map + +| Area | Status | Architectural outcome or N/A reason | +| --- | --- | --- | +| frontend | affected | `useScreenSync` реже опрашивает статус и тем самым реже наблюдает ресурсы, сохраняя немедленное обновление после terminal state. | +| backend | N/A | Status и resource contracts не меняются. | +| specs | affected | Delta фиксирует пятиисекундную верхнюю частоту и итоговое наблюдение после terminal state. | +| docs | N/A | Пользовательские и эксплуатационные инструкции не меняются. | + +## Risks / Trade-offs + +- Промежуточно готовые данные могут появиться до четырёх секунд позже, чем + раньше; пользователь явно выбрал меньший трафик в обмен на эту задержку. +- Terminal state обнаруживается следующей status-проверкой, поэтому его + отображение также может ждать до пяти секунд после фактического завершения + backend work. После обнаружения дополнительной задержки нет. +- Смена только общей константы затрагивает все экраны-потребители; тесты + module защищают единое ожидаемое поведение. + +## Migration Plan + +1. Изменить policy interval у существующего screen-sync module. +2. Адаптировать и дополнить его seam tests для пятиисекундного ритма и + terminal refresh. +3. Выполнить локальные frontend quality gates перед поставкой. + +### Rollback Contract + +| Field | Decision | +| --- | --- | +| Status | `N/A` | +| Reason | Изменение локальной frontend polling policy не меняет данные, публичный contract, security или миграции; rollback состоит в возврате прежнего значения интервала. | +| Trigger | N/A | +| Actions | N/A | +| Data safety | N/A | +| Verification | N/A | diff --git a/openspec/changes/reduce-screen-sync-polling/proposal.md b/openspec/changes/reduce-screen-sync-polling/proposal.md new file mode 100644 index 0000000..3de0478 --- /dev/null +++ b/openspec/changes/reduce-screen-sync-polling/proposal.md @@ -0,0 +1,50 @@ +## Why + +Пока экран ожидает синхронизацию T-Bank, клиент опрашивает её состояние каждую +секунду. Каждый новый ответ запускает наблюдение всех ресурсов открытого экрана. +На экранах с несколькими финансовыми выборками это создаёт непропорционально +много запросов при том, что пользователь готов увидеть промежуточный результат +с небольшой задержкой. + +## What Changes + +- Во время выполняющейся экранной синхронизации приложение реже проверяет её + состояние и обновляет наблюдаемые финансовые ресурсы не чаще одного раза за + пять секунд. +- После terminal state синхронизации приложение сразу наблюдает ресурсы + открытого экрана, чтобы отобразить итоговый результат без дополнительной + задержки. +- Существующие состояния ожидания, доступные частичные результаты, + автоматическое восстановление чтения и прекращение работы после ухода с + экрана сохраняются. + +Ожидаемый результат: длительная синхронизация создаёт существенно меньше +фоновых HTTP-запросов, а пользователь получает промежуточные результаты с +задержкой не более пяти секунд и итоговые данные сразу после завершения. + +Non-goals: + +- Изменять запуск синхронизации, её scope, доступ к данным или финансовые + расчёты. +- Добавлять новые пользовательские элементы, ручное управление частотой или + отдельный канал доставки изменений. +- Гарантировать обновления финансовых данных в реальном времени. + +## Capabilities + +### New Capabilities + + + +### Modified Capabilities + +- `specs/frontend-data-resilience/spec.md`: ограниченная частота наблюдения + ресурсов во время выполняющейся синхронизации и немедленное наблюдение после + terminal state. + +## Impact + +Изменение затрагивает финансовые экраны, использующие экранную синхронизацию: +счета, детали счёта, операции, доходы, события и страницы инструментов. Оно +сокращает фоновый HTTP-трафик при продолжающейся синхронизации, сохраняя +автоматическое отображение готовых данных и существующие правила устойчивости. diff --git a/openspec/changes/reduce-screen-sync-polling/specs/frontend-data-resilience/spec.md b/openspec/changes/reduce-screen-sync-polling/specs/frontend-data-resilience/spec.md new file mode 100644 index 0000000..cb58273 --- /dev/null +++ b/openspec/changes/reduce-screen-sync-polling/specs/frontend-data-resilience/spec.md @@ -0,0 +1,85 @@ +## MODIFIED Requirements + +### Requirement: Временные сбои чтения восстанавливаются автоматически + +Frontend SHALL автоматически повторять временно неуспешное чтение и +восстанавливать получение необходимых текущему экрану данных без ручного +обновления. Повторы одной попытки MUST иметь конечный предел и паузы, +исключающие непрерывную череду запросов. При исчерпании предела доступные данные +SHALL сохраняться, а при их отсутствии SHALL показываться локальная +недоступность. Возвращение сети, возвращение пользователя к открытому экрану и +повторное открытие экрана MUST возобновлять получение отсутствующих или +требующих обновления данных без перезагрузки страницы. Свежий полный результат +MUST NOT требовать обращения к источнику только из-за такого события. + +Наблюдая выполняющуюся экранную синхронизацию, frontend MUST проверять её +состояние и повторно читать связанные ресурсы не чаще одного раза за пять +секунд. После получения terminal state этой синхронизации frontend MUST сразу +наблюдать ресурсы текущего экрана, не ожидая следующего пятиисекундного +интервала. + +Восстановление MUST учитывать сбой чтения результата и сбой самого получения +данных из источника, даже если чтение состояния завершилось успешно. Наблюдение +уже выполняющейся работы MUST NOT запускать её повторно. Уход с экрана MUST +прекращать новые попытки его восстановления; это не требует отменять уже +начатую работу источника. Автоматическое восстановление MUST NOT повторять +запросы, требующие исправления ввода, входа или восстановления доступа, и MUST +NOT переносить старые параметры в новую пользовательскую выборку. + +#### Scenario: Кратковременный сбой чтения +- **WHEN** чтение текущей выборки временно не удалось, а следующая разрешённая + автоматическая попытка успешна +- **THEN** экран самостоятельно показывает результат без ручного действия и без + сообщения о сбое или восстановлении + +#### Scenario: Экранная синхронизация продолжается +- **WHEN** экран наблюдает синхронизацию, которая остаётся в состоянии running + после очередной проверки +- **THEN** frontend выполняет следующую проверку состояния и наблюдение + связанных ресурсов не ранее чем через пять секунд + +#### Scenario: Экранная синхронизация завершилась +- **WHEN** очередная проверка экранной синхронизации возвращает terminal state +- **THEN** frontend сразу наблюдает связанные ресурсы текущего экрана, чтобы + показать итоговый результат без ожидания следующего интервала + +#### Scenario: Источник завершил работу ошибкой +- **WHEN** чтение сохранённых данных успешно, но получение необходимых новых + данных из источника временно не удалось +- **THEN** приложение применяет ограниченное автоматическое восстановление к + неуспешной работе, а не считает успешное чтение доказательством её успеха + +#### Scenario: Повторы исчерпаны +- **WHEN** временная недоступность сохраняется после конечного предела + автоматических попыток +- **THEN** приложение прекращает серию повторов, сохраняет доступный результат + либо локальную недоступность без бесконечной загрузки и ожидает следующего + события восстановления + +#### Scenario: Сеть или пользователь вернулись +- **WHEN** после временного сбоя восстановилась сеть либо пользователь вернулся + к экрану с отсутствующим или требующим обновления результатом +- **THEN** получение данных возобновляется автоматически для текущей выборки и + при успехе заменяет состояние недоступности содержимым + +#### Scenario: Несколько событий восстановления совпали +- **WHEN** сеть восстановилась одновременно с возвращением пользователя на экран +- **THEN** приложение не запускает дублирующую работу получения одного набора + данных + +#### Scenario: Работа источника ещё выполняется +- **WHEN** приложение восстанавливает чтение состояния уже выполняющейся работы +- **THEN** оно продолжает получение её результата без повторного запуска той же + работы + +#### Scenario: Пользователь покинул экран +- **WHEN** пользователь ушёл со страницы с ожидающим восстановлением +- **THEN** новые попытки для покинутого экрана прекращаются, а уже начатая работа + не изменяет содержимое другой выборки + +#### Scenario: Ошибка требует действия пользователя +- **WHEN** подтверждены недействительное подключение, отсутствие доступа или + некорректный ввод +- **THEN** автоматическая серия повторов прекращается и появляется + соответствующее действие или локальная ошибка без технической кнопки повторной + загрузки diff --git a/openspec/changes/reduce-screen-sync-polling/tasks.md b/openspec/changes/reduce-screen-sync-polling/tasks.md new file mode 100644 index 0000000..4530ba0 --- /dev/null +++ b/openspec/changes/reduce-screen-sync-polling/tasks.md @@ -0,0 +1,30 @@ +## 1. Screen synchronization policy + +- [x] 1.1 [frontend] Change the screen-sync status polling policy from one + second to five seconds while keeping the existing `useScreenSync` interface + and terminal-state resource observation. + - **Covers:** `frontend-data-resilience` — `Временные сбои чтения восстанавливаются автоматически` + - **Verification:** Run the colocated screen-sync test file and confirm its + MSW assertions show no subsequent status or observe request before five + seconds, with resources observed on a terminal status response. + +- [x] 1.2 [frontend] Update colocated screen-sync tests with fake timers to + cover the five-second running cadence, immediate terminal observation, and + existing stop-on-unmount behavior. + - **Covers:** `frontend-data-resilience` — `Временные сбои чтения восстанавливаются автоматически` + - **Verification:** `nvm use --silent && npm test -- screen-sync.test.tsx` + +## 2. Frontend delivery + +- [x] 2.1 [frontend] Run the frontend's canonical verification after the + polling-policy and regression-test changes. + - **Covers:** `N/A` — This task verifies the affected frontend delivery; it + introduces no separate observable behavior beyond the requirement covered + by tasks 1.1 and 1.2. + - **Verification:** `nvm use --silent && npm run verify` + +- [x] 2.2 [specs] Verify the completed OpenSpec change against the + `wealth-ledger-specs` store before implementation review. + - **Covers:** `N/A` — This task validates the planning artifacts and their + traceability; it does not introduce runtime behavior. + - **Verification:** `openspec validate --change reduce-screen-sync-polling --store wealth-ledger-specs`