Mutations GraphQL (écriture)
Créez, modifiez et supprimez via GraphQL
À partir du palier Business, le point d'entrée GraphQL propose 12 mutations d'écriture : créer, modifier et supprimer sur les ordres de travail, les actifs et les pièces, plus adjustStock pour les mouvements de stock. Les mutations passent par les mêmes services que l'application elle-même : journal d'audit, notifications et génération automatique des références (WO-XX, ASS-XX, PART-XX) se comportent à l'identique. La onzième, addMeterReading, enregistre les relevés de compteur (heures de marche, totalisateurs) — voir plus bas. La douzième, setPurchaseOrderErpReference, inscrit sur un bon de commande le numéro de document de votre ERP (clé à accès FULL uniquement) et ne déclenche aucun webhook : votre ERP ne reçoit jamais sa propre écriture en retour.
Mutations disponibles
- 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
Forme d'entrée
Chaque mutation a un InputType avec des champs sécurisés uniquement : companyId, sequenceNumber, reference et createdById sont remplis côté serveur. Vous transmettez uniquement title, description, status, priority, assetId, locationId, etc. Les inputs de pièce acceptent aussi barcode, maxStockLevel, locationId et vendorId, et quantity/minQuantity/maxStockLevel prennent des décimales (ex. 0.5). Les champs énumérés sont vérifiés : priority doit valoir LOW, MEDIUM, HIGH, CRITICAL ; le status d'un ordre de travail OPEN, SCHEDULED, IN_PROGRESS, ON_HOLD, COMPLETED, VALIDATED, CANCELLED, CLOSED ; le status d'un actif OPERATIONAL, DEGRADED, DOWN, MAINTENANCE, STANDBY, RETIRED. Toute autre valeur est refusée avec BAD_REQUEST. Les inputs de pièce acceptent aussi customReference — votre propre code pour la pièce (celui de votre ERP, par exemple), auquel part(barcode:) correspond ensuite. Son unicité n'est pas imposée : c'est à vous de la garantir.
Exemple : créer un bon de travail
Créer un ordre de travail : mutation($i: WorkOrderCreateInput!) { createWorkOrder(input: $i) { id title reference status createdAt } } avec les variables {"i": {"title": "Pump #3 leak", "priority": "HIGH"}}
Ajuster le stock
Pour modifier la quantité d'une pièce, utilisez adjustStock avec un delta signé — négatif pour consommer, positif pour réceptionner. Il met à jour la quantité et écrit une ligne d'audit StockMovement dans une seule transaction atomique, et ne laisse jamais le stock passer sous zéro. Pour une pièce suivie par emplacement, passez locationId : le mouvement s'applique à cet emplacement, et sans lui l'appel est refusé : errors[0].extensions.code vaut BAD_REQUEST et extensions.reason vaut LOCATION_STOCK_REQUIRES_LOCATION. updatePart(quantity), lui, définit une valeur absolue : il est refusé sur une pièce suivie par emplacement pour la même raison, et sinon enregistre l'écart comme un mouvement ADJUSTMENT. Vous pouvez aussi consigner l'origine des marchandises : vendorId et documentNumber (n° de facture ou de bon de livraison du fournisseur, 64 caractères max) sont enregistrés sur le mouvement lui-même, donc l'historique montre qui a fourni et sous quel document. Les deux sont facultatifs — une consommation ordinaire n'en envoie aucun. Le fournisseur doit appartenir à votre entreprise.
Enregistrer des relevés de compteur
addMeterReading enregistre un relevé sur un compteur — heures de marche, totalisateur, odomètre, jauge — pour qu'un système externe (SCADA, passerelle automate, ERP) alimente la maintenance préventive sur compteur sans que personne ne ressaisisse le chiffre. Trouvez d'abord l'id du compteur : query { meters(assetId: 7) { id reference name unit type lastReadingValue lastReadingDate } } Envoyez ensuite SOIT value (le total absolu affiché par le compteur), SOIT incrementValue (par exemple les heures de marche depuis le dernier relevé, que le serveur ajoute au relevé précédent) — exactement l'un des deux : mutation { addMeterReading(meterId: 12, value: 1250.5, date: "2026-09-25T06:00:00Z") { id value date isAnomaly } } date est facultative (ISO 8601, maintenant par défaut) et peut être dans le passé, jamais dans le futur. Sur les compteurs RUNTIME et COUNTER, une valeur inférieure au relevé précédent est refusée avec BAD_REQUEST — après une remise à zéro ou un remplacement du compteur, renvoyez-la avec confirmRegression: true. Le relevé passe par le même service que l'écran Compteurs de l'application : s'il est le plus récent, les déclencheurs et la maintenance préventive sur compteur réagissent exactement comme pour un relevé saisi par un technicien. Cette mutation exige une clé d'accès FULL.
Attribution
Chaque mutation s'exécute en tant que propriétaire de la clé — la personne au nom de laquelle la clé agit —, avec ses autorisations, sa visibilité sur les données et son nom dans le journal d'audit. Une clé n'approuve jamais une étape du flux de travail, même quand son propriétaire le pourrait.
Réessayer sans risque (Idempotency-Key)
Un délai réseau dépassé ne dit pas si une mutation a été exécutée. Envoyez un en-tête Idempotency-Key (8 à 64 lettres, chiffres ou tirets — un UUID convient) avec chaque requête qui écrit, et renvoyez la MÊME clé quand vous la réessayez. Pendant 7 jours, un nouvel essai avec la même clé renvoie le résultat enregistré du premier appel (la réponse porte "Idempotent-Replayed: true") au lieu d'exécuter la mutation une seconde fois : pas de deuxième ordre de travail, pas de mouvement de stock en double.
- Une clé par écriture. Dans une requête qui contient plusieurs mutations avec alias, chaque mutation est enregistrée séparément sous cette clé. Les valeurs envoyées ne sont pas comparées : la même clé avec d'autres valeurs renvoie le résultat du premier appel.
- Un appel en échec ne garde rien : le réessayer avec la même clé l'exécute de nouveau.
- IDEMPOTENCY_KEY_REUSED — sous cette clé, le même nom (champ ou alias) a déjà exécuté une autre mutation, ou un autre appelant a utilisé la clé : utilisez une nouvelle clé pour une nouvelle écriture.
- IDEMPOTENCY_IN_PROGRESS — le premier appel est encore en cours : attendez quelques secondes et réessayez.
Erreurs courantes
- GRAPHQL_VALIDATION_FAILED — la forme de l'entrée ne correspond pas (par exemple un titre obligatoire manquant)
- BAD_REQUEST — la validation d'une valeur a échoué (par exemple un titre de plus de 500 caractères)
- FORBIDDEN — votre palier est inférieur à Business
- NOT_FOUND — l'id n'existe pas, ou appartient à une autre société
- FORBIDDEN — le niveau d'accès de la clé est insuffisant (par exemple une clé READ qui appelle une mutation)
Astuce
Articles liés
Cette page vous a-t-elle été utile ?