Определения дополнительных полей
Все операции. Авторизация. Запросы и повторы.
Все пути в этом файле дополняют /api/v1 на домене организации.
Описание и ограничения
Назначение
Создание и изменение типизированных полей актов, клиентов, оборудования, выездов и сценариев ТО.
Поля и назначение
| Публичное поле | Формат и смысл | Доступ |
|---|---|---|
id, name, code |
id, название и стабильный код |
только чтение / чтение и запись |
entity |
act / customer / equipment / visit / maintenance_schedule |
при создании |
scenario_id |
id/null, конкретный сценарий | при создании |
type |
text/textarea/richtext/число/select/multiselect/date/дата и время/toggle/url/email/money/phone/radio/checkbox_list | при создании |
is_required, is_active, show_in_table, is_searchable |
логическое значение | чтение и запись |
sort_order, section |
порядок и секция | чтение и запись |
settings |
настройки типа по списку разрешённых значений | чтение и запись |
version, updated_at |
строка Unix-секунд и UTC timestamp/null | только чтение |
Обязательность и null указаны в схемах каждой операции ниже.
Доступ и выборка
custom_fields:read требует «Системные настройки → Базовый доступ к системе», право просмотра соответствующей сущности и возможность custom_fields. Для оборудования и заявок также нужна возможность maintenance. Дополнительный разрешение на чтение бизнес-ресурса не требуется. custom_fields:write требует «Системные настройки → Информация о компании»; поле сценария дополнительно требует «ТОиР — Обслуживание → Изменение» и актуальную доступность сценария. Право записи определения не требует права просмотра каждой бизнес-сущности.
Фильтры: filter[entity], filter[scenario_id], filter[is_active]. Сценарий фильтруется точно, без автоматического добавления глобальных полей. Пагинация по курсору и сортировки id/-id по общему контракту; неизвестные параметры запроса отклоняются. GET карточки поддерживает ETag/304.
Создание не требует версии и возвращает 201. Update/archive требуют If-Resource-Version определения, возвращают 200 и карточку; тело archive — {}. Повтор проверяет текущие разрешения подключения, права и доступ к сценарию. Удалённое штатным путём определение не восстанавливается из записи об операции.
Значения custom_fields в ресурсах
Одинаковый формат для customers, acts, equipment, visits и execution заявки ТО:
{"custom_fields": [{"field_id": 17, "value": "Тестовый объект"}, {"field_id": 18, "value": false}]}
Это массив не более 100 объектов, каждый из которых содержит ровно field_id (целый идентификатор определения) и value. Повторяющиеся field_id запрещены. Идентификатор однозначно определяет поле, даже если коды глобального поля и поля сценария совпадают. В ответе используется тот же формат, только для доступных определений.
| Тип | Публичный value |
|---|---|
| text/textarea/richtext/url/email/phone | строка; text/email до 255, url до 2048, textarea/richtext до 10000; формат url/email/phone проверяется |
| число | десятичная строка без экспоненты; min/max/step из определения |
| money | денежный объект amount/currency по conventions |
| toggle | логическое значение JSON; false не считается отсутствием |
| дата/datetime | YYYY-MM-DD / дата и время с секундами и явным смещением (например, 2026-05-03T14:20:00+03:00 или 2026-05-03T11:20:00Z); допускается дробная часть секунды до 6 знаков |
| select/radio | строковое value активного варианта, не его id или label |
| multiselect/checkbox_list | массив уникальных строковых value, полная замена значения одного поля |
При изменении отсутствующий field_id сохраняется, value:null очищает необязательное поле, custom_fields:[] ничего не меняет. custom_fields:null не принимается. При создании и завершении обязательные поля проверяются по итоговому набору; очистка обязательного — 422. Для начатой заявки определения и варианты берутся из её сохранённый снимок, включая ранее допустимое значение архивного варианта. Смена значения на новый архивный вариант не допускается.
Сохранённое datetime с явным смещением выдаётся как записано. Для сохранённого значения без смещения применяется текущая IANA-зона организации: время на часах сохраняется, а offset вычисляется для этой даты. Если при переходе на зимнее время локальное время повторяется, выбирается более ранний из двух возможных моментов. Это предположение, поскольку исходный момент из значения без смещения восстановить невозможно. Несуществующее локальное время при переходе на летнее время, некорректная дата или недопустимая зона вызывают ошибку; время не сдвигается автоматически. Для записи datetime требуется явное смещение.
Для типа richtext разрешены только теги p, br, strong, em, u, s, ul, ol, li, h2, h3 и a. У ссылок допускается только безопасный href с протоколом HTTP или HTTPS. Стили, обработчики событий и вложенные файлы удаляются. Числа, денежные значения и даты передаются в форматах, указанных в таблице типов.
Создание определения
Обязательны name, code, entity и type. code — стабильная строка [a-z][a-z0-9_]{0,190}, уникальность в области entity/scenario, с проверкой зарезервированных кодов. scenario_id разрешён только для maintenance_schedule. Значения по умолчанию: is_active=true, is_required=false, show_in_table=false, is_searchable=false, sort_order=0, section=null, settings={}. settings: для number разрешены min/max/step (десятичные строки, step>0), для textarea — rows (1–20); остальные типы в принимают только {}. Варианты выбора создаются отдельным ресурсом options.
name — непустая строка до 255 символов; section — строка до 255 символов или null; sort_order — целое число JSON от −2 147 483 648 до 2 147 483 647. Флаги принимают логические значения JSON. settings всегда передаётся объектом и заменяет доступные настройки поля. Отсутствующие при изменении поля сохраняются. Пустой объект настроек у поля без настроек ничего не меняет. min не превышает max, step строго положителен. Числа вместо десятичных строк и экспоненциальная запись не принимаются.
Правила и связи
- Допустимые значения
entityперечислены в схеме запроса. Другие значения не принимаются. - Определение поля отдельно от значения
custom_fieldsконкретного акта или заявки. - type/entity/scenario_id доступны только при создании.
codeможно изменить до появления значений; затем команда возвращает 409. - Для сценария различаются глобальные и scenario_id-поля; защищённые системные коды запрещены.
- Архив сохраняет значения и сохранённые снимки старых выполнений.
- Изменение определения, его варианта и родительского сценария обновляет их версии и создаёт соответствующие события. Если данные не изменились, версии и события сохраняются без изменений. Снимки начатых заявок не переписываются.
- Код
codeдолжен быть уникален в выбранной области, в том числе для глобальных полей сscenario_id=null.
Операции
| Метод | Путь | Назначение |
|---|---|---|
| GET | /custom-fields |
Разрешённые определения полей по сущности/сценарию |
| POST | /custom-fields |
Создание поля |
| GET | /custom-fields/{id} |
Одно определение |
| POST | /custom-fields/{id}/update |
Изменение разрешённых настроек |
| POST | /custom-fields/{id}/archive |
Отключение поля без удаления истории |
GET /custom-fields
Разрешённые определения полей по сущности/сценарию.
Доступ. Разрешения подключения: custom_fields:read. Права сотрудника: «Системные настройки → Базовый доступ к системе». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.
Параметры
| Имя | Где | Тип | Обязательно | null | Ограничения |
|---|---|---|---|---|---|
Authorization |
заголовок | строка | да | нет | Bearer <SERVICEAPP_TOKEN> |
filter[q] |
параметр запроса | строка | нет | нет | не более 200 символов |
sort |
параметр запроса | строка | нет | нет | Допустимо: "id", "-id" |
page[size] |
параметр запроса | целое число | нет | нет | ≥ 1; ≤ 100 |
page[cursor] |
параметр запроса | строка | нет | нет | не более 8192 символов |
filter[entity] |
параметр запроса | строка | нет | нет | Допустимо: "act", "customer", "equipment", "visit", "maintenance_schedule" |
filter[scenario_id] |
параметр запроса | целое число | нет | нет | ≥ 1 |
filter[is_active] |
параметр запроса | строка | нет | нет | Допустимо: "0", "1", "true", "false" |
Ответы
| HTTP | Назначение и схема |
|---|---|
| 200 | Успех. Полная схема и пример |
| 401 | Требуется действующий Bearer. Коды и формат ошибки |
| 403 | Недостаточно допуска. Коды и формат ошибки |
| 404 | Не найдено или недоступно. Коды и формат ошибки |
| 422 | Ошибка входных данных. Коды и формат ошибки |
| 429 | Лимит запросов, Retry-After. Коды и формат ошибки |
| 503 | Временно недоступно. Коды и формат ошибки |
Каждый ответ содержит новый X-Request-Id в заголовке. Общие транспортные отказы и правила повтора действуют также при отказе до контроллера; см. ошибки.
Пример запроса
Запускается из каталога комплекта после настройки переменных в быстром старте. Замените демонстрационные идентификаторы 101 и UUID идентификаторами доступных записей. $RESOURCE_VERSION берётся из GET владельца версии, описанного выше. Для нового действия сохраните новый ключ; для повтора используйте прежний.
curl --silent --show-error --globoff \
"$API/custom-fields" \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header "Accept: application/json"
POST /custom-fields
Создание поля.
Доступ. Разрешения подключения: custom_fields:write. Права сотрудника: «Системные настройки → Информация о компании». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.
Параметры
| Имя | Где | Тип | Обязательно | null | Ограничения |
|---|---|---|---|---|---|
Authorization |
заголовок | строка | да | нет | Bearer <SERVICEAPP_TOKEN> |
Idempotency-Key |
заголовок | строка | да | нет | не менее 1 символов; не более 128 символов; Шаблон: ^[A-Za-z0-9._:-]+$ |
Тело запроса
Content-Type: application/json. Тело обязательно.
| Поле | Тип | Обязательно | null | Ограничения и смысл |
|---|---|---|---|---|
name |
строка | да | нет | не более 255 символов |
code |
строка | да | нет | не более 191 символов; Шаблон: ^[a-z][a-z0-9_]*$; Запрещено: {"enum": ["today", "state", "equipment", "customer", "days_since_last_maintenance"]} |
entity |
строка | да | нет | Допустимо: "act", "customer", "equipment", "visit", "maintenance_schedule" |
type |
строка | да | нет | Допустимо: "text", "textarea", "richtext", "number", "money", "phone", "select", "multiselect", "date", "datetime", "toggle", "url", "email", "radio", "checkbox_list" |
scenario_id |
целое число / null | нет | да | ≥ 1 |
is_required |
логическое значение | нет | нет | — |
is_active |
логическое значение | нет | нет | — |
show_in_table |
логическое значение | нет | нет | — |
is_searchable |
логическое значение | нет | нет | — |
sort_order |
целое число | нет | нет | ≥ -2147483648; ≤ 2147483647 |
section |
строка / null | нет | да | не более 255 символов |
settings |
объект | нет | нет | — |
settings.min |
строка | нет | нет | — |
settings.max |
строка | нет | нет | — |
settings.step |
строка | нет | нет | — |
settings.rows |
целое число | нет | нет | — |
settings[] |
строка | да | нет | — |
Ответы
| HTTP | Назначение и схема |
|---|---|
| 201 | Создано. Полная схема и пример |
| 401 | Требуется действующий Bearer. Коды и формат ошибки |
| 403 | Недостаточно допуска. Коды и формат ошибки |
| 404 | Не найдено или недоступно. Коды и формат ошибки |
| 409 | Конфликт состояния или повтора. Коды и формат ошибки |
| 422 | Ошибка входных данных. Коды и формат ошибки |
| 429 | Лимит запросов, Retry-After. Коды и формат ошибки |
| 503 | Временно недоступно. Коды и формат ошибки |
| HTTP | Заголовок ответа | Тип | Описание |
|---|---|---|---|
| 201 | Location |
строка |
Каждый ответ содержит новый X-Request-Id в заголовке. Общие транспортные отказы и правила повтора действуют также при отказе до контроллера; см. ошибки.
У принятого POST Location и meta.operation_id указывают на журнал операции; ETag отсутствует. При повторе запроса сохраняются исходные data/meta, добавляется Idempotency-Replayed: true. Версии передавайте по назначению, указанному в описании ресурса.
Пример запроса
Запускается из каталога комплекта после настройки переменных в быстром старте. Замените демонстрационные идентификаторы 101 и UUID идентификаторами доступных записей. $RESOURCE_VERSION берётся из GET владельца версии, описанного выше. Для нового действия сохраните новый ключ; для повтора используйте прежний.
curl --silent --show-error --globoff --request POST \
"$API/custom-fields" \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header "Accept: application/json" \
--header "Idempotency-Key: example:v1-custom-fields-create:001" \
--header "Content-Type: application/json" \
--data-binary '@examples/requests/v1.custom-fields.create.json'
GET /custom-fields/{id}
Одно определение.
Доступ. Разрешения подключения: custom_fields:read. Права сотрудника: «Системные настройки → Базовый доступ к системе». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.
Параметры
| Имя | Где | Тип | Обязательно | null | Ограничения |
|---|---|---|---|---|---|
Authorization |
заголовок | строка | да | нет | Bearer <SERVICEAPP_TOKEN> |
id |
путь | строка | да | нет | Шаблон: ^(?:[0-9]+)$ |
If-None-Match |
заголовок | строка | нет | нет | — |
Ответы
| HTTP | Назначение и схема |
|---|---|
| 200 | Успех. Полная схема и пример |
| 304 | Представление не изменилось, без тела. Условный GET |
| 401 | Требуется действующий Bearer. Коды и формат ошибки |
| 403 | Недостаточно допуска. Коды и формат ошибки |
| 404 | Не найдено или недоступно. Коды и формат ошибки |
| 422 | Ошибка входных данных. Коды и формат ошибки |
| 429 | Лимит запросов, Retry-After. Коды и формат ошибки |
| 503 | Временно недоступно. Коды и формат ошибки |
| HTTP | Заголовок ответа | Тип | Описание |
|---|---|---|---|
| 200 | ETag |
строка | |
| 304 | ETag |
строка |
Каждый ответ содержит новый X-Request-Id в заголовке. Общие транспортные отказы и правила повтора действуют также при отказе до контроллера; см. ошибки.
Пример запроса
Запускается из каталога комплекта после настройки переменных в быстром старте. Замените демонстрационные идентификаторы 101 и UUID идентификаторами доступных записей. $RESOURCE_VERSION берётся из GET владельца версии, описанного выше. Для нового действия сохраните новый ключ; для повтора используйте прежний.
curl --silent --show-error --globoff \
"$API/custom-fields/101" \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header "Accept: application/json"
POST /custom-fields/{id}/update
Изменение разрешённых настроек.
Доступ. Разрешения подключения: custom_fields:write. Права сотрудника: «Системные настройки → Информация о компании». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.
Параметры
| Имя | Где | Тип | Обязательно | null | Ограничения |
|---|---|---|---|---|---|
Authorization |
заголовок | строка | да | нет | Bearer <SERVICEAPP_TOKEN> |
id |
путь | строка | да | нет | Шаблон: ^(?:[0-9]+)$ |
Idempotency-Key |
заголовок | строка | да | нет | не менее 1 символов; не более 128 символов; Шаблон: ^[A-Za-z0-9._:-]+$ |
If-Resource-Version |
заголовок | строка | да | нет | не менее 1 символов; не более 128 символов; Шаблон: ^[A-Za-z0-9._~-]+$ |
Тело запроса
Content-Type: application/json. Тело обязательно.
| Поле | Тип | Обязательно | null | Ограничения и смысл |
|---|---|---|---|---|
name |
строка | нет | нет | не более 255 символов |
code |
строка | нет | нет | не более 191 символов; Шаблон: ^[a-z][a-z0-9_]*$; Запрещено: {"enum": ["today", "state", "equipment", "customer", "days_since_last_maintenance"]} |
is_required |
логическое значение | нет | нет | — |
is_active |
логическое значение | нет | нет | — |
show_in_table |
логическое значение | нет | нет | — |
is_searchable |
логическое значение | нет | нет | — |
sort_order |
целое число | нет | нет | ≥ -2147483648; ≤ 2147483647 |
section |
строка / null | нет | да | не более 255 символов |
settings |
объект | нет | нет | — |
settings.min |
строка | нет | нет | — |
settings.max |
строка | нет | нет | — |
settings.step |
строка | нет | нет | — |
settings.rows |
целое число | нет | нет | — |
settings[] |
строка | да | нет | — |
Ответы
| HTTP | Назначение и схема |
|---|---|
| 200 | Успех. Полная схема и пример |
| 401 | Требуется действующий Bearer. Коды и формат ошибки |
| 403 | Недостаточно допуска. Коды и формат ошибки |
| 404 | Не найдено или недоступно. Коды и формат ошибки |
| 409 | Конфликт состояния или повтора. Коды и формат ошибки |
| 412 | Версия устарела. Коды и формат ошибки |
| 422 | Ошибка входных данных. Коды и формат ошибки |
| 428 | Нужно предусловие версии. Коды и формат ошибки |
| 429 | Лимит запросов, Retry-After. Коды и формат ошибки |
| 503 | Временно недоступно. Коды и формат ошибки |
| HTTP | Заголовок ответа | Тип | Описание |
|---|---|---|---|
| 200 | Location |
строка |
Каждый ответ содержит новый X-Request-Id в заголовке. Общие транспортные отказы и правила повтора действуют также при отказе до контроллера; см. ошибки.
У принятого POST Location и meta.operation_id указывают на журнал операции; ETag отсутствует. При повторе запроса сохраняются исходные data/meta, добавляется Idempotency-Replayed: true. Версии передавайте по назначению, указанному в описании ресурса.
Пример запроса
Запускается из каталога комплекта после настройки переменных в быстром старте. Замените демонстрационные идентификаторы 101 и UUID идентификаторами доступных записей. $RESOURCE_VERSION берётся из GET владельца версии, описанного выше. Для нового действия сохраните новый ключ; для повтора используйте прежний.
curl --silent --show-error --globoff --request POST \
"$API/custom-fields/101/update" \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header "Accept: application/json" \
--header "Idempotency-Key: example:v1-custom-fields-update:001" \
--header "If-Resource-Version: $RESOURCE_VERSION" \
--header "Content-Type: application/json" \
--data-binary '@examples/requests/v1.custom-fields.update.json'
POST /custom-fields/{id}/archive
Отключение поля без удаления истории.
Доступ. Разрешения подключения: custom_fields:write. Права сотрудника: «Системные настройки → Информация о компании». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.
Параметры
| Имя | Где | Тип | Обязательно | null | Ограничения |
|---|---|---|---|---|---|
Authorization |
заголовок | строка | да | нет | Bearer <SERVICEAPP_TOKEN> |
id |
путь | строка | да | нет | Шаблон: ^(?:[0-9]+)$ |
Idempotency-Key |
заголовок | строка | да | нет | не менее 1 символов; не более 128 символов; Шаблон: ^[A-Za-z0-9._:-]+$ |
If-Resource-Version |
заголовок | строка | да | нет | не менее 1 символов; не более 128 символов; Шаблон: ^[A-Za-z0-9._~-]+$ |
Тело запроса
Content-Type: application/json. Тело обязательно.
Тело — пустой JSON-объект {}. Другие ключи не принимаются.
Ответы
| HTTP | Назначение и схема |
|---|---|
| 200 | Успех. Полная схема и пример |
| 401 | Требуется действующий Bearer. Коды и формат ошибки |
| 403 | Недостаточно допуска. Коды и формат ошибки |
| 404 | Не найдено или недоступно. Коды и формат ошибки |
| 409 | Конфликт состояния или повтора. Коды и формат ошибки |
| 412 | Версия устарела. Коды и формат ошибки |
| 422 | Ошибка входных данных. Коды и формат ошибки |
| 428 | Нужно предусловие версии. Коды и формат ошибки |
| 429 | Лимит запросов, Retry-After. Коды и формат ошибки |
| 503 | Временно недоступно. Коды и формат ошибки |
| HTTP | Заголовок ответа | Тип | Описание |
|---|---|---|---|
| 200 | Location |
строка |
Каждый ответ содержит новый X-Request-Id в заголовке. Общие транспортные отказы и правила повтора действуют также при отказе до контроллера; см. ошибки.
У принятого POST Location и meta.operation_id указывают на журнал операции; ETag отсутствует. При повторе запроса сохраняются исходные data/meta, добавляется Idempotency-Replayed: true. Версии передавайте по назначению, указанному в описании ресурса.
Пример запроса
Запускается из каталога комплекта после настройки переменных в быстром старте. Замените демонстрационные идентификаторы 101 и UUID идентификаторами доступных записей. $RESOURCE_VERSION берётся из GET владельца версии, описанного выше. Для нового действия сохраните новый ключ; для повтора используйте прежний.
curl --silent --show-error --globoff --request POST \
"$API/custom-fields/101/archive" \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header "Accept: application/json" \
--header "Idempotency-Key: example:v1-custom-fields-archive:001" \
--header "If-Resource-Version: $RESOURCE_VERSION" \
--header "Content-Type: application/json" \
--data-binary '@examples/requests/v1.custom-fields.archive.json'