Files
docs/domains/operations/overview.md
T
codex-bot 03fb045a9e
Docs security / security (push) Successful in 8s
Docs verify / verify (push) Successful in 14s
docs: document income without comparisons and unified payouts (WealthLedger/main#33) (#40)
docs: document income without comparisons and unified payouts (WealthLedger/main#33)
2026-10-13 18:16:59 +03:00

108 lines
10 KiB
Markdown

# Журнал операций
Журнал отвечает на вопрос «какие события брокер исполнил по счёту».
Каждая запись соответствует одной операции T-Bank, а не вычисленному
приложением изменению стоимости портфеля. Пользователь открывает полный
журнал на `/accounts/:accountId/operations`; обзор счёта показывает пять
последних записей и ссылку на него. Ошибка этого блока не скрывает портфель.
[Общий режим](../portfolio/all-accounts.md#общая-пагинация-операций)
объединяет операции доступных счетов, сохраняя источник каждой записи.
## Что означает запись
Исполненная операция содержит тип события, его категорию, описание,
момент совершения, доступные сведения об инструменте и денежное движение.
Запросы отменённых или ожидающих исполнения поручений не образуют этот журнал.
Суммы остаются точными десятичными строками в исходной валюте; frontend
только форматирует их. Положительное и отрицательное движение сохраняют
знак. Отсутствие `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).
Фильтр конкретной бумаги и общий режим расширяют исходное описание отдельного
счёта; их механизм раскрыт на страницах инструментов и общего портфеля.