126 lines
12 KiB
Markdown
126 lines
12 KiB
Markdown
# Журнал операций
|
|
|
|
Журнал отвечает на вопрос «какие события брокер исполнил по счёту».
|
|
Каждая запись соответствует одной операции T-Bank, а не вычисленному
|
|
приложением изменению стоимости портфеля. Пользователь открывает полный
|
|
журнал на `/accounts/:accountId/operations`; обзор счёта показывает пять
|
|
последних записей и ссылку на него. Ошибка этого блока не скрывает портфель.
|
|
[Общий режим](../portfolio/all-accounts.md#общая-пагинация-операций)
|
|
объединяет операции доступных счетов, сохраняя источник каждой записи.
|
|
|
|
## Что означает запись
|
|
|
|
Исполненная операция содержит тип события, его категорию, описание,
|
|
момент совершения, доступные сведения об инструменте и денежное движение.
|
|
Запросы отменённых или ожидающих исполнения поручений не образуют этот журнал.
|
|
Суммы остаются точными десятичными строками в исходной валюте. Frontend
|
|
форматирует их и считает визуальный итог группы по показанным записям
|
|
(см. [группировку](#группировка-в-режиме-все-счета)). Положительное и отрицательное
|
|
движение сохраняют знак. Отсутствие `payment` означает «Без движения денег», а не нулевую сумму.
|
|
|
|
## Группировка в режиме «Все счета»
|
|
|
|
Только в режиме `all` записи журнала и превью обзора, которые относятся к одному
|
|
дню экрана, одному инструменту и точному типу операции, объединяются в группу.
|
|
Ключом служат день, `instrumentUid` (иначе `figi`) и тип; группа образуется при
|
|
двух и более записях, в том числе одного счёта. Группа стоит на месте первой записи.
|
|
Каждая запись остаётся отдельной строкой с названием счёта простым текстом и своей суммой.
|
|
Одиночный счёт не группируется.
|
|
|
|
Группировка выполняется после лимита: превью обзора сначала берёт пять записей,
|
|
затем группирует только их. Полный журнал группирует страницу, уже загруженную
|
|
курсором; группы не переносятся между страницами. Курсор и порядок записей не меняются.
|
|
|
|
Итог группы — точная сумма по каждой валюте, без конвертации. Он показывается только
|
|
если полнота журнала `complete`, у каждой записи группы есть `payment`, и ни одна сумма
|
|
не равна нулю. Иначе итог скрыт, а строки счетов остаются.
|
|
|
|
Категории объединяют разные события для фильтрации: сделка (`trade`),
|
|
доход (`income`), налог (`tax`), комиссия (`fee`), перевод (`transfer`)
|
|
и прочее (`other`). Принадлежность к категории дохода сама по себе не
|
|
означает включение в [пассивный доход](../income/overview.md): тот использует
|
|
только точные типы исполненных купонов и дивидендов.
|
|
|
|
Количество сделки берётся из исполненного `quantityDone`; если его нет,
|
|
количество неизвестно и не заменяется порученным. Цена, НКД и комиссия
|
|
сохраняются как доступные детали операции. Комиссия сделки не создаёт
|
|
дубликат отдельной записи журнала. Метаданные логотипа дополняют представление,
|
|
но их недоступность не меняет финансовое событие.
|
|
|
|
Журнал не вычисляет остаток после операции, историческую стоимость портфеля,
|
|
совокупный налог или валютную конвертацию. Изменение рыночной цены не становится
|
|
операцией. Переводы между счетами не схлопываются в одну запись; одинаковые
|
|
ID операций разных счетов не означают дубликат.
|
|
|
|
## Период и навигация
|
|
|
|
Полный журнал позволяет выбрать период включительно и несколько категорий.
|
|
Без периода начало — 1 января текущего года в UTC, конец — текущее время.
|
|
Поля «С» и «По» используют формат `ДД.ММ.ГГГГ`, русский календарь и взаимные
|
|
ограничения дат. Изменение полей меняет только черновик. «Применить» сохраняет
|
|
его в URL, загружает результат и сбрасывает пагинацию; «Сбросить» очищает
|
|
фильтры и сразу возвращает период по умолчанию и все категории.
|
|
«Назад» и «Далее» используют последний применённый фильтр.
|
|
|
|
На [страницах акций](../instruments/stocks.md) и
|
|
[облигаций](../instruments/bonds.md) этот же журнал становится личной историей
|
|
конкретной бумаги. Фильтр `instrumentUid` применяется к локальным операциям. Ручная сверка
|
|
личной истории может ограничить источниковый запрос этой бумагой, не присваивая
|
|
такому subset полноту всех операций счёта. Без явного начала периода он охватывает историю с открытия счёта;
|
|
в общем режиме — с самой ранней известной даты открытия доступных счетов.
|
|
Если даты открытия неполны, нижняя граница — Unix epoch. Это позволяет
|
|
видеть прошлые операции уже проданной бумаги, но не обещает историю
|
|
закрытых и недоступных счетов.
|
|
|
|
## Получение и полнота
|
|
|
|
`GET /api/v1/brokerage-accounts/:accountId/operations` читает сохранённые
|
|
операции и coverage после локальной проверки доступа. Период, категории,
|
|
UID, cursor и limit применяются к этой выборке. Транспорт описан в
|
|
[HTTP API](../../architecture/http-api.md).
|
|
|
|
Стабильность broker operation ID в пределах счёта и подключения принята как
|
|
допущение проекта. Повторный ID обновляет ту же запись без двойного учёта.
|
|
Страницы источника сначала сохраняются в staging. Полный успешный обход
|
|
разрешает upsert, удаление исчезнувших записей в перечитанном predicate
|
|
и публикацию coverage одной транзакцией. При повторной сверке полного
|
|
показанного периода транзакция охватывает все его окна и счета.
|
|
|
|
Полнота относится к UTC-интервалу `[from,to)`, включая подтверждённый пустой.
|
|
Категории, размер страницы и `hasNext=false` её не определяют. При первичном
|
|
импорте подтверждённые строки видны как partial; итоги ждут полного периода.
|
|
Догрузка остальной истории обозначается отдельно. Без известной нижней
|
|
границы нельзя заявить полную историю счёта.
|
|
|
|
Cursor связан с пользователем, подключением, membership для `all`, фильтрами
|
|
и ревизией набора операций. Изменение строк даёт `INVALID_OPERATIONS_CURSOR`;
|
|
клиент возвращается на первую страницу, сохраняя применённые фильтры.
|
|
Coverage/status без изменения rowset cursor не ломают. Перезапуск сохраняет
|
|
опубликованные интервалы; незавершённая работа возобновляется только запросом.
|
|
|
|
## Представление и ошибки
|
|
|
|
Полный журнал и превью используют одинаковую компактную строку: логотип
|
|
или буквенная заглушка, описание, дата, инструмент и денежное движение.
|
|
Исполненные купоны и дивиденды показываются единым предметным представлением
|
|
выплаты — тем же, что на странице дохода, в прогнозе и графиках инструментов;
|
|
денежная метка называет точное исполненное событие. Для прочих
|
|
операций метка называет категорию. Она показывается один раз, без повтора рядом с датой.
|
|
Знак и цвет обозначают направление денег; отсутствие движения нейтрально.
|
|
Если описание отсутствует, показывается локализованный тип операции.
|
|
|
|
Полный журнал не выводит цену, количество, НКД и комиссию; личная история
|
|
инструмента добавляет количество, цену и ссылку на счёт. Даты показываются
|
|
как `ДД.ММ.ГГГГ`, время операций явно обозначено UTC.
|
|
|
|
При первом открытии виден каркас фильтров и строк. Уже полученный результат
|
|
не заменяется каркасом при применении действий или фоновом обновлении.
|
|
Ошибки `TBANK_NOT_CONNECTED`, `INVALID_TBANK_TOKEN`, недоступный счёт (`404`)
|
|
и `TBANK_UNAVAILABLE` сохраняют [общую семантику API](../../architecture/http-api.md).
|
|
Только полный пустой ответ означает отсутствие подходящих операций.
|
|
Partial empty сообщает о неполноте; source failure сохраняет прежний результат.
|
|
|
|
Согласованное поведение описано в [спецификации журнала](https://git.personal.ksv741.ru/WealthLedger/specs/src/commit/9e227a563dda67620f0ad78228aa8a4c18bf35a0/openspec/specs/brokerage-account-ledger/spec.md).
|
|
Фильтр конкретной бумаги и общий режим расширяют исходное описание отдельного
|
|
счёта; их механизм раскрыт на страницах инструментов и общего портфеля.
|