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

Дополнительные параметры — Администрирование

Обзор

Домен ext-params отвечает за администрирование дополнительных параметров (ДП), которые используются как кастомные поля задач.

В админ-контуре здесь используется комбинация:

  • автоадминки (dbadmin) для прямой работы с конфигурационными таблицами;
  • ручных Admin API-контроллеров для операций, которые не укладываются в простой CRUD;
  • форм категории (категорийный контур), где ДП включаются в конкретные подкатегории и получают category-level поведение.

EntityEditor-схем для ext-params нет.

Документ фокусируется на том, где и что настраивается, и как диагностировать мисконфигурацию. Детали реализации backend-логики, сервисов и runtime API вынесены в docs/domains/ext-params/backend.md.

Механизмы администрирования

Автоадминка (dbadmin)

Alias формы Название Таблица БД Полей Секций Основное назначение
ext-param-blocks Блоки ДП dbo.ExtParamBlocks 15 1 Блоки, в которые группируются ДП на форме задачи
extparam-blocks-groups Группы блоков ДП dbo.ExtParamBlocksGroups 11 1 Группы блоков (верхний уровень группировки)
custom-task-used-as-ep-block-settings Параметры таблицы БИ dbo.CustomTaskUsedAsEpBlockSettings 24 1 Настройки отображения таблицы БИ для ДП типа Table
extparam-view-personal-settings ДП в личных папках dbo.ExtParamViewPersonalSettings 3 1 Отображение ДП в персональных папках/представлениях
ep-rights-flat Flat: гибкие права dbo.EPRightsFlat 5 1 Гибкий доступ к задачам через ДП SelectUsers
ep-rights-lkp Lookup: гибкие права dbo.EPRightsLkp 6 1 Гибкий доступ через цепочку Lookup -> SelectUsers
ep-rights-mlt Multilookup: гибкие права dbo.EPRightsMlt 6 1 Гибкий доступ через Multilookup -> SelectUsers

Кастомные SPA-страницы (в дереве автоадминки)

Alias формы Название Url Таблица БД Основное назначение
extparams Параметры (ДП) /administration/extparams-all dbo.ExtParams Глобальная карточка ДП: тип, имя, базовые флаги
extparamlinks Связи параметров /administration/extparamlinks dbo.ExtParamLink Master-slave связи между ДП

Примечания:

  • Источник карты форм: docs/reference/database/dbadmin-forms-map.md.
  • Форма extparams фигурирует и в домене categories, но здесь рассматривается как часть жизненного цикла ДП.

EntityEditor

Для ext-params отсутствуют JSON-схемы EntityEditor.

Следствие:

  • настройка домена идет через dbadmin и специализированные Admin API;
  • расширение формы через EntityEditor для ДП-карточек в текущей архитектуре не используется.

Admin API контроллеры

Фактически в коде домена используются 7 профильных контроллеров под ExtParams.

Контроллер Базовый маршрут Основные методы Назначение
ExtParamsController /api/admin/extparams POST, GET short, GET {id}/subcategories, GET {id}/signatures, DELETE {id} CRUD глобального ДП и анализ использования
ExtParamsInSubcatController /api/admin/subcat/extparams GET, POST, DELETE, reorder, copypermissons, copypermissonsstates, copy-ep-values, propagate-defaults Привязка ДП к категории и category-level настройки. При редактировании настроек матрицы доступа (клик на карандаш рядом с «Доступ = Матрица доступа») система автоматически создаёт записи в таблице ExtParamTableSettingsInSubcat с уникальными Guid. Это может привести к конфликту первичного ключа при импорте конфигурации между площадками в режиме KeepIdentity, так как дедупликация по составному PK (SubcatId, ExtParamId, ColumnId) в этом режиме не выполняется.
ExtParamSettingsController /api/admin/extparams/settings GET {extParamId}, POST, POST {extParamId}/sync-table-values Глобальные настройки ДП по типам
ExtParamBlocksController /api/admin/subcat/extparams/blocks CRUD блоков, CRUD групп, links, reorder Блоки/группы блоков ДП и их состав
ExtParamsLinksController /api/admin/ext-params/links POST, GET, POST {linkId}, DELETE {linkId} Связи между ДП
ExtParamOptionsController /api/admin/extparam/options add, update, delete, delete-all Опции для list/combobox ДП
ExtParamsTableController /api/admin/ext-params/table GET template, PUT template Шаблон и рендер ДП типа Table

Полный backend-разбор контроллеров и сервисов: docs/domains/ext-params/backend.md.

Ключевые настройки

1) Типы ДП (ExtParamType)

Где настраивается:

  • автоадминка: форма extparams;
  • API: ExtParamsController.Create(...), ExtParamSettingsController.

Таблица БД: dbo.ExtParams.

