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
Artigos relacionados
Esta página foi útil?