## 1. Backend: expose ISIN - [x] 1.1 Расширить тип `TbankInstrument` полем `isin?: string` в `tbank.client.ts` - [x] 1.2 Добавить nullable `isin` в `PortfolioPositionDto` в `portfolio.dto.ts` - [x] 1.3 Возвращать `isin: metadata?.isin?.trim() || null` в `position()` в `portfolio.service.ts` - [x] 1.4 Обновить `portfolio.service.spec.ts`: моки и ожидания `isin`, включая отсутствие ISIN - [x] 1.5 Проверить backend: `npm run lint`, `npm test`, `npm run build` ## 2. Frontend: OpenAPI contract и display-helper - [x] 2.1 Обновить snapshot и `schema.d.ts`: `npm run openapi:sync` (поле `isin`) - [x] 2.2 Добавить helper `formatShare(numerator, denominator)` в `display.ts` (строка %, 1 знак, `null` при недоступности) - [x] 2.3 Добавить unit-тесты `formatShare` в `display.test.ts` ## 3. Frontend: Position Card grid-плитки - [x] 3.1 Заменить `Card`-строки в `PositionSection` на `SimpleGrid cols={{ base: 1, sm: 2, md: 3 }}` в `AccountPage.view.tsx` - [x] 3.2 Вычислить во view сумму `currentValue` позиций по каждой валюте (без Cash Balance) и передать её плиткам - [x] 3.3 Рендерить плитку: имя, `isin` (mono, dim), количество, `currentValue`, `absoluteReturn` (зелёный/красный), `averagePurchasePrice`, долю; скрывать null-метрики - [x] 3.4 Добавить стили плитки в `AccountPage.module.css` - [x] 3.5 Добавить i18n-ключи в `ru.ts` (средняя цена покупки, доля, ISIN) ## 4. Frontend: тесты - [x] 4.1 Обновить `AccountPage.test.tsx`: заменить проверку «—» на скрытие null, добавить проверки плиток, `isin`, доли и сохранения upstream-порядка - [x] 4.2 Проверить frontend: `npm run verify` ## 5. Документация - [x] 5.1 Добавить термин Instrument в `CONTEXT.md` - [x] 5.2 Обновить `docs/features/portfolio-view.md`: grid-плитки, метрики, `isin`, доля; API-секция про `isin` ## 6. Верификация и архив - [x] 6.1 Прогнать `opsx-verify` по change - [ ] 6.2 Архив change через `openspec archive` и синхронизация delta в main spec - [ ] 6.3 Закоммитить по репозиториям: specs, docs, backend, frontend