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
Powiązane artykuły
Czy ta strona była pomocna?