Files
specs/openspec/changes/archive/2026-08-17-redesign-position-cards/proposal.md
T

28 lines
3.4 KiB
Markdown

## Why
Position Card на странице Account Portfolio выглядит вытянутой: полноширинный ряд на колонке 960px с данными только по краям и пустой серединой. Показываются всего четыре метрики, хотя API уже отдаёт `averagePurchasePrice`, а ISIN инструмента доступен у T-Bank, но не пробрасывается backend-ом. Карточка не даёт ответить на «сколько эта позиция весит в портфеле» и «по какой цене куплена» с первого взгляда.
## What Changes
- **Backend**: `PortfolioPositionDto` получает nullable `isin` из metadata инструмента (T-Bank уже возвращает `isin` в ответах `GetInstrumentBy`); тип `TbankInstrument` расширяется полем `isin`.
- **Frontend**: Position Card перестаёт быть полноширинной строкой и становится компактной плиткой в grid (`base: 1, sm: 2, md: 3`). Плитка показывает: `displayName`, количество, `currentValue` (главная метрика), `absoluteReturn` (цвет зелёный/красный), `averagePurchasePrice`, долю позиции среди позиций той же валюты, ISIN (dim, моноширинный, под именем). Null-метрики скрываются, а не отображаются как «—».
- **Не меняется**: upstream-порядок внутри секций, разбиение на секции Акции/Облигации/Другие, Totals-карточки, Cash Balance, «Последние события», остальные страницы. Плитки некликабельны. Относительная доходность в % и тикер не добавляются.
- **Документация**: `CONTEXT.md` получает термин Instrument; `docs/features/portfolio-view.md` обновляет описание отображения позиций и поля `isin`.
## Capabilities
### New Capabilities
- (нет новых возможностей — изменение затрагивает только существующий portfolio-view)
### Modified Capabilities
- `portfolio-view`: Portfolio Position получает nullable `isin`; клиент отображает позиции компактными плитками в grid с расширенным составом метрик (средняя цена покупки, доля среди позиций той же валюты, ISIN), скрывает отсутствующие метрики и раскрашивает доход.
## Impact
- **backend** (`/api/v1/brokerage-accounts/:accountId/portfolio`): `PortfolioPositionDto` + поле `isin`; тип `TbankInstrument`; маппинг в `portfolio.service.ts`; тесты `portfolio.service.spec.ts`.
- **frontend**: OpenAPI snapshot и `schema.d.ts` (`openapi:sync`), `display.ts` (расчёт доли), `AccountPage.view.tsx`, `AccountPage.module.css`, i18n `ru.ts`, тесты `AccountPage.test.tsx` и `display.test.ts`.
- **docs**: `CONTEXT.md`, `docs/features/portfolio-view.md`.
- Внешних зависимостей и breaking-изменений нет: `isin` добавляется как nullable-поле.