67 lines
5.6 KiB
Markdown
67 lines
5.6 KiB
Markdown
# Загрузка портфеля
|
||
|
||
Экран `/accounts/:accountId` читает последний полный snapshot из SQLite после
|
||
проверки сессии, подключения и локального membership. Если список счетов ещё
|
||
неизвестен, сервер сообщает о загрузке доступа без выдачи личных данных
|
||
неизвестного ID. Известный недоступный счёт возвращает `404`.
|
||
|
||
## Основной обмен
|
||
|
||
Обычный GET и retry возвращают read-only локальный `{ data, meta }` envelope:
|
||
они не ждут и не вызывают T-Bank и не предлагают ручную синхронизацию. Часовой
|
||
обход текущего подключения обновляет Portfolio независимо от экрана. Для нового
|
||
полного snapshot ему нужны оба финансовых ответа `GetPortfolio` и
|
||
`GetPositions`; суммы и позиции публикуются вместе. Metadata инструмента и
|
||
классификация (сектор и эмитент) дополняют представление независимо,
|
||
с доступным UID/FIGI вместо имени до их загрузки.
|
||
|
||
## Обновление сектора и эмитента
|
||
|
||
Часовой обход также обновляет сектор и эмитента позиций типов `share`, `bond`
|
||
и `etf`. Значения хранятся как последнее известное ([ADR
|
||
022](../../../adr/022-stored-instrument-classification.md)): сектор — как его
|
||
определяет T-Bank, эмитент — бренд актива (`uid` и `name`). Каждое поле
|
||
обновляется при первом обходе, начавшемся не ранее чем через 24 часа после его
|
||
последнего успешного получения; пока значение не получено, попытка повторяется
|
||
в каждом обходе. Сектор и эмитент обновляются независимо.
|
||
|
||
Неуспешное получение не мешает публикации snapshot и не меняет
|
||
`lastSuccessfulAt` и `isStale`; сохранённое значение остаётся доступным.
|
||
Исключение — отказ token: он обрабатывается так же, как отказ token при
|
||
обходе Portfolio. Инструмент ищется по UID, затем по FIGI; ответ «не найдено»
|
||
сохраняет прежнее значение и отсчёт 24 часов начинается заново. Позиции без
|
||
полученных значений участвуют в разрезах вкладки
|
||
[«Концентрация»](../concentration.md) как «Сектор не указан» и
|
||
«Эмитент не указан».
|
||
|
||
Открытый экран выполняет локальное перечитывание не чаще одного раза в
|
||
30 минут; retry также повторяет только HTTP GET. `data: null` означает, что
|
||
полного snapshot ещё нет, а не нулевой портфель. Пустой подтверждённый portfolio
|
||
остаётся available complete result. Секции могут быть готовы независимо.
|
||
Подробнее — [свежесть](../../../architecture/cross-cutting/data-freshness.md).
|
||
|
||
## Границы доступа
|
||
|
||
Публикация проверяет connection revision и attempt в той же транзакции. Замена
|
||
или удаление подключения не допускает позднюю запись прежней работы. Frontend
|
||
очищает недоступный personal view и отклоняет запоздалые ответы. В режиме
|
||
[«Все счета»](../all-accounts.md#полнота-свежесть-и-доступ) состав accounts и
|
||
snapshots читается согласованно, но их source times могут различаться.
|
||
|
||
## Ошибки и результат для пользователя
|
||
|
||
Нет подключения — `409 TBANK_NOT_CONNECTED`, известный отказ токена —
|
||
`400 INVALID_TBANK_TOKEN`, недоступный счёт — `404`. Они не маскируются
|
||
запасным snapshot. Временная ошибка часового обхода оставляет прежний полный
|
||
portfolio и его исходное `lastSuccessfulAt`; `meta.lastAttempt` сообщает о
|
||
failed или partial попытке отдельно. `Portfolio.isStale` сообщает возраст
|
||
snapshot, а Client Cached Snapshot и ошибка браузерного HTTP-перечитывания
|
||
имеют независимый смысл. При отсутствии полного snapshot `data: null` и
|
||
metadata обозначает initial loading либо временную недоступность, без нулевых
|
||
итогов. `503` означает ошибку обслуживания самого HTTP-запроса, а не
|
||
завершившуюся фоновую работу.
|
||
|
||
Денежные правила находятся в [справочнике](../data-reference.md), проверка
|
||
расхождения — в [диагностике](../how-to/investigate-discrepancy.md), RPC/лимиты
|
||
— в [интеграции T-Bank](../../../integrations/tbank.md).
|