Mutações GraphQL (escrita)

Crie, atualize e exclua via GraphQL

6 min de leitura
Imprimir esta seção

A partir do plano Business, o endpoint GraphQL oferece 12 mutations de escrita: criar, atualizar e excluir em Ordens de serviço, Ativos e Peças, além de adjustStock para as movimentações de estoque. As mutations passam pelos mesmos serviços que o próprio aplicativo usa, então registro de auditoria, notificações e geração automática de referências (WO-XX, ASS-XX, PART-XX) se comportam de forma idêntica. A décima primeira, addMeterReading, registra leituras de medidores (horas de funcionamento, contadores): veja abaixo. A décima segunda, setPurchaseOrderErpReference, grava em um pedido de compra o número de documento do seu ERP (somente com uma chave de acesso FULL) e não dispara nenhum webhook, então o seu ERP nunca recebe de volta a própria gravação.

Mutações disponíveis

  • 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

Forma de entrada

Cada mutação possui um InputType apenas com campos seguros - companyId, sequenceNumber, reference ecreatedById são preenchidos no lado do servidor. Você passa apenas título, descrição, status, prioridade, assetId, locationId, etc. Os inputs de peça também aceitam barcode, maxStockLevel, locationId e vendorId, e quantity/minQuantity/maxStockLevel aceitam decimais (ex.: 0.5). Os campos enumerados são validados: priority precisa ser LOW, MEDIUM, HIGH, CRITICAL; o status de uma ordem de serviço OPEN, SCHEDULED, IN_PROGRESS, ON_HOLD, COMPLETED, VALIDATED, CANCELLED, CLOSED; o status de um ativo OPERATIONAL, DEGRADED, DOWN, MAINTENANCE, STANDBY, RETIRED. Qualquer outro valor é recusado com BAD_REQUEST. As entradas de peça também aceitam customReference — o seu próprio código para a peça (o do seu ERP, por exemplo), com o qual part(barcode:) passa a corresponder. A unicidade não é imposta: garanti-la é com você.

Exemplo: criar uma ordem de serviço

Criar uma ordem de serviço: mutation($i: WorkOrderCreateInput!) { createWorkOrder(input: $i) { id title reference status createdAt } } com as variáveis {"i": {"title": "Pump #3 leak", "priority": "HIGH"}}

Ajustar o estoque

Para alterar a quantidade de uma peça, use adjustStock com um delta com sinal — negativo para consumir, positivo para receber. Ele atualiza a quantidade e grava uma linha de auditoria StockMovement em uma única transação atômica, e nunca deixa o estoque cair abaixo de zero. Para uma peça controlada por local, informe locationId: o movimento é aplicado a esse local e, sem ele, a chamada é recusada: errors[0].extensions.code é BAD_REQUEST e extensions.reason é LOCATION_STOCK_REQUIRES_LOCATION. Já o updatePart(quantity) define um valor absoluto: ele é recusado em uma peça controlada por local pelo mesmo motivo e, nos demais casos, registra a diferença como um movimento ADJUSTMENT. Você também pode registrar a origem da mercadoria: vendorId e documentNumber (nº da nota fiscal ou romaneio do fornecedor, máx. 64 caracteres) ficam gravados no próprio movimento, então o histórico mostra quem forneceu e sob qual documento. Ambos são opcionais — um consumo comum não envia nenhum. O fornecedor precisa pertencer à sua empresa.

Registrar leituras de medidores

addMeterReading registra uma leitura em um medidor — horas de funcionamento, contador, hodômetro, indicador — para que um sistema externo (SCADA, gateway de CLP, ERP) alimente a manutenção preventiva por medidor sem que ninguém redigite o número. Primeiro obtenha o id do medidor: query { meters(assetId: 7) { id reference name unit type lastReadingValue lastReadingDate } } Depois envie OU value (o total absoluto mostrado pelo medidor) OU incrementValue (por exemplo as horas de funcionamento desde a última leitura, que o servidor soma à leitura anterior), exatamente um dos dois: mutation { addMeterReading(meterId: 12, value: 1250.5, date: "2026-09-25T06:00:00Z") { id value date isAnomaly } } date é opcional (ISO 8601, padrão agora) e pode estar no passado, nunca no futuro. Nos medidores RUNTIME e COUNTER, um valor menor que a leitura anterior é recusado com BAD_REQUEST; depois de um zeramento ou troca do medidor, reenvie com confirmRegression: true. A leitura passa pelo mesmo serviço da tela de medidores do aplicativo: se for a mais recente, os gatilhos e a manutenção preventiva por medidor disparam exatamente como para uma leitura digitada por um técnico. Esta mutation exige uma chave com acesso FULL.

Atribuição

Toda mutation é executada como o proprietário da chave — a pessoa em nome de quem a chave age — com as permissões dele, a visibilidade de dados dele e o nome dele no log de auditoria. Uma chave nunca aprova uma etapa do fluxo de trabalho, mesmo quando o proprietário poderia.

Tentar de novo com segurança (Idempotency-Key)

Um tempo limite de rede não diz se uma mutação foi executada. Envie um cabeçalho Idempotency-Key (de 8 a 64 letras, dígitos ou hifens — um UUID funciona) em toda requisição que grava, e envie a MESMA chave ao tentar de novo. Por 7 dias, uma nova tentativa com a mesma chave retorna o resultado salvo da primeira chamada (a resposta traz "Idempotent-Replayed: true") em vez de executar a mutação outra vez: nenhuma segunda ordem de serviço, nenhuma movimentação de estoque duplicada.

  • Uma chave por gravação. Em uma requisição com várias mutações com alias, cada mutação é registrada separadamente sob essa chave. Os valores enviados não são comparados: a mesma chave com outros valores retorna o resultado da primeira chamada.
  • Uma chamada que falhou não guarda nada: tentá-la de novo com a mesma chave a executa novamente.
  • IDEMPOTENCY_KEY_REUSED — com esta chave, o mesmo nome (campo ou alias) já executou outra mutação, ou outro chamador usou a chave: use uma nova chave para cada nova gravação.
  • IDEMPOTENCY_IN_PROGRESS — a primeira chamada ainda está em andamento: aguarde alguns segundos e tente de novo.

Erros comuns

  • GRAPHQL_VALIDATION_FAILED — o formato da entrada não corresponde (por exemplo, falta um título obrigatório)
  • BAD_REQUEST — a validação de um valor falhou (por exemplo, um título com mais de 500 caracteres)
  • FORBIDDEN — seu plano é inferior ao Business
  • NOT_FOUND — o id não existe ou pertence a outra empresa
  • FORBIDDEN — o nível de acesso da chave é insuficiente (por exemplo, uma chave READ chamando uma mutation)

Dica

Se você receber um erro de serialização DateTime, verifique o escalar DateTime do seu cliente — o FreeMaint emite strings ISO 8601.

Esta página foi útil?