Mutacje GraphQL (zapis)

Twórz, aktualizuj i usuwaj przez GraphQL

Czas czytania: 6 min
Drukuj tę sekcję

Od planu Business endpoint GraphQL obsługuje 12 mutacji zapisu: tworzenie, aktualizację i usuwanie zleceń, zasobów i części, a także adjustStock dla ruchów magazynowych. Mutacje przechodzą przez te same usługi, z których korzysta sama aplikacja, więc dziennik audytu, powiadomienia i automatyczne numerowanie (WO-XX, ASS-XX, PART-XX) działają identycznie. Jedenasta, addMeterReading, zapisuje odczyty liczników (motogodziny, liczniki sztuk) — patrz niżej. Dwunasta, setPurchaseOrderErpReference, zapisuje w zamówieniu zakupu numer dokumentu z Twojego ERP (tylko kluczem z dostępem FULL) i nie wywołuje żadnego webhooka, więc Twój ERP nigdy nie dostaje z powrotem własnego zapisu.

Dostępne mutacje

  • 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

Kształt wejściowy

Każda mutacja ma InputType zawierający wyłącznie bezpieczne pola — companyId, sequenceNumber, reference i createdById są wypełniane po stronie serwera. Podajesz tylko title, description, status, priority, assetId, locationId itp. Dane wejściowe części przyjmują też barcode, maxStockLevel, locationId i vendorId, a quantity/minQuantity/maxStockLevel akceptują wartości dziesiętne (np. 0.5). Pola wyliczeniowe są sprawdzane: priority musi być jednym z LOW, MEDIUM, HIGH, CRITICAL; status zlecenia jednym z OPEN, SCHEDULED, IN_PROGRESS, ON_HOLD, COMPLETED, VALIDATED, CANCELLED, CLOSED; status zasobu jednym z OPERATIONAL, DEGRADED, DOWN, MAINTENANCE, STANDBY, RETIRED. Każda inna wartość jest odrzucana z BAD_REQUEST. Dane wejściowe części przyjmują również customReference — Twój własny kod części (na przykład kod z ERP), do którego następnie dopasowuje się part(barcode:). Unikalność nie jest wymuszana: to Ty musisz ją zagwarantować.

Przykład: utwórz zlecenie pracy

Utworzenie zlecenia: mutation($i: WorkOrderCreateInput!) { createWorkOrder(input: $i) { id title reference status createdAt } } ze zmiennymi {"i": {"title": "Pump #3 leak", "priority": "HIGH"}}

Korekta stanu magazynowego

Aby zmienić ilość części, użyj adjustStock ze znakiem delty — ujemnej do zużycia, dodatniej do przyjęcia. Aktualizuje ilość i zapisuje wiersz audytu StockMovement w jednej atomowej transakcji, i nigdy nie pozwala, aby stan spadł poniżej zera. W przypadku części, której stan jest śledzony według lokalizacji, przekaż locationId: ruch zostanie zastosowany do tej lokalizacji, a bez niego wywołanie zostanie odrzucone — errors[0].extensions.code ma wartość BAD_REQUEST, a extensions.reason wartość LOCATION_STOCK_REQUIRES_LOCATION. updatePart(quantity) ustawia natomiast wartość bezwzględną: dla części śledzonej według lokalizacji jest odrzucane z tego samego powodu, a w pozostałych przypadkach zapisuje różnicę jako ruch ADJUSTMENT. Możesz też zapisać pochodzenie towaru: vendorId i documentNumber (numer faktury lub dowodu dostawy dostawcy, maks. 64 znaki) zapisują się na samym ruchu, więc historia pokazuje, kto dostarczył i na jakim dokumencie. Oba są opcjonalne — zwykłe zużycie nie wysyła żadnego. Dostawca musi należeć do Twojej firmy.

Zapisywanie odczytów liczników

