Конвейер регистрации и подготовки данных как каркас нетиповых обменов в 1С
Нетиповой обмен редко остается простым. Сначала нужно зарегистрировать изменение объекта и передать его во внешнюю систему. Затем появляются условия выгрузки, несколько получателей, маршрутизация, связанные объекты, разные форматы сообщений и новые сценарии.
Постепенно один механизм начинает отвечать сразу за всё:
- какой сценарий регистрации выполнить;
- какие объекты действительно должны попасть в обмен;
- достаточно ли для решения текущего состояния объекта;
- кому предназначены данные;
- как преобразовать объект 1С в интеграционное сообщение;
- что сделать с готовым сообщением;
- как зарегистрировать связанные объекты;
- как отлаживать отдельные этапы.
В результате прикладной код превращается в инфраструктурный монолит, который сложно расширять, переиспользовать и отлаживать по частям.
Идея этой статьи: регистрацию изменений и подготовку исходящих сообщений можно строить не как один большой алгоритм, а как расширяемый каркас, в котором сценарий описывается кодом, а исполняемый алгоритм собирается из обработчиков с согласованными контрактами. Каркас и пример реализации прилагаются.
Разберем основные архитектурные решения такого подхода: реестр сценариев, диспетчер, конвейер обработчиков, единый контекст, пакетную регистрацию, работу с предыдущим состоянием объекта, связанную регистрацию и независимую отладку отдельных этапов.
Речь пойдет именно о регистрации изменений, маршрутизации, формировании и помещении исходящих сообщений в очередь. Транспорт, гарантии доставки, повторные попытки и обработка входящего потока остаются за границами рассматриваемого каркаса.
Рубрикатор
1. Сценарий регистрации как код
Проблема: конфигурация алгоритма и сам алгоритм хранятся в данных
Если настройки регистрации хранятся в информационной базе или сторонней конфигурации, поведение механизма определяется уже не только исходным кодом.
Две базы с одинаковой версией конфигурации могут выполнять один сценарий по-разному. Чтобы воспроизвести его на другой базе, недостаточно перенести разработку - нужно отдельно переносить и синхронизировать настройки.
Такие настройки хуже анализируются и средствами разработки: они не находятся рядом с реализацией обработчиков, не участвуют непосредственно в сравнении версий исходного кода и могут незаметно различаться между базами.
Решение: Configuration as Code
В каркасе сценарии регистрации описываются непосредственно кодом в реестре сценариев.
Реестр связывает направление обмена и объект метаданных с описанием сценария:
- используемым конвейером;
- набором обработчиков;
- дополнительными параметрами выполнения.
Сам реестр ничего не выполняет. Это конфигурация, по которой другой компонент - диспетчер - собирает исполняемый алгоритм.
У хранения сценария в коде есть еще одно интересное следствие: конфигурация алгоритма становится доступна тем же инструментам разработки, что и сам алгоритм.
Это особенно актуально с развитием LLM и агентных средств разработки. Когда сценарий существует как данные информационной базы, для его анализа недостаточно исходного кода: необходимо отдельно получить состояние конкретной базы, восстановить настройки и связать их с реализацией.
При Configuration as Code описание сценария находится непосредственно в исходниках рядом с реализацией каркаса и обработчиков. LLM может увидеть состав конвейера, найти реализации входящих в него обработчиков, сопоставить их контракты и анализировать композицию алгоритма целиком.
В результате изменение можно формулировать на уровне задачи: например, добавить в существующий сценарий дополнительную фильтрацию, заменить маршрутизацию или собрать новый сценарий из уже существующих обработчиков. Если архитектурные правила и конфигурация алгоритма представлены кодом, LLM получает существенно больше контекста для подготовки соответствующих изменений в исходниках.
Это, конечно, не отменяет проверки разработчиком и тестирования результата. Но конфигурация перестает быть скрытым состоянием информационной базы и становится полноценной частью кодовой базы, доступной в том числе для AI-assisted development.
Что это дает? Сценарий становится частью исходного кода: версионируется, сравнивается, переносится и изменяется вместе с разработкой.

