docs(specs): archive stock ticker change
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
## 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
|
||||
|
||||
1. Расширить backend-нормализацию и публичный contract nullable ticker без
|
||||
изменения существующих полей или cache semantics.
|
||||
2. Синхронизировать generated frontend contract с runtime OpenAPI и применить
|
||||
type-specific presentation rule в карточке.
|
||||
3. Обновить 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. |
|
||||
Reference in New Issue
Block a user