Перейти к содержанию

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-блок).

В разговоре и в коде легко слить:

  1. Раскладку — где на экране лежат строки (сетка, полоса, колонки шапки «Компонент / Сведения», узкий vs широкий режим).
  2. Содержимое ячейки — что именно пользователь видит в позиции строки: примитив лампы, текстовый глиф, ссылка, кнопка, смешанный блок.
  3. Доменную строку снимка — стабильный 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 задаёт терминологию, не обязательную сущность в репозитории на дату принятия.