ADR 0068: Полезная нагрузка строки канала и проекция на поверхность (layout vs cell content)¶
Статус: Accepted
Дата: 2026-04-19
Связанные ADR¶
| ADR / документ | Роль |
|---|---|
| 0021 | Канал vs слот; глоссарий presentation |
| 0021 § глоссарий | Слот презентации vs проекция строки (не путать) |
| 0023 | Канал readiness vs IDE Health |
| 0036 | Канал → композитор → UI |
| 0063 | ContentRepresentation vs instrument deck |
| 0064 | Примитивы лампы, отрисовка |
| 0066 | Cockpit UI vs хром IDE |
environment-readiness-glance-v1.md |
Чертёж readiness |
Не путать: «проекция представления» здесь — как строка снимка становится лампой/глифом; это уровень ниже, чем слот региона в 0021 и не замена ContentRepresentation в 0063.
Контекст¶
По мере развития продукта один и тот же логический снимок канала (например готовность окружения) показывается несколькими способами: компактная полоса ламп, список карточек, «таблица» с колонками, возможные будущие режимы (плотность, только бейджи, отдельный MFD-блок).
В разговоре и в коде легко слить:
- Раскладку — где на экране лежат строки (сетка, полоса, колонки шапки «Компонент / Сведения», узкий vs широкий режим).
- Содержимое ячейки — что именно пользователь видит в позиции строки: примитив лампы, текстовый глиф, ссылка, кнопка, смешанный блок.
- Доменную строку снимка — стабильный id, уровень сигнала, заголовок, деталь, короткая подпись на линзе и т.д.
Пока все строки однородны (один record-тип, например AnnunciatorLampItem), слияние не болит. Когда появятся разные виды строк (действие в ячейке, Rich-текст, вторичный индикатор), без именованного разделения рефакторинг превращается в разрастание DataTemplate и дублирование полосы и таблицы.
Нужен устойчивый словарь слоёв, не обязательно отдельная сборка типов на каждый экран с первого дня.
Решение¶
1. Три осмысленных слоя (термины для ADR, ревью и кода):
| Слой | Вопрос | Примечание |
|---|---|---|
| Полезная нагрузка строки / ячейки (row payload) | Что канал утверждает о мире в этой строке? | Снимок домена: идентичность, статус, тексты, будущие варианты вида строки. Строится в Services/ / у источника данных, без Avalonia. |
| Идентичность слота (slot identity) | Где строка стоит в упорядоченном наборе и как на неё ссылаются тесты и пресеты? | Стабильные id ячеек, порядок в deck (напр. EnvironmentReadinessInstrumentDeck.OrderedCellIds), связь с каналом readiness (0023). Ортогонально тому, как нарисована ячейка. |
| Проекция представления (presentation projection) | Как конкретная поверхность отображает ту же полезную нагрузку: линза в полосе, та же линза в первой колонке таблицы, текстовый глиф-заглушка, интерактив в хроме IDE? | Выбор примитива и шаблона; может переиспользовать AnnunciatorLampMetrics / LabeledAnnunciatorLampFace (0064); интерактив и «не прибор» — по 0066. |
Инвариант: смена раскладки (полоса ↔ таблица ↔ карточки) не меняет контракт полезной нагрузки; меняется только проекция и композитор/View. Смена семантики строки (новый вид содержимого) — расширение payload и/или дискриминатор вида строки, затем отдельные проекции по виду.
2. Связь с осями 0063: ось ContentRepresentation (Strip / Page / …) задаёт форму контейнера региона; instrument deck — что и в каком порядке в этом контейнере. Проекция представления в этом ADR — уровень ниже: внутри выбранной формы, как каждая строка снимка превращается в пиксели/контролы. Три слоя выше не заменяют ContentRepresentation и deck; они уточняют, где не смешивать данные канала и варианты отрисовки одной строки.
3. Прагматичный v1: допустимо хранить снимок в одном типе строки (AnnunciatorLampItem и аналоги), пока все строки однородны. Это не отменяет различения слоёв в голове и в ревью: полоса и таблица — две проекции одного payload, а не два разных «канала».
4. Когда появляется гетерогенность ячеек: вводить явное различение в модели полезной нагрузки (discriminated union, несколько record-типов, ключ шаблона) и сопоставлять проекции по виду строки; не размножать несовместимые снимки одного канала без причины.
5. Дублирование одной и той же проекции (например полоса ламп сверху и снова лампы в первом столбце таблицы) — продуктовый выбор: осознанное дублирование glance vs деталь или удаление избыточности. Архитектурно это решение на уровне какие проекции включены в режим, а не смешение payload с layout.
Последствия¶
- Новые экраны каналов с deck-метафорой явно разделяют сборку снимка, стабильные id/order и выбор проекций в View / композиторе.
- Рефакторинг «лампа в ячейке таблицы вместо глифа» трогает проекцию и переиспользование примитива (0064), а не обязан менять
EnvironmentReadinessSnapshotBuilder, если семантика строки не менялась. - Тесты: контракт payload и порядок id — отдельно от визуальных тестов проекции (если они появляются).
Открыто¶
- Имена типов/интерфейсов в коде (
IRowPayload,PresentationProjectionи т.д.) — вводить по мере появления второго гетерогенного канала или повторяющегося паттерна; этот ADR задаёт терминологию, не обязательную сущность в репозитории на дату принятия.