GraphQL-мутации (запись)
Создавайте, обновляйте и удаляйте через GraphQL
Начиная с тарифа Business, эндпоинт GraphQL поддерживает 12 мутаций записи: создание, изменение и удаление для заявок, оборудования и запчастей, плюс adjustStock для складских движений. Мутации проходят через те же сервисы, что и само приложение, поэтому журнал аудита, уведомления и автогенерация номеров (WO-XX, ASS-XX, PART-XX) работают одинаково. Одиннадцатая, addMeterReading, записывает показания счётчиков (моточасы, счётчики изделий) — см. ниже. Двенадцатая, setPurchaseOrderErpReference, записывает в заказ на закупку номер документа вашей ERP (только ключом с доступом FULL) и не вызывает ни одного вебхука, поэтому ваша ERP никогда не получает собственную запись обратно.
Доступные мутации
- createWorkOrder(input) → WorkOrder
- updateWorkOrder(id, input) → WorkOrder
- deleteWorkOrder(id) → DeleteResult
- createAsset(input) → Asset
- updateAsset(id, input) → Asset
- deleteAsset(id, force?) → DeleteResult
- createPart(input) → Part
- updatePart(id, input) → Part
- deletePart(id, force?) → DeleteResult
- adjustStock(id, quantity, reason?, vendorId?, documentNumber?) → Part
- addMeterReading(meterId, value?, incrementValue?, date?, notes?, confirmRegression?) → MeterReading
- setPurchaseOrderErpReference(id, erpReference?) → PurchaseOrder
Введите форму
Каждая мутация имеет InputType только с безопасными полями — companyId, sequenceNumber, reference и createdById заполняются на стороне сервера. Вы передаёте только title, description, status, priority, assetId, locationId и т. д. Входные данные запчасти также принимают barcode, maxStockLevel, locationId и vendorId, а quantity/minQuantity/maxStockLevel допускают дробные значения (например, 0.5). Перечисляемые поля проверяются: priority должен быть одним из LOW, MEDIUM, HIGH, CRITICAL; status наряд-заказа — одним из OPEN, SCHEDULED, IN_PROGRESS, ON_HOLD, COMPLETED, VALIDATED, CANCELLED, CLOSED; status актива — одним из OPERATIONAL, DEGRADED, DOWN, MAINTENANCE, STANDBY, RETIRED. Любое другое значение отклоняется с BAD_REQUEST. Входные данные запчасти принимают также customReference — ваш собственный код детали (например, из ERP), с которым затем сопоставляется part(barcode:). Уникальность не навязывается: обеспечить её — ваша задача.
Пример: создать заказ на работу
Создать заявку: mutation($i: WorkOrderCreateInput!) { createWorkOrder(input: $i) { id title reference status createdAt } } с переменными {"i": {"title": "Pump #3 leak", "priority": "HIGH"}}
Корректировка запаса
Чтобы изменить количество детали, используйте adjustStock со знаковой дельтой — отрицательной для расхода, положительной для прихода. Он обновляет количество и записывает строку аудита StockMovement в одной атомарной транзакции и никогда не позволяет запасу опуститься ниже нуля. Для детали, запас которой учитывается по местам хранения, передайте locationId: движение применяется к этому месту, а без него вызов отклоняется — errors[0].extensions.code равен BAD_REQUEST, а extensions.reason — LOCATION_STOCK_REQUIRES_LOCATION. updatePart(quantity), напротив, задаёт абсолютное значение: на детали с учётом по местам хранения он отклоняется по той же причине, а в остальных случаях записывает разницу как движение ADJUSTMENT. Можно также зафиксировать происхождение товара: vendorId и documentNumber (номер счёта или накладной поставщика, не более 64 символов) сохраняются на самом движении, поэтому история показывает, кто поставил и по какому документу. Оба поля необязательны — обычное списание не передаёт ни одного. Поставщик должен принадлежать вашей компании.
Запись показаний счётчиков
addMeterReading записывает показание счётчика — моточасы, счётчик изделий, одометр, датчик, — чтобы внешняя система (SCADA, шлюз ПЛК, ERP) питала обслуживание по наработке без ручного ввода цифр. Сначала найдите id счётчика: query { meters(assetId: 7) { id reference name unit type lastReadingValue lastReadingDate } } Затем отправьте ЛИБО value (абсолютное значение, которое показывает счётчик), ЛИБО incrementValue (например, моточасы с момента последнего показания — сервер прибавит их к предыдущему показанию), ровно одно из двух: mutation { addMeterReading(meterId: 12, value: 1250.5, date: "2026-09-25T06:00:00Z") { id value date isAnomaly } } date необязателен (ISO 8601, по умолчанию — текущий момент) и может быть в прошлом, но не в будущем. Для счётчиков RUNTIME и COUNTER значение меньше предыдущего показания отклоняется с BAD_REQUEST — после сброса или замены счётчика отправьте его повторно с confirmRegression: true. Показание проходит через тот же сервис, что и экран счётчиков в приложении: если оно самое последнее, триггеры и обслуживание по наработке срабатывают точно так же, как для показания, введённого техником. Для этой мутации нужен ключ с доступом FULL.
Атрибуция
Каждая мутация выполняется от имени владельца ключа — того, от чьего имени действует ключ, — с его разрешениями, его видимостью данных и его именем в журнале аудита. Ключ никогда не утверждает шаг рабочего процесса, даже если его владелец мог бы это сделать.
Безопасный повтор (Idempotency-Key)
Истёкший сетевой тайм-аут не говорит, выполнилась ли мутация. Передавайте заголовок Idempotency-Key (от 8 до 64 букв, цифр или дефисов — подойдёт UUID) в каждом запросе, который что-то записывает, и при повторе отправляйте ТОТ ЖЕ ключ. В течение 7 дней повтор с тем же ключом возвращает сохранённый результат первого вызова (в ответе есть "Idempotent-Replayed: true") вместо повторного выполнения мутации: ни второго наряда, ни двойного движения запасов.
- Один ключ на одну запись. В запросе с несколькими мутациями под псевдонимами каждая мутация сохраняется под этим ключом отдельно. Отправленные значения не сравниваются: тот же ключ с другими значениями возвращает результат первого вызова.
- Неудачный вызов ничего не сохраняет: повтор с тем же ключом выполнит его снова.
- IDEMPOTENCY_KEY_REUSED — с этим ключом то же имя (поле или псевдоним) уже выполнило другую мутацию, либо ключ использовал другой вызывающий: для новой записи используйте новый ключ.
- IDEMPOTENCY_IN_PROGRESS — первый вызов ещё выполняется: подождите несколько секунд и повторите.
Распространенные ошибки
- GRAPHQL_VALIDATION_FAILED — форма входных данных не совпадает (например, отсутствует обязательный title)
- BAD_REQUEST — проверка значения не пройдена (например, title длиннее 500 символов)
- FORBIDDEN — ваш тариф ниже Business
- NOT_FOUND — id не существует или принадлежит другой компании
- FORBIDDEN — уровень доступа ключа недостаточен (например, ключ READ вызывает mutation)
Совет
Похожие статьи
Эта страница была полезна?