spec: add reduce-screen-sync-polling change #21

Merged
ksv741 merged 2 commits from codex/reduce-screen-sync-polling into develop 2026-10-07 14:25:16 +03:00
5 changed files with 271 additions and 0 deletions
Showing only changes of commit 271024b8d8 - Show all commits
@@ -0,0 +1,2 @@
schema: wealth-ledger-sdd
created: 2026-10-07
@@ -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 |
@@ -0,0 +1,50 @@
## Why
Пока экран ожидает синхронизацию T-Bank, клиент опрашивает её состояние каждую
секунду. Каждый новый ответ запускает наблюдение всех ресурсов открытого экрана.
На экранах с несколькими финансовыми выборками это создаёт непропорционально
много запросов при том, что пользователь готов увидеть промежуточный результат
с небольшой задержкой.
## What Changes
- Во время выполняющейся экранной синхронизации приложение реже проверяет её
состояние и обновляет наблюдаемые финансовые ресурсы не чаще одного раза за
пять секунд.
- После terminal state синхронизации приложение сразу наблюдает ресурсы
открытого экрана, чтобы отобразить итоговый результат без дополнительной
задержки.
- Существующие состояния ожидания, доступные частичные результаты,
автоматическое восстановление чтения и прекращение работы после ухода с
экрана сохраняются.
Ожидаемый результат: длительная синхронизация создаёт существенно меньше
фоновых HTTP-запросов, а пользователь получает промежуточные результаты с
задержкой не более пяти секунд и итоговые данные сразу после завершения.
Non-goals:
- Изменять запуск синхронизации, её scope, доступ к данным или финансовые
расчёты.
- Добавлять новые пользовательские элементы, ручное управление частотой или
отдельный канал доставки изменений.
- Гарантировать обновления финансовых данных в реальном времени.
## Capabilities
### New Capabilities
<!-- None. -->
### Modified Capabilities
- `specs/frontend-data-resilience/spec.md`: ограниченная частота наблюдения
ресурсов во время выполняющейся синхронизации и немедленное наблюдение после
terminal state.
## Impact
Изменение затрагивает финансовые экраны, использующие экранную синхронизацию:
счета, детали счёта, операции, доходы, события и страницы инструментов. Оно
сокращает фоновый HTTP-трафик при продолжающейся синхронизации, сохраняя
автоматическое отображение готовых данных и существующие правила устойчивости.
@@ -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** автоматическая серия повторов прекращается и появляется
соответствующее действие или локальная ошибка без технической кнопки повторной
загрузки
@@ -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`