ДокументацияИнженерия контента4. Мапперы: входящие и исходящие

Мапперы: входящие и исходящие

Почему это важно. Классификатор решает, какого рода инцидент это событие; маппер решает, как он выглядит. Входящий маппер превращает сырой вендорский JSON, который попадает в SOARForge, в поля кейса, которые читают ваши аналитики — заголовок, severity, статус, адрес отправителя, целевой хост — сохраняя при этом нетронутый оригинал для аудита. Сделайте маппинг правильно — и аналитики видят чистый, единообразный кейс независимо от того, из какого из дюжины источников он пришёл; сделайте неправильно — и они таращатся на кейс с пустым заголовком и стеной неподписанных атрибутов.

Эта глава покрывает два направления маппера, когда и как именно входящий маппер отрабатывает во время ingest, полный редактор маппинга, грамматику путей и операторов, которую понимает маппер, как протестировать маппер сквозь и где на самом деле используются исходящие мапперы.


4.1. Концепция: два направления, одна модель полей

Маппер — это именованный, переиспользуемый объект, привязанный к бренду интеграции (source key коннектора) и направлению:

  • Входящий маппер — отрабатывает в момент ingest. Вход — сырой JSON события; выход — набор значений полей кейса. Это мост между схемой вендора и моделью кейса SOARForge.
  • Исходящий маппер — отрабатывает, когда изменение кейса зеркалится обратно в систему-источник. Вход — поля кейса; выход — payload, сформированный под вендора. Исходящие мапперы выполняются только для инстансов коннекторов с включённым зеркалированием (см. §4.12).

Куда пишет входящий маппер. Понимание модели хранения — ключ к грамотному использованию мапперов. У созданного кейса четыре дома данных, и входящий маппер решает, что куда идёт:

Хранилище кейса Что сюда попадает Задаётся
Встроенные колонки кейса (title, description, severity, status, tags, occurred, …) Встроенные цели маппера Правилами, целящими в name, details, severity, status, tags, occurred, category, owner, phase, …
custom_fields Каждая кастомная (не встроенная) цель, которую сопоставил маппер Правилами, целящими в machine-имя кастомного поля, напр. emailfrom
raw_json Неизменяемый исходный payload события Никогда не маппится — хранится дословно, всегда
labels Каждый сырой атрибут события, который маппер не сопоставил Автоматически — см. ниже

Неизменяемый оригинал хранится всегда. raw_json — это нетронутое событие, каким оно прибыло; маппер никогда его не переписывает. Всё, что маппер явно не сопоставляет, тоже не теряется — писатель ingest материализует каждый несопоставленный сырой атрибут в метку ({ type: "<path>", value }), так что ни одно поле молча не исчезает. Несопоставленные данные идут в labels, никогда в custom_fields — это пространство имён зарезервировано для полей, которые маппер сопоставил намеренно.


4.2. Когда запускается входящий маппер

Входящий маппер — это один этап конвейера ingest. Алерты входят через POST /ingest, ставятся в очередь на RabbitMQ, и воркер ingest обрабатывает каждый внутри одной транзакции базы данных. Порядок фиксирован:

  1. Построить конверт — воркер нормализует payload в канонический конверт: source, sourceInstance, sourceRef, payload (сырое событие) и производные скаляры (name, details, occurred).
  2. Правила pre-processing — опциональные правила, которые могут отбросить или подправить событие.
  3. Классифицировать — классификатор, привязанный к инстансу коннектора, отрабатывает первым и выбирает тип инцидента (или fallback incident type инстанса).
  4. Смаппитьзатем отрабатывает входящий маппер, привязанный к тому же инстансу, ограниченный тем типом инцидента, который только что выбрал классификатор.
  5. Спроецировать и записать — вывод маппера проецируется в запись кейса и записывается: встроенные — в колонки кейса, кастомные цели — в custom_fields, оригинал — в raw_json, несопоставленные атрибуты — в labels.

Сначала классификатор, затем маппер для выбранного типа. Решение классификатора выбирает, какие правила маппера применяются. Вот почему у маппера есть и common-правила (гоняются для каждого типа инцидента), и specific-правила (гоняются, только когда кейс одного типа инцидента) — см. §4.4.