Матрица связи направления, объекта и сценария
В демо-конфигурации смотри обработку Демо_КОД_РеестрСценариев_ОбменССайтом и привязку реестра к плану обмена в общем модуле КОД_ДиспетчерРегистрацииКОбменуПереопределяемый.


2. Диспетчер: единая точка выбора и запуска сценария
Реестр отвечает на вопрос «что выполнить?». Диспетчер использует это описание, чтобы найти и инициировать требуемый сценарий.
Его задача остается инфраструктурной:
событие регистрации
|
v
найти сценарий в реестре
|
v
получить конвейер
и объекты обработчиков
|
v
передать обработчики
конвейеру
|
v
инициировать выполнение
При этом диспетчер не реализует сам механизм исполнения цепочки. Он управляет сессией регистрации: создает общую очередь заданий и менеджер временных таблиц, выбирает сценарии и запускает их. Внутренний контекст выполнения отдельного сценария, передача управления между обработчиками и политика обработки исключений относятся к следующему уровню - конвейеру.
Диспетчер также не знает прикладного назначения обработчиков: что такое заказ, товар, web-обмен, фильтрация или преобразование в JSON. Для него сценарий состоит из компонентов, соблюдающих известные каркасу программные контракты.
Поэтому добавление нового бизнес-сценария не приводит к появлению очередной ветки условий внутри диспетчера.
Пока новые сценарии соблюдают существующие контракты, их добавление не требует изменения диспетчера.
3. Конвейер как исполняемая композиция алгоритма
Сценарий определяет, из каких обработчиков состоит алгоритм, но сами по себе эти обработчики еще не образуют исполняемую последовательность.
Эту задачу решает конвейер. Он является инфраструктурным объектом, который превращает набор обработчиков в единый исполняемый алгоритм и управляет жизненным циклом его конкретного запуска.
В рассматриваемой реализации у конвейера четыре основные ответственности:
- сборка цепочки - обработчики последовательно добавляются в конвейер и связываются через Следующий();
- создание контекста выполнения - конвейер создает общее состояние конкретного запуска, включая входные данные, параметры выполнения, менеджер временных таблиц и рабочие данные;
- запуск цепочки - выполнение начинается с первого обработчика, после чего управление последовательно передается дальше;
- обработка исключений - граница выполнения всей цепочки находится внутри конвейера, поэтому он может поглотить исключение либо передать его вызывающему коду. При штатном запуске через диспетчер исключение передается выше.
Диспетчер
|
| сценарий + обработчики
v
+----------------------------------+
| Конвейер |
|----------------------------------|
| 1. собрать цепочку |
| 2. создать Context |
| 3. запустить первый обработчик |
| 4. обработать исключение |
+----------------+-----------------+
|
v
Filter -> Router -> Mapper -> Output
Таким образом, диспетчер отвечает за выбор сценария и его компонентов, а конвейер - за механику выполнения выбранного сценария.
Штатный запуск выполняется синхронно в рамках текущего вызова. Если один из обработчиков завершится с ошибкой, исключение остановит текущую сессию регистрации и затронет весь переданный пакет. Поэтому тяжелые операции и размер пакета следует выбирать с учетом допустимого времени транзакции и области отказа.
Архитектурной основой композиции служит идея паттерна Pipes and Filters из каталога Enterprise Integration Patterns Грегора Хопе и Бобби Вульфа: сложная обработка строится как последовательность этапов с согласованными контрактами.