Что важно:

  • тип ДП задает допустимый формат значения, таблицу хранения и UI-редактор;
  • изменение типа у уже используемого ДП может приводить к несовместимости старых значений;
  • в коде enum Valhalla.Integration.Enums.ExtParams.ExtParamType содержит 21 основное значение.

Практически используемые типы (примерно):

  • Text, TextArea, TextareaWOFormat;
  • NumericValue, Money, Checkbox;
  • Date, Datetime;
  • Select, Combobox;
  • LookUpField, MultiSlctSubcatTasks;
  • SelectUsers, File, Table, Through, Address, URL, ExtParamAddressees, Numerator, Tree.

2) Создание и глобальная настройка ДП

Где настраивается:

  • форма extparams;
  • API: POST /api/admin/extparams и POST /api/admin/extparams/settings.

Ключевые элементы:

  • имя/локализация;
  • тип и type-specific опции;
  • валидационные правила и флаги поведения.

Эффект в runtime:

  • глобальная часть влияет сразу на все категории, где ДП уже используется;
  • после смены критичных настроек может понадобиться пересчет/синхронизация данных (особенно для Table).

3) Привязка ДП к категории

Где настраивается:

  • API: ExtParamsInSubcatController;
  • UI-узел категории: subcategory-extparam-settings и связанный список ДП.

Таблицы БД:

  • dbo.ExtParamsInSubcat (привязка);
  • таблицы прав и видимости в category-level контуре;
  • связи ДП с блоками (BlockId и related-таблицы блоков).

Ключевые сценарии:

  • добавить глобальный ДП в категорию;
  • задать порядок и обязательность;
  • скрыть/показать ДП;
  • настроить копирование прав и прав по статусам;
  • включить/отключить индекс по ДП;
  • массово перенести значения между ДП.

Критичные зависимости:

  • права по статусам нужно пересматривать при добавлении новых статусов маршрута;
  • копирование прав массово перезаписывает target-настройки;
  • индекс полезен для поиска, но должен применяться осознанно.

Актуализация AdminSPA (2026-02-11):

Смарт-доступ к ДП:

  • Настройки смарт-доступа редактируются в отдельном модальном окне.
  • Каждое правило сохраняется независимо кнопкой "Добавить параметр" внутри модального окна, без необходимости сохранения всей формы настроек ДП.
  • После успешного сохранения правила:
  • Отображается уведомление "Смарт доступ сохранён"
  • Форма автоматически очищается для добавления следующего правила
  • Правило сразу доступно в списке
  • Действует защита от дублирования при повторных кликах на кнопку сохранения.
  • Закрытие модального окна не требует дополнительного сохранения — все добавленные правила уже сохранены на сервер.

Другие изменения:

  • Названия, порядок и подсказки режимов доступа фиксируются по текущему UI AdminSPA.
  • Для ДП типа Большой текст с форматированием доступен редактор Markdown.
  • Для настройки Количество занимаемых колонок в текущем UI доступны только 3 значения: 1/3 размера, 1/2 размера, Во всю ширину.
  • 1/3 размера — ДП занимает треть ширины (до 3 ДП в строке)
  • 1/2 размера — ДП занимает половину ширины (до 2 ДП в строке)
  • Во всю ширину — ДП занимает всю ширину строки (1 ДП в строке)
  • Историческая справка: в версиях до 2026-02 были доступны варианты с 4 и 5 колонками, которые удалены из интерфейса для упрощения компоновки форм и улучшения UX.
  • Настройка применяется к формам MTF (карточка задачи) и NTF (форма создания задачи).
  • Для ДП Файл с включенным режимом Мультифайл поведение подсказки выровнено с остальными типами ДП (без дублей в NTF, доступно в read-only режиме MTF).

UI-инструкции: Подробное описание работы с настройками ДП в категории см. в ../form-controls/README.md

4) Блоки ДП и группы блоков

Где настраивается:

  • формы ext-param-blocks, extparam-blocks-groups;
  • API: ExtParamBlocksController.

Таблицы БД:

  • dbo.ExtParamBlocks;
  • dbo.ExtParamBlocksGroups;
  • таблицы связей ДП-блок.

Что контролируют:

  • визуальная группировка ДП на карточке задачи;
  • порядок отображения блоков и элементов внутри блоков;
  • привязка одного ДП к нескольким блокам (сценарий поддерживается).

Риски мисконфигурации:

  • «потерявшиеся» поля при неверном порядке/связях;
  • дублирование отображения одного ДП в нескольких блоках без договоренной UX-логики.

UI-настройки блока (название, цвет, порядок, группа, 4 смарт-фильтра «Сворачивать/Скрывать × карточка/постановка»), системный блок «Шапка задачи», группы блоков, БИ-таблица в блоке ДП — описаны в ../task-forms/blocks-reference.md и ../task-forms/block-layout-database.md. Контекст события WhenOpenTask (EventID 64), используемый смарт-фильтрами блока, — ../smart-actions/known-issues.md. Системный блок «Шапка задачи» — ../categories/business.md. Таблица ExtParamsInSubcatToBlocksdatabase.md.