Как выбирается маппер — приоритет. Глобального маппера по умолчанию нет. Выбор целиком привязан к инстансу:

  • Каждый инстанс коннектора (конфигурация, которую вы задаёте в Settings → Integrations → Connectors → Advanced SettingsIncoming Mapper) держит incomingMapperId. Это маппер, который воркер ingest гоняет для событий с этого инстанса.
  • Если у разрешённого инстанса есть привязанный маппер с хотя бы одним правилом, воркер гоняет его. Иначе он откатывается к проекции только по конверту — задаются лишь встроенные из конверта (title, description, occurred), а каждый листовой атрибут становится меткой. Ни одно правило никогда не «отрабатывает наполовину».

Привязывайте маппер на инстансе. Маппер, существующий в реестре, сам по себе ничего не делает. Он участвует в ingest, только когда инстанс коннектора направляет свою настройку Incoming Mapper на него. Редактор маппинга может создать и сохранить эту привязку за вас, когда вы открываете его из инстанса коннектора (§4.4).


4.3. Где мапперы в интерфейсе

Маршрут: /admin/incident-types (Objects Setup → Incident Types & Pipelines, группа Classification) · Права: incident_types.view, incident_types.manage

К мапперам добираются с двух взаимодополняющих поверхностей:

  1. Реестр объектов маппинга — единая таблица, перечисляющая классификаторы и оба направления мапперов. Используйте её, чтобы просматривать, клонировать, удалять и открывать любой маппер, а также создавать новые. Разобрано в §4.9.
  2. Incoming Mapping Editor — живой, управляемый инстансом визуальный редактор, где вы фактически собираете входящий маппер по реальным данным событий. Разобран далее.

Открытие входящего маппера из реестра ведёт в визуальный редактор. Открытие исходящего маппера открывает более простой диалог таблицы правил (тот же диалог, что вы используете для его создания) — у исходящих мапперов нет живого JSON-дерева, потому что они гоняются по полям кейса, а не по входящим событиям.


4.4. Редактор входящего маппинга

Маршрут: /admin/incident-types?tab=classification&classificationTab=incident-mapper · Права: incident_types.view, incident_types.manage

Почему это важно. Именно здесь фактически происходит маппинг. Он кладёт реальный JSON события с одной стороны и поля кейса с другой и позволяет соединять их кликом или перетаскиванием — затем показывает точное значение, которое получило бы каждое поле, вычисленное тем же движком, что гоняется в момент ingest. Что вы видите в превью — то и получаете.

Редактор — это двухпанельное рабочее пространство под управляющим заголовком.

Элементы заголовка

Элемент Назначение
Mapper name Имя, под которым сохраняется объект-маппер.
Save mapper Сохранить маппер. Если вы открыли редактор из инстанса коннектора, сохранение также привязывает маппер к этому инстансу.
Branch (тип инцидента) Какому типу инцидента принадлежат specific-правила на экране.
Scope (Common / Specific) Редактируете ли вы правила, гоняющиеся для каждого типа (Common), или только для выбранного типа инцидента (Specific).
Connector / Instance Инстанс коннектора, из которого тянуть образцы событий и (опционально) к которому привязать маппер.
Data (Pull / Schema / Upload) Откуда берутся события превью: Pull живых событий из инстанса, генерировать Schema/образец события или Upload (вставить) свой JSON.
Pull (+ limit / sort) Забрать события превью; для живых pull выберите сколько и newest/oldest first.

Под элементами управления кнопки веток показывают число common-правил и число правил каждого релевантного типа инцидента; ветка, которую классификатор может произвести, но у которой пока нет правил, подсвечена, чтобы вы замечали пробелы покрытия. Сворачиваемая панель details резюмирует активную ветку, привязанный классификатор, источник превью, поля конверта интеграции и живое превью того, какие сырые атрибуты пока несопоставлены (и какие станут метками).

Левая панель — список целевых полей

Левая панель перечисляет каждое поле, в которое можно маппить, взятое из двух источников:

  • Встроенные цели — канонические поля кейса, которые распознаёт маппер: name (title), details (description), severity, status, tags, occurred, owner, phase, category, dueDate, closeNotes, closeReason, playbookId.
  • Поля инцидента — кастомные и системные поля инцидента, обнаруженные для бренда коннектора.

Список можно фильтровать (поле поиска), показывать только mapped или unmapped поля и добавлять ad-hoc кастомную цель, набрав её machine-имя. Два имени отклоняются намеренно: всё, что начинается с case. (устаревшая форма), и имена, принадлежащие конверту, — source / sourceInstance / sourceRef (ими владеет интеграция, а не маппер).