Технически передача управления между обработчиками реализована близко к Chain of Responsibility: каждый обработчик хранит ссылку на следующий и после собственной работы передает ему управление.
Это не каноническая реализация Pipes and Filters с изолированными каналами сообщений. Управление передается по цепочке, а наборы данных могут передаваться через общий контекст и менеджер временных таблиц. Поэтому точнее рассматривать решение как сочетание Pipes and Filters, Chain of Responsibility и Context Object.
За счет этого один и тот же конвейер может исполнять совершенно разные сценарии:
Filter -> Router -> Mapper -> Output
или, например:
Filter -> Router -> Связанная регистрация -> Регистрация в плане обмена
Сам конвейер при этом не знает смысла ни одного из этих этапов. Для него они являются элементами одной исполняемой цепочки.
В демо-конфигурации смотри обработку КОД_КонвейерОбработчиковБазовый.

Основой реализации стала открытая архитектура Дмитрия Жичкина из статьи «Конвейеры обработки сообщений».
В ней обработчики реализованы отдельными объектами конфигурации Обработка, имеют единый интерфейс и связываются через метод Следующий().
В данном каркасе эта модель используется как исполняемое представление сценария регистрации: состав цепочки задается реестром, диспетчер получает требуемые компоненты, а конвейер связывает обработчики и управляет выполнением полученной композиции.
Статья Дмитрия послужила отправной точкой и вдохновением для создания данного решения.
Конвейер не содержит бизнес-алгоритм. Он предоставляет механизм, который превращает набор обработчиков в исполняемый алгоритм.
4. Обработчик как функциональная единица алгоритма
Если конвейер отвечает за композицию и выполнение алгоритма, то его функциональное содержание находится в обработчиках.
Каждый обработчик реализован отдельным объектом конфигурации Обработка и отвечает за одну законченную часть алгоритма: например фильтрацию объектов, маршрутизацию, преобразование данных, связанную регистрацию, запись сообщения в очередь или любое другое действие. Функциональные границы логической единицы алгоритма разработчик волен определять самостоятельно.
При этом обработчик не знает устройство всего сценария. Его задача ограничена собственным входным контрактом, собственной логикой и результатом, который он передает дальше. Независимость здесь обеспечивается соглашениями: обработчики должны одинаково понимать структуру контекста, имена временных таблиц и схему передаваемых данных.
Конвейер
|
v
+---------------------+
| Обработчик |
|---------------------|
| входной контракт |
| | |
| v |
| логика |
| | |
| v |
| выходной контракт |
+---------------------+
|
v
следующий обработчик
Такое разделение дает обработчику сразу несколько свойств:
- его можно использовать в разных сценариях;
- его можно заменить другим обработчиком с совместимым контрактом;
- его можно развивать отдельно от остальных этапов, пока сохраняется контракт;
- его можно запускать отдельно от полного конвейера, подготовив требуемый вход.
В демо-конфигурации реализован готовый механизм записи документа заказа в исходящую очередь при его изменении. Смотри соответствующие обработки:

Конвейер определяет, как выполняется композиция. Обработчики определяют, что эта композиция делает.
5. «Горячая» замена компонентов алгоритма
Проблема: изменение алгоритма требует обновления конфигурации
Реестр, конвейер и отдельные обработчики существуют как объекты одного типа - Обработка. Следовательно, для них можно использовать не только встроенную в конфигурацию реализацию, но и внешнюю.
В обычной ситуации изменение даже небольшого участка боевого алгоритма означает изменение конфигурации или расширения и последующее обновление информационной базы. Для интеграционного механизма это не всегда удобно: необходимость быстро исправить маршрутизацию или преобразование сообщения не обязательно должна требовать обновления всей поставки.
Решение: внешняя реализация через БСП
Для этого каркас предусматривает точку интеграции со стандартным механизмом Дополнительные отчеты и обработки БСП.
После включения этой интеграции диспетчер при получении исполняемого объекта может использовать встроенную обработку из конфигурации либо подключенную внешнюю обработку с той же ролью в каркасе.
Диспетчер
|
v
получить компонент
|
+----------+----------+
| |
v v
встроенная внешняя
обработка обработка
| |
+----------+----------+
|
v
единый программный
интерфейс
Для остальной архитектуры способ получения реализации при этом несущественен. Реестр по-прежнему описывает сценарий, конвейер по-прежнему собирает цепочку, а обработчики работают по тем же контрактам.
Это позволяет вынести во внешние обработки компоненты разных уровней:
- реестр - и тем самым заменить описание сценариев и состав собираемых конвейеров;
- конвейер - заменить инфраструктурную реализацию сборки и выполнения цепочки, формирования контекста и обработки исключений;
- отдельный обработчик - заменить только конкретный функциональный этап алгоритма.
Наиболее интересен последний вариант. Если проблема локализована, например, в Mapper, нет необходимости заменять весь механизм обмена. Можно подключить внешнюю версию только этого обработчика, сохранив неизменными Filter, Router, Output и сам сценарий.
Было:
Filter -> Router -> Mapper v1 -> Output
После замены:
Filter -> Router -> Mapper v2 -> Output
^
|
внешняя обработка
Получается «горячая» подмена реализации: новая версия компонента может быть подключена средствами БСП без включения ее кода непосредственно в конфигурацию.
При этом важно, что речь идет не о произвольном выполнении внешнего файла. Внешние реализации подключаются через штатную подсистему БСП Дополнительные отчеты и обработки, то есть остаются внутри предусмотренного 1С механизма регистрации и исполнения внешнего кода.
Такая возможность полезна не только при аварийных исправлениях. Она позволяет обкатывать новую реализацию отдельного этапа, временно подменять компонент при диагностике или развивать часть интеграционного алгоритма независимо от основного релизного цикла конфигурации.
У подмены есть цена. Фактическое поведение информационной базы снова начинает зависеть не только от версии исходников, но и от того, какие внешние обработки подключены в конкретной базе. Поэтому внешние версии, факт их подключения и права на их выполнение следует учитывать в релизном процессе и журналировании изменений.
Открытая поставка не зависит от БСП и может использоваться без нее. Для конфигураций, в которые БСП уже встроена, в демо оставлен отключенный пример интеграции.
1. В каждом обработчике есть универсальная функция СведенияОВнешнейОбработке() с закомментированным содержимым. При встраивании в конфигурацию с БСП этот код следует адаптировать к используемой версии библиотеки и раскомментировать.
2. В переопределяемом общем модуле КОД_ДиспетчерРегистрацииКОбменуПереопределяемый предусмотрены методы ПриПолученииОбъектаОбработки() и НайтиДополнительнуюОбработку(). После адаптации и включения кода диспетчер сможет искать активную внешнюю обработку в справочнике ДополнительныеОтчетыИОбработки по полю ИмяОбъекта и подставлять ее вместо встроенной реализации.

6. Как отлаживать один этап, а не весь обмен
Отладочная форма как точка входа
Обработчики реализованы отдельными обработками 1С и могут иметь собственные отладочные формы.
Такая форма:
- создает контекст выполнения;
- подготавливает входной контракт этапа;
- запускает боевой обработчик;
- показывает результат его работы.
Например, для Router форма подготавливает временную таблицу, которую в обычном сценарии создает Filter:
Обычное выполнение:
Filter -> Router -> Mapper -> Output
Отладка Router:
[Отладочная форма]
|
| ВТ_СсылкиПослеФильтра
v
Router
|
v
ВТ_СсылкиПоУзлам
Для Mapper можно аналогично подготовить результат маршрутизации и посмотреть сформированные тело сообщения, заголовки и получателей:
[Отладочная форма]
|
| входные контракты
v
Mapper
|
v
Тело / Заголовки / Получатели
При этом отдельной «отладочной версии» алгоритма не появляется.
В демо-конфигурации для основных обработчиков реализованы отладочные формы. Обработку можно сохранить как внешний файл и открыть отдельно либо запустить из подсистемы или из раздела «Функции для технического специалиста».

