При переносе почтового клиента или обработчика входящих обращений в базу 1С разработчики часто сталкиваются с вопросом выбора оптимальной структуры метаданных. Попытка перенести архитектуру из реляционных СУБД или объектных языков программирования без учета особенностей платформы 1С может привести к блокировкам данных, проблемам с правами доступа и падению производительности. Разберем ключевые архитектурные ошибки, особенности хранения табличных частей и правильную организацию совместной работы с письмами.
Распространенным заблуждением является предположение, что для каждого элемента справочника при наличии табличной части создается отдельная таблица в СУБД. Проанализируем, как это устроено на уровне платформы:
Ссылка / _Reference_ID).Тем не менее использование табличных частей справочников для хранения изменяемых пользовательских статусов или связей типа «многие ко многим» является антипаттерном. Если хранить отметки о прочтении, исполнении или правах доступа непосредственно в табличной части объекта (или пользователя), при любом изменении статуса одним сотрудником весь объект блокируется транзакционной блокировкой. Это делает невозможной параллельную работу нескольких пользователей с одним письмом.
Для организации связей между пользователями, учетными записями и письмами вместо табличных частей необходимо использовать непериодические регистры сведений. Рассмотрим подробнее основные сущности:
Пользователи — стандартный справочник системы.УчетныеЗаписиЭлектроннойПочты — содержит настройки подключения, адреса и общие параметры почтовых ящиков.ЭлектронныеПисьма (или документы) — содержит заголовок, тело письма, дату получения, отправителя и получателей.ПраваДоступаКУчетнымЗаписям — измерения УчетнаяЗапись и Пользователь. Позволяет гибко сопоставлять нескольких пользователей с общими ящиками (например, sale@domain.com или office@domain.com) без изменения самих объектов.СостоянияСообщенийЭлектроннойПочты — измерения Письмо (ведущее) и Пользователь (ведущее), ресурсы Прочитано (Булево), ДатаПрочтения (Дата) и т.д.Флаг Ведущее в свойствах измерений регистра сведений обеспечивает автоматическую очистку записей регистра при физическом удалении соответствующего элемента справочника из базы данных. Если письмо или пользователь окончательно удаляются, платформа автоматически удалит зависимые записи из регистра.
// Пример запроса для получения списка входящих сообщений
// с учетом прав доступа и персонального статуса прочтения
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Письма.Ссылка КАК Письмо,
| Письма.Дата КАК Дата,
| Письма.Тема КАК Тема,
| Письма.Отправитель КАК Отправитель,
| ЕСТЬNULL(Состояния.Прочитано, ЛОЖЬ) КАК Прочитано
|ИЗ
| Справочник.ЭлектронныеПисьма КАК Письма
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ПраваДоступаКУчетнымЗаписям КАК Доступ
| ПО Письма.УчетнаяЗапись = Доступ.УчетнаяЗапись
| И Доступ.Пользователь = &ТекущийПользователь
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияСообщенийЭлектроннойПочты КАК Состояния
| ПО Письма.Ссылка = Состояния.Письмо
| И Состояния.Пользователь = &ТекущийПользователь
|УПОРЯДОЧИТЬ ПО
| Письма.Дата УБЫВ";
Запрос.УстановитьПараметр("ТекущийПользователь", ПараметрыСеанса.ТекущийПользователь);
Результат = Запрос.Выполнить();
Когда входящая почта используется для обработки заказов, заявок или обращений в техподдержку (HelpDesk), попытка возложить логику маршрутизации и контроля исполнения на сам объект письма приводит к перегрузке архитектуры. Письмо и бизнес-задача представляют собой принципиально разные сущности:
Разберем по шагам правильный алгоритм совместной обработки входящей почты:
ЭлектронноеПисьмо.Задача (или стартует БизнесПроцесс).При реализации масштабного почтового модуля обратим внимание на следующие критические моменты:
ХранилищеЗначения) в основной таблице справочника писем. Файлы необходимо хранить в отдельном подчиненном справочнике или выносить на внешние тома (сетевые диски, S3), сохраняя в базе только пути и метаданные. Это предотвратит раздувание таблиц динамических списков и деградацию производительности СУБД.RLS. Условия доступа должны строиться через простые соединения с денормализованными регистрами прав, избегая условий по табличным частям или сложных подзапросов в текстах ограничений.ПередЗаписью и ПередУдалением модуля объекта.