Forge
markdowndeeb25a2
1# ADR 0068: Полезная нагрузка строки канала и проекция на поверхность (layout vs cell content)
2
3**Статус:** Accepted
4**Дата:** 2026-04-19
5
6## Связанные ADR
7
8| ADR / документ | Роль |
9|----------------|------|
10| [0021](0021-pfd-mfd-cockpit-attention-model.md) | Канал vs слот; глоссарий presentation |
11| [0021 § глоссарий](0021-pfd-mfd-cockpit-attention-model.md#glossary-presentation-vs-channel) | Слот презентации vs проекция строки (**не путать**) |
12| [0023](0023-environment-readiness-glance.md) | Канал readiness vs IDE Health |
13| [0036](0036-cds-channel-compositor-surface-pipeline.md) | Канал → композитор → UI |
14| [0063](0063-instrument-deck-named-composition-one-anchor.md) | ContentRepresentation vs instrument deck |
15| [0064](0064-deck-primitives-visual-language-render-layer-and-palette.md) | Примитивы лампы, отрисовка |
16| [0066](0066-cockpit-ui-vs-ide-presentation-layer.md) | Cockpit UI vs хром IDE |
17| [`environment-readiness-glance-v1.md`](../design/environment-readiness-glance-v1.md) | Чертёж readiness |
18
19**Не путать:** «проекция представления» здесь — как **строка снимка** становится лампой/глифом; это уровень **ниже**, чем слот региона в [0021](0021-pfd-mfd-cockpit-attention-model.md) и не замена **ContentRepresentation** в [0063](0063-instrument-deck-named-composition-one-anchor.md).
20
21---
22## Контекст
23
24По мере развития продукта один и тот же **логический снимок канала** (например готовность окружения) показывается **несколькими способами**: компактная полоса ламп, список карточек, «таблица» с колонками, возможные будущие режимы (плотность, только бейджи, отдельный MFD-блок).
25
26В разговоре и в коде легко **слить**:
27
281. **Раскладку** — где на экране лежат строки (сетка, полоса, колонки шапки «Компонент / Сведения», узкий vs широкий режим).
292. **Содержимое ячейки** — что именно пользователь видит в позиции строки: примитив лампы, текстовый глиф, ссылка, кнопка, смешанный блок.
303. **Доменную строку снимка** — стабильный id, уровень сигнала, заголовок, деталь, короткая подпись на линзе и т.д.
31
32Пока все строки **однородны** (один record-тип, например `AnnunciatorLampItem`), слияние не болит. Когда появятся **разные виды строк** (действие в ячейке, Rich-текст, вторичный индикатор), без именованного разделения рефакторинг превращается в разрастание `DataTemplate` и дублирование полосы и таблицы.
33
34Нужен **устойчивый словарь слоёв**, не обязательно отдельная сборка типов на каждый экран с первого дня.
35
36---
37
38## Решение
39
40<a id="adr0068-p1"></a>
41
42**1. Три осмысленных слоя (термины для ADR, ревью и кода):**
43
44| Слой | Вопрос | Примечание |
45|------|--------|------------|
46| **Полезная нагрузка строки / ячейки (row payload)** | Что **канал** утверждает о мире в этой строке? | Снимок домена: идентичность, статус, тексты, будущие варианты вида строки. Строится в `Services/` / у источника данных, **без** Avalonia. |
47| **Идентичность слота (slot identity)** | Где строка **стоит** в упорядоченном наборе и как на неё ссылаются тесты и пресеты? | Стабильные id ячеек, порядок в deck (напр. `EnvironmentReadinessInstrumentDeck.OrderedCellIds`), связь с каналом readiness ([0023](0023-environment-readiness-glance.md)). Ортогонально тому, **как** нарисована ячейка. |
48| **Проекция представления (presentation projection)** | Как **конкретная поверхность** отображает **ту же** полезную нагрузку: линза в полосе, та же линза в первой колонке таблицы, текстовый глиф-заглушка, интерактив в хроме IDE? | Выбор примитива и шаблона; может переиспользовать `AnnunciatorLampMetrics` / `LabeledAnnunciatorLampFace` ([0064](0064-deck-primitives-visual-language-render-layer-and-palette.md)); интерактив и «не прибор» — по [0066](0066-cockpit-ui-vs-ide-presentation-layer.md). |
49
50**Инвариант:** смена **раскладки** (полоса ↔ таблица ↔ карточки) **не** меняет контракт **полезной нагрузки**; меняется только проекция и композитор/View. Смена **семантики строки** (новый вид содержимого) — расширение payload и/или дискриминатор вида строки, затем отдельные проекции по виду.
51
52<a id="adr0068-p2"></a>
53
54**2. Связь с осями [0063](0063-instrument-deck-named-composition-one-anchor.md):** ось **ContentRepresentation** (Strip / Page / …) задаёт **форму контейнера** региона; **instrument deck** — **что и в каком порядке** в этом контейнере. **Проекция представления** в этом ADR — уровень **ниже**: *внутри* выбранной формы, как **каждая строка снимка** превращается в пиксели/контролы. Три слоя выше **не заменяют** ContentRepresentation и deck; они уточняют, **где не смешивать** данные канала и варианты отрисовки одной строки.
55
56<a id="adr0068-p3"></a>
57
58**3. Прагматичный v1:** допустимо хранить снимок в **одном** типе строки (`AnnunciatorLampItem` и аналоги), пока все строки **однородны**. Это не отменяет различения слоёв в голове и в ревью: полоса и таблица — **две проекции** одного payload, а не два разных «канала».
59
60<a id="adr0068-p4"></a>
61
62**4. Когда появляется гетерогенность ячеек:** вводить явное различение в **модели полезной нагрузки** (discriminated union, несколько record-типов, ключ шаблона) и сопоставлять **проекции** по виду строки; не размножать несовместимые снимки одного канала без причины.
63
64<a id="adr0068-p5"></a>
65
66**5. Дублирование одной и той же проекции** (например полоса ламп сверху и снова лампы в первом столбце таблицы) — **продуктовый** выбор: осознанное дублирование glance vs деталь или удаление избыточности. Архитектурно это решение на уровне **какие проекции включены в режим**, а не смешение payload с layout.
67
68---
69
70## Последствия
71
72- Новые экраны каналов с deck-метафорой **явно разделяют** сборку снимка, стабильные id/order и выбор проекций в View / композиторе.
73- Рефакторинг «лампа в ячейке таблицы вместо глифа» трогает **проекцию** и переиспользование примитива ([0064](0064-deck-primitives-visual-language-render-layer-and-palette.md)), а не обязан менять `EnvironmentReadinessSnapshotBuilder`, если семантика строки не менялась.
74- Тесты: контракт **payload** и порядок id — отдельно от визуальных тестов **проекции** (если они появляются).
75
76## Открыто
77
78- Имена типов/интерфейсов в коде (`IRowPayload`, `PresentationProjection` и т.д.) — вводить **по мере** появления второго гетерогенного канала или повторяющегося паттерна; этот ADR задаёт **терминологию**, не обязательную сущность в репозитории на дату принятия.
79
View only · write via MCP/CIDE