Отлаживается тот же боевой компонент. Меняются только его вход и точка наблюдения результата.
7. Единый контекст выполнения
Для передачи данных между обработчиками используется единый контекст выполнения. Архитектурной основой подхода служит паттерн Context Design.
При этом внешний контракт обработчика остается стабильным:
Обработать(Контекст, Вход)
А данные внутри контекста разделяются по назначению:
Контекст
|
+-- Вход
| +-- МассивСсылок
| +-- ОбъектМетаданных
|
+-- Выполнение
| +-- Идентификатор
| +-- Сценарий
| +-- Режим
| +-- ПланОбменаМета
| +-- МенеджерВременныхТаблиц
|
+-- Данные
+-- рабочие данные
+-- таблица сообщений
+-- результаты отладки
Особую роль играет общий МенеджерВременныхТаблиц. Через него обработчики могут передавать друг другу наборы данных без изменения программного интерфейса.
Общий контекст упрощает развитие каркаса, но одновременно становится частью неявного контракта. Поэтому имена полей, временных таблиц и их схемы следует документировать и изменять так же аккуратно, как экспортные методы.
Контекст может развиваться вместе с каркасом, пока сохраняется совместимость его документированных полей и наборов данных.
8. Пакетная регистрация как базовый входной контракт
Проблема: инфраструктура вокруг одной ссылки
Если механизм изначально рассчитан на один объект, массовая регистрация превращается в многократный запуск одних и тех же операций:
Объект 1 -> Filter -> Router -> Mapper Объект 2 -> Filter -> Router -> Mapper Объект 3 -> Filter -> Router -> Mapper ...
Для каждого объекта заново выполняются инфраструктурные действия и запросы, которые естественнее выполнить сразу над множеством.
Решение: массив ссылок на входе
Публичный интерфейс каркаса принимает не одну ссылку, а массив ссылок одного типа.
[Объект 1, Объект 2, Объект 3, ...]
|
v
Filter
|
v
Router
|
v
Mapper
Filter и Router работают с множествами и передают промежуточные результаты через временные таблицы. Mapper также получает данные пакетными запросами, после чего выполняет fan-out: формирует отдельное сообщение для каждого объекта и вызывает Output для каждого сообщения.
Множество ссылок
|
v
Filter -> Router -> Mapper
|
+-- сообщение 1 -> Output
+-- сообщение 2 -> Output
+-- сообщение 3 -> Output
Таким образом, реализация является гибридной: наиболее тяжелые операции отбора, маршрутизации и чтения данных выполняются над множествами, а конечная обработка происходит по сообщениям.
Пакетность здесь не локальная оптимизация, а свойство публичного входного контракта и операций над исходным множеством.
9. Предыдущая версия объекта как часть контракта
Проблема: нового состояния иногда недостаточно
Когда инициирующим событием является изменение объекта, решение о регистрации не всегда можно принять только по его новому состоянию.
Представим, что объект раньше удовлетворял условию выгрузки, а после изменения перестал:
Было Стало Условие выгрузки = Истина -> Условие выгрузки = Ложь Объект уже передан Filter исключает объект во внешнюю систему
Если анализировать только новое состояние, объект выпадет из обмена. Но внешняя система уже знает о его предыдущей версии и должна получить изменение, чтобы актуализировать свое состояние.
Та же проблема возникает при изменении данных, участвующих в маршрутизации. Новое состояние определяет новых получателей, но обработка может потребоваться и для прежних.
Решение: захват состояния до записи
Предыдущая версия читается из информационной базы в подписке перед записью объекта и передается в механизм регистрации через временную таблицу с согласованным именем ВТ_ПредыдущаяВерсия.
изменение объекта
|
v
подписка перед записью
|
v
предыдущее состояние
|
v
ВТ_ПредыдущаяВерсия
|
МассивСсылок -----------+
|
v
Filter
|
v
Router
При этом предыдущая версия не становится обязательным параметром каждого обработчика.
- Если она нужна обработчику - он использует ВТ_ПредыдущаяВерсия.
- Если не нужна - обработчик ничего о ней не знает.
- Если регистрация запущена без предыдущего состояния - демо-обработчики фильтрации создают пустую таблицу требуемой структуры.
В демонстрационной реализации снимок включает стандартные и обычные реквизиты объекта, но не табличные части. Автоматическая подписка показана для документов; для других типов объектов и для данных табличных частей требуется отдельная интеграция.
Предыдущее состояние становится частью инфраструктурного контракта, но не усложняет интерфейс каждого обработчика.
Подписка на событие Демо_КОД_ОбменПередЗаписьюДокументы.