Где настраивается:

  • форма extparamlinks;
  • API: ExtParamsLinksController.

Таблица БД: dbo.ExtParamLink.

Назначение:

  • master-slave зависимости ДП;
  • фильтрация допустимых значений зависимого ДП на основе выбранного значения master-ДП.

Ключевые проверки:

  • source/target должны быть совместимы по типу сценария;
  • у master-ДП должны быть стабильно заполненные значения в задачах, иначе зависимый ДП будет «пустым».

6) Опции ДП (list/combobox + type-specific)

Где настраивается:

  • API: ExtParamOptionsController;
  • type-specific страницы в manual (lookup/list/file/table/through и др.).

Таблицы БД:

  • опции list/combobox в контуре настроек ДП;
  • значения задач в runtime-таблицах (см. docs/reference/database/extparams.md).

Особенности:

  • delete-all для опций обнуляет справочник выбора и потенциально ломает существующие заполнения;
  • для File, Table, Lookup, Multilookup, Through есть специализированные настройки и отдельные риски.

7) Гибкие права на ДП / задачи

Где настраивается:

  • формы ep-rights-flat, ep-rights-lkp, ep-rights-mlt.

Таблицы БД:

  • dbo.EPRightsFlat;
  • dbo.EPRightsLkp;
  • dbo.EPRightsMlt.

Режимы:

  • Flat: доступ определяется значением ДП SelectUsers в этой же категории;
  • Lookup: доступ в категории A через lookup на категорию B, где хранится SelectUsers;
  • Multilookup: то же через множественную ссылку.

Ключевой инвариант:

  • в SelectUsers для этих сценариев не используется выбор орг.единиц, если модель прав строится только на пользователях/группах.

8) Таблица БИ для ДП Table

Где настраивается:

  • форма custom-task-used-as-ep-block-settings;
  • API: ExtParamsTableController, ExtParamSettingsController.SyncTableValues.

Таблица БД: dbo.CustomTaskUsedAsEpBlockSettings.

Что контролируется:

  • шаблон рендера таблицы;
  • параметры вывода колонок/строк;
  • синхронизация HTML-представления по существующим задачам.

Риски:

  • изменение шаблона без синхронизации приводит к «старому» отображению в части задач;
  • крупные перезапуски синхронизации нужно планировать по нагрузке.

9) Валидация значений: регулярное выражение и маска

Где задаётся:

  • автоадминка ДП → вкладка «Основные настройки» → поля «Регулярное выражение» и «Пояснение к полю»;
  • API: POST /api/admin/extparams/settings — поля в корне DTO: regExp (шаблон), regExpErrorMessage (текст ошибки). Не путать с UI-маской textSettings.mask (см. §«Справочник body-форматов» → Text/MaskedText).

Поведение:

  • значение, не прошедшее проверку, подсвечивается; под полем выводится текст из «Пояснение». Если пояснение пустое — стандартный текст ошибки.
  • если «Регулярное выражение» не задано, текст «Пояснение» используется как обычная подсказка под ДП.
  • для типа Text при одновременно заполненных mask (UI-маска ввода) и regExp — приоритет у регулярного выражения.

⚠️ Регулярные выражения не работают для типов:

  • Checkbox (Галочка),
  • Tree (Дерево),
  • TextArea (Большой текст с форматированием),
  • SelectUsers (Выбор пользователей).

⚠️ Также не применяется для Text с активной опцией «Отображать ДП текст как телефон» — в этом случае вшита фиксированная маска +X (XXX) XXX-XXXX.

Часто используемые шаблоны:

Что проверяется Регулярное выражение Комментарий
ФИО (рус.) ^[А-ЯЁа-яё]+(?:-[А-ЯЁа-яё]+)* [А-ЯЁа-яё]+(?: [А-ЯЁа-яё]+)?$ Учитывает двойные фамилии и составные имена. Без цифр, латиницы и спецсимволов кроме дефиса и пробела
Серия и номер паспорта РФ ^\d{4} \d{6}$ 4 цифры серии, пробел, 6 цифр номера
ИНН (юр. лицо) ^\d{10}$ 10 цифр
ИНН (физ. лицо) ^\d{12}$ 12 цифр
БИК ^\d{9}$ 9 цифр
Мобильный телефон РФ ^\+7 \(\d{3}\) \d{3}-\d{2}-\d{2}$ Формат +7 (xxx) xxx-xx-xx
Дата ДД.ММ.ГГГГ (формат) ^(0[1-9]\|[12][0-9]\|3[01])\.(0[1-9]\|1[0-2])\.\d{4}$ Только формат, без проверки корректности дня в месяце и високосного года
E-mail ^[\w.+-]+@[\w-]+(\.[\w-]+)*\.[a-zA-Z]{2,}$ Стандартный формат

