Document local data ownership, coverage and freshness, refresh behavior, failure recovery and additive migration rollback. Record ADR 017.
9.7 KiB
Портфель по всем счетам
Режим «Все счета» объединяет открытые поддерживаемые инвестиционные счета,
доступные через текущее подключение T-Bank. Состав совпадает с политикой
списка счетов; закрытые и недоступные счета не включаются.
all — зарезервированное обозначение общего режима, которое не передаётся
брокеру как идентификатор счёта.
Маршруты и навигация
| Маршрут | Содержание |
|---|---|
/accounts |
Список отдельных счетов и действие открытия общего портфеля |
/accounts/all |
Общий портфель и превью операций, дохода и будущих событий |
/accounts/all/operations |
Общий журнал исполненных операций |
/accounts/all/income |
Купоны и дивиденды за календарный период |
/accounts/all/events |
Будущие события всех доступных счетов |
Общий режим использует те же страницы разделов с обозначением all.
На страницах счёта и общего режима переключатель «Счёт»
сохраняет текущий раздел и применённые URL-фильтры. При переключении пагинация
начинается заново. Журнал хранит применённые from, to и categories в URL;
черновые значения применяются кнопкой. Раздел дохода сохраняет свой прежний
календарный контракт. Хлебные крошки называют общий режим «Все счета».
Данные и вычисления
Backend публикует статические маршруты под /api/v1/brokerage-accounts/all:
/portfolio, /operations, /income-summary, /income-analytics, /events.
У них те же формы данных и фильтры, что у соответствующих разделов отдельного
счёта. Позиции, операции (включая выплаты дохода) и события сохраняют источник
в поле account: { id, name }; в ответах одного счёта это поле отсутствует.
Валютные итоги и деньги агрегированы. Точную форму транспорта задаёт
OpenAPI backend.
- Портфель и доступные денежные остатки суммируются сервером точно, по исходной валюте, с точной десятичной арифметикой. FX-конвертации нет; правила неизвестных значений и состава сумм наследуются от портфеля.
- Одинаковые бумаги разных счетов показаны одной карточкой с общим названием и идентификатором. Внутри всегда видны строки счетов: ссылка на портфель, количество, доступная стоимость, результат, средняя цена и доля позиции. Денежные показатели и количества остаются исходными для каждого счёта; общая средняя цена и суммарное количество карточки не рассчитываются. Группировка выполняется по типу инструмента и первому доступному идентификатору: UID, затем FIGI, затем ISIN. Разные выбранные идентификаторы или их отсутствие, а также одно лишь совпадение имени или тикера не объединяют позиции. Повторные строки одного счёта остаются отдельными. API сохраняет позиции каждого счёта; объединяется только их представление. Порядок карточек задаёт первое вхождение бумаги; порядок счетов внутри карточки сохраняется. Одиночные позиции используют прежнюю карточку. Доля относится к позициям той же валюты во всём показанном портфеле, без денежных остатков.
- Журнал объединяет операции по убыванию времени, при равном времени использует порядок идентификаторов счетов и операций. ID операций разных счетов не считаются дублями. Переводы не схлопываются.
- Доходы рассчитываются из согласованной локальной выборки операций за общие периоды. Итоги, сравнения, временные интервалы и принадлежность выплат рассчитывает сервис дохода. Для сравнения с годом ранее используется текущий состав счетов; новый счёт добавляет только реально полученные выплаты. При известных датах открытия всех счетов доступность сравнения определяется самым ранним открытием в этом составе. Закрытые счета в историческое сравнение не добавляются.
- Будущие события сортируются по дате и сохраняют отдельную строку каждого счёта. Прогноз не включается в реализованные доходы.
Полнота, свежесть и доступ
Общий запрос читает membership и разрешённые snapshots из SQLite в одной
согласованной границе. Время источников может различаться: это не обещание
одновременного наблюдения счетов у брокера. Неполный счёт делает aggregate
неполным; отсутствующие суммы не подменяются нулями. lastSuccessfulAt
показывает самое раннее время обязательных источников.
Секции портфеля, операций, дохода и событий готовы независимо. Ошибка обновления сохраняет прежний полный результат того же scope и периода. Известный отказ доступа и смена подключения очищают personal view.
Общая пагинация операций
Страница строится из локальных строк с порядком occurredAt, accountId и ID
операции. Cursor проверяет пользователя, подключение, membershipRevision,
фильтры, limit и ревизии операций. Изменение rowset возвращает
400 INVALID_OPERATIONS_CURSOR; клиент сбрасывает стек страниц, сохраняя
применённые фильтры. Coverage/status без изменения строк не ломают cursor.
Продолжение не зависит от RAM-кэша или перезапуска.
Повторная сверка полного показанного периода публикует все счета и интервалы одной транзакцией; успешное первое окно не смешивается с прежними остальными. Подробнее — журнал.
Совместимость и границы требований
Общий режим использует те же persistent sources и envelope, что и отдельный счёт. Новый envelope несовместим с прежним bare response: backend и frontend поставляются согласованной парой по HTTP contract. Additive migration сохраняет прежние таблицы; rollback приложения не удаляет новые данные и не заменяет рабочую базу старым backup. Возврат требует заранее проверенной совместимой пары; произвольный прежний клиент не считается совместимым. Процедура backup/restore описана в runbook.
Основные спецификации областей сохраняют исходные понятия отдельного счёта.
Утверждённый change persist-tbank-data распространяет полноту, локальный
доступ, атомарную сверку и состояния синхронизации на режим all.