From 0469756d3bc983e32811470b671d743cd5009739 Mon Sep 17 00:00:00 2001 From: codex-bot Date: Tue, 3 Nov 2026 07:45:09 +0300 Subject: [PATCH] spec: allow warning and retry after exhausted read retries (WealthLedger/specs#79) (#80) --- .../spec.md | 7 ++-- .../brokerage-account-ledger/spec.md | 7 ++-- .../brokerage-account-upcoming-events/spec.md | 5 +-- .../brokerage/brokerage-accounts/spec.md | 5 +-- .../frontend-data-resilience/spec.md | 34 ++++++++++++++++--- .../frontend-loading-presentation/spec.md | 5 +-- .../frontend-ui-resilience/spec.md | 5 ++- .../frontend-user-feedback/spec.md | 12 +++++-- .../specs/portfolio/portfolio-view/spec.md | 2 +- 9 files changed, 61 insertions(+), 21 deletions(-) diff --git a/openspec/specs/brokerage/brokerage-account-income-analytics/spec.md b/openspec/specs/brokerage/brokerage-account-income-analytics/spec.md index 8f08d4c..e105d4b 100644 --- a/openspec/specs/brokerage/brokerage-account-income-analytics/spec.md +++ b/openspec/specs/brokerage/brokerage-account-income-analytics/spec.md @@ -113,8 +113,9 @@ totals, comparisons, buckets или breakdown как полный результат. При временной недоступности клиент MUST сохранять предыдущий полный результат той же выборки либо показывать нейтральную недоступность соответствующего расчёта без технических сообщений -и ручного повтора. Восстановление SHALL выполняться автоматически по -`frontend-data-resilience`. +и ручного повтора, пока автоматические повторы не исчерпаны; после их исчерпания +применяются предупреждение и «Повторить» по `frontend-data-resilience`. +Восстановление SHALL выполняться автоматически по `frontend-data-resilience`. Доступные независимые части MUST оставаться видимыми; неполное сравнение MUST обозначаться как недоступное без нулевой базы и окончательной разницы. Успешный @@ -148,7 +149,7 @@ summary «Получено купонами и дивидендами» за п Пустой или неуспешный расчёт MUST оставаться локальным состоянием блока и MUST NOT заменять успешно отображённый Portfolio или другие блоки обзора. Временная ошибка обновления MUST сохранять доступную сводку той же выборки без -предупреждения и ручного повтора. При отсутствии результата SHALL показываться +предупреждения и ручного повтора, пока автоматические повторы не исчерпаны. При отсутствии результата SHALL показываться нейтральная недоступность после первичного ожидания с автоматическим восстановлением. #### Scenario: Обзор показывает доход текущего месяца diff --git a/openspec/specs/brokerage/brokerage-account-ledger/spec.md b/openspec/specs/brokerage/brokerage-account-ledger/spec.md index 175e27a..89bb159 100644 --- a/openspec/specs/brokerage/brokerage-account-ledger/spec.md +++ b/openspec/specs/brokerage/brokerage-account-ledger/spec.md @@ -70,7 +70,7 @@ показываются в заголовке группы. Неуспешный или пустой запрос MUST оставаться локальным состоянием блока и MUST NOT заменять успешно отображённый Portfolio. При временном сбое обновления блок MUST сохранять доступные записи без технического предупреждения -или ручного повтора. При отсутствии результата он SHALL показывать первичное +или ручного повтора, пока автоматические повторы не исчерпаны. При отсутствии результата он SHALL показывать первичное ожидание либо нейтральную недоступность, автоматически восстанавливая чтение. Неподтверждённая пустота MUST NOT представляться отсутствием операций. @@ -185,14 +185,15 @@ обновления и восстанавливать чтение автоматически по `frontend-data-resilience`. Период, категории и выбранная страница MUST сохраняться; результат другой выборки MUST NOT подменять текущую. Страница MUST NOT показывать время получения, -технические статусы или действия ручного повтора. Даты операций, фильтры, +технические статусы или действия ручного повтора до исчерпания автоматических +повторов (далее по `frontend-data-resilience`). Даты операций, фильтры, действия их применения и переходы по страницам MUST оставаться доступными. При отсутствии результата SHALL применяться первичное ожидание и нейтральная недоступность, а не сообщение об отсутствии операций до подтверждения полноты. #### Scenario: Обновление журнала временно не удалось - **WHEN** для применённого периода и страницы уже есть записи, а обновление завершается временной ошибкой -- **THEN** записи и параметры просмотра сохраняются без предупреждения и кнопки повтора до автоматического восстановления +- **THEN** записи и параметры просмотра сохраняются без предупреждения и кнопки повтора до автоматического восстановления либо до исчерпания автоматических повторов #### Scenario: Следующая страница ещё не получена - **WHEN** пользователь перешёл к следующей странице, но её загрузка временно не удалась diff --git a/openspec/specs/brokerage/brokerage-account-upcoming-events/spec.md b/openspec/specs/brokerage/brokerage-account-upcoming-events/spec.md index c42251a..397e8e8 100644 --- a/openspec/specs/brokerage/brokerage-account-upcoming-events/spec.md +++ b/openspec/specs/brokerage/brokerage-account-upcoming-events/spec.md @@ -100,7 +100,8 @@ MUST объяснять, что прогноз основан на позици При временном сбое обновления страница MUST сохранять ранее доступный результат той же выборки с его исходными `calculatedAt` и окном, без индикации -собственного чтения и ручного повтора. Состояние источника из `meta`, включая +собственного чтения и ручного повтора до исчерпания автоматических повторов +(затем применяются предупреждение и «Повторить» по `frontend-data-resilience`). Состояние источника из `meta`, включая неуспех последней часовой попытки и неполноту, MUST представляться по `frontend-data-resilience`. При отсутствии результата SHALL показываться первичное ожидание либо нейтральная недоступность с автоматическим @@ -117,7 +118,7 @@ MUST скрывать личные данные независимо от нал #### Scenario: Ошибка страницы - **WHEN** запрос будущих событий завершается временной ошибкой -- **THEN** страница сохраняет доступный результат той же выборки либо показывает нейтральную недоступность без ручного повтора, восстанавливая чтение автоматически и не выдавая частичные данные за полный прогноз +- **THEN** страница сохраняет доступный результат той же выборки либо показывает нейтральную недоступность без ручного повтора до исчерпания автоматических повторов, восстанавливая чтение автоматически и не выдавая частичные данные за полный прогноз #### Scenario: Прогнозный дивиденд с неизвестной суммой - **WHEN** прогноз содержит дивиденд с известной датой реестра, но без суммы diff --git a/openspec/specs/brokerage/brokerage-accounts/spec.md b/openspec/specs/brokerage/brokerage-accounts/spec.md index ced67a5..a500605 100644 --- a/openspec/specs/brokerage/brokerage-accounts/spec.md +++ b/openspec/specs/brokerage/brokerage-accounts/spec.md @@ -71,7 +71,8 @@ в течение 60 секунд. После истечения этого срока открытие или возвращение на экран SHALL инициировать получение актуального списка; имеющийся Client Cached Snapshot MUST оставаться видимым во время обновления и после временной -ошибки без индикации собственного чтения и действий повтора. +ошибки без индикации собственного чтения и действий повтора, пока автоматические +повторы не исчерпаны (далее по `frontend-data-resilience`). Автоматическое восстановление SHALL соответствовать `frontend-data-resilience`. Открытый экран MAY периодически перечитывать backend-результат, сохраняя видимый snapshot, и MUST NOT создавать импорт T-Bank. Состояние источника из @@ -124,7 +125,7 @@ Money-итогов в исходных валютах и обозначать н #### Scenario: Ошибка фонового обновления не скрывает snapshot - **WHEN** обновление устаревшего списка завершается временной ошибкой при наличии последнего успешного Client Cached Snapshot -- **THEN** клиент сохраняет snapshot видимым без предупреждения и ручного повтора и восстанавливает получение данных автоматически +- **THEN** клиент сохраняет snapshot видимым без предупреждения и ручного повтора до исчерпания автоматических повторов и восстанавливает получение данных автоматически #### Scenario: Карточка ограничивает валютные итоги - **WHEN** доступная сводка счёта содержит итоги в трёх или более валютах diff --git a/openspec/specs/frontend-platform/frontend-data-resilience/spec.md b/openspec/specs/frontend-platform/frontend-data-resilience/spec.md index 4ec3f28..ef83369 100644 --- a/openspec/specs/frontend-platform/frontend-data-resilience/spec.md +++ b/openspec/specs/frontend-platform/frontend-data-resilience/spec.md @@ -18,7 +18,9 @@ Portfolio и других экранов чтения при фоновом об выборки как результат новой. Доступный результат MUST оставаться видимым без индикаторов фонового чтения -клиента, технических предупреждений об этом чтении и действий ручного повтора. +клиента, технических предупреждений об этом чтении и действий ручного повтора, +пока автоматические повторы не исчерпаны; после их исчерпания применяется +требование «Временные сбои чтения восстанавливаются автоматически». Frontend MUST NOT подменять внутренние признаки свежести и полноты, успешное время источника или ошибку обновления только ради отсутствия их отображения. Client Cached Snapshot MUST оставаться отличным от server-side fallback; @@ -43,14 +45,14 @@ MUST NOT возвращать их на экран. #### Scenario: Resource сохраняется после неуспешной часовой попытки - **WHEN** response содержит полный `data` и `meta`, обозначающий неуспех последней часовой попытки -- **THEN** frontend сохраняет `data` и его исходное время видимыми и отдельно обозначает неуспех попытки, не предлагая ручной повтор +- **THEN** frontend сохраняет `data` и его исходное время видимыми и отдельно обозначает неуспех попытки, не предлагая запуск повторного получения данных из источника #### Scenario: Обновление Portfolio завершается ошибкой после успешного ответа - **WHEN** экран Brokerage Account уже показывает Client Cached Snapshot Portfolio, а последующее обновление этого же Portfolio завершается временной ошибкой -- **THEN** frontend сохраняет Portfolio видимым без предупреждения и ручного повтора, а восстановление выполняется автоматически +- **THEN** frontend сохраняет Portfolio видимым без предупреждения и ручного повтора, а восстановление выполняется автоматически, пока автоматические повторы не исчерпаны #### Scenario: Server-side fallback и client cached snapshot различаются -- **WHEN** backend возвращает Portfolio с `isStale` либо фоновое обновление Client Cached Snapshot завершается временной ошибкой +- **WHEN** backend возвращает Portfolio с `isStale` либо фоновое обновление Client Cached Snapshot завершается временной ошибкой, а автоматические повторы ещё не исчерпаны - **THEN** frontend сохраняет доступные данные без технических сообщений и не подменяет один внутренний вид состояния другим #### Scenario: Подтверждённая пустота переживает фоновую ошибку @@ -75,7 +77,17 @@ Frontend SHALL автоматически повторять временно н получение необходимых текущему экрану данных без ручного обновления. Повторы одной попытки MUST иметь конечный предел и паузы, исключающие непрерывную череду запросов. При исчерпании предела доступные данные SHALL сохраняться, -а при их отсутствии SHALL показываться локальная недоступность. Возвращение сети, +а при их отсутствии SHALL показываться локальная недоступность. На экранах +Account, Accounts, Income, Operations, Events и секций деталей инструмента при исчерпании предела +frontend SHALL дополнительно показывать неблокирующее локализованное предупреждение +о неудачном обновлении и действие «Повторить» рядом с затронутым результатом либо +локальной недоступностью. Действие MUST повторять только чтение (GET) затронутого +запроса, не запускать получение данных из источника и не менять выбранные +фильтры, период, открытые разделы и ввод; успешное чтение MUST снимать +предупреждение и MUST NOT сообщать об успехе. Предупреждение MUST NOT дублировать +состояние источника из `meta` и MUST NOT изменять `Portfolio.isStale`. На остальных +экранах чтения, включая поиск, диапазон графика, карты и настройки подключения, +предупреждение и действие повтора MUST NOT показываться. Возвращение сети, возвращение пользователя к открытому экрану и повторное открытие экрана MUST возобновлять получение отсутствующих или требующих обновления данных без перезагрузки страницы. Свежий полный результат MUST NOT требовать обращения @@ -101,6 +113,18 @@ Frontend SHALL автоматически повторять временно н - **WHEN** временная недоступность сохраняется после конечного предела автоматических попыток - **THEN** приложение прекращает серию повторов, сохраняет доступный результат либо локальную недоступность без бесконечной загрузки и ожидает следующего события восстановления +#### Scenario: Повторы исчерпаны при сохранённом результате +- **WHEN** на экране Account, Accounts, Income, Operations, Events либо в секции деталей инструмента автоматические повторы исчерпаны, а ранее полученный результат остаётся доступным +- **THEN** результат и его исходное состояние источника остаются видимыми, рядом показываются неблокирующее предупреждение о неудачном обновлении и действие «Повторить», а активация действия повторяет только чтение затронутого запроса и после успеха снимает предупреждение + +#### Scenario: Повторы исчерпаны без результата +- **WHEN** на тех же экранах автоматические повторы исчерпаны, а результата выборки нет +- **THEN** локальная недоступность содержит действие «Повторить», повторяющее только чтение затронутого запроса, и результат одной секции деталей не блокирует восстановление остальных + +#### Scenario: Поиск, график и карты остаются тихими +- **WHEN** автоматические повторы исчерпаны при чтении результата поиска, диапазона графика, карт либо настроек подключения +- **THEN** приложение не показывает предупреждение и действие повтора и сохраняет прежнее локальное поведение + #### Scenario: Сеть или пользователь вернулись - **WHEN** после временного сбоя восстановилась сеть либо пользователь вернулся к экрану с отсутствующим или требующим обновления результатом - **THEN** получение данных возобновляется автоматически для текущей выборки и при успехе заменяет состояние недоступности содержимым diff --git a/openspec/specs/frontend-platform/frontend-loading-presentation/spec.md b/openspec/specs/frontend-platform/frontend-loading-presentation/spec.md index 6e5e92e..38f5c80 100644 --- a/openspec/specs/frontend-platform/frontend-loading-presentation/spec.md +++ b/openspec/specs/frontend-platform/frontend-loading-presentation/spec.md @@ -79,7 +79,8 @@ MUST NOT заменять уже доступный контекст skeleton pl ожидание соответствующей области. После неуспешного завершения получения либо истечения ограниченного времени первичного ожидания область MUST переходить в спокойное локализованное состояние недоступности без технических подробностей -и ручного повтора. Это состояние MUST NOT утверждать, что результат пустой, +и ручного повтора, пока автоматические повторы не исчерпаны (далее по +`frontend-data-resilience`). Это состояние MUST NOT утверждать, что результат пустой, или требовать перезагрузки страницы. Продолжающееся автоматическое восстановление MUST NOT заставлять область постоянно переключаться между недоступностью и skeleton. После успешного получения содержимое SHALL появляться автоматически. @@ -94,7 +95,7 @@ skeleton. После успешного получения содержимое #### Scenario: Первое получение данных не удалось - **WHEN** у области нет результата и первоначальная загрузка завершилась ошибкой или превысила ограниченное время ожидания -- **THEN** область показывает нейтральную недоступность без кнопки повтора, вымышленных данных и бесконечного индикатора занятости +- **THEN** область показывает нейтральную недоступность без кнопки повтора до исчерпания автоматических повторов, вымышленных данных и бесконечного индикатора занятости #### Scenario: Восстановление продолжается после недоступности - **WHEN** область уже показывает недоступность и выполняется очередная разрешённая попытка восстановления diff --git a/openspec/specs/frontend-platform/frontend-ui-resilience/spec.md b/openspec/specs/frontend-platform/frontend-ui-resilience/spec.md index 752e66c..31adaa9 100644 --- a/openspec/specs/frontend-platform/frontend-ui-resilience/spec.md +++ b/openspec/specs/frontend-platform/frontend-ui-resilience/spec.md @@ -30,7 +30,10 @@ Frontend SHALL сохранять локальное отображение из Account, Portfolio и T-Bank connection. Эти состояния MUST NOT заменяться глобальным fallback. Временная ошибка фонового чтения MUST сохранять доступный результат без предупреждения об устаревании, технической ошибки и ручного -повтора. При отсутствии результата SHALL показываться локальная недоступность +повтора, пока автоматические повторы не исчерпаны; для Brokerage Account и +Portfolio после их исчерпания применяется `frontend-data-resilience` +(предупреждение и «Повторить»), для T-Bank connection поведение остаётся тихим. +При отсутствии результата SHALL показываться локальная недоступность с автоматическим восстановлением. Подтверждённая необходимость входа, восстановления подключения или выбора доступного счёта MUST сохранять понятное объяснение и соответствующее действие, не маскируясь сохранёнными личными данными. diff --git a/openspec/specs/frontend-platform/frontend-user-feedback/spec.md b/openspec/specs/frontend-platform/frontend-user-feedback/spec.md index a1fff19..c5df166 100644 --- a/openspec/specs/frontend-platform/frontend-user-feedback/spec.md +++ b/openspec/specs/frontend-platform/frontend-user-feedback/spec.md @@ -15,7 +15,11 @@ об успехе либо временной ошибке такого обновления. Приложение MUST NOT предоставлять кнопки или иные действия ручного обновления и повторной загрузки, включая их иконные варианты. Эти сведения MUST NOT переноситься в уведомления, подсказки -или объявления вспомогательных технологий. Даты операций, выплат, открытия +или объявления вспомогательных технологий. Единственное исключение — предупреждение +о неудачном обновлении и действие «Повторить» на экранах Account, Accounts, Income, Operations, Events и секций деталей инструмента после +исчерпания конечной серии автоматических повторов (по `frontend-data-resilience`); +запрет по-прежнему действует до этого момента, на остальных экранах и для иконных +вариантов обновления. Даты операций, выплат, открытия счёта и выбранных периодов MUST сохранять свой предметный смысл. Запрет технических действий MUST NOT удалять применение фильтров, переходы между @@ -24,9 +28,13 @@ сохранённый ввод обычным действием формы. #### Scenario: Фоновая загрузка завершилась ошибкой -- **WHEN** на любом из перечисленных экранов уже есть доступный результат и его фоновое обновление временно не удалось +- **WHEN** на любом из перечисленных экранов уже есть доступный результат и его фоновое обновление временно не удалось, а автоматические повторы ещё не исчерпаны - **THEN** результат остаётся видимым без предупреждения, времени получения, индикатора, уведомления и действия ручного повтора +#### Scenario: Автоматические повторы исчерпаны на экране инвестиций +- **WHEN** на экране Account, Accounts, Income, Operations, Events либо в секции деталей инструмента автоматические повторы исчерпаны +- **THEN** экран показывает неблокирующее предупреждение и действие «Повторить» по `frontend-data-resilience`, не показывает время получения, индикатор или уведомление и не объявляет их вспомогательным технологиям как успех или прогресс + #### Scenario: Фоновая загрузка завершилась успешно - **WHEN** приложение получает обновлённые данные без явного действия сохранения со стороны пользователя - **THEN** содержимое обновляется без сообщения об успешной загрузке и без переноса фокуса diff --git a/openspec/specs/portfolio/portfolio-view/spec.md b/openspec/specs/portfolio/portfolio-view/spec.md index 451fc3f..0417b0b 100644 --- a/openspec/specs/portfolio/portfolio-view/spec.md +++ b/openspec/specs/portfolio/portfolio-view/spec.md @@ -248,7 +248,7 @@ Portfolio и предложить возврат к списку счетов. #### Scenario: Первичный Portfolio пока недоступен - **WHEN** данных Portfolio нет, а первичное получение не удалось или превысило ограниченное время ожидания -- **THEN** клиент показывает нейтральную недоступность без кнопки повтора и автоматически заменяет её содержимым после успешного восстановления +- **THEN** клиент показывает нейтральную недоступность без кнопки повтора до исчерпания автоматических повторов и автоматически заменяет её содержимым после успешного восстановления #### Scenario: Требуется восстановить подключение - **WHEN** клиент получает `TBANK_NOT_CONNECTED` или `INVALID_TBANK_TOKEN` при наличии сохранённого личного Portfolio