Примеры — общеупотребимые варианты. Один и тот же контракт может быть выражен разными regex; при необходимости подбирать под фактический формат ввода клиента.

10) Тип ДП «Дерево» (Tree) — узкие настройки

Назначение: хранение значения, выбираемого из внутренней иерархии узлов, которую администратор формирует вручную в настройках ДП. Это собственное дерево значений ДП, не иерархия категорий и не Lookup в иерархическом режиме (см. lookup/settings-reference.md для иерархического Lookup).

Хранение: ExtParamValues.ExtParamValue (текст узла) + DataSourceItemID (ID узла). Денормализация — varchar/nvarchar(1000). См. types-reference.md.

Настройка узлов в админке:

  • Ввести название в поле «Текст создаваемого узла» → кнопка «Создать узел» → новый узел добавляется на первый уровень.
  • Чтобы добавить дочерний узел: предварительно нажать на родительский узел, затем создать.
  • Иерархия меняется перетаскиванием узлов мышью.
  • Редактирование названия и удаление узла — кнопки справа от названия в дереве.

API: body для POST /api/admin/extparams/settings использует treeSettings (DTO ExtParamSettingsTreeDto); см. таблицу маппинга в §«Справочник body-форматов».

Ограничения:

  • регулярные выражения для Tree не работают (см. §9);
  • изменение типа ДП после создания невозможно — types-reference.md.

11) Тип ДП «Выпадающий список» (Select / Combobox) — узкие настройки

Различие двух типов:

Параметр Select Combobox
Произвольный текст нельзя — только выбор из списка можно ввести своё значение (сохраняется в задачу, но не в источник)
Радиокнопки поддерживаются не поддерживаются
Максимальная длина значения 200 символов 200 символов

Источник данных: задаётся в selectSettings.dataSource / comboboxSettings.dataSource.

Источник Когда использовать Быстрые подсказки
Набор элементов Фиксированный перечень, редко меняется Поддерживаются (3 последних выбранных значения в категории)
Из таблицы (БД / SQL-view) Динамический список из таблицы Не поддерживаются

Поля при «Набор элементов»:

  • задаются массивом selectSettings.elements / comboboxSettings.elements (см. §«Справочник body-форматов» → Select/Combobox);
  • каждый элемент: value, isDefault, локализованное значение;
  • при обновлении передаётся полный список — перезатирает предыдущие.

Поля при «Из таблицы»:

Параметр Описание
Имя таблицы Название таблицы БД или SQL-view
Колонка значения Уникальный ID, сохраняется в DataSourceItemID
Колонка текста Отображается пользователю, сохраняется в ExtParamValue
Колонка сортировки По какой колонке сортировать. При активном «Автоматически сортировать по алфавиту» приоритет у автосортировки
Колонка контекст текущей задачи TaskID; если заполнена — список фильтруется по совпадению значения колонки с ID текущей задачи

⚠️ Поля «Колонка значения» и «Колонка текста» не должны содержать пустых значений в источнике.

Радиокнопки (только Select):

  • «Использовать отображение в виде радиокнопок» — ДП рендерится блоком радиокнопок;
  • «Отображать радиокнопки в ряд» — горизонтальное расположение (иначе вертикальное);
  • ⚠️ для радиокнопок нет возможности отменить выбор — применять только для обязательных ДП и обязательно задавать значение по умолчанию.

⚠️ Performance warning для «Из таблицы»: API (включая мобильное приложение и форму создания задачи NTF) передаёт все значения списка. Для таблиц с большим количеством записей это перегружает клиент — фильтровать на уровне источника или переходить на LookUpField (там источник — категория с пейджингом и смарт-фильтром).

12) Выбор между Multilookup, Таблицей и БИ («Используется»)

При проектировании связанной информации внутри задачи возникает выбор между тремя инструментами. Критерии:

Инструмент Когда использовать Когда не использовать
Multilookup (MultiSlctSubcatTasks) Важен только признак «выбран / не выбран» элемента; никакие другие атрибуты не отслеживаются (пример: сегменты рынка, отрасли клиента) Нужны атрибуты у выбранного элемента в контексте этой задачи
Таблица (Table) У каждого выбранного элемента есть дополнительные характеристики, которые наполняются именно в этой задаче (пример: позиции заказа с количеством и ценой; опыт работы по специальности в карточке соискателя) У элементов есть собственный жизненный цикл и статусы
БИ (блок «Используется») на категорию-источник (1) у элементов собственный жизненный цикл и смена статусов с автоматизациями (пример: участники мероприятия — «Приглашён → Принял → Оплатил»); (2) нужно разделение доступа к элементам (для строк Table и содержимого ДП смарт-доступ невозможен — только для задач); (3) элементы должны быть видны в нескольких частях системы через перекрёстные ссылки (карточка мероприятия ↔ карточка клиента) Достаточно простого отбора без жизненного цикла

