Mutações GraphQL (escrita)

Crie, atualize e elimine via GraphQL

6 min de leitura
Imprimir esta secção

A partir do plano Business, o endpoint GraphQL oferece 12 mutations de escrita: criar, atualizar e eliminar em Ordens de trabalho, Ativos e Peças, além de adjustStock para os movimentos de stock. As mutations passam pelos mesmos serviços que a própria aplicação usa, pelo que registo 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, regista leituras de contador (horas de funcionamento, totalizadores): ver abaixo. A décima segunda, setPurchaseOrderErpReference, escreve numa encomenda de compra o número de documento do seu ERP (apenas com uma chave de acesso FULL) e não dispara nenhum webhook, pelo que o seu ERP nunca recebe de volta a sua própria escrita.

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 tem um InputType só com campos seguros — companyId, sequenceNumber, reference e createdById são preenchidos pelo servidor. Passa apenas title, description, status, priority, assetId, locationId, etc. Os inputs de peça aceitam também barcode, maxStockLevel, locationId e vendorId, e quantity/minQuantity/maxStockLevel aceitam decimais (p. ex. 0.5). Os campos enumerados são verificados: priority tem de ser LOW, MEDIUM, HIGH ou CRITICAL; o status de uma ordem de trabalho OPEN, SCHEDULED, IN_PROGRESS, ON_HOLD, COMPLETED, VALIDATED, CANCELLED ou CLOSED; o status de um ativo OPERATIONAL, DEGRADED, DOWN, MAINTENANCE, STANDBY ou RETIRED. Qualquer outro valor é recusado com BAD_REQUEST. Os inputs de peça aceitam ainda customReference — o seu próprio código para a peça (o do seu ERP, por exemplo), ao qual part(barcode:) passa a corresponder. A unicidade não é imposta: garanti-la cabe-lhe a si.

Exemplo: criar uma ordem de trabalho

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

Ajustar o stock

Para alterar a quantidade de uma peça, use adjustStock com um delta com sinal — negativo para consumir, positivo para rececionar. Atualiza a quantidade e escreve uma linha de auditoria StockMovement numa única transação atómica, e nunca deixa o stock descer abaixo de zero. Para uma peça gerida por localização, indique locationId: o movimento é aplicado a essa localização e, sem ele, a chamada é recusada: errors[0].extensions.code é BAD_REQUEST e extensions.reason é LOCATION_STOCK_REQUIRES_LOCATION. O updatePart(quantity), por sua vez, define um valor absoluto: é recusado numa peça gerida por localização pelo mesmo motivo e, nos restantes casos, regista a diferença como um movimento ADJUSTMENT. Também pode registar a origem da mercadoria: vendorId e documentNumber (n.º de fatura ou guia de remessa do fornecedor, máx. 64 caracteres) ficam guardados no próprio movimento, pelo que o histórico mostra quem forneceu e sob que documento. Ambos são opcionais — um consumo normal não envia nenhum. O fornecedor tem de pertencer à sua empresa.

Registar leituras de contador

addMeterReading regista uma leitura num contador — horas de funcionamento, totalizador, conta-quilómetros, indicador — para que um sistema externo (SCADA, gateway de PLC, ERP) alimente a manutenção preventiva por contador sem que ninguém volte a escrever o número. Obtenha primeiro o id do contador: query { meters(assetId: 7) { id reference name unit type lastReadingValue lastReadingDate } } Depois envie OU value (o total absoluto que o contador mostra) 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, por omissão agora) e pode estar no passado, nunca no futuro. Nos contadores RUNTIME e COUNTER, um valor inferior à leitura anterior é recusado com BAD_REQUEST; após uma reposição a zero ou substituição do contador, reenvie-o com confirmRegression: true. A leitura passa pelo mesmo serviço que o ecrã de contadores da aplicação: se for a mais recente, os acionadores e a manutenção preventiva por contador disparam exatamente como para uma leitura introduzida por um técnico. Esta mutation exige uma chave com acesso FULL.

Atribuição

Cada mutação é executada como o proprietário da chave — a pessoa em nome de quem a chave atua — com as permissões dele, a visibilidade de dados dele e o nome dele no registo de auditoria. Uma chave nunca aprova uma etapa do fluxo de trabalho, mesmo quando o proprietário o poderia fazer.

Repetir em segurança (Idempotency-Key)

Um tempo limite de rede não diz se uma mutação foi executada. Envie um cabeçalho Idempotency-Key (8 a 64 letras, algarismos ou hífenes — um UUID serve) em cada pedido que escreve, e envie a MESMA chave quando o repetir. Durante 7 dias, uma repetição com a mesma chave devolve o resultado guardado da primeira chamada (a resposta inclui "Idempotent-Replayed: true") em vez de executar a mutação outra vez: nenhuma segunda ordem de trabalho, nenhum movimento de stock em duplicado.

  • Uma chave por escrita. Num pedido com várias mutações com alias, cada mutação fica registada à parte sob essa chave. Os valores enviados não são comparados: a mesma chave com outros valores devolve o resultado da primeira chamada.
  • Uma chamada que falhou não guarda nada: repeti-la com a mesma chave volta a executá-la.
  • 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 chave nova para uma nova escrita.
  • IDEMPOTENCY_IN_PROGRESS — a primeira chamada ainda está em curso: aguarde alguns segundos e tente de novo.

Erros comuns

  • GRAPHQL_VALIDATION_FAILED — a forma 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 — o seu plano é inferior a 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 a chamar uma mutation)

Dica

Se 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?