7.4 KiB
Context
Portfolio уже нормализуется backend-ом из финансовых данных и metadata инструмента, после чего frontend получает только OpenAPI-контракт. Metadata разрешается по instrument UID с fallback на FIGI и уже содержит тикер для построения отображаемого имени, однако тикер не входит в нормализованную Portfolio Position. Карточка позиции отображает ISIN независимо от типа инструмента.
Изменение расширяет публичный ответ Portfolio nullable presentation metadata и затрагивает обе стороны committed OpenAPI-контракта. Денежные значения, расчёты, доступ к счёту, metadata lookup и cache policies остаются прежними.
Goals / Non-Goals
Goals:
- Передавать доступный тикер через нормализованную Portfolio Position без отдельного источника данных на клиенте.
- Отображать на карточке
STOCKтикер либо ISIN как определённый fallback. - Сохранить единый backend-owned API contract и generated frontend types.
Non-Goals:
- Не менять правила формирования отображаемого имени, порядок, секции или финансовые данные Portfolio.
- Не менять представление облигаций и иных типов позиций.
- Не вводить новый upstream lookup, cache, endpoint, хранилище или клиентскую интеграцию с T-Bank.
Decisions
Nullable ticker остаётся metadata Portfolio Position
Backend добавляет nullable ticker к нормализованной Position и заполняет его
из уже разрешённой metadata инструмента. Пустое значение и отсутствие metadata
нормализуются в null, как существующие presentation metadata. Это делает
данные доступными одинаково для всех типов Position, не меняет уже принятый
порядок разрешения metadata и не влияет на финансовый Snapshot.
Не использовать тикер непосредственно из исходной Portfolio Position: это обошло бы единый UID/FIGI resolution path и могло бы расходиться с другими metadata полями. Не запрашивать metadata на frontend: это нарушило бы server-side boundary T-Bank и создало бы второй источник контрактных данных.
OpenAPI — единственный межрепозиторный шов
DTO backend-а объявляет nullable ticker; опубликованный runtime OpenAPI
документ становится источником для committed frontend snapshot и generated
types. Frontend не создаёт ручной transport type и не меняет контракт локально.
Так additive field остаётся синхронным между runtime API и клиентом.
Выбор идентификатора принадлежит presentation layer карточки
Существующая VM продолжает передавать structural Portfolio Position из
generated контракта. Карточка определяет подпись только из уже переданных
type, ticker и isin: для STOCK выбирает ticker ?? isin, для остальных
типов сохраняет isin. Это локальная presentation-логика одного значения,
поэтому не переносит в view fetching, группировку или финансовые вычисления.
Delivery Map
| Area | Status | Architectural outcome or N/A reason |
|---|---|---|
| frontend | affected |
Получает синхронизированные generated types и отображает на карточке STOCK тикер с ISIN fallback, не меняя карточки иных типов. |
| backend | affected |
Нормализует nullable ticker из существующей metadata и публикует его в Portfolio API/OpenAPI. |
| specs | affected |
Delta portfolio-view закрепляет nullable ticker и type-specific presentation fallback. |
| docs | affected |
После проверенной реализации feature documentation Portfolio описывает поле ticker и stock-only правило отображения. |
Contract Gate Decision
| Gate | Status | Reason |
|---|---|---|
| runtime-openapi | required |
Backend публикует additive поле Portfolio API, а frontend потребляет его через committed OpenAPI snapshot и generated types. |
Risks / Trade-offs
- Ticker остаётся best-effort metadata; nullable contract и ISIN fallback не скрывают Position при его отсутствии.
- Additive публичное поле требует синхронной поставки runtime OpenAPI и committed frontend snapshot; contract gate предотвращает их расхождение.
- Неэквивалентность тикера и отображаемого имени намеренна: имя сохраняет существующий приоритет, тикер служит компактной подписью только акции.
Migration Plan
- Расширить backend-нормализацию и публичный contract nullable ticker без изменения существующих полей или cache semantics.
- Синхронизировать generated frontend contract с runtime OpenAPI и применить type-specific presentation rule в карточке.
- Обновить as-built Portfolio documentation после подтверждения delivered поведения.
Rollback Contract
| Field | Decision |
|---|---|
| Status | required |
| Trigger | Обнаружено, что новое поле или его отображение нарушает совместимость Portfolio API либо неправильно идентифицирует акции. |
| Actions | Сначала вернуть frontend-карточки акций к ISIN. Nullable ticker не удалять из backend публичного ответа во время rollback, чтобы не ломать уже синхронизированный клиентский contract; последующее удаление возможно только отдельным compatibility change. |
| Data safety | Тикер — производная metadata текущего in-memory Portfolio Snapshot; миграций, persistent data и денежных расчётов нет. |
| Verification | Подтвердить сохранение ISIN на stock-карточках и соответствие runtime OpenAPI committed frontend snapshot. |