Один процесс может комбинировать все три инструмента: Multilookup на этапе сбора заявок (отбор магазинов), Lookup + блок «Используется» после согласования (отдельные задачи на каждый магазин), Table внутри каждой задачи для атрибутов выполнения.

См. также business.md (бизнес-модель ДП), ../categories/business.md (категория как сущность с жизненным циклом), lookup/settings-reference.md (Lookup и Multilookup), table/settings-reference.md (Table).

CustomSettings — глобальные ключи поведения ДП

Задаются на странице «Настройки приложения» → «Пользовательские ключи». Источник: dbo.SettingsCustom.

Ключ Тип / Default Назначение
DecodeBigTextEp bool / false Отображение эмодзи в ДП «Большой текст без/с форматированием». Исключения — список ID в DecodeBigTextEpExcept
DecodeBigTextEpExcept array ID ДП, к которым DecodeBigTextEp не применяется
ExtParamTableLookUpTextLength int Максимум символов для значения Lookup-колонки ДП «Таблица». При превышении — обрезка
ExtParamExtraSettings JSON Перевод ДП «Файл» в режим «только сканирование» (в UI остаётся только кнопка «Сканировать», без вложений)
ExperimentalMultilookupEpIds array ID ДП Multilookup с поддержкой выбора элементов развёрнутых/неразвёрнутых групп при активной опции «Чекбоксы для групп в мультилукапе». ⚠️ Экспериментальная функция
TableEpIdsOldUI array ID ДП «Таблица» в старом представлении (с выключенной опцией «Использовать новую таблицу»), которые при открытии задачи сразу разворачиваются в режим редактирования. Остальные старые таблицы открываются в режиме чтения
UseNewExtParamsAndTaskUsed JSON Включает новые ДП и блок «Используется» для пользователей в указанных категориях/группах. Формат: [{"subcats":[ids],"groups":[ids]}]
CustomTaskUsedAsEpBlocksExtSettings JSON Не закрывать модальное окно создания задачи из БИ — позволяет последовательно добавлять несколько записей
EveryTagExtParams array ID ДП «Файл», для которых при скачивании/просмотре отправляется метка времени в файловый провайдер EveryTag
EveryTagSubcats array То же, что EveryTagExtParams, но на уровне категорий

Типичные ошибки настройки

На PostgreSQL в полях SQL-функций доступа при настройке дополнительного параметра нельзя использовать квадратные скобки в имени функции. Указывайте имя в формате schema.function_name. Ограничение действует для полей AccessFunc и AccessFuncBatch; на MSSQL это ограничение не применяется.

Симптом Вероятная причина Где проверить SQL-диагностика
ДП не отображается в категории ДП не добавлен в ExtParamsInSubcat или скрыт category-level настройкой Категория → список ДП (subcategory-extparam-settings) см. Q1
ДП отображается, но в «неправильном» месте Некорректный порядок в категории или в блоке Блоки ДП + порядок ДП см. Q2
Подчиненный lookup пустой Ошибка в ExtParamLink или неконсистентные master-значения extparamlinks + карточки задач см. Q3
Пользователь видит/не видит задачи не по ожиданию (flex rights) Ошибка в EPRightsFlat/Lkp/Mlt или в source ДП SelectUsers Формы ep-rights-* см. Q4
После изменения шаблона Table часть задач в старом виде Не выполнена синхронизация sync-table-values Настройки table + API лог см. Q5
Копирование прав на все ДП испортило точечные настройки Вызван copypermissons/copypermissonsstates без сегментации API-операции category-level см. Q6
Массовое копирование значений дало неожиданный результат Несовместимые типы источника и приемника copy-ep-values + типы ДП см. Q7
Нельзя удалить глобальный ДП ДП используется в категориях или подписях GET {id}/subcategories + GET {id}/signatures см. Q8
ДП отображается некорректно по ширине Устаревшее значение колонок (4 или 5) в ExtParamsInSubcat Настройки ДП категории см. Q9

SQL-диагностика (Q1-Q9)

-- Q1: есть ли привязка ДП к категории
select
        eisc.SubcatID,
        eisc.ExtParamID,
        eisc.SubcatOrder,
        eisc.IsRequired,
        eisc.Hidden
from dbo.ExtParamsInSubcat eisc with (nolock)
where eisc.SubcatID = @subcat_id and
      eisc.ExtParamID = @ext_param_id;
-- Q2: порядок ДП в категории и в блоках
select
        eisc.SubcatID,
        eisc.ExtParamID,
        eisc.SubcatOrder as extparam_order,
        eisc.BlockId