addMeterReading zapisuje odczyt licznika — motogodzin, licznika sztuk, drogomierza, wskaźnika — aby system zewnętrzny (SCADA, bramka PLC, ERP) zasilał konserwację zapobiegawczą opartą na licznikach bez ręcznego przepisywania liczby. Najpierw znajdź id licznika: query { meters(assetId: 7) { id reference name unit type lastReadingValue lastReadingDate } } Następnie wyślij ALBO value (bezwzględną sumę wskazywaną przez licznik), ALBO incrementValue (np. motogodziny od ostatniego odczytu, które serwer doda do poprzedniego odczytu) — dokładnie jedno z nich: mutation { addMeterReading(meterId: 12, value: 1250.5, date: "2026-09-25T06:00:00Z") { id value date isAnomaly } } date jest opcjonalne (ISO 8601, domyślnie teraz) i może być w przeszłości, nigdy w przyszłości. Na licznikach RUNTIME i COUNTER wartość niższa od poprzedniego odczytu jest odrzucana z BAD_REQUEST — po wyzerowaniu lub wymianie licznika wyślij ją ponownie z confirmRegression: true. Odczyt przechodzi przez tę samą usługę co ekran liczników w aplikacji: jeśli jest najnowszy, wyzwalacze i konserwacja zapobiegawcza oparta na licznikach uruchamiają się dokładnie tak, jak przy odczycie wpisanym przez technika. Ta mutacja wymaga klucza z dostępem FULL.

Atrybucja

Każda mutacja jest wykonywana jako właściciel klucza — osoba, w imieniu której działa klucz — z jej uprawnieniami, jej widocznością danych i jej nazwiskiem w dzienniku audytu. Klucz nigdy nie zatwierdza etapu przepływu pracy, nawet jeśli jego właściciel mógłby to zrobić.

Bezpieczne ponawianie (Idempotency-Key)

Przekroczenie limitu czasu sieci nie mówi, czy mutacja została wykonana. Do każdego żądania, które zapisuje dane, dołączaj nagłówek Idempotency-Key (od 8 do 64 liter, cyfr lub myślników — wystarczy UUID), a ponawiając je, wysyłaj TEN SAM klucz. Przez 7 dni ponowienie z tym samym kluczem zwraca zapisany wynik pierwszego wywołania (odpowiedź zawiera "Idempotent-Replayed: true") zamiast ponownie wykonywać mutację: bez drugiego zlecenia pracy i bez podwójnego ruchu magazynowego.

  • Jeden klucz na jeden zapis. W żądaniu z kilkoma mutacjami z aliasami każda mutacja jest zapisywana osobno pod tym kluczem. Wysyłane wartości nie są porównywane: ten sam klucz z innymi wartościami zwraca wynik pierwszego wywołania.
  • Nieudane wywołanie niczego nie zachowuje: ponowienie z tym samym kluczem wykona je ponownie.
  • IDEMPOTENCY_KEY_REUSED — pod tym kluczem ta sama nazwa (pole lub alias) wykonała już inną mutację albo klucza użył inny wywołujący: do nowego zapisu użyj nowego klucza.
  • IDEMPOTENCY_IN_PROGRESS — pierwsze wywołanie wciąż trwa: odczekaj kilka sekund i spróbuj ponownie.

Typowe błędy

  • GRAPHQL_VALIDATION_FAILED — kształt danych wejściowych się nie zgadza (na przykład brakuje wymaganego title)
  • BAD_REQUEST — walidacja wartości nie powiodła się (na przykład title dłuższy niż 500 znaków)
  • FORBIDDEN — twój plan jest niższy niż Business
  • NOT_FOUND — id nie istnieje albo należy do innej firmy
  • FORBIDDEN — poziom dostępu klucza jest zbyt niski (na przykład klucz READ wywołujący mutation)

Wskazówka

Jeśli pojawi się błąd serializacji DateTime, sprawdź skalar DateTime swojego klienta — FreeMaint emituje ciągi znaków ISO 8601.

Czy ta strona była pomocna?