10. Прикладной конвейер: Filter -> Router -> Mapper -> Output
Соберем предыдущие решения в конкретный сценарий.
Зарегистрированное множество объектов проходит четыре этапа:
Filter -> Router -> Mapper -> Output.
| Этап | Главный вопрос | Результат |
|---|---|---|
| Filter | Что обрабатывать? | ВТ_СсылкиПослеФильтра |
| Router | Кому предназначены данные? | ВТ_СсылкиПоУзлам |
| Mapper | Что отправлять? | Интеграционное сообщение |
| Output | Что сделать с сообщением? | Запись / отправка / регистрация |
Filter: что обрабатывать?
Filter применяет бизнес-условия к исходному множеству и формирует стандартный промежуточный контракт - ВТ_СсылкиПослеФильтра.
При этом таблица не обязана содержать только ссылку. В ней можно сразу сохранить данные, необходимые следующему этапу.
Например, при регистрации заказов вместе со ссылкой передается склад, который затем участвует в маршрутизации:
ВТ_СсылкиПослеФильтра Ссылка Склад ----------------------------------------- Заказ1 Склад1 Заказ2 Склад2 Заказ3 Склад1
Обработчики Демо_КОД_Обработчик_ФильтрЗаказов, Демо_КОД_Обработчик_ФильтрТоваров.

Router: кому предназначены данные?
Router получает результат фильтрации и определяет получателей каждого объекта.
Его выход - ВТ_СсылкиПоУзлам:
ВТ_СсылкиПоУзлам Ссылка Узел ----------------------------------------- Заказ1 WEB-1 Заказ1 WEB-2 Заказ2 WEB-2
Один объект может получить несколько маршрутов. При этом Router уже не решает, должен ли объект участвовать в обмене вообще: эту ответственность выполнил Filter.
Обработки Демо_КОД_Обработчик_МаршрутизаторЗаказов, Демо_КОД_Обработчик_МаршрутизаторТоваров.

Mapper: что отправлять?
После Router известны две вещи:
- какие объекты нужно обработать;
- кому предназначен результат.
Mapper преобразует данные 1С в интеграционное сообщение: формирует тело, заголовки и список получателей.
Логики выбора узлов внутри Mapper уже нет - это ответственность предыдущего этапа.
Обработчики Демо_КОД_Обработчик_ЗаказыВJSON, Демо_КОД_Обработчик_ТоварыВJSON.

Output: что сделать с сообщением?
Output получает готовое интеграционное сообщение и выполняет конечное действие.
В рассматриваемой реализации это запись сообщения во внутреннюю исходящую очередь. Такой Output не выполняет сетевой вызов во время записи исходного объекта и не увеличивает транзакцию ожиданием внешней системы.
Доставка из очереди во внешнюю систему находится за границами демонстрационного сценария. Повторные попытки, идемпотентность, подтверждения, порядок сообщений и отдельная очередь ошибок должны обеспечиваться транспортным слоем. Для самого конвейера конкретный способ фиксации или передачи результата не принципиален.
Можно заменить Output, не меняя Filter, Router и Mapper.
Обработчик Демо_КОД_Обработчик_ОтправительСообщенияВОчередь.