from dbo.ExtParamsInSubcat eisc with (nolock)
where eisc.SubcatID = @subcat_id
order by eisc.SubcatOrder, eisc.BlockId;
-- Q3: связи ДП master-slave
select
        l.MasterExtParamID,
        l.ChildExtParamID,
        l.MasterColumnName,
        l.ChildIDColumnName,
        l.ChildNameColumnName,
        l.ChildSource,
        l.HardLink
from dbo.ExtParamLink l with (nolock)
where l.MasterExtParamID = @master_ep_id or
      l.ChildExtParamID = @child_ep_id;
-- Q4: настройки гибких прав по категории
select top (200) *
from dbo.EPRightsFlat with (nolock);

select top (200) *
from dbo.EPRightsLkp with (nolock);

select top (200) *
from dbo.EPRightsMlt with (nolock);
-- Q5: значения табличного ДП и следы синхронизации
select top (200)
        tv.TaskID,
        tv.ColumnID,
        tv.RowID,
        tv.Value
from dbo.ExtParamTableValues tv with (nolock)
where tv.ExtParamID = @ext_param_id
order by tv.TaskID desc, tv.RowID, tv.ColumnID;
-- Q6: права по статусам для ДП категории
select
        esv.SubcatID,
        esv.ExtParamID,
        esv.StateID,
        esv.CanRead,
        esv.CanEdit
from dbo.ExtParamStateView esv with (nolock)
where esv.SubcatID = @subcat_id
order by esv.ExtParamID, esv.StateID;
-- Q7: совместимость типов source/target перед copy-ep-values
select
        ep.ExtParamID,
        ep.ExtParamName,
        ep.ExtParamType
from dbo.ExtParams ep with (nolock)
where ep.ExtParamID in (@ext_param_from_id, @ext_param_to_id);
-- Q8: использование ДП в категориях и подписях
select
        eisc.SubcatID,
        eisc.ExtParamID
from dbo.ExtParamsInSubcat eisc with (nolock)
where eisc.ExtParamID = @ext_param_id;

select
        s.SignatureID,
        s.ExtParamID,
        s.Description
from dbo.Signatures s with (nolock)
where s.ExtParamID = @ext_param_id;
-- Q9: проверка настроек ширины ДП в категории
select
        eisc.SubcatID,
        eisc.ExtParamID,
        ep.ExtParamName,
        eisc.ColumnCount,
        case eisc.ColumnCount
            when 1 then '1/3 размера'
            when 2 then '1/2 размера'
            when 3 then 'Во всю ширину'
            when 4 then 'Устаревшее значение (4 колонки)'
            when 5 then 'Устаревшее значение (5 колонок)'
            else 'Неизвестное значение'
        end as DisplayName
from dbo.ExtParamsInSubcat eisc with (nolock)
join dbo.ExtParams ep with (nolock) on ep.ExtParamID = eisc.ExtParamID
where eisc.SubcatID = @subcat_id
order by eisc.SubcatOrder;

-- Поиск категорий с устаревшими значениями ширины колонок
select
        eisc.SubcatID,
        sc.SubcatName,
        count(*) as ExtParamsWithOldValues
from dbo.ExtParamsInSubcat eisc with (nolock)
join dbo.Subcategories sc with (nolock) on sc.SubcatID = eisc.SubcatID
where eisc.ColumnCount in (4, 5)
group by eisc.SubcatID, sc.SubcatName
order by ExtParamsWithOldValues desc;

Справочник body-форматов для POST /api/admin/extparams/settings

Эндпоинт обновляет глобальные type-specific настройки ДП. Каждый тип ДП требует свойство с конкретным именем в body. Если sub-settings = null, сервис вызовет UpdateSettings(id, null) → NPE.

Критично: контроллер использует Newtonsoft.Json (не STJ). Десериализация case-insensitive, enum'ы — строками ("Default", не 0).

Корневые поля (общие для всех типов)

{
  "id": 125290,
  "name": "TM_Lookup",
  "type": "LookUpField",
  "toolTip": "",
  "regExp": "",
  "regExpErrorMessage": "",
  "localizable": false,
  "<typeSettings>": { ... }
}

type — строковое значение из ExtParamType enum: Text (0), TextArea (1), Checkbox (2), Date (3), Datetime (4), Select (5), Combobox (6), File (7), Numerator (8), MultiSlctSubcatTasks (10), LookUpField (11), TextareaWOFormat (12), Money (13), URL (14), Through (15), Table (16), SelectUsers (17), NumericValue (18), Tree (19), ExtParamAddressees (20), Address (21).

Маппинг type → поле sub-settings

