Mutation GraphQL (scrittura)
Crea, aggiorna ed elimina tramite GraphQL
Dal piano Business, l'endpoint GraphQL offre 12 mutation di scrittura: creare, aggiornare ed eliminare su Ordini di lavoro, Asset e Ricambi, più adjustStock per i movimenti di magazzino. Le mutation passano dagli stessi servizi usati dall'applicazione, quindi log di audit, notifiche e generazione automatica dei riferimenti (WO-XX, ASS-XX, PART-XX) si comportano allo stesso modo. L'undicesima, addMeterReading, registra le letture dei contatori (ore di funzionamento, contapezzi): vedi sotto. La dodicesima, setPurchaseOrderErpReference, scrive su un ordine di acquisto il numero di documento del tuo ERP (solo con una chiave ad accesso FULL) e non genera alcun webhook, così il tuo ERP non riceve mai indietro la propria scrittura.
Mutazioni disponibili
- 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 di input
Ogni mutazione ha un InputType solo con campi sicuri: companyId, sequenceNumber, reference e createdById vengono riempiti lato server. Si passano solo title, description, status, priority, assetId, locationId, ecc. Gli input dei ricambi accettano anche barcode, maxStockLevel, locationId e vendorId, e quantity/minQuantity/maxStockLevel ammettono decimali (es. 0.5). I campi enumerati sono verificati: priority deve essere LOW, MEDIUM, HIGH, CRITICAL; lo status di un ordine di lavoro OPEN, SCHEDULED, IN_PROGRESS, ON_HOLD, COMPLETED, VALIDATED, CANCELLED, CLOSED; lo status di un asset OPERATIONAL, DEGRADED, DOWN, MAINTENANCE, STANDBY, RETIRED. Qualsiasi altro valore viene rifiutato con BAD_REQUEST. Gli input dei ricambi accettano anche customReference — il vostro codice per il pezzo (per esempio quello dell'ERP), a cui part(barcode:) corrisponde poi. L'unicità non è imposta: garantirla spetta a voi.
Esempio: creare un ordine di lavoro
Creare un ordine di lavoro: mutation($i: WorkOrderCreateInput!) { createWorkOrder(input: $i) { id title reference status createdAt } } con le variabili {"i": {"title": "Pump #3 leak", "priority": "HIGH"}}
Regolare lo stock
Per modificare la quantità di un articolo, usa adjustStock con un delta con segno — negativo per consumare, positivo per ricevere. Aggiorna la quantità e scrive una riga di audit StockMovement in un'unica transazione atomica, e non lascia mai scendere lo stock sotto zero. Per un articolo gestito per ubicazione, passa locationId: il movimento viene applicato a quell'ubicazione e, senza, la chiamata viene rifiutata: errors[0].extensions.code è BAD_REQUEST ed extensions.reason è LOCATION_STOCK_REQUIRES_LOCATION. updatePart(quantity), invece, imposta un valore assoluto: per lo stesso motivo viene rifiutato su un articolo gestito per ubicazione e, negli altri casi, registra la differenza come movimento ADJUSTMENT. Puoi anche registrare la provenienza della merce: vendorId e documentNumber (numero di fattura o bolla del fornitore, max 64 caratteri) sono salvati sul movimento stesso, così lo storico mostra chi ha fornito e con quale documento. Entrambi sono facoltativi: un consumo ordinario non ne invia nessuno. Il fornitore deve appartenere alla tua azienda.
Registrare le letture dei contatori
addMeterReading registra una lettura su un contatore — ore di funzionamento, contapezzi, contachilometri, indicatore — così un sistema esterno (SCADA, gateway PLC, ERP) alimenta la manutenzione preventiva a contatore senza che nessuno ridigiti il numero. Trova prima l'id del contatore: query { meters(assetId: 7) { id reference name unit type lastReadingValue lastReadingDate } } Poi invia O value (il totale assoluto indicato dal contatore) O incrementValue (per esempio le ore di funzionamento dall'ultima lettura, che il server somma alla lettura precedente), esattamente uno dei due: mutation { addMeterReading(meterId: 12, value: 1250.5, date: "2026-09-25T06:00:00Z") { id value date isAnomaly } } date è facoltativa (ISO 8601, predefinita adesso) e può essere nel passato, mai nel futuro. Sui contatori RUNTIME e COUNTER, un valore inferiore alla lettura precedente viene rifiutato con BAD_REQUEST: dopo un azzeramento o una sostituzione del contatore, reinvialo con confirmRegression: true. La lettura passa dallo stesso servizio della schermata contatori dell'app: se è la più recente, trigger e manutenzione preventiva a contatore scattano esattamente come per una lettura inserita da un tecnico. Questa mutation richiede una chiave con accesso FULL.
Attribuzione
Ogni mutation viene eseguita come il proprietario della chiave — la persona per conto della quale agisce la chiave — con i suoi permessi, la sua visibilità sui dati e il suo nome nel registro di audit. Una chiave non approva mai un passaggio del flusso di lavoro, anche quando il suo proprietario potrebbe farlo.
Riprovare in sicurezza (Idempotency-Key)
Un timeout di rete non dice se una mutazione è stata eseguita. Invia un'intestazione Idempotency-Key (da 8 a 64 lettere, cifre o trattini: va bene un UUID) con ogni richiesta che scrive, e invia la STESSA chiave quando la riprovi. Per 7 giorni, un nuovo tentativo con la stessa chiave restituisce il risultato salvato della prima chiamata (la risposta contiene "Idempotent-Replayed: true") invece di eseguire di nuovo la mutazione: nessun secondo ordine di lavoro, nessun movimento di magazzino doppio.
- Una chiave per scrittura. In una richiesta con più mutazioni con alias, ogni mutazione viene registrata separatamente con quella chiave. I valori inviati non vengono confrontati: la stessa chiave con valori diversi restituisce il risultato della prima chiamata.
- Una chiamata fallita non lascia nulla: riprovarla con la stessa chiave la esegue di nuovo.
- IDEMPOTENCY_KEY_REUSED — con questa chiave, lo stesso nome (campo o alias) ha già eseguito un'altra mutazione, oppure un altro chiamante ha usato la chiave: usa una nuova chiave per una nuova scrittura.
- IDEMPOTENCY_IN_PROGRESS — la prima chiamata è ancora in corso: attendi qualche secondo e riprova.
Errori comuni
- GRAPHQL_VALIDATION_FAILED — la forma dell'input non corrisponde (per esempio manca un titolo obbligatorio)
- BAD_REQUEST — la convalida di un valore è fallita (per esempio un titolo oltre 500 caratteri)
- FORBIDDEN — il tuo piano è inferiore a Business
- NOT_FOUND — l'id non esiste o appartiene a un'altra azienda
- FORBIDDEN — il livello di accesso della chiave è insufficiente (per esempio una chiave READ che chiama una mutation)
Suggerimento
Articoli correlati
Questa pagina è stata utile?