Files
specs/openspec/changes/archive/2026-08-26-polish-stock-position-cards/design.md
T

110 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Context
Страница Portfolio уже подготавливает presentation-model позиций во ViewModel и
рендерит чистые view-компоненты. Акции и облигации выводятся одним широким
вариантом Position Card: в нём есть логотип, идентификатор, стоимость,
доходность, средняя цена и доля. Текущие требования задают состав метрик,
одноколоночность, логотип и цветовую семантику дохода, но не закрепляют
внутреннюю визуальную иерархию карточки.
Изменение остаётся в presentation layer: состав Portfolio, ViewModel-данные,
маршруты и интерактивные действия не меняются. У страницы нет действия для
Position Card, поэтому клавиатурный focus-стиль должен быть только следствием
имеющегося focusable-элемента, а не превращать карточку в контрол.
## Goals / Non-Goals
**Goals:**
- Сделать стоимость и доходность акции визуально первичными, а идентификатор и
служебные метрики — спокойным вторым уровнем без конкурирующих акцентов.
- Сохранить цветовую семантику доходности без отдельного badge, фона или
декоративной иконки.
- Сохранить читаемость одноколоночной карточки на узком и широком экранах.
**Non-Goals:**
- Изменение состава, вычисления или форматирования данных Portfolio.
- Изменение карточек облигаций и других типов позиций, порядка секций,
навигации, кликабельности или API.
- Добавление новых UI-библиотек, токенов, изображений либо интерактивных
состояний без существующего контролa.
## Decisions
### D1 — Визуальный вариант передаётся для секции акций
Position Section передаёт в существующую карточку presentation-only вариант для
`STOCK`. Это позволяет сделать акцию выразительнее и оставить карточки
облигаций в поставленном виде без копирования разметки или расхождения метрик.
Альтернатива — отдельная Stock Card — отклонена: она дублирует уже общий
контент карточки и повышает риск расхождения при будущих изменениях метрик.
### D2 — Две главные зоны и одна тихая мета-строка
Главная строка имеет только две зоны: слева логотип, название и одна
объединённая строка количества с ISIN; справа — текущая стоимость и доходность
простым цветным текстом. Средняя цена и доля переходят в единую приглушённую
мета-строку под разделителем. Локальная CSS-сетка обеспечивает устойчивое
выравнивание, усечение длинного имени и перенос метаданных без изменения DOM
порядка или доступных текстовых значений. Альтернатива — отдельные вложенные
карточки/панели — отклонена: лишняя декоративная вложенность ослабляет
плотность списка.
### D3 — Доходность остаётся текстовой метрикой
Доходность использует только существующие positive/negative theme colors и
умеренную насыщенность шрифта; ни фон, ни скруглённый контейнер не создаются.
При нулевой доходности цветной treatment не применяется. Альтернатива — новая
палитра или иконка направления — отклонена: цвет и знак уже передают нужный
сигнал, а дополнительный символ создаёт шум.
### D4 — Hover и focus не добавляются к некликабельной карточке
Карточка остаётся неинтерактивной. Допустим только ненавязчивый hover для
визуального отклика указателя; focus-стиль не добавляется, потому что Card не
участвует в keyboard navigation. Альтернатива — сделать карточку button/link —
отклонена как выходящая за границы change навигационная функция.
## Delivery Map
| Area | Status | Architectural outcome or N/A reason |
| --- | --- | --- |
| frontend | `affected` | Position Card получает presentation-only вариант акции и локальные стили группировки, статуса доходности и адаптивной компоновки; существующие page tests уточняют ожидаемую разметку акций. |
| backend | `N/A` | Контракт, data fetching и финансовые расчёты Portfolio не меняются. |
| specs | `affected` | Change хранит утверждённые Proposal и Design с `skip_specs: true`, поскольку существующие требования уже покрывают состав и семантику карточки. |
| docs | `affected` | As-built описание Portfolio кратко фиксирует уточнённую визуальную иерархию карточек акций после поставки. |
### Contract Gate Decision
| Gate | Status | Reason |
| --- | --- | --- |
| runtime-openapi | `N/A` | Ни backend, ни frontend API contract и generated snapshot не меняются. |
## Risks / Trade-offs
- Длинное имя инструмента может конкурировать с суммой на узком экране → имя
остаётся усечённым, а стоимость занимает приоритетную правую область.
- Слишком заметная доходность может перегрузить список → используется только
существующий цвет текста без фона, badge или отдельной иконки.
- Различие внешнего вида акций и облигаций может восприниматься как
несогласованность → оно ограничено явной пользовательской целью и не меняет
общий набор метрик, одноколоночность или логотип.
## Migration Plan
Поставка ограничена обратимой заменой presentation-разметки и локальных
стилей frontend, затем обновлением as-built documentation. Данные, миграции и
совместимость между приложениями не затрагиваются.
### Rollback Contract
| Field | Decision |
| --- | --- |
| Status | `N/A` |
| Reason | Change не меняет security, данные, миграции, публичный контракт или другое труднообратимое решение; прежний вид возвращается обратимой правкой frontend presentation layer. |
| Trigger | N/A |
| Actions | N/A |
| Data safety | N/A |
| Verification | N/A |