type Поле в body DTO класс Файл
LookUpField lookUpFieldSettings ExtParamSettingsLookupDto ExtParamSettingsTypes/ExtParamSettingsLookupDto.cs
Text textSettings ExtParamSettingsTextDto ExtParamSettingsTypes/ExtParamSettingsTextDto.cs
Select selectSettings ExtParamSettingsSelectDto ExtParamSettingsTypes/ExtParamSettingsSelectDto.cs
Combobox comboboxSettings ExtParamSettingsDropDownEditableDto ExtParamSettingsTypes/ExtParamSettingsDropDownEditableDto.cs
MultiSlctSubcatTasks selectSubcatTasksSettings ExtParamSettingsSubcatTasksDto ExtParamSettingsTypes/ExtParamSettingsSubcatTasksDto.cs
TextArea textAreaSettings ExtParamSettingsTexAreatDto ExtParamSettingsTypes/ExtParamSettingsTexAreatDto.cs
Date dateSettings ExtParamSettingsDateDto ...DateDto.cs
Datetime dateTimeSettings ExtParamSettingsDateTimeDto ...DateTimeDto.cs
File fileSettings ExtParamSettingsFileDto ...FileDto.cs
NumericValue numericSettings ExtParamSettingsNumericDto ...NumericDto.cs
Money moneySettings ExtParamSettingsMoneyDto ...MoneyDto.cs
SelectUsers selectUsersSettings ExtParamSettingsSelectUsersDto ...SelectUsersDto.cs
Tree treeSettings ExtParamSettingsTreeDto ...TreeDto.cs
Address addressesSettings ExtParamSettingsAddressesDto ...AddressesDto.cs
Numerator numeratorSettings ExtParamSettingsNumeratorDto ...NumeratorDto.cs
Through throughSettings ExtParamSettingsThroughDto ...ThroughDto.cs
Table tableSettings ExtParamSettingsTableDto ...TableDto.cs
Checkbox checkboxSettings ExtParamSettingsCheckboxDto ...CheckboxDto.cs
URL, TextareaWOFormat (нет sub-settings) ExtParamSettingsAdminServce.cs:283,291

Полный DTO: Valhalla.Integration.Admin/Dto/ExtParamSettings/ExtParamCommonSettingsRequestDto.cs. Маппинг type→sub-settings: Valhalla.Admin/ExtParams/ExtParamSettingsAdminServce.cs, метод UpdateSubSettings (строки 233–310).

Примеры рабочих body (верифицированы на dev 2026-02-27)

LookUp (lookUpFieldSettings)

{
  "id": 125290,
  "name": "TM_Lookup",
  "type": "LookUpField",
  "toolTip": "",
  "regExp": "",
  "regExpErrorMessage": "",
  "localizable": false,
  "lookUpFieldSettings": {
    "subcatId": 70400,
    "states": [],
    "isHierarchical": false,
    "disableFolderSelection": false,
    "displayFilteredParts": false,
    "isLayoutPlan": false,
    "isDropdownLookup": false,
    "groupsCollapsed": false,
    "gridVirtualPageSize": 0,
    "viewPageSize": 0,
    "viewAsText": false,
    "isTooltipVisible": true,
    "displayAsRadioButtons": false,
    "skin": "Default"
  }
}

Gotchas: - states обязательно передавать (хотя бы []). Если null → NPE на sett.States.ToArray() (строка 126 ExtParamSettingsLookupAdminService.cs). - skin — строка ("Default"), не число. Enum LookupSkinType. - subcatId — ID категории-источника (не lookupSubcategoryId, не subcategory.id). - При пустом states: [] сервер автоматически подставляет все состояния категории-источника.

MultiLookup (selectSubcatTasksSettings)

{
  "id": 125300,
  "name": "TM_MultiLookup",
  "type": "MultiSlctSubcatTasks",
  "toolTip": "",
  "regExp": "",
  "regExpErrorMessage": "",
  "localizable": false,
  "selectSubcatTasksSettings": {
    "subcategory": {"id": 70400},
    "checkPermissionToShowTasks": false,
    "viewAsText": false,
    "isTooltipVisible": true,
    "isHierarchical": false,
    "isLayoutPlan": false,
    "isDropdownLookup": false,
    "skin": "Default",
    "groupsCollapsed": false
  }
}

Gotchas: - Источник указывается как "subcategory": {"id": N} (вложенный объект), не "subcatId": N.

Select (selectSettings)

{
  "id": 125370,
  "name": "TM_Select",
  "type": "Select",
  "toolTip": "",
  "regExp": "",
  "regExpErrorMessage": "",
  "localizable": false,
  "selectSettings": {
    "elements": [
      {"value": "Опция 1", "isDefault": true},
      {"value": "Опция 2", "isDefault": false},
      {"value": "Опция 3", "isDefault": false}
    ],
    "autoSortByAlphabet": false,
    "dataSource": 0
  }
}

Combobox (comboboxSettings)

{
  "id": 125380,
  "name": "TM_Combobox",
  "type": "Combobox",
  "toolTip": "",
  "regExp": "",
  "regExpErrorMessage": "",
  "localizable": false,
  "comboboxSettings": {
    "elements": [
      {"value": "Вариант A", "isDefault": true},
      {"value": "Вариант B", "isDefault": false},
      {"value": "Вариант C", "isDefault": false}
    ],
    "autoSortByAlphabet": false,
    "dataSource": 0
  }
}

