Compare commits
6
Commits
v0.1.2
..
e0bceea936
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0bceea936 | ||
|
|
9a9b0409cc | ||
|
|
256d49b045 | ||
|
|
9477e688d1 | ||
|
|
0ee54ca952 | ||
|
|
6fa62fb8b5 |
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": ".markdownlint.json",
|
||||
"MD024": {
|
||||
"siblings_only": true
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"MD013": false
|
||||
},
|
||||
"customRules": [
|
||||
"markdownlint-rule-relative-links"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"filter": [
|
||||
"CHANGELOG.md"
|
||||
],
|
||||
"config": {
|
||||
"MD024": {
|
||||
"siblings_only": true
|
||||
}
|
||||
},
|
||||
"combine": "merge"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require('markdownlint-rule-relative-links').default;
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"MD013": false
|
||||
}
|
||||
@@ -1,5 +1,17 @@
|
||||
# Changelog
|
||||
|
||||
## [0.1.3](https://git.personal.ksv741.ru/WealthLedger/docs/compare/v0.1.2...v0.1.3) (2026-10-07)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **deps:** refresh docs security baseline ([256d49b](https://git.personal.ksv741.ru/WealthLedger/docs/commit/256d49b04591d55d980a22c49b413432c9bda746))
|
||||
* **deps:** remove vulnerable docs tooling ([9477e68](https://git.personal.ksv741.ru/WealthLedger/docs/commit/9477e688d180783881abc92f8835517715880279))
|
||||
|
||||
### Documentation
|
||||
|
||||
* record code quality review and refactoring ([6fa62fb](https://git.personal.ksv741.ru/WealthLedger/docs/commit/6fa62fb8b51aba82766fb50b3e5871572af8be27))
|
||||
* record minimal runtime coordination ([0ee54ca](https://git.personal.ksv741.ru/WealthLedger/docs/commit/0ee54ca952db6ca7264c0d7fe8cf5759b3187c5b))
|
||||
|
||||
## [0.1.2](https://git.personal.ksv741.ru/WealthLedger/docs/compare/v0.1.1...v0.1.2) (2026-09-26)
|
||||
|
||||
### Documentation
|
||||
|
||||
+4
-3
@@ -177,9 +177,10 @@ Markdown-only правки не требуют тестов приложения
|
||||
|
||||
`security.yml` при push, PR и ежедневно проверяет всю Git-историю через
|
||||
Gitleaks 8.30.1 с redacted-выводом и все npm dependencies через
|
||||
`npm audit --include=dev --audit-level=low`. Override `smol-toml` исправляет
|
||||
DoS в TOML parser markdownlint-cli2; его можно удалить, когда родительский
|
||||
пакет примет исправленную версию.
|
||||
`npm audit --include=dev --audit-level=low`. Overrides `smol-toml` и `js-yaml`
|
||||
исправляют DoS в parsers markdownlint-cli; overrides для release-it обновляют
|
||||
уязвимые basic-ftp и undici. Их можно удалить, когда родительские пакеты
|
||||
примут исправленные версии.
|
||||
|
||||
Renovate объединяет minor/patch updates; major требует согласования в
|
||||
Dependency Dashboard, automerge не включён. Required checks включаются
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
**Status:** Accepted; supersedes the refresh-token reuse rule in ADR-006.
|
||||
|
||||
Cookie-clearing policy уточнена в [ADR 018](018-minimal-runtime-coordination.md):
|
||||
неуспешный refresh больше не удаляет cookie. CAS и отказ superseded token сохранены.
|
||||
|
||||
## Context
|
||||
|
||||
Два одновременных запроса могут предъявить один действительный refresh token. Отзыв Session для проигравшего запроса делает недействительной сессию успешного запроса, а сохранение отдельной истории token или grace-window для различения replay добавляет непропорциональное состояние локальному MVP.
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
**Status:** Accepted — архитектурное направление согласовано.
|
||||
|
||||
Prefetch policy ниже заменена [ADR 018](018-minimal-runtime-coordination.md):
|
||||
свечи загружаются по запрошенному диапазону, без предварительной загрузки
|
||||
всей истории бумаг портфеля. Остальные гарантии локального хранения сохранены.
|
||||
|
||||
Реализация `persist-tbank-data` добавлена в рабочие ветки приложения;
|
||||
performance/browser и canonical application gates пройдены. Это не отметка
|
||||
развёртывания в production. Ниже сохранён контекст
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# 018. Минимальная runtime-координация
|
||||
|
||||
**Status:** Accepted. Уточняет cookie policy ADR 009 и prefetch policy ADR 017.
|
||||
|
||||
## Context
|
||||
|
||||
Изоляция владельцев данных, атомарные финансовые изменения и локальное чтение
|
||||
не требуют отдельного протокола согласования каждого HTTP-ответа. Дополнительная
|
||||
координация оправдана только наблюдаемым поведением, которое иначе нарушается.
|
||||
|
||||
## Decision
|
||||
|
||||
- Refresh сохраняет атомарную ротацию. Неуспешный refresh не меняет cookie:
|
||||
поздний отказ не должен удалять cookie успешного запроса. Logout очищает cookie.
|
||||
- Frontend объединяет refresh и упорядочивает cookie-writing requests только
|
||||
внутри вкладки. Cross-tab auth synchronization не является требованием;
|
||||
после изменения сессии в другой вкладке допускаются reload или re-login.
|
||||
- Отменой, сбросом и публикацией query results владеет TanStack Query.
|
||||
Смена session/connection очищает соответствующий cache; отдельные registries
|
||||
HTTP-запросов, access epochs и URL-wide latest-read counters не используются.
|
||||
Локальная auth boundary предотвращает применение старого auth result и
|
||||
повтор mutation под другой identity.
|
||||
- Status GET читает только состояние работы. Открытый экран перечитывает
|
||||
resources через `sync=observe` во время работы и после завершения.
|
||||
Сверка hashes между status и data GET, публичные progress counters и
|
||||
невыдаваемые sync states не нужны. Полнота истории остаётся в resource metadata.
|
||||
- Свечи загружаются для запрошенного диапазона. Предзагрузки всей истории
|
||||
портфеля и автоматического расширения короткого периода до `all` нет.
|
||||
- Backend формирует согласованные entries и aggregates из одних исходных
|
||||
данных; frontend доверяет этому contract и не выполняет вторую сверку групп.
|
||||
- Request context и HTTP completion принадлежат `nestjs-pino`/`pino-http`.
|
||||
Проект сохраняет safe field filtering, redaction и route-template logging.
|
||||
- Deployment всегда выполняет один stop → backup → migration → readiness
|
||||
цикл. No-op и frontend-only оптимизации не обещаются; короткий простой принят.
|
||||
|
||||
## Consequences
|
||||
|
||||
Первое открытие нового диапазона свечей может ждать загрузку. Наблюдение активной
|
||||
работы может перечитать неизменившиеся локальные данные, зато не требует
|
||||
checksum protocol. Повтор deployment создаёт новый backup и может остановить API.
|
||||
|
||||
DB ownership подключения, conditional publication, coverage, staging,
|
||||
банковские intent fingerprints и версии записей сохраняются. Отмена HTTP
|
||||
не считается отменой уже выполняющейся server-side transaction.
|
||||
Сохранённый полный forecast не заменяется candidate с изменившимися dependencies.
|
||||
@@ -0,0 +1,25 @@
|
||||
# 019. Часовой обход и онлайн-справочник инструментов
|
||||
|
||||
**Status:** Accepted. Дополняет [ADR 017](017-local-tbank-reads-and-background-sync.md)
|
||||
и [ADR 018](018-minimal-runtime-coordination.md).
|
||||
|
||||
## Decision
|
||||
|
||||
- Личные T-Bank данные обновляются владельцами источников через durable hourly
|
||||
walk; обычные GET не запускают screen import.
|
||||
- Quotes, candles, operations, forecasts и события сохраняют собственные
|
||||
локальные состояния и время последнего успешного чтения.
|
||||
- Detail, company, catalog search и ticker lookup получают ответ онлайн через
|
||||
существующие integration clients. Их ошибки не заменяют сохранённые
|
||||
финансовые данные или подписи snapshot.
|
||||
- Старые справочные строки не являются источником актуальности и удаляются
|
||||
только отдельной совместимой миграцией после проверки FK и свечей.
|
||||
- Клиент повторяет открытые инвестиционные GET не чаще одного раза в 30 минут;
|
||||
retry повторяет чтение и не создаёт screen sync work.
|
||||
|
||||
## Consequences
|
||||
|
||||
Карточки инструментов зависят от доступности публичного upstream в момент
|
||||
чтения. Финансовые экраны сохраняют последний успешный snapshot, а статус
|
||||
последнего hourly walk показывается отдельно. OpenAPI backend остаётся единственным
|
||||
источником HTTP-контракта; frontend использует опубликованный snapshot.
|
||||
@@ -0,0 +1,42 @@
|
||||
# 020. Evidence for hourly sync read boundaries
|
||||
|
||||
**Status:** Accepted. Evidence for [ADR 019](019-hourly-reads-and-online-instrument-reference.md).
|
||||
|
||||
## Measurements
|
||||
|
||||
The backend persisted-read budget was measured with `npm run test:performance`
|
||||
using a synthetic SQLite dataset: three accounts, 100,000 operations per
|
||||
account, 200 instruments, and 5,000 candles per instrument. The run used Node
|
||||
24.21.0 on Apple M1 Pro with 32 GiB RAM and a failing synthetic upstream after
|
||||
population. It measured 100 reads per route family, excluding transport
|
||||
limiter cost.
|
||||
|
||||
The generated evidence is written by the test to its temporary
|
||||
`persistent-budget.json` file. This is a repeatable measurement, not a
|
||||
production SLA: it does not include network latency, real T-Bank quotas, or
|
||||
multi-process SQLite contention.
|
||||
|
||||
The successful run produced a 617,263,104-byte SQLite database and measured
|
||||
zero upstream calls during the persisted-read phase. Backend p50/p95 response
|
||||
times were approximately 1.3/2.3 ms for account and portfolio reads,
|
||||
3.9/4.5 ms for account operations, 6.7/7.2 ms for aggregate operations,
|
||||
40.0/41.5 ms for account income analytics, and 128.1/134.2 ms for aggregate
|
||||
income analytics. These figures are local synthetic measurements only.
|
||||
|
||||
## Durability
|
||||
|
||||
The migration durability check passes against a separately built repository at
|
||||
the pre-history migration prefix. It verifies preservation of users, sessions,
|
||||
T-Bank connection data, bank-card data, operations, categories, archive state,
|
||||
and replay behavior across migration and restart.
|
||||
|
||||
The executed command was `node test/bank-cards-durability.cjs` with a separately
|
||||
built pre-history repository. It completed with `PASS durability`.
|
||||
|
||||
## Limits
|
||||
|
||||
The configured T-Bank start limiter is `TBANK_RATE_LIMIT_PER_SECOND`, default
|
||||
`5` per backend instance. The hourly scheduler therefore remains a single
|
||||
durable reservation owner; the measurement does not justify increasing this
|
||||
limit or changing the hourly cadence. Any production tuning requires current
|
||||
T-Bank documentation and a new measurement with the deployed topology.
|
||||
@@ -22,3 +22,6 @@
|
||||
- [015 — SQLite в ограниченном single-server deployment](015-single-server-sqlite-deployment.md)
|
||||
- [016 — Версионируемый комплект развёртывания](016-versioned-deployment-bundle.md)
|
||||
- [017 — Локальное чтение данных T-Bank и фоновая синхронизация](017-local-tbank-reads-and-background-sync.md)
|
||||
- [018 — Минимальная runtime-координация](018-minimal-runtime-coordination.md)
|
||||
- [019 — Часовой обход и онлайн-справочник инструментов](019-hourly-reads-and-online-instrument-reference.md)
|
||||
- [020 — Evidence for hourly sync read boundaries](020-hourly-sync-verification-evidence.md)
|
||||
|
||||
@@ -195,9 +195,9 @@ access token и вращаемый refresh token. [Политика query-кэш
|
||||
|
||||
Авторизация доступа, недопущение token в публичный ответ и атомарность
|
||||
ротации сессии — отдельные свойства; наличие типизированного клиента
|
||||
не доказывает их. Известные расхождения регистрации и деталей валидации
|
||||
отмечены в [аутентификации](../domains/authentication/overview.md#регистрация-и-вход)
|
||||
и [HTTP API](http-api.md#error-contract).
|
||||
не доказывает их. Известное расхождение регистрации отмечено в
|
||||
[аутентификации](../domains/authentication/overview.md#регистрация-и-вход),
|
||||
а действующий формат ошибок описан в [HTTP API](http-api.md#error-contract).
|
||||
|
||||
Поддерживается локальный Compose и ограниченная single-server topology с SQLite.
|
||||
Origin браузера, адрес API и cookie policy должны быть согласованы.
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# Свежесть данных и повторное использование
|
||||
|
||||
WealthLedger читает инвестиционные данные из SQLite. Обычный GET возвращает
|
||||
сохранённый результат и запрашивает фоновые зависимости, если они отсутствуют
|
||||
или устарели. HTTP-ответ не ждёт T-Bank. Модель принята в
|
||||
сохранённый результат и не запускает личную синхронизацию. Общие справочные
|
||||
данные инструментов запрашиваются онлайн, когда это требуется карточке;
|
||||
финансовый HTTP-ответ не ждёт T-Bank. Модель принята в
|
||||
[ADR 017](../../adr/017-local-tbank-reads-and-background-sync.md).
|
||||
|
||||
## Клиентский и серверный снимки
|
||||
@@ -23,7 +24,8 @@ WealthLedger читает инвестиционные данные из SQLite.
|
||||
| --- | --- |
|
||||
| Portfolio, котировки, изменяемый хвост дневных свечей | Через 60 секунд |
|
||||
| Membership и изменяемый хвост операций | Через 5 минут |
|
||||
| Metadata, поиск каталога, company и календари | Через сутки |
|
||||
| Metadata, поиск каталога и company | Онлайн при чтении |
|
||||
| Календари | Через часовой обход |
|
||||
| Полные прошлые интервалы операций и завершённые свечи | При явном обновлении показанного периода |
|
||||
|
||||
TTL не создаёт таймер импорта. Запрошенная работа может закончиться после
|
||||
@@ -31,8 +33,9 @@ TTL не создаёт таймер импорта. Запрошенная ра
|
||||
следующий подходящий запрос повторяет незавершённый интервал с первой страницы,
|
||||
переиспользуя полные интервалы. Cursor брокера не служит durable checkpoint.
|
||||
|
||||
Ручное «Обновить» перечитывает зависимости текущего экрана и применённый
|
||||
период независимо от TTL. Повторная сверка полного периода публикуется одной
|
||||
Повторное чтение перечитывает общие справочные данные онлайн, а финансовые
|
||||
ресурсы используют сохранённый результат и применяемую политику свежести.
|
||||
Повторная сверка полного периода публикуется одной
|
||||
транзакцией после всех страниц, интервалов и счетов, включая `all`.
|
||||
Сбой сохраняет весь прежний результат. Первая загрузка может публиковать
|
||||
полные малые интервалы и показывать частичный период без окончательных сумм.
|
||||
@@ -43,6 +46,10 @@ Status GET и data GET с `sync=observe` не запускают работу.
|
||||
наблюдение прекращается. Поздний ответ не заменяет уже принятый новый.
|
||||
[HTTP API](../http-api.md) объясняет envelope и экранный refresh.
|
||||
|
||||
Отменой query lifecycle владеет TanStack Query. Status не пересобирает
|
||||
финансовые ответы и не передаёт hash notifications. Свечи нового диапазона
|
||||
загружаются при его открытии; предзагрузка всей истории портфеля не выполняется.
|
||||
|
||||
## Смена подключения
|
||||
|
||||
Каждое чтение проверяет локальную сессию, текущее подключение, известный отказ
|
||||
|
||||
@@ -142,20 +142,15 @@ backups находятся рядом с data directory, вне checkout, и а
|
||||
не удаляются. Незавершённая копия помечается `.partial-` и не подходит для restore.
|
||||
Ключ шифрования хранится отдельно. Локальная копия не защищает от потери диска.
|
||||
|
||||
## Независимое обновление frontend
|
||||
## Единый цикл обновления
|
||||
|
||||
Если изменились только image или конфигурация frontend, backend не
|
||||
пересоздаётся, backup и migration не выполняются. Возможен короткий перерыв
|
||||
на внешней точке входа; старым browser tabs может потребоваться reload.
|
||||
При неизменных исправных контейнерах повтор команды не пересоздаёт сервисы.
|
||||
|
||||
## Независимое обновление backend
|
||||
|
||||
Изменение image или конфигурации backend запускает stop → backup → migration →
|
||||
readiness. Неизменный frontend не пересоздаётся. Во время простоя возможен 502.
|
||||
Каждое обновление, включая повтор того же тега и изменение только frontend,
|
||||
выполняет stop → backup → migration → readiness. Сравнение hashes контейнеров
|
||||
и конфигурации не выполняется. Приняты короткий простой API и дополнительный
|
||||
backup; во время простоя возможен 502, вкладкам может потребоваться reload.
|
||||
Ошибка migration блокирует старт, ошибка готовности останавливает новый backend;
|
||||
ошибка frontend не останавливает исправный backend. Успех фиксируется только
|
||||
после проверок запуска затронутых компонентов.
|
||||
после проверок запуска обоих компонентов.
|
||||
|
||||
Одна file lock защищает установку от параллельных команд. Маркер незавершённого
|
||||
обновления блокирует повтор до разбора оператором. Он содержит этап, версии
|
||||
|
||||
+12
-12
@@ -26,8 +26,8 @@ T-Bank data GET возвращают envelope `{ data, meta }`. `data` може
|
||||
при missing или неполном финансовом агрегате; partial ledger/candles могут
|
||||
содержать подтверждённые строки. `meta` разделяет availability, freshness,
|
||||
lastSuccessfulAt, sync, coverage и состояния зависимостей. `dataRevision`
|
||||
описывает набор данных, `stateVersion` — наблюдаемое состояние, включая
|
||||
пустое завершённое покрытие. Ни одно поле не раскрывает connection revision.
|
||||
описывает набор данных; пустое завершённое покрытие явно представлено в coverage.
|
||||
Публичной hash-версии состояния нет. Ни одно поле не раскрывает connection revision.
|
||||
|
||||
Обычный GET планирует missing/stale зависимости после проверки доступа.
|
||||
GET с `sync=observe` только читает. `POST /api/v1/tbank-sync` принимает
|
||||
@@ -35,6 +35,11 @@ GET с `sync=observe` только читает. `POST /api/v1/tbank-sync` пр
|
||||
scope. `GET /api/v1/tbank-sync/:id` наблюдает разрешённую работу; чужой или
|
||||
прежний handle возвращает `404`. Приём работы не означает её успех.
|
||||
|
||||
Status возвращает state/errorCode без данных ресурсов и численных progress
|
||||
counters. Клиент перечитывает показанные resources через `sync=observe` во время
|
||||
работы и после завершения, сохраняя generated query identity. Sync states ресурса:
|
||||
`idle`, `running`, `failed`; отдельного публичного `queued` нет.
|
||||
|
||||
Source failure принятой работы передаётся безопасным `meta.sync.errorCode`;
|
||||
HTTP transport/access/input errors сохраняют Problem Details. Старые данные
|
||||
при transient failure сохраняют исходное успешное время. Детали поведения —
|
||||
@@ -65,16 +70,11 @@ message/stack. Типичный ответ:
|
||||
|
||||
Для input validation контракт требует `400`, `VALIDATION_ERROR` и `errors` как
|
||||
массив `{ pointer, detail }`, где pointer адресует поле запроса. Это требование
|
||||
не считается проверенным одним описанием OpenAPI: нужна проверка реального
|
||||
HTTP-ответа после всех стадий обработки запроса.
|
||||
|
||||
**Известное расхождение:** согласованная
|
||||
[спецификация аутентификации](https://git.personal.ksv741.ru/WealthLedger/specs/src/commit/9e227a563dda67620f0ad78228aa8a4c18bf35a0/openspec/specs/user-authentication/spec.md#requirement-стандартные-ответы-об-ошибках)
|
||||
требует `pointer` и `detail` для невалидных полей. В текущей конфигурации
|
||||
валидация формирует строковые сообщения, а фильтр ожидает структурированные
|
||||
ошибки полей; поэтому корректность деталей `errors` не подтверждена.
|
||||
Исправление требует отдельного изменения реализации и проверки полного
|
||||
HTTP-потока. OpenAPI сам по себе этого расхождения не устраняет.
|
||||
проверяется реальным HTTP-ответом после всех стадий обработки запроса. Глобальная
|
||||
валидация передаёт фильтру структурированные ошибки без исходных значений и DTO,
|
||||
а фильтр формирует JSON Pointer, включая вложенные поля. HTTP suites подтверждают
|
||||
детали ошибок регистрации, банковской карты и синхронизации; OpenAPI отдельно
|
||||
фиксирует форму ответа.
|
||||
|
||||
Ответ не включает автоматически все поля RFC (`type`, `title`, `instance`).
|
||||
Добавление обязательного поля является изменением публичного контракта.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -55,15 +55,16 @@ sequenceDiagram
|
||||
B-->>F: Access token, профиль, новая refresh-cookie
|
||||
F->>B: Protected request с Bearer
|
||||
else Cookie нет или refresh отклонён
|
||||
B-->>F: 401 и очистка cookie
|
||||
B-->>F: 401 без изменения cookie
|
||||
Note over F: Готовое неавторизованное состояние
|
||||
end
|
||||
```
|
||||
|
||||
В одном экземпляре frontend одновременные refresh используют один
|
||||
незавершённый запрос. Между вкладками используется Web Locks, если браузер
|
||||
его поддерживает. Backend всё равно защищает ротацию атомарно: координация
|
||||
браузеров не заменяет серверную проверку.
|
||||
В одной вкладке одновременные refresh используют один незавершённый запрос;
|
||||
cookie-writing requests упорядочены локально. Межвкладочная синхронизация
|
||||
не поддерживается: после смены сессии в другой вкладке допустимы reload/re-login.
|
||||
Backend защищает ротацию атомарно. Неуспешный refresh не удаляет cookie
|
||||
победившего запроса; недействительный token по-прежнему не восстанавливает сессию.
|
||||
|
||||
Обычный защищённый запрос с `401 UNAUTHORIZED` проходит refresh и один повтор
|
||||
через общий транспорт; auth endpoints из этого цикла исключены. Само
|
||||
|
||||
@@ -91,13 +91,11 @@ Selected, previous и yearAgo имеют независимую готовнос
|
||||
серверным правилом; клиент воспринимает ключ как непрозрачную строку.
|
||||
Это поле принадлежит ответу аналитики; общий журнал операций его не требует.
|
||||
|
||||
Frontend проверяет принадлежность выплат по полученному ключу до подготовки
|
||||
плоского списка выплат. Отсутствующий, пустой или
|
||||
нестроковый ключ, неоднозначные ключи инструментов, неизвестная группа, другая
|
||||
валюта или несовпадение числа выплат приводят к существующему локальному
|
||||
состоянию ошибки аналитики с повторной попыткой. Частичный список выплат не показывается как
|
||||
полный; формула идентификации в клиенте не восстанавливается. Полностью пустой
|
||||
ответ допустим. Состав и исходный серверный порядок записей и знак сумм
|
||||
Backend обеспечивает принадлежность выплат, валюту и receipt count при
|
||||
построении entries и instrument groups из одного набора данных. Frontend
|
||||
доверяет типизированному contract, не восстанавливает формулу идентификации
|
||||
и не выполняет второй consistency validator. Полностью пустой ответ допустим.
|
||||
Состав и исходный серверный порядок записей и знак сумм
|
||||
сохраняются, frontend не пересчитывает денежные итоги. Стабильный ID в пределах подключения и счёта определяет одну операцию:
|
||||
повторная сверка обновляет её без двойного учёта. Одинаковые ID разных счетов
|
||||
остаются разными выплатами. Изменение источника логотипа позволяет заново
|
||||
|
||||
@@ -143,3 +143,9 @@ BondBy переиспользуется зависимостями выпуск
|
||||
и [проверками](https://git.personal.ksv741.ru/WealthLedger/backend/src/commit/016782657acfd35ff3fd755462007938fac35156/src/modules/investments/instruments/bonds/application/bond.spec.ts).
|
||||
Границы источников описаны в [разделе интеграций](../../integrations/README.md),
|
||||
сходное разделение рыночных и личных данных — в [акциях](stocks.md).
|
||||
|
||||
## Online reference
|
||||
|
||||
Bond detail, search, and ticker lookup are read from the upstream integration
|
||||
on each request. Saved quotes, candles, events, ratings, and portfolio labels
|
||||
retain their own freshness and failure boundaries.
|
||||
|
||||
@@ -184,3 +184,10 @@ scope. Частичные строки видны с предупреждени
|
||||
[рыночным данным](https://git.personal.ksv741.ru/WealthLedger/backend/src/commit/016782657acfd35ff3fd755462007938fac35156/src/modules/investments/instruments/stocks/application/stock-market.service.ts),
|
||||
[выплатам](https://git.personal.ksv741.ru/WealthLedger/backend/src/commit/016782657acfd35ff3fd755462007938fac35156/src/modules/investments/instruments/stocks/application/stock-income.service.ts) и [проверкам](https://git.personal.ksv741.ru/WealthLedger/backend/src/commit/016782657acfd35ff3fd755462007938fac35156/src/modules/investments/instruments/stocks/application/stock.spec.ts).
|
||||
Сопоставление с облигациями — на [странице облигаций](bonds.md).
|
||||
|
||||
## Online reference
|
||||
|
||||
Stock detail, company data, search, and ticker lookup are read from the
|
||||
upstream integration on each request. Saved positions, quotes, candles, and
|
||||
events remain independent local resources and are not replaced by a reference
|
||||
read failure.
|
||||
|
||||
@@ -152,6 +152,15 @@ _Не использовать_: валютная позиция, заблоки
|
||||
|
||||
_Не использовать_: история портфеля, snapshot для графика.
|
||||
|
||||
## Точка истории стоимости портфеля
|
||||
|
||||
Полная оценка одного Brokerage Account в одной валюте на момент успешного
|
||||
обновления Portfolio; последовательность таких точек описывает изменение
|
||||
оценки во времени, включая неторговые дни. Не является Portfolio Snapshot
|
||||
или инвестиционной доходностью; отсутствие цены позиции не приравнивается к нулю.
|
||||
|
||||
_Не использовать_: снимок состава портфеля, доходность.
|
||||
|
||||
## Client Cached Snapshot
|
||||
|
||||
Технический термин: последний успешно полученный frontend-ответ React Query, который остаётся
|
||||
|
||||
@@ -130,15 +130,12 @@ Backend хранит token в шифротексте AES-256-GCM с новым n
|
||||
[validateEnv](https://git.personal.ksv741.ru/WealthLedger/backend/src/commit/016782657acfd35ff3fd755462007938fac35156/src/config/env.validation.ts) (справочный источник).
|
||||
Общий FIFO-лимитер ограничивает поток RPC и не допускает более 50
|
||||
ожидающих. Для `UNAVAILABLE`, `DEADLINE_EXCEEDED` и `RESOURCE_EXHAUSTED`
|
||||
обычный RPC допускает один повтор через секунду. Deadline каждой попытки — 15 секунд,
|
||||
каждый RPC допускает один повтор через секунду. Deadline каждой попытки — 15 секунд,
|
||||
а ожидание места в лимитере не является временем этой сетевой попытки.
|
||||
Для поиска метаданных `GetInstrumentBy` разрешены две повторные попытки
|
||||
с паузами 2 и 4 секунды после неудачных попыток. Они применяются к тем же
|
||||
временным кодам и к переполнению локальной очереди; перед каждой попыткой
|
||||
проверяется её вместимость. Постоянные ошибки и отказ авторизации
|
||||
Метаданные используют ту же retry policy. Переполненная очередь завершается
|
||||
ошибкой сразу, без повторов admission. Постоянные ошибки и отказ авторизации
|
||||
не повторяются. Подтверждённый `NOT_FOUND` при поиске метаданных означает
|
||||
отсутствие инструмента, а не временный сбой. Остальные RPC при полной
|
||||
очереди завершаются сразу.
|
||||
отсутствие инструмента, а не временный сбой.
|
||||
Параметры попыток принадлежат
|
||||
[T-Bank client](https://git.personal.ksv741.ru/WealthLedger/backend/src/commit/016782657acfd35ff3fd755462007938fac35156/src/integrations/tbank/tbank.client.ts) (справочный источник);
|
||||
решение об ограниченных повторах — [ADR 005](../adr/005-tbank-upstream-resilience.md).
|
||||
|
||||
Generated
+339
-485
File diff suppressed because it is too large
Load Diff
+12
-6
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "wealth-ledger-docs",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.3",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": "24.21.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "markdownlint-cli2 \"**/*.md\" \"#node_modules\"",
|
||||
"lint": "markdownlint --dot --rules .markdownlint-rule-relative-links.cjs --ignore node_modules --ignore CHANGELOG.md -- \"**/*.md\" && markdownlint --config .markdownlint-changelog.json --rules .markdownlint-rule-relative-links.cjs -- CHANGELOG.md",
|
||||
"verify": "npm run lint && git diff --check",
|
||||
"release:preview": "release-it --dry-run --ci",
|
||||
"release:prepare": "release-it --ci",
|
||||
@@ -17,13 +17,19 @@
|
||||
"@commitlint/config-conventional": "21.2.2",
|
||||
"@release-it/conventional-changelog": "12.0.0",
|
||||
"conventional-changelog-conventionalcommits": "10.4.0",
|
||||
"markdownlint-cli2": "0.23.2",
|
||||
"markdownlint-rule-relative-links": "5.1.2",
|
||||
"markdownlint-cli": "0.49.1",
|
||||
"markdownlint-rule-relative-links": "5.1.3",
|
||||
"release-it": "21.0.2"
|
||||
},
|
||||
"overrides": {
|
||||
"markdownlint-cli2@0.23.2": {
|
||||
"smol-toml": "1.8.0"
|
||||
"katex": "0.19.0",
|
||||
"markdownlint-cli@0.49.1": {
|
||||
"js-yaml": "5.4.2",
|
||||
"smol-toml": "1.9.0"
|
||||
},
|
||||
"release-it": {
|
||||
"basic-ftp": "6.2.1",
|
||||
"undici": "7.29.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user