Полный поток данных выглядит так:
МассивСсылок
|
v
Filter
|
| ВТ_СсылкиПослеФильтра
v
Router
|
| ВТ_СсылкиПоУзлам
v
Mapper
|
| fan-out: сообщения
+-- Тело + Заголовки + Ссылка + Получатели -> Output
+-- Тело + Заголовки + Ссылка + Получатели -> Output
+-- ...
Filter решает, что обрабатывать. Router - кому. Mapper - что отправлять. Output - что сделать с результатом.
11. Связанная регистрация без жестких зависимостей
Проблема: один сценарий начинает знать о другом
Изменение одного объекта нередко требует зарегистрировать связанные объекты.
Например:
изменился Объект A
|
v
нужно зарегистрировать
Объекты B
Решение: повторный вход через очередь заданий регистрации
Обработчик связанной регистрации не запускает чужой конвейер. Он добавляет найденные ссылки во внутрипроцессную очередь заданий текущей сессии регистрации.
После завершения текущего задания диспетчер извлекает добавленную работу из очереди. Как именно обрабатывать объект B, снова решает его собственный сценарий из реестра.
Эта очередь не является брокером сообщений или постоянным хранилищем: она существует в памяти и обрабатывается синхронно в рамках текущего вызова. Если предметная область допускает циклические связи A -> B -> A или повторное порождение одинаковых ссылок, механизм следует дополнить дедупликацией и защитой от циклов.
Обработка Демо_КОД_Обработчик_СвязаннаяРегистрацияТоваров.

Сценарий A знает, какую работу нужно породить, но не знает, каким алгоритмом эта работа будет выполнена.
12. Демо-расширение: как запустить и проверить сценарий
Проект опубликован в двух репозиториях:
- 1c-exchange-pipeline - ядро каркаса без прикладных объектов и конкретных сценариев;
- 1c-exchange-pipeline-demo - самостоятельное демонстрационное расширение, в которое уже включены ядро, прикладные объекты и готовый сценарий подготовки исходящих сообщений.
Оба проекта распространяются по лицензии MIT. Для знакомства достаточно demo-расширения: ядро уже включено в его состав. Готовый файл demo_pipeline_v1_0_1.cfe и архив исходников demo_pipeline_v1_0_1.zip доступны в актуальном релизе.
Расширение подготовлено в режиме совместимости 8.3.24; проверять его следует в отдельной тестовой информационной базе.
Какие данные создаются автоматически?
После загрузки расширения и первого запуска режима 1С:Предприятие выполняется версионированное начальное заполнение. Оно создает:
- три категории: «Электроника», «Бытовая техника» и «Инструменты»;
- три склада: основной, резервный и региональный;
- шесть товаров, распределенных по категориям;
- текущий узел ERP и три внешних узла плана обмена: WEB, MARKET и B2B;
- четыре заказа с разными складами и составом: три проведенных и один непроведенный.
Для внешних узлов сразу настраивается маршрутизация по складам:
| Склад заказа | Получатели |
|---|---|
| Основной склад | WEB, B2B |
| Резервный склад | MARKET |
| Региональный склад | B2B |
При создании начальных заказов механизм регистрации временно отключается. Поэтому само заполнение не создает сообщения, а регистр Исходящая очередь сообщений (Демо) после первого запуска остается пустым. Повторные запуски приложения не дублируют данные: выполненная версия заполнения хранится в отдельной константе.
Как запустить основной сценарий?
- Скачайте demo_pipeline_v1_0_1.cfe из актуального релиза, подключите его к отдельной тестовой базе и запустите 1С:Предприятие.
- Откройте раздел Конвейер обмена данными и убедитесь, что появились демо-заказы, товары, склады, план обмена и исходящая очередь.
- Откройте один из проведенных заказов, измените количество товара или другой реквизит и повторно проведите документ.
- Откройте Исходящую очередь сообщений (Демо) и проверьте появившиеся записи.
Для заказа должны появиться сообщения типа Документ.Демо_Заказ с получателями, соответствующими его складу. В теле находится актуальное JSON-представление заказа, а в заголовках - тип операции и тип содержимого.
Тот же запуск порождает связанную регистрацию товаров из табличной части заказа. После завершения сценария заказа диспетчер обработает добавленное задание, и в очереди появятся отдельные сообщения типа Справочник.Демо_КОД_Товары для тех же направлений обмена. Так одним действием можно увидеть работу Filter, Router, Mapper, Output и механизма связанной регистрации.
Что еще проверить?
- Фильтрацию. Запись непроведенного заказа не должна создавать сообщения. После проведения тот же заказ пройдет Filter и попадет в очередь.
- Предыдущую версию и старые маршруты. Измените склад проведенного заказа с основного на резервный и повторно проведите документ. Сообщение должно быть подготовлено как для нового получателя MARKET, так и для прежних получателей WEB и B2B, которым уже могла быть известна предыдущая версия заказа.
- Состав сообщения. Сопоставьте поля заказа и товаров с телом JSON, проверьте заголовки, отправителя, получателя и тип сообщения.
- Отдельные этапы. Откройте формы Filter, Router или Mapper из группы демо-обработчиков. Они позволяют подготовить вход конкретного этапа и исследовать его результат без полного автоматического сценария.
Обработка «Ручная регистрация» пока оставлена как архитектурный каркас и не входит в работающий демонстрационный сценарий.
Итог
Основной эффект дает не один конкретный паттерн, а их совместная работа.
- Реестр превращает сценарий в конфигурацию.
- Диспетчер управляет сессией регистрации, выбирает сценарии и инициирует их выполнение.
- Конвейер собирает обработчики в исполняемую композицию, создает среду выполнения и задает границу обработки исключений.
- Обработчик становится отдельной функциональной и исполняемой единицей алгоритма с согласованным контрактом.
- Интеграция с внешними обработками БСП позволяет при необходимости заменять отдельные реализации без изменения основного кода конфигурации.
- Контекст дает обработчикам общее состояние.
- Пакетный входной контракт позволяет выполнять тяжелые операции сразу над множеством объектов.
- Предыдущая версия позволяет учитывать переход объекта из одного состояния в другое.
- Очередь заданий регистрации развязывает связанные сценарии внутри текущего запуска.
- Отладочные формы позволяют запускать боевые компоненты с подготовленным входом.
В результате новый нетиповой обмен больше не обязательно означает новый механизм целиком.

