docs: refresh project onboarding entrypoints
This commit is contained in:
@@ -14,6 +14,7 @@ bash ../specs/scripts/verify-runtime-openapi.sh
|
|||||||
## Границы
|
## Границы
|
||||||
|
|
||||||
- `adr/` - долгоживущие решения, `architecture/` - устройство системы, `development/` - процесс разработки, `features/` - фактическое поведение завершенных фич.
|
- `adr/` - долгоживущие решения, `architecture/` - устройство системы, `development/` - процесс разработки, `features/` - фактическое поведение завершенных фич.
|
||||||
|
- Перед изменением фактического описания системы сверяться с [`architecture/system-overview.md`](architecture/system-overview.md) и [`architecture/domain-glossary.md`](architecture/domain-glossary.md); development-документы индексируются в [`development/README.md`](development/README.md).
|
||||||
- Для диаграмм использовать Mermaid в Markdown. Feature-документация описывает пользовательский поток, API-сценарий и ограничения.
|
- Для диаграмм использовать Mermaid в Markdown. Feature-документация описывает пользовательский поток, API-сценарий и ограничения.
|
||||||
- Не хранить OpenSpec-артефакты, code приложений или секреты; requirements, design, delta-specs и tasks остаются только в `../specs/openspec`.
|
- Не хранить OpenSpec-артефакты, code приложений или секреты; requirements, design, delta-specs и tasks остаются только в `../specs/openspec`.
|
||||||
- Не создавать и не коммитить framework-specific planning/spec/task/design artifacts, включая `superpowers/plans`; `../references/**` остаётся read-only исключением.
|
- Не создавать и не коммитить framework-specific planning/spec/task/design artifacts, включая `superpowers/plans`; `../references/**` остаётся read-only исключением.
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
# Architecture
|
# Архитектура
|
||||||
|
|
||||||
Здесь описывается фактическое устройство системы, общие границы компонентов и интеграций. Диаграммы Mermaid добавляются, когда они проясняют взаимодействие.
|
Здесь описывается фактическое устройство WealthLedger и границы компонентов.
|
||||||
|
|
||||||
|
- [Обзор системы](system-overview.md) — поставленные возможности, локальные
|
||||||
|
границы и основные потоки данных.
|
||||||
|
- [Глоссарий домена](domain-glossary.md) — канонические значения терминов.
|
||||||
|
- [ADR](../adr/README.md) — долгоживущие решения и их последствия.
|
||||||
|
|||||||
@@ -0,0 +1,119 @@
|
|||||||
|
# Глоссарий домена
|
||||||
|
|
||||||
|
## T-Bank connection
|
||||||
|
|
||||||
|
Единственное принадлежащее User подключение к T-Bank Invest, содержащее
|
||||||
|
зашифрованный token для server-side запросов.
|
||||||
|
|
||||||
|
_Не использовать_: аккаунт T-Bank, авторизация T-Bank.
|
||||||
|
|
||||||
|
## Brokerage Account
|
||||||
|
|
||||||
|
Открытый поддерживаемый инвестиционный счёт T-Bank, доступный через T-Bank
|
||||||
|
connection: брокерский счёт, ИИС, Инвесткопилка или фонд денежного рынка.
|
||||||
|
|
||||||
|
_Не использовать_: счёт T-Bank, банковский счёт.
|
||||||
|
|
||||||
|
## Investment Account Type
|
||||||
|
|
||||||
|
Нормализованная категория Brokerage Account, независимая от upstream enum
|
||||||
|
T-Bank.
|
||||||
|
|
||||||
|
_Не использовать_: тип аккаунта T-Bank, protobuf type.
|
||||||
|
|
||||||
|
## Portfolio
|
||||||
|
|
||||||
|
Текущее нормализованное состояние инвестиций одного Brokerage Account,
|
||||||
|
включающее позиции, доступные денежные остатки и итоги по каждой валюте.
|
||||||
|
|
||||||
|
_Не использовать_: общий портфель, баланс счёта.
|
||||||
|
|
||||||
|
## Portfolio Position
|
||||||
|
|
||||||
|
Ненулевой обычный инвестиционный актив в составе Portfolio с количеством и
|
||||||
|
доступными оценочными показателями.
|
||||||
|
|
||||||
|
_Не использовать_: валютная позиция, виртуальная позиция.
|
||||||
|
|
||||||
|
## Instrument
|
||||||
|
|
||||||
|
Ценная бумага или иной торгуемый актив T-Bank, на который ссылается Portfolio
|
||||||
|
Position через FIGI или instrument UID. Metadata Instrument обогащают
|
||||||
|
отображение Position, но не определяют количество или стоимость.
|
||||||
|
|
||||||
|
_Не использовать_: бумага, тикер, актив позиции.
|
||||||
|
|
||||||
|
## Cash Balance
|
||||||
|
|
||||||
|
Ненулевой доступный денежный остаток Portfolio в одной валюте; не является
|
||||||
|
Portfolio Position.
|
||||||
|
|
||||||
|
_Не использовать_: валютная позиция, заблокированные средства.
|
||||||
|
|
||||||
|
## Portfolio Snapshot
|
||||||
|
|
||||||
|
Полный успешно полученный состав Portfolio на определённый момент времени,
|
||||||
|
который может быть свежим или устаревшим fallback-представлением.
|
||||||
|
|
||||||
|
_Не использовать_: история портфеля, snapshot для графика.
|
||||||
|
|
||||||
|
## Client Cached Snapshot
|
||||||
|
|
||||||
|
Последний успешно полученный frontend-ответ React Query, который остаётся
|
||||||
|
видимым во время фонового обновления или после его ошибки. Не является
|
||||||
|
server-side fallback и не использует поле `Portfolio.isStale`.
|
||||||
|
|
||||||
|
_Не использовать_: устаревший Portfolio Snapshot, fallback портфеля.
|
||||||
|
|
||||||
|
## Account Ledger
|
||||||
|
|
||||||
|
Упорядоченная read-only история исполненных операций одного Brokerage Account,
|
||||||
|
отражающая фактические денежные и инструментальные движения без рыночной
|
||||||
|
переоценки или расчёта остатка после операции.
|
||||||
|
|
||||||
|
_Не использовать_: история Portfolio, баланс счёта.
|
||||||
|
|
||||||
|
## Ledger Entry
|
||||||
|
|
||||||
|
Нормализованное представление одной операции T-Bank в Account Ledger; хранит
|
||||||
|
исходные суммы и доступные детали операции, не создавая синтетических записей
|
||||||
|
для комиссии сделки.
|
||||||
|
|
||||||
|
_Не использовать_: проводка, рассчитанная операция.
|
||||||
|
|
||||||
|
## Ledger Page Cache
|
||||||
|
|
||||||
|
Кэш страницы Account Ledger, отделённый от кэша отдельных операций.
|
||||||
|
|
||||||
|
_Не использовать_: operations cache, кэш отдельных операций.
|
||||||
|
|
||||||
|
## Ledger Page Cache Key
|
||||||
|
|
||||||
|
Каноническая идентичность страницы Ledger Page Cache: User, Brokerage Account,
|
||||||
|
нормализованные диапазон и categories, opaque upstream cursor и limit.
|
||||||
|
|
||||||
|
_Не использовать_: сырой URL query, ключ отдельной Ledger Entry.
|
||||||
|
|
||||||
|
## Concurrent Refresh Attempt
|
||||||
|
|
||||||
|
Два или более перекрывающихся запроса с одним ещё действительным refresh token
|
||||||
|
одной Session; один становится Refresh Winner, остальные — Refresh Loser и
|
||||||
|
получают `401`, не отзывая Session победителя.
|
||||||
|
|
||||||
|
_Не использовать_: повторное использование refresh token, последовательный
|
||||||
|
refresh.
|
||||||
|
|
||||||
|
## Superseded Refresh Token
|
||||||
|
|
||||||
|
Refresh token, который перестал быть действительным после успешной ротации
|
||||||
|
Session; его предъявление получает `401`, но само по себе не отзывает Session.
|
||||||
|
|
||||||
|
_Не использовать_: активный refresh token, признак взлома сессии.
|
||||||
|
|
||||||
|
## Future Cash Event
|
||||||
|
|
||||||
|
Прогнозируемое на ближайший период денежное или связанное корпоративное
|
||||||
|
событие одного Brokerage Account, рассчитанное по текущей Portfolio Position;
|
||||||
|
не является исполненной Ledger Entry.
|
||||||
|
|
||||||
|
_Не использовать_: будущая операция, гарантированная выплата.
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
# Обзор системы
|
||||||
|
|
||||||
|
WealthLedger — локальное приложение для просмотра инвестиционных данных через
|
||||||
|
безопасное server-side подключение к T-Bank Invest.
|
||||||
|
|
||||||
|
## Поставленные возможности
|
||||||
|
|
||||||
|
- [Аутентификация](../features/authentication.md): access/refresh-сессии и
|
||||||
|
защищённые маршруты.
|
||||||
|
- [Подключение T-Bank](../features/tbank-connection.md): один зашифрованный
|
||||||
|
token на User.
|
||||||
|
- [Брокерские счета](../features/brokerage-accounts.md),
|
||||||
|
[Portfolio](../features/portfolio-view.md),
|
||||||
|
[Account Ledger](../features/brokerage-account-ledger.md) и
|
||||||
|
[Future Cash Events](../features/brokerage-account-upcoming-events.md).
|
||||||
|
- [Frontend UI resilience](../features/frontend-ui-resilience.md): явные
|
||||||
|
loading, error, empty и cached-snapshot состояния.
|
||||||
|
|
||||||
|
Термины этих возможностей определяет [глоссарий домена](domain-glossary.md), а
|
||||||
|
причины ключевых технических решений — [ADR](../adr/README.md).
|
||||||
|
|
||||||
|
## Локальные границы
|
||||||
|
|
||||||
|
- Frontend — React-клиент; он не вызывает T-Bank напрямую.
|
||||||
|
- Backend — NestJS API `/api/v1`, владеющий auth, SQLite-данными и T-Bank
|
||||||
|
gRPC boundary.
|
||||||
|
- OpenAPI backend — единственный контракт frontend; committed client
|
||||||
|
генерируется штатным workflow.
|
||||||
|
- Поставка остаётся локальной: deployment, Docker, CI/CD и облачные сервисы не
|
||||||
|
входят в текущие границы.
|
||||||
|
- Snapshot Portfolio и кэш Ledger существуют только в runtime-памяти; система
|
||||||
|
не предоставляет историческое хранилище портфеля.
|
||||||
|
|
||||||
|
## Поток auth/session
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
participant U as User
|
||||||
|
participant F as Frontend
|
||||||
|
participant B as Backend
|
||||||
|
participant D as SQLite
|
||||||
|
U->>F: Регистрация или вход
|
||||||
|
F->>B: POST /api/v1/auth/*
|
||||||
|
B->>D: Создаёт User и Session
|
||||||
|
B-->>F: Access token + refresh cookie
|
||||||
|
F->>B: Защищённый запрос с Bearer token
|
||||||
|
B-->>F: Данные или Problem Details
|
||||||
|
F->>B: POST /api/v1/auth/refresh при истечении access token
|
||||||
|
B->>D: Ротирует refresh token
|
||||||
|
B-->>F: Новый access token + refresh cookie
|
||||||
|
```
|
||||||
|
|
||||||
|
## Поток инвестиционных данных
|
||||||
|
|
||||||
|
```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: Открывает счета или Portfolio
|
||||||
|
F->>B: GET /api/v1/brokerage-accounts/* (Bearer)
|
||||||
|
B->>D: Читает T-Bank connection
|
||||||
|
B->>T: Запрос через server-side gRPC boundary
|
||||||
|
T-->>B: Upstream-данные
|
||||||
|
B-->>F: Нормализованные данные или Problem Details
|
||||||
|
F-->>U: Экран с данными или локальным состоянием ошибки
|
||||||
|
```
|
||||||
|
|
||||||
|
Подробный статус локальных gates и deferred Prisma e2e находится в
|
||||||
|
[audit remediation registry](../development/audit-remediation.md).
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
# Development
|
# Разработка
|
||||||
|
|
||||||
Здесь размещаются устойчивые правила разработки, локальной проверки и поставки. Требования и планы изменений остаются в `../specs/openspec`.
|
Здесь размещаются устойчивые правила разработки, локальной проверки и поставки. Требования и планы изменений остаются в `../specs/openspec`.
|
||||||
|
|
||||||
|
- [Frontend workflow](frontend-workflow.md) — Node 22, локальный запуск и
|
||||||
|
frontend verification.
|
||||||
|
- [Backend workflow](backend-workflow.md) — bootstrap backend, локальные
|
||||||
|
non-mutating gates и границы e2e.
|
||||||
- [Audit remediation registry](audit-remediation.md) — текущий статус findings, следующий OpenSpec change и evidence завершённых улучшений.
|
- [Audit remediation registry](audit-remediation.md) — текущий статус findings, следующий OpenSpec change и evidence завершённых улучшений.
|
||||||
- [OpenSpec authority и lifecycle](openspec-authority-and-lifecycle.md) — единственный SDD store, границы постоянной документации и условия archive.
|
- [OpenSpec authority и lifecycle](openspec-authority-and-lifecycle.md) — единственный SDD store, границы постоянной документации и условия archive.
|
||||||
- [Проверка runtime OpenAPI](runtime-openapi-verification.md) — отдельный read-only contract gate и его границы.
|
- [Проверка runtime OpenAPI](runtime-openapi-verification.md) — отдельный read-only contract gate и его границы.
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# Рабочий процесс backend
|
||||||
|
|
||||||
|
## Предварительные условия
|
||||||
|
|
||||||
|
Backend требует Node 22. Создайте `backend/.env` на основе
|
||||||
|
`backend/.env.example` и замените placeholder-значения `JWT_SECRET` и
|
||||||
|
`TOKEN_ENCRYPTION_KEY`; token T-Bank в этот файл не записывается.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
cp .env.example .env
|
||||||
|
npm ci
|
||||||
|
```
|
||||||
|
|
||||||
|
## Локальная проверка
|
||||||
|
|
||||||
|
Следующие команды не изменяют versioned-файлы:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run lint
|
||||||
|
npm run typecheck:app
|
||||||
|
npm run typecheck:test
|
||||||
|
npm test -- --runInBand
|
||||||
|
```
|
||||||
|
|
||||||
|
`npm run lint:fix` — явная записывающая команда. Runtime OpenAPI сверяется с
|
||||||
|
frontend snapshot из workspace:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash specs/scripts/verify-runtime-openapi.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
`npm run test:e2e` временно не является passing gate: Prisma schema engine
|
||||||
|
останавливает migration до Jest. Точная диагностика и trigger пересмотра
|
||||||
|
зафиксированы в [audit remediation registry](audit-remediation.md).
|
||||||
+12
-1
@@ -1,3 +1,14 @@
|
|||||||
# Features
|
# Возможности
|
||||||
|
|
||||||
Здесь документируется фактическое поведение завершенных пользовательских фич: пользовательский поток, API-сценарий и ограничения. Не реализованные возможности сюда не добавляются.
|
Здесь документируется фактическое поведение завершенных пользовательских фич: пользовательский поток, API-сценарий и ограничения. Не реализованные возможности сюда не добавляются.
|
||||||
|
|
||||||
|
- [Аутентификация](authentication.md) — регистрация, сессии и refresh.
|
||||||
|
- [Подключение T-Bank](tbank-connection.md) — безопасное управление
|
||||||
|
подключением.
|
||||||
|
- [Брокерские счета](brokerage-accounts.md) — список поддерживаемых счетов.
|
||||||
|
- [Портфель](portfolio-view.md) — состав инвестиций и freshness states.
|
||||||
|
- [Account Ledger](brokerage-account-ledger.md) — исполненные операции счёта.
|
||||||
|
- [Future Cash Events](brokerage-account-upcoming-events.md) — прогнозируемые
|
||||||
|
события по текущим позициям.
|
||||||
|
- [Frontend UI resilience](frontend-ui-resilience.md) — устойчивые состояния
|
||||||
|
интерфейса.
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ sequenceDiagram
|
|||||||
|
|
||||||
`INVALID_TBANK_TOKEN` означает, что T-Bank отклонил аутентификацию или права доступа. `TBANK_UNAVAILABLE` означает временную ошибку, превышение лимита, ожидание в очереди или другую ошибку внешнего сервиса.
|
`INVALID_TBANK_TOKEN` означает, что T-Bank отклонил аутентификацию или права доступа. `TBANK_UNAVAILABLE` означает временную ошибку, превышение лимита, ожидание в очереди или другую ошибку внешнего сервиса.
|
||||||
|
|
||||||
## Configuration and limits
|
## Конфигурация и ограничения
|
||||||
|
|
||||||
- `TOKEN_ENCRYPTION_KEY` - закодированный в base64 32-байтный ключ AES-256-GCM; обязателен при запуске.
|
- `TOKEN_ENCRYPTION_KEY` - закодированный в base64 32-байтный ключ AES-256-GCM; обязателен при запуске.
|
||||||
- `TBANK_GRPC_ENDPOINT` по умолчанию имеет значение `invest-public-api.tbank.ru:443`.
|
- `TBANK_GRPC_ENDPOINT` по умолчанию имеет значение `invest-public-api.tbank.ru:443`.
|
||||||
@@ -35,6 +35,12 @@ FIFO-ограничитель на экземпляр запускает не б
|
|||||||
|
|
||||||
Портфель с большим числом ранее не кэшированных инструментов создаёт отдельные metadata lookup. Если в такой ситуации очередь переполняется и позиции получают FIGI вместо names, увеличьте `TBANK_RATE_LIMIT_PER_SECOND` в соответствии с разрешённой upstream-квотой; для локального портфеля из множества позиций использовалось значение `50`.
|
Портфель с большим числом ранее не кэшированных инструментов создаёт отдельные metadata lookup. Если в такой ситуации очередь переполняется и позиции получают FIGI вместо names, увеличьте `TBANK_RATE_LIMIT_PER_SECOND` в соответствии с разрешённой upstream-квотой; для локального портфеля из множества позиций использовалось значение `50`.
|
||||||
|
|
||||||
## MVP limits
|
## Ограничения
|
||||||
|
|
||||||
Реализована только проверка токена. Счета, портфели, кэш метаданных инструментов, ротация ключа, распределенное ограничение запросов и сериализация параллельного обновления подключения отложены. Вендорные protobuf-контракты взяты из `references/moex-vibe`; при необходимости обновляйте их вручную по официальной документации T-Bank Invest API.
|
Подключение используется поставленными сценариями Brokerage Accounts,
|
||||||
|
Portfolio, Account Ledger и Future Cash Events; frontend не обращается к
|
||||||
|
T-Bank напрямую. Token encryption key не ротируется, rate limit остаётся
|
||||||
|
per-instance, а обновление connection не сериализуется между распределёнными
|
||||||
|
экземплярами backend. Вендорные protobuf-контракты взяты из
|
||||||
|
`references/moex-vibe`; при необходимости обновляйте их вручную по официальной
|
||||||
|
документации T-Bank Invest API.
|
||||||
|
|||||||
Reference in New Issue
Block a user