Mulai dari paket Business, endpoint GraphQL mendukung 12 mutation tulis: buat, ubah, dan hapus pada Perintah Kerja, Aset, dan Suku Cadang, ditambah adjustStock untuk pergerakan stok. Mutation melewati layanan yang sama dengan yang dipakai aplikasi itu sendiri, sehingga log audit, notifikasi, dan penomoran referensi otomatis (WO-XX, ASS-XX, PART-XX) berperilaku sama persis. Yang kesebelas, addMeterReading, mencatat pembacaan meter (jam operasi, penghitung) — lihat di bawah. Yang kedua belas, setPurchaseOrderErpReference, menulis nomor dokumen ERP Anda ke pesanan pembelian (hanya dengan kunci berakses FULL) dan tidak memicu webhook apa pun, sehingga ERP Anda tidak pernah menerima kembali tulisannya sendiri.
Mutasi yang tersedia
- 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
Bentuk input
Setiap mutasi memiliki InputType dengan hanya field yang aman — companyId, sequenceNumber, reference, dan createdById diisi di sisi server. Anda hanya perlu mengirim title, description, status, priority, assetId, locationId, dsb. Input suku cadang juga menerima barcode, maxStockLevel, locationId, dan vendorId, dan quantity/minQuantity/maxStockLevel menerima desimal (misalnya 0.5). Field berjenis enum divalidasi: priority harus salah satu dari LOW, MEDIUM, HIGH, CRITICAL; status perintah kerja salah satu dari OPEN, SCHEDULED, IN_PROGRESS, ON_HOLD, COMPLETED, VALIDATED, CANCELLED, CLOSED; status aset salah satu dari OPERATIONAL, DEGRADED, DOWN, MAINTENANCE, STANDBY, RETIRED. Nilai lain ditolak dengan BAD_REQUEST. Input suku cadang juga menerima customReference — kode Anda sendiri untuk barang itu (misalnya kode ERP), yang kemudian dicocokkan oleh part(barcode:). Keunikannya tidak dipaksakan: itu tanggung jawab Anda.
Contoh: membuat perintah kerja
Membuat perintah kerja: mutation($i: WorkOrderCreateInput!) { createWorkOrder(input: $i) { id title reference status createdAt } } dengan variabel {"i": {"title": "Pump #3 leak", "priority": "HIGH"}}
Menyesuaikan stok
Untuk mengubah kuantitas suku cadang, gunakan adjustStock dengan delta bertanda — negatif untuk mengonsumsi, positif untuk menerima. Ini memperbarui kuantitas dan menulis baris audit StockMovement dalam satu transaksi atomik, dan tidak pernah membiarkan stok turun di bawah nol. Untuk suku cadang yang stoknya dilacak per lokasi, kirim locationId: pergerakan diterapkan pada lokasi tersebut, dan tanpanya panggilan ditolak: errors[0].extensions.code bernilai BAD_REQUEST dan extensions.reason bernilai LOCATION_STOCK_REQUIRES_LOCATION. Sebaliknya, updatePart(quantity) mengatur nilai absolut: mutasi ini ditolak pada suku cadang yang dilacak per lokasi dengan alasan yang sama, dan selain itu mencatat selisihnya sebagai pergerakan ADJUSTMENT. Anda juga dapat mencatat asal barang: vendorId dan documentNumber (nomor faktur atau surat jalan pemasok, maksimal 64 karakter) disimpan pada pergerakan itu sendiri, sehingga riwayat menunjukkan siapa yang memasok dan dengan dokumen apa. Keduanya opsional — pemakaian biasa tidak mengirim satu pun. Pemasok harus milik perusahaan Anda.
Mencatat pembacaan meter
addMeterReading mencatat pembacaan pada sebuah meter — jam operasi, penghitung, odometer, pengukur — agar sistem eksternal (SCADA, gateway PLC, ERP) dapat mengisi pemeliharaan preventif berbasis meter tanpa ada yang mengetik ulang angkanya. Cari dulu id meter: query { meters(assetId: 7) { id reference name unit type lastReadingValue lastReadingDate } } Lalu kirim value (total absolut yang ditunjukkan meter) ATAU incrementValue (misalnya jam operasi sejak pembacaan terakhir, yang ditambahkan server ke pembacaan sebelumnya) — tepat satu dari keduanya: mutation { addMeterReading(meterId: 12, value: 1250.5, date: "2026-09-25T06:00:00Z") { id value date isAnomaly } } date bersifat opsional (ISO 8601, bawaan sekarang) dan boleh di masa lalu, tidak pernah di masa depan. Pada meter RUNTIME dan COUNTER, nilai yang lebih rendah dari pembacaan sebelumnya ditolak dengan BAD_REQUEST — setelah meter direset atau diganti, kirim ulang dengan confirmRegression: true. Pembacaan melewati layanan yang sama dengan layar meter di aplikasi: jika itu yang terbaru, pemicu meter dan pemeliharaan preventif berbasis meter berjalan persis seperti untuk pembacaan yang diketik teknisi. Mutasi ini memerlukan kunci dengan akses FULL.
Atribusi
Setiap mutasi berjalan sebagai pemilik kunci — orang yang diwakili kunci tersebut — dengan izinnya, visibilitas datanya, dan namanya di log audit. Kunci tidak pernah menyetujui langkah alur kerja, bahkan ketika pemiliknya bisa.
Mencoba ulang dengan aman (Idempotency-Key)
Batas waktu jaringan yang habis tidak memberi tahu apakah sebuah mutasi sudah dijalankan. Kirim header Idempotency-Key (8 sampai 64 huruf, angka, atau tanda hubung — UUID bisa dipakai) pada setiap permintaan yang menulis data, dan kirim kunci YANG SAMA saat mencobanya lagi. Selama 7 hari, percobaan ulang dengan kunci yang sama mengembalikan hasil tersimpan dari panggilan pertama (respons membawa "Idempotent-Replayed: true") alih-alih menjalankan mutasi lagi: tidak ada perintah kerja kedua, tidak ada pergerakan stok ganda.
- Satu kunci untuk setiap penulisan. Dalam permintaan dengan beberapa mutasi beralias, setiap mutasi dicatat terpisah di bawah kunci tersebut. Nilai yang dikirim tidak dibandingkan: kunci yang sama dengan nilai berbeda mengembalikan hasil panggilan pertama.
- Panggilan yang gagal tidak menyimpan apa pun: mencobanya lagi dengan kunci yang sama akan menjalankannya kembali.
- IDEMPOTENCY_KEY_REUSED — dengan kunci ini, nama yang sama (field atau alias) sudah menjalankan mutasi lain, atau pemanggil lain telah memakai kunci ini: gunakan kunci baru untuk penulisan baru.
- IDEMPOTENCY_IN_PROGRESS — panggilan pertama masih berjalan: tunggu beberapa detik lalu coba lagi.
Kesalahan umum
- GRAPHQL_VALIDATION_FAILED — bentuk masukan tidak cocok (misalnya title wajib tidak ada)
- BAD_REQUEST — validasi nilai gagal (misalnya title lebih dari 500 karakter)
- FORBIDDEN — paket Anda di bawah Business
- NOT_FOUND — id tidak ada atau milik perusahaan lain
- FORBIDDEN — level akses kunci terlalu rendah (misalnya kunci READ memanggil mutation)
Tips
Artikel terkait
Apakah halaman ini membantu?