Gotchas для Select/Combobox: - Опции задаются массивом elements внутри sub-settings, НЕ через POST /api/admin/extparam/options/{epId}/add. - dataSource: 0 = "Набор элементов" (enum EpSelectDataSource). - При обновлении — передавать полный список elements (перезатирает предыдущие).

Text / MaskedText (textSettings)

{
  "id": 125480,
  "name": "TM_MaskedText",
  "type": "Text",
  "toolTip": "Format: XXX-XX-XXXX",
  "regExp": "^\\d{3}-\\d{2}-\\d{4}$",
  "regExpErrorMessage": "Формат: 123-45-6789",
  "localizable": false,
  "textSettings": {
    "mask": "",
    "phoneOption": false,
    "suggestType": 0
  }
}

Gotchas: - textSettings обязательно передавать (даже пустое). Если null → NPE в ExtParamSettingsTextAdminService.UpdateOptions (строка 60). - regExp и regExpErrorMessage — в корне DTO (не внутри textSettings). - mask — маска ввода UI (формат типа ###-##-####), не regex. Regex валидация — через корневой regExp. - suggestType: 0 = без автоподсказок.

GET настроек ДП

GET /api/admin/extparams/settings/{extParamId} (path param, не query string).

Ответ: type-specific settings в едином поле settings (не в именованных sub-settings как в request DTO).

{
  "data": {
    "id": 125290,
    "name": "TM_Lookup",
    "type": "LookUpField",
    "settings": {
      "subcatId": 70400,
      "states": [1, 2, 3, 4],
      "isHierarchical": false,
      "skin": "Default",
      ...
    }
  }
}

Связь с grid columns

Для отображения EP-колонок в гриде категории — отдельный эндпоинт:

POST /api-core/datasource/settings/save

{
  "entityId": 70400,
  "type": "subcat",
  "isAdmin": true,
  "clientSettings": {
    "columnState": [
      {"colId": "task", "width": 160, "hide": false, ...},
      {"colId": "ExtParam125220", "width": 160, "hide": false, ...}
    ],
    "columnGroupState": null,
    "filterState": {},
    "tasksState": null,
    "myTasks": null
  }
}
  • isAdmin: true — admin-level (видно всем, UserId=null в БД). Без isAdmin — user-level (только для текущего пользователя).
  • colId для EP: "ExtParam" + ExtParamID (конкатенация строки).
  • Подробнее: docs/domains/grids/backend.md.

Заполнение ДП через API

POST("/api/extParams/update", [{
    "extParamStr": "#n{epId}#v{value}",  # несколько ДП через ::
    "taskId": N,
    "userId": N,
    "writeComment": False
}])

TextArea: значение — HTML (<p>текст</p>). Не начинать с заголовка — у ДП уже есть название.

Admin API — создание ДП

POST /api/admin/extparams?name=ИмяДП&type=Text — тип и имя передаются в URL, body пустой {}.

Типы ДП в API

Интуитивно API type Примечание
Строка Text
Число NumericValue Не Number, не Integer
Галочка Checkbox Не Bool, не Boolean
Лукап LookUpField Не Lookup
Мультифайл File Тот же тип что File, разница в настройках

Добавление значений (Options)

POST /api/admin/extparam/options/{id}/add принимает массив [{Value, IsDefault}], не одиночный объект.

Table EP — настройка колонок

# 1. GET текущие настройки
settings = GET(f"/api/admin/extparams/settings/{epId}")

# 2. Добавить колонки в settings.extParamTableSettings
settings["extParamTableSettings"].append({
    "id": 0,  # 0 = новая колонка
    "name": "Колонка",
    "type": 0  # 0=Текст, 1=Большой текст, 5=Дата-время
})

# 3. POST полный DTO
POST("/api/admin/extparams/settings", settings)

LookUpField — требует настройки после создания

  1. POST /api/admin/extparams/settings — указать subcatId источника
  2. Настроить колонки грида

Без настройки — lookup пустой.

Table и MultiSlctSubcatTasks — опасность

Создание ДП этих типов без конфигурации колонок/источника ломает рендер всей DP-панели. Создавать в отдельной категории и конфигурировать через POST /api/admin/extparams/settings сразу после создания.

Связанные документы

  • docs/domains/ext-params/README.md
  • docs/domains/ext-params/business.md
  • docs/domains/ext-params/backend.md
  • docs/domains/ext-params/data-flow.md
  • docs/domains/ext-params/through.md
  • docs/domains/ext-params/migration.md
  • docs/platform/backend/admin-architecture.md
  • docs/reference/database/dbadmin-forms-map.md
  • docs/reference/database/extparams.md