38 lines
5.0 KiB
Markdown
38 lines
5.0 KiB
Markdown
# Журнал операций брокерского счёта
|
||
|
||
Авторизованный пользователь просматривает исполненные операции одного доступного брокерского счёта на `/accounts/:accountId/operations`. На обзоре `/accounts/:accountId` отображаются пять последних событий и ссылка на полный журнал. Ошибка или пустой результат этого блока не заменяет Portfolio.
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant U as User
|
||
participant F as Frontend
|
||
participant B as Backend
|
||
participant D as SQLite
|
||
participant T as T-Bank gRPC
|
||
U->>F: Открывает журнал счёта
|
||
F->>B: GET /api/v1/brokerage-accounts/:accountId/operations
|
||
B->>D: Читает T-Bank connection
|
||
B->>T: GetAccounts(OPEN)
|
||
B->>T: GetOperationsByCursor(EXECUTED)
|
||
B-->>F: Страница Account Ledger
|
||
F-->>U: Операции, фильтры и навигация
|
||
```
|
||
|
||
## API
|
||
|
||
`GET /api/v1/brokerage-accounts/:accountId/operations` требует Bearer access token. Необязательные `from` и `to` задают включительный период; без периода запрос начинается с 1 января текущего года. `categories` принимает `trade`, `income`, `tax`, `fee`, `transfer`, `other`; `cursor` и `limit` управляют cursor-пагинацией.
|
||
|
||
Ответ передаёт `accountId`, `items`, `nextCursor`, `hasNext` и `observedAt`. Каждая `Ledger Entry` соответствует ровно одной операции T-Bank и содержит её тип, категорию, описание, дату, доступный инструмент, nullable `logoName`, `payment`, `quantity`, `price`, `accruedInterest` и `commission`. `logoName` — presentation metadata: если она недоступна, это не меняет запись журнала.
|
||
|
||
Деньги передаются decimal strings в исходной ISO-валюте. Frontend только форматирует значения. Комиссия сделки остаётся деталью той же записи; операции без `payment` отображаются как «Без движения денег».
|
||
|
||
## Поведение и ограничения
|
||
|
||
- Запрашиваются только исполненные операции T-Bank.
|
||
- Полный журнал фильтруется по периоду и категориям, а изменение фильтра сбрасывает cursor-пагинацию.
|
||
- В полном журнале и пяти последних записях обзора одна и та же компактная строка показывает логотип инструмента либо буквенный fallback, описание операции, дату, инструмент, категорию и денежное движение. Положительная сумма обозначается как «Поступление» с `+`, отрицательная — как «Списание» с `−`; подпись и знак сохраняют значение независимо от цвета.
|
||
- Полный журнал не показывает цену, количество, НКД и комиссию записи.
|
||
- Backend хранит в памяти процесса до 100 страниц Account Ledger: свежая страница живёт до 30 секунд, а при переполнении вытесняется давно не использовавшаяся страница (LRU). Ключ включает пользователя, счёт, нормализованные период и categories, cursor и limit; отсутствующий `to` приводится к текущему 30-секундному bucket. Проверка подключения и доступа к счёту выполняется до выдачи кэшированной страницы. Ключ не включает версию T-Bank token, поэтому после успешной замены T-Bank connection для того же User, Brokerage Account и query уже сохранённая страница может оставаться видимой до истечения 30-секундного TTL. Операции не сохраняются и не синхронизируются локально.
|
||
- Журнал не рассчитывает остаток после операции, суммарные доходы или налоги, историческую стоимость Portfolio, конвертацию валют и рыночные изменения цены.
|
||
- `409 TBANK_NOT_CONNECTED`, `400 INVALID_TBANK_TOKEN`, `404` недоступного счёта и `503 TBANK_UNAVAILABLE` используют существующую семантику ошибок T-Bank.
|