GraphQL-Mutationen (schreiben)
Erstellen, aktualisieren und löschen über GraphQL
Ab dem Business-Tarif bietet der GraphQL-Endpunkt 12 Schreib-Mutationen: Anlegen, Ändern und Löschen bei Arbeitsaufträgen, Anlagen und Ersatzteilen, dazu adjustStock für Lagerbewegungen. Mutationen laufen über dieselben Services wie die Anwendung selbst, sodass Audit-Log, Benachrichtigungen und die automatische Referenzvergabe (WO-XX, ASS-XX, PART-XX) identisch funktionieren. Die elfte, addMeterReading, erfasst Zählerstände (Betriebsstunden, Stückzähler) — siehe unten. Die zwölfte, setPurchaseOrderErpReference, schreibt die Belegnummer Ihres ERP auf eine Bestellung (nur mit einem Schlüssel mit FULL-Zugriff) und löst keinen Webhook aus – Ihr ERP bekommt seinen eigenen Schreibvorgang also nie zurückgemeldet.
Verfügbare Mutationen
- 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
Eingabeform
Jede Mutation hat einen InputType nur mit sicheren Feldern – companyId, sequenceNumber, reference und createdById werden serverseitig ausgefüllt. Sie übergeben nur title, description, status, priority, assetId, locationId usw. Eingaben für Teile akzeptieren zusätzlich barcode, maxStockLevel, locationId und vendorId; quantity/minQuantity/maxStockLevel erlauben Dezimalwerte (z. B. 0.5). Aufzählungsfelder werden geprüft: priority muss LOW, MEDIUM, HIGH oder CRITICAL sein; der status eines Arbeitsauftrags OPEN, SCHEDULED, IN_PROGRESS, ON_HOLD, COMPLETED, VALIDATED, CANCELLED oder CLOSED; der status einer Anlage OPERATIONAL, DEGRADED, DOWN, MAINTENANCE, STANDBY oder RETIRED. Alles andere wird mit BAD_REQUEST abgelehnt. Eingaben für Teile akzeptieren außerdem customReference — Ihren eigenen Code für das Teil (etwa den aus Ihrem ERP), auf den part(barcode:) dann trifft. Eindeutigkeit wird nicht erzwungen: dafür sorgen Sie selbst.
Beispiel: Erstellen Sie einen Arbeitsauftrag
Einen Arbeitsauftrag anlegen: mutation($i: WorkOrderCreateInput!) { createWorkOrder(input: $i) { id title reference status createdAt } } mit den Variablen {"i": {"title": "Pump #3 leak", "priority": "HIGH"}}
Bestand anpassen
Um die Menge eines Teils zu ändern, verwenden Sie adjustStock mit einem vorzeichenbehafteten Delta — negativ zum Verbrauchen, positiv zum Einbuchen. Es aktualisiert die Menge und schreibt eine StockMovement-Audit-Zeile in einer einzigen atomaren Transaktion und lässt den Bestand nie unter null fallen. Bei einem Teil, dessen Bestand pro Lagerort geführt wird, übergeben Sie locationId: Die Bewegung wird auf diesen Lagerort gebucht, und ohne diesen Parameter wird der Aufruf abgelehnt: errors[0].extensions.code ist BAD_REQUEST und extensions.reason ist LOCATION_STOCK_REQUIRES_LOCATION. updatePart(quantity) setzt dagegen einen absoluten Wert: Es wird aus demselben Grund bei einem pro Lagerort geführten Teil abgelehnt und bucht die Differenz ansonsten als ADJUSTMENT-Bewegung. Sie können auch die Herkunft der Ware festhalten: vendorId und documentNumber (Rechnungs- oder Lieferscheinnummer des Lieferanten, max. 64 Zeichen) werden an der Buchung selbst gespeichert, sodass die Historie zeigt, wer geliefert hat und unter welchem Beleg. Beides ist optional — ein gewöhnlicher Verbrauch sendet keines davon. Der Lieferant muss zu Ihrem Unternehmen gehören.
Zählerstände erfassen
addMeterReading erfasst einen Stand an einem Zähler — Betriebsstunden, Stückzähler, Kilometerzähler, Messanzeige —, damit ein externes System (SCADA, SPS-Gateway, ERP) die zählerbasierte vorbeugende Wartung speist, ohne dass jemand die Zahl abtippt. Ermitteln Sie zuerst die id des Zählers: query { meters(assetId: 7) { id reference name unit type lastReadingValue lastReadingDate } } Senden Sie dann ENTWEDER value (den absoluten Gesamtwert, den der Zähler anzeigt) ODER incrementValue (z. B. die Betriebsstunden seit dem letzten Stand, die der Server zum vorherigen Stand addiert) — genau eines von beiden: mutation { addMeterReading(meterId: 12, value: 1250.5, date: "2026-09-25T06:00:00Z") { id value date isAnomaly } } date ist optional (ISO 8601, Standard: jetzt) und darf in der Vergangenheit liegen, nie in der Zukunft. Bei RUNTIME- und COUNTER-Zählern wird ein Wert unter dem vorherigen Stand mit BAD_REQUEST abgelehnt — nach einem Zurücksetzen oder Austausch des Zählers senden Sie ihn erneut mit confirmRegression: true. Der Stand läuft über denselben Dienst wie die Zähleransicht der App: Ist er der neueste, lösen Zählertrigger und zählerbasierte vorbeugende Wartung genau so aus wie bei einem von einem Techniker eingegebenen Stand. Diese Mutation erfordert einen Schlüssel mit FULL-Zugriff.
Namensnennung
Jede Mutation läuft als Eigentümer des Schlüssels — die Person, als die der Schlüssel handelt — mit dessen Berechtigungen, dessen Datensichtbarkeit und dessen Namen im Audit-Protokoll. Ein Schlüssel genehmigt niemals einen Workflow-Schritt, selbst wenn sein Eigentümer es könnte.
Sicher wiederholen (Idempotency-Key)
Eine Netzwerk-Zeitüberschreitung verrät nicht, ob eine Mutation ausgeführt wurde. Senden Sie bei jeder schreibenden Anfrage einen Idempotency-Key-Header (8 bis 64 Buchstaben, Ziffern oder Bindestriche – eine UUID eignet sich) und senden Sie beim Wiederholen DENSELBEN Schlüssel. 7 Tage lang liefert eine Wiederholung mit demselben Schlüssel das gespeicherte Ergebnis des ersten Aufrufs (die Antwort trägt "Idempotent-Replayed: true"), statt die Mutation erneut auszuführen: kein zweiter Arbeitsauftrag, keine doppelte Lagerbewegung.
- Ein Schlüssel pro Schreibvorgang. In einer Anfrage mit mehreren Mutationen mit Alias wird jede Mutation unter diesem Schlüssel einzeln erfasst. Die gesendeten Werte werden nicht verglichen: Derselbe Schlüssel mit anderen Werten liefert das Ergebnis des ersten Aufrufs.
- Ein fehlgeschlagener Aufruf hinterlässt nichts: Eine Wiederholung mit demselben Schlüssel führt ihn erneut aus.
- IDEMPOTENCY_KEY_REUSED — unter diesem Schlüssel hat derselbe Name (Feld oder Alias) bereits eine andere Mutation ausgeführt, oder ein anderer Aufrufer hat den Schlüssel verwendet: Verwenden Sie für einen neuen Schreibvorgang einen neuen Schlüssel.
- IDEMPOTENCY_IN_PROGRESS – der erste Aufruf läuft noch: Warten Sie einige Sekunden und versuchen Sie es erneut.
Häufige Fehler
- GRAPHQL_VALIDATION_FAILED — die Eingabestruktur passt nicht (zum Beispiel fehlt ein Pflichttitel)
- BAD_REQUEST — eine Wertprüfung ist fehlgeschlagen (zum Beispiel ein Titel über 500 Zeichen)
- FORBIDDEN — Ihr Tarif liegt unter Business
- NOT_FOUND — die id existiert nicht oder gehört zu einem anderen Unternehmen
- FORBIDDEN — die Zugriffsstufe des Schlüssels reicht nicht aus (zum Beispiel ein READ-Schlüssel, der eine Mutation aufruft)
Tipp
Verwandte Artikel
War diese Seite hilfreich?