Новый сценарий = новая конфигурация существующих этапов + только те обработчики, в которых действительно появилась новая ответственность.
Что дальше?
Эта статья получилась обзорной: здесь я постарался показать архитектуру каркаса целиком и основные решения, из которых он состоит. При этом вокруг темы остается еще немало вопросов, которые можно отдельно разобрать.
Есть несколько мыслей для возможных продолжений:
- От требований до исходящей очереди: реализуем обмен с сайтом на конвейерном каркасе - разбор полноценного прикладного сценария от постановки задачи до Filter, Router, Mapper и записи готового сообщения в очередь
- Конвейер загрузки данных как каркас нетиповых обменов в 1С - применение тех же архитектурных принципов для входящего потока: разбор сообщения, поиск объекта, валидация, преобразование и запись
- Внутренние очереди обменов как прозрачная архитектура интеграций в 1С - зачем отделять подготовку сообщения от транспорта, как организовать исходящие и входящие очереди и где провести границу ответственности между 1С и транспортным слоем
- Оперативный мониторинг внутренних очередей обмена в 1С - состояние обменов, зависшие сообщения, очереди ошибок, повторная обработка и инструменты оперативной диагностики. Связка 1С->Prometheus->Alert manager->Telegram на практическом примере
- Централизированное логирование сообщений, проходящих через RabbitMQ, на практическом примере - рассматриваем связку 1С->RabbitMQ->Logstash->Elasticsearch на практическом примере.
Мне интересно обсудить эти направления в комментариях. Если какая-то тема кажется особенно полезной для отдельной статьи - напишите. Если есть другие вопросы вокруг архитектуры нетиповых обменов в 1С, которые стоило бы разобрать, пожалуйста предлагайте.
Проверено на следующих конфигурациях и релизах:
- 1С:Библиотека стандартных подсистем, редакция 3.1, релизы 3.1.12.310
Вступайте в нашу телеграмм-группу Инфостарт