Files
specs/openspec/specs/hourly-investment-sync/spec.md
T
ksv741 29c4ee443a
Conventional commits / commits (pull_request) Successful in 13s
Specs security / security (pull_request) Successful in 8s
Specs verify / verify (pull_request) Successful in 10s
spec: archive harden-hourly-sync-lifecycle change (WealthLedger/backend#56)
2026-10-12 22:41:23 +03:00

12 KiB
Raw Blame History

hourly-investment-sync Specification

Purpose

Определяет независимое от открытых экранов часовое обновление личных инвестиционных данных и безопасно наблюдаемый результат последней попытки.

Requirements

Requirement: Часовой обход личных инвестиционных данных

Система SHALL начинать первый часовой обход после успешного подключения T-Bank и последующие обходы не ранее чем через 60 минут от начала предыдущей попытки этого подключения. После простоя система MUST выполнить не более одного актуального обхода и MUST NOT воспроизводить пропущенные часы. Неуспешная попытка MUST NOT повторяться ранее следующего часового срока. Перекрывающиеся обходы MUST NOT выполняться: срок, наступивший во время выполняющегося обхода, MUST быть пропущен и MUST NOT ставиться в очередь; следующий обход становится допустимым только в следующий 60-минутный срок, отсчитанный от начала выполнявшейся попытки. Обход MUST обновлять доступные счета, Portfolio каждого доступного счёта, изменяемый хвост операций и будущие события по бумагам текущего Portfolio. Он MUST NOT повторно загружать полные прошлые интервалы операций, завершённые свечи или полную рыночную историю и MUST NOT зависеть от открытия frontend-экрана.

Scenario: Первое подключение

  • WHEN User успешно подключает T-Bank между часовыми сроками
  • THEN первый обход начинается без ожидания следующего календарного часа

Scenario: Возобновление после простоя

  • WHEN backend запускается после пропуска нескольких часовых сроков
  • THEN система выполняет один актуальный обход без синтетических прошлых обновлений

Scenario: Перекрытый срок

  • WHEN предыдущий обход всё ещё выполняется в момент очередного срока
  • THEN система не начинает второй обход и не ставит пропущенный обход в очередь

Scenario: Длительный обход пропускает один срок

  • WHEN обход начался в 10:00, всё ещё выполняется в 11:00 и завершился до 12:00
  • THEN система не запускает обход в 11:00 и может начать следующий не ранее 12:00

Requirement: Последний результат обхода доступен только для наблюдения

Система SHALL предоставлять авторизованному User результат последнего обхода только в границе его текущего подключения: время начала, состояние выполнения, полного успеха, частичного успеха либо неуспеха и безопасный перечень проблемных счетов или разделов. Это состояние MUST быть доступно в meta каждого затронутого resource read вместе с freshness, полнотой и доступностью его data. Успех одного счёта или раздела MUST сохраняться независимо от ошибки другого; ошибка MUST NOT заменять его последнее успешное состояние или время. Итог попытки MUST определяться фактическим результатом каждого обязательного шага обхода: попытка, не завершившая обязательный шаг, MUST обозначаться частичным успехом либо неуспехом и MUST NOT обозначаться полным успехом. Отсутствие состоявшейся попытки MUST отличаться от успешной попытки. Наблюдение результата MUST NOT предоставлять способ начать личную синхронизацию.

Scenario: Частичный успех

  • WHEN Portfolio одного доступного счёта обновился, а другого не обновился
  • THEN новый Portfolio первого сохраняется, прежний успешный Portfolio второго остаётся доступным, а результат обхода обозначает частичный успех и проблемный счёт

Scenario: Наблюдение не запускает обход

  • WHEN User запрашивает результат последнего обхода
  • THEN система возвращает доступный сохранённый результат без нового обращения к T-Bank

Scenario: Старая граница подключения

  • WHEN User заменил либо удалил подключение и запрашивает результат прежнего обхода
  • THEN система не раскрывает результат прежней границы подключения

Scenario: Сбой после частичного обновления

  • WHEN попытка прервана ошибкой либо сбоем сохранения после обновления Portfolio одного доступного счёта
  • THEN результат попытки обозначает частичный успех с проблемными шагами, а не полный успех, а обновлённый Portfolio сохраняется

Scenario: Сбой до первого обновления

  • WHEN попытка прервана до обновления любого обязательного шага
  • THEN результат попытки обозначает неуспех, а не полный успех

Requirement: Каждая попытка обхода достигает итога в ограниченное время

Каждая начатая попытка часового обхода MUST достигать итогового состояния в ограниченное время. Ожидание завершения каждого обязательного шага MUST быть ограничено; шаг, не завершившийся в это ограничение, MUST быть учтён как проблемный, а попытка MUST быть закрыта частичным успехом либо неуспехом после того, как каждый обязательный шаг достиг терминального результата либо был учтён как проблемный. Истечение ограничения MUST NOT отменять уже начатые шаги.

Scenario: Шаг не завершается

  • WHEN обязательный шаг не покидает состояние выполнения дольше ограничения ожидания
  • THEN шаг учитывается как проблемный, попытка закрывается частичным успехом либо неуспехом, а её состояние перестаёт быть выполняющимся

Scenario: Наблюдение не ждёт без ограничения

  • WHEN попытка не может завершиться из-за незавершённых шагов
  • THEN наблюдение результата получает итоговое состояние в ограниченное время и не ожидает завершения бесконечно

Requirement: Восстановление после сбоя сохранения не блокирует последующие обходы

Если попытка осталась в состоянии выполнения после сбоя завершения шага, публикации результата либо закрытия попытки, система MUST привести её к диагностируемому итоговому состоянию: частичный успех либо неуспех с сохранёнными результатами шагов, а не полный успех. Последующий обход MUST становиться допустимым по обычному правилу срока, отсчитанному от начала этой попытки. Восстановление MUST NOT создавать перекрывающийся обход и MUST NOT повторять уже полученные результаты шагов.

Scenario: Потерянное закрытие попытки

  • WHEN закрытие попытки не сохранилось, а процесс продолжает работать
  • THEN система закрывает попытку итогом из фактических результатов шагов, наблюдение получает итоговое состояние, а следующая допустимая попытка может стартовать

Scenario: Перезапуск процесса

  • WHEN процесс остановился после начала попытки и запускается снова
  • THEN брошенная попытка обозначается частичным успехом либо неуспехом с сохранёнными результатами шагов, а новый обход начинается не ранее следующего часового срока от её начала

Requirement: Устаревшая публикация не влияет на актуальную попытку

Результат шага попытки, у которой появился преемник, MUST отклоняться как устаревший: он MUST NOT обновлять данные и MUST NOT учитываться в итоге актуальной попытки. Шаг устаревшей попытки MUST наблюдаться как устаревший относительно актуального преемника. Результат шага текущей попытки, полученный до фиксации её итога, MUST сохраняться и учитываться в этом итоге независимо от того, наступил ли он до или после истечения ограничения ожидания.

Scenario: Поздняя публикация после появления преемника

  • WHEN шаг старой попытки завершается после запуска следующей попытки
  • THEN его результат отклоняется как устаревший, данные не обновляются, а итог актуальной попытки не меняется

Scenario: Поздняя публикация до фиксации итога

  • WHEN шаг завершился после истечения ограничения ожидания, но итог его попытки ещё не зафиксирован
  • THEN его результат сохраняется и учитывается при выводе итога этой попытки