Кнопка Auto-map просит бэкенд оценить текущее событие против целевых полей и заполняет высоко-уверенные предложения путей, не перезаписывая маппинги, которые вы задали вручную.

Правая панель — JSON события

Правая панель показывает текущее выбранное событие превью как цветокодированное дерево (значения окрашены по типу), сырое JSON-представление и вкладку guide с разобранными примерами путей. Поле поиска подсвечивает совпадающие ключи. Массивы показывают короткий образец своего содержимого, чтобы вы видели, что собираетесь маппить.

Маппинг поля: построчная строка и мастер

Каждое целевое поле — это строка. Чтобы его смаппить:

  1. Кликните Choose data path на строке (или кнопку {}), затем кликните нужное значение в JSON-дереве — или перетащите лист из дерева на строку. Выбранный путь заполняет поле источника строки.
  2. Строка Result: под строкой показывает значение, которое производит этот путь, после фильтров и трансформеров, вычисленное живой симуляцией превью.

Кнопка (Filters & transformers) на сопоставленной строке открывает встроенный мастер, меню из трёх строк:

Строка мастера Что настраивает
Get Путь источника (пере-открывает выбор пути).
Where Цепочку фильтров, применяемую к забранному значению (см. §4.6).
Transformers Цепочку трансформеров, применяемую после фильтров.

Иконка корзины на строке Get очищает всё правило (путь, фильтры, трансформеры и любые расширенные настройки). Добавление фильтра или трансформера открывает редактор цепочки: каждый шаг — пронумерованная карточка с выпадающим списком выбора оператора, описанием, динамически отрисованными вводами аргументов (текст, число, чекбокс или JSON-текстовая область в зависимости от оператора) и кнопкой удаления. Add filter / Add transformer дописывает шаг в конец цепочки; порядок карточек — порядок выполнения.

Переупорядочивание цепочки. Шаги выполняются сверху вниз в показанном порядке. Встроенный редактор позволяет добавить шаг (в конец), сменить оператор шага на месте и удалить шаг. Чтобы переупорядочить, удалите и пере-добавьте в нужном порядке.

Если тип сопоставленного значения источника не совпадает с типом целевого поля, строка показывает предупреждение с конкретным предложением исправления (например, добавить трансформер Join with comma или First item, чтобы подать текстовому полю значение из массива).


4.5. Синтаксис путей

Маппер резолвит путь источника относительно контекста события небольшой, предсказуемой грамматикой — это не общий язык запросов.

  • Точечная нотация. payload.sender.emailAddress.address идёт по вложенным объектам ключ за ключом.
  • Префикс payload.. Поля события живут под payload.*. Редактор добавляет префикс автоматически, когда вы выбираете путь из дерева. Горстка скаляров конверта адресуется в корне вместо этого: source, sourceInstance, sourceRef, name, details, occurred.
  • Числовой индекс массива. Числовой ключ индексирует массив: payload.toRecipients.0.emailAddress.address берёт первого получателя.
  • Проекция массива. Нечисловой ключ, применённый к массиву, проецируется по каждому элементу и собирает результаты: payload.toRecipients.emailAddress.address возвращает адрес каждого получателя как массив (undefined-элементы отбрасываются).

Это вся грамматика. Нет wildcard (*), нет [*]-слайса и нет выражения/интерполяции внутри пути источника. Логика формования значений — включая выражения в стиле DT — живёт в цепочке трансформеров, а не в пути (трансформер DT резолвит выражение относительно уже забранного значения; он не часть резолвинга путей).


4.6. Фильтры (Where) и трансформеры

Каждое правило маппинга прогоняет забранное значение через фиксированный конвейер:

путь источника → Where (фильтры) → значение по умолчанию (если пусто) → Трансформеры → запись в цель

  • Where / фильтры отрабатывают первыми. Они урезают значение — отбрасывают пустые элементы, оставляют уникальные или первые элементы или оставляют только те элементы массива, что совпадают с условием. Если после фильтрации значение пусто, подставляется значение по умолчанию правила (если задано).
  • Трансформеры отрабатывают последними. Они переформовывают значение — обрезают пробелы, удаляют HTML, меняют регистр, разбивают/склеивают, форматируют даты, сопоставляют одну строку другой, извлекают индикаторы и многое другое.

Аргументы операторов. Операторы, которым нужны аргументы, экспонируют их в мастере как типизированные вводы. Обязательные аргументы помечены *. Аргумент regex валидируется при сохранении — невалидный или небезопасный (с катастрофическим бэктрекингом) паттерн отклоняется заранее, а не падает молча в момент ingest.

Расширенное поведение на уровне правила (несётся на правиле, задаётся через диалог реестра):

Настройка Эффект
Overwrite policy always (по умолчанию), if_empty (только когда цель ещё пуста) или never (оставить существующее значение в покое).
Required Если правило не производит значения, ingest фиксирует предупреждение (кейс всё равно создаётся).
On error Если фильтр/трансформер бросает: skip_field (по умолчанию — оставить поле незаданным), use_raw_value, set_default или fail_rule.

Каталог операторов велик — 138 трансформеров (семейства string, array, object, date/time, math, encoding и security/IOC) плюс 10 фильтров (compact, drop_empty, unique, first, where_exists, where_equals, filter, If-Then-Else, RegexExtractAll, SetByIndex) — 148 записей реестра всего. Полный справочник — каждый оператор, его аргументы и его поведение — живёт в файле-спутнике mapper-operators-reference.ru.md; разобранный пример в §4.11 использует лишь горстку из них.

Один и тот же движок повсюду. Фильтры и трансформеры оцениваются одним общим движком, используемым воркером ingest, превью редактора и инструментами теста. «Приближения превью» нет — превью и есть рантайм.


4.7. Типы полей и приведение

Маппер не заставляет сопоставленное значение принять тип цели; он пишет то, что произвёл конвейер, а проектор кейса нормализует встроенные поля:

  • Severity нормализуется к одному из critical / high / medium / low / informational (без учёта регистра, пробелы в подчёркивания; infoinformational). Числовая severity — число или числовая строка — отображается на шкалу по нижней границе диапазона: 0/0.5informational, 1low, 2medium, 3high, ≥ 4critical (значения выше шкалы обрезаются; дробные округляются вниз, так что 2.7medium). Только значение, которое не является ни распознанным термином, ни неотрицательным конечным числом, откатывается к severity по умолчанию типа инцидента.
  • Status нормализуется к одному из new / open / in_progress / pending_approval / resolved / closed, иначе откатывается к new. Числовой статус не приводится — единой межвендорной числовой конвенции статусов нет, поэтому числовой статус откатывается, а не угадывается. Отобразите его явно трансформером маппера (MapPattern) в принятый термин.
  • Tags принимают массив или строку через запятую; каждый становится обрезанным тегом.
  • Title ограничен 500 символами. Если на текстовое поле (title/description) маппится не-строковое значение, оно сериализуется в JSON-строку, а не отбрасывается — вот почему маппинг целого объекта на name производит JSON-кляксу как заголовок. Маппьте скалярный лист вместо этого.

Для кастомных полей приведения по схеме нет — значение хранится, как произведено. Вот почему важно предупреждение о несовпадении типа в редакторе: оно сигнализирует, например, о массиве, смапленном на одно-значное поле, чтобы вы могли вставить трансформер joinComma или first до сохранения.


4.8. Диалог правил маппера (реестр / исходящий)

Создание исходящего маппера или редактирование любого маппера из таблицы реестра без JSON-дерева использует диалог таблицы правил. Он экспонирует поля, которые визуальный редактор прячет за своим мастером, и это поверхность, где значения по умолчанию и сырые цепочки трансформеров вводятся напрямую:

Поле диалога Назначение
Mapper Name Имя маппера.
Integration Brand Source key коннектора, для которого этот маппер.
Schema Source Как маппер обнаружил свою форму: Instance / Schema / JSON sample.
Content Source System / Marketplace / Custom (новые мапперы по умолчанию Custom).
System denylist Имена атрибутов, никогда не материализуемые в метки автоматически (по умолчанию включают dbot_status, close_notes, …).
Enabled Участвует ли маппер.
Common Mapping rules Правила, гоняющиеся для каждого типа инцидента. Каждая строка: Target field, JSON path, Transformers (как JSON-вызовы операторов), Default value, Rule enabled.
Specific Mapping rules То же плюс Incident Type — правило гоняется только для этого типа.

Два способа добраться до одного объекта. Визуальный редактор и этот диалог редактируют один и тот же подлежащий маппер; визуальный редактор — более богатый способ собрать входящий маппер по живым данным, диалог — компактный способ просмотреть или отредактировать правила вручную (и единственный редактор для исходящих мапперов).


4.9. Управление мапперами

Таблица реестра объектов маппинга перечисляет классификаторы и оба направления мапперов вместе. Колонки:

Колонка Значение
Name Кликните, чтобы открыть объект в его редакторе.
Type Classifier, Mapper (incoming) или Mapper (outgoing).
Instances Сколько инстансов коннекторов сейчас привязывают этот объект.
Description Сводка (для маппера: направление, число common-правил, число specific-типов).
System True, когда объект принадлежит system/marketplace (а не Custom).

Действия панели инструментов: Edit, Clone, Delete и меню New (New Incident Classifier / New Incoming Mapper / New Outgoing Mapper). Поле поиска фильтрует по имени, бренду или описанию.

Clone / duplicate. Clone копирует выбранный маппер в новый редактируемый объект: к имени добавляется суффикс (copy) ((copy 2), (copy 3), … при необходимости), правила копируются, а Content Source копии сбрасывается на Custom, так что маппер, принадлежащий system или marketplace, становится свободно редактируемым. Clone — рекомендуемый способ адаптировать поставленный маппер.

Мапперы, поставленные паком. Content-паки из Marketplace могут поставлять мапперы; они приходят помеченными как принадлежащие system/marketplace (Content Source не Custom), и реестр помечает их System: True. Предпочитайте Clone редактированию pack-owned маппера на месте — последующее обновление пака может перезаписать маппер, которым он владеет, отбросив правки на месте, тогда как ваш Custom-клон ваш и останется.

Удаление маппера. Маппер, который всё ещё привязан к одному или нескольким инстансам коннекторов, удалить нельзя — платформа отказывает с ошибкой конфликта. Сначала отвяжите его от каждого инстанса (очистите настройку Incoming/Outgoing Mapper инстанса).


4.10. Сквозное тестирование маппера

У вас есть две возможности проверки, и они проверяют разное.

1. Живое превью редактора. По мере сборки редактор непрерывно симулирует текущий собираемый маппер против выбранного события превью и показывает, по полям, точное значение, которое он произвёл бы (строка Result:), сырые атрибуты, всё ещё несопоставленные, и какие из них станут метками. Поскольку превью гоняет тот же движок, что и ingest, значение, появляющееся здесь, — это значение, которое получил бы реальный кейс. Вытяните несколько живых событий (или вставьте репрезентативное) и пройдитесь по ним, чтобы подтвердить, что маппер держится поперёк вариаций.

2. Вкладка Test. Objects Setup → Incident Types & Pipelines → ClassificationTest (/admin/incident-types?tab=classification&classificationTab=test) гоняет весь фронт конвейера вместе: выберите коннектор и инстанс, вставьте образец payload ingest ({ source, sourceInstance, payload }) и Run Test. Результат показывает:

  • Classification — какой тип инцидента победил и по какому правилу (или fallback-тип), с построчной трассировкой условий.
  • Mapped Fields Preview — вывод маппера для разрешённого типа инцидента, поле за полем.

Это самый быстрый способ подтвердить, что классификатор и его маппер согласны — что тип, который выбирает классификатор, — это тип, чьи specific-правила вы ожидаете запустить.

Проверяйте, прежде чем полагаться. Тестируйте на реальных (или реалистичных) событиях, а не на идеализированном. Вендоры варьируют форму поля между видами алертов — адрес, который иногда строка, а иногда объект, severity, которое иногда числовое — и только реальный образец это вскрывает.


4.11. Разобранный пример

Допустим, коннектор почтового ящика Microsoft 365 доставляет отчёты о фишинге, и вы хотите чистый кейс Phishing. Репрезентативный payload события:

{
  "source": "o365",
  "sourceInstance": "o365-soc-mailbox",
  "payload": {
    "subject": "  Re: Invoice overdue — please verify  ",
    "severity": "High",
    "categories": ["phishing", "", "external"],
    "body": { "content": "<p>Click <a href='http://bad.example'>here</a></p>" },
    "sender": { "emailAddress": { "address": "Billing@BAD.example", "name": "Billing" } },
    "toRecipients": [
      { "emailAddress": { "address": "alice@corp.local", "name": "Alice" } },
      { "emailAddress": { "address": "bob@corp.local", "name": "Bob" } }
    ]
  }
}

Входящий маппер из шести правил (scope показан по строкам; все используют overwrite policy always):

# Путь источника Фильтры (Where) Трансформеры Целевое поле
1 payload.subject trim name (заголовок кейса)
2 payload.severity toLowerCase severity
3 payload.body.content htmlToText details (описание)
4 payload.sender.emailAddress.address toLowerCase emailfrom (custom)
5 payload.toRecipients.emailAddress.address joinComma emailto (custom)
6 payload.categories compact tags

Что производит каждое правило:

  1. TitleRe: Invoice overdue — please verify (пробелы обрезаны).
  2. Severityhigh (в нижний регистр, затем нормализовано к enum).
  3. Description → HTML, ободранный до читаемого текста.
  4. emailfrom (custom) → billing@bad.example, хранится в custom_fields.
  5. emailto (custom) → alice@corp.local, bob@corp.local — проекция массива собирает оба адреса получателей, joinComma складывает их в одну строку.
  6. Tags["phishing", "external"]compact отбрасывает пустую строку.

Всё, что шесть правил не сопоставили (например payload.sender.name), становится меткой на кейсе, а весь payload выше сохраняется дословно в raw_json. Каждый использованный здесь оператор (trim, toLowerCase, htmlToText, joinComma, compact) существует в каталоге операторов; об остальных см. mapper-operators-reference.ru.md и работу по операторному конвейеру в главе 5.


4.12. Исходящие мапперы

Исходящий маппер — зеркальное отражение: он отрабатывает, когда изменение кейса зеркалится обратно в систему-источник. Он привязан к outgoingMapperId инстанса коннектора и выполняется только для инстансов, чей режим зеркалирования — outgoing или both. Когда кейс создаётся или меняется зеркалируемое поле, платформа ставит в очередь задачу зеркалирования; сервис коннектора загружает привязанный исходящий маппер, проверяет его направление, гоняет его правила по полям кейса (тот же движок правил, что и у входящего) и передаёт получившийся payload интеграции для проталкивания наверх. Действие preview mirroring позволяет увидеть исходящий payload для конкретного кейса до включения потока.

Исходящие мапперы авторятся в диалоге таблицы правил (§4.8) — JSON-дерева нет, потому что «источник» — это кейс, а не входящее событие. Выражения путей, фильтры, трансформеры, значения по умолчанию и политики на уровне правил работают ровно так же, как во входящем.

Гоняется только то, что использует зеркалирование. Исходящий маппер, не привязанный к инстансу с включённым зеркалированием, инертен — он хранится и редактируется, но никакой рантайм-путь его не выполняет, пока инстанс не начнёт зеркалить через него.


Распространённые ошибки

  • Маппер сохранён, но в момент ingest ничего не меняется. Маппер гоняется, только когда инстанс коннектора его привязывает (Incoming Mapper в advanced settings инстанса). Непривязанные мапперы ничего не делают; инстанс откатывается к проекции только по конверту.
  • Обязательное поле выходит пустым. Классификатор выбирает тип инцидента, и только specific-правила этого типа гоняются рядом с common-правилами. Если поле смаплено только в specific-ветке для другого типа, оно не заполнится. Кладите type-агностичные маппинги в Common.
  • Путь резолвится в ничто. Следите за неверным префиксом (поля события под payload.*), массивом там, где вы ждали объект (используйте числовой индекс или положитесь на проекцию), или полем, которое присутствует в одном виде алерта и отсутствует в другом. Строка Result: редактора и панель несопоставленных полей показывают промахи немедленно.
  • Заголовок — JSON-клякса. Не-строковое значение, смапленное на name/details, сериализуется в JSON, а не отбрасывается. Маппьте скалярный лист или добавьте трансформер (напр. first, joinComma), чтобы свести массив/объект к тексту.
  • Severity или status «игнорируются». Эти встроенные нормализуются к фиксированному enum. Severity также принимает числовую шкалу (0→informational … ≥4→critical, §4.7); status числа не приводит. Значение вне набора (или числовой статус) откатывается к умолчанию — маппьте вендорское значение через трансформер MapPattern/SetIfEmpty, чтобы перевести его в принимаемый термин.
  • Редактирование pack-owned маппера. Правки на месте system/marketplace-маппера (System: True) могут быть перезаписаны более поздним обновлением пака. Сначала Clone его — копия Custom и её безопасно менять.
  • Маппер не удаляется. Он всё ещё привязан к инстансу коннектора. Очистите настройку маппера инстанса везде, где он используется, затем удаляйте.
  • Превью выглядело хорошо, но прод отличается. Проверяйте на реальных, разнообразных событиях. Движок превью идентичен рантайму, так что расхождение почти всегда означает, что живое событие отличается по форме от вашего образца.