Panduan Penyepaduan ERP dan Sistem

Tentukan skop penyepaduan sebelum anda membinanya: apa yang dicapai oleh API, apa yang tidak, dan di mana letaknya sempadan

9 minit bacaan
Cetak bahagian ini

Panduan ini ditujukan kepada pembangun yang sedang menentukan skop penyepaduan antara FreeMaint dan sistem lain — sebuah ERP, sebuah historian SCADA, sistem gudang atau pakej perakaunan. Artikel lain dalam bahagian ini menerangkan cara memanggil API; yang ini sengaja bercakap tentang sempadan, kerana kesilapan yang mahal bukanlah pengepala yang salah: ia ialah mendapati di pertengahan pembinaan bahawa sesuatu keupayaan yang anda sangkakan wujud sebenarnya tidak wujud. Setiap had di bawah dinyatakan dengan sengaja.

Satu kunci, tiga pintu

Kunci API (bermula dengan fmk_) dicipta di Tetapan Syarikat > API (/company-settings/api) oleh pentadbir, atau oleh seseorang untuk dirinya sendiri di Profil > Keselamatan > Kunci API, dan dihantar sebagai Authorization: Bearer fmk_... . Ia mengesahkan tepat tiga perkara: titik akhir GraphQL di POST /api/v1/graphql, titik akhir penyerapan tenaga, serta /public-api/whoami dan /public-api/ping. Ia TIDAK mengesahkan laluan REST di bawah /api/v1/{resource} — laluan tersebut ialah API dalaman aplikasi itu sendiri dan memerlukan sesi pengguna (JWT). Binalah penyepaduan anda di atas GraphQL: itulah permukaan yang dicapai oleh sesebuah kunci.

Apa yang diberikan oleh kunci API

Kunci mentah hanya dipaparkan sekali, semasa penciptaan, dan tidak pernah boleh dipulihkan selepas itu: hanya cincangan SHA-256 disimpan, bersama 6 aksara selepas fmk_ supaya senarai dapat mengenal pasti kunci itu pada skrin.

Nama

Label yang mudah difahami manusia — «Jambatan ERP Oracle», «Kiosk barisan 2». Keluarkan satu kunci bagi setiap sistem yang menggunakannya supaya anda boleh membatalkan satu kunci tanpa mengganggu yang lain.

Tahap capaian

READ, READ_STOCK atau FULL, satu hierarki bertertib di atas kebenaran pemilik. READ hanya menjalankan pertanyaan dan merupakan nilai lalai. READ_STOCK menambah mutasi adjustStock. FULL membenarkan setiap operasi yang dibenarkan oleh peranan pemilik, termasuk mencipta, mengemas kini dan memadam — serta titik akhir penyerapan tenaga apabila pemilik dibenarkan mencipta bacaan tenaga.

Tamat tempoh

Satu expiresAt yang bersifat pilihan. Selepas saat itu, kunci berhenti mengesahkan. Biarkan kosong untuk penyepaduan perkhidmatan yang kekal; isikan untuk kontraktor atau projek perintis.

Pembatalan

isActive ialah suis bagi setiap kunci yang berkuat kuasa dalam beberapa saat. Barisnya dikekalkan untuk audit, jadi kunci yang dibatalkan kekal boleh dijejaki dan bukannya lenyap begitu sahaja.

Kali terakhir digunakan

lastUsedAt merekodkan panggilan disahkan yang terkini — cukup untuk mengesan kunci yang sudah tidak digunakan oleh sesiapa.

Pemilik

Orang yang diwakili oleh kunci. Setiap panggilan membawa kebenaran dan keterlihatan datanya, dan namanya menandatangani apa yang ditulis oleh kunci. Untuk ERP, cipta pengguna khusus — “Integrasi ERP” — dengan peranan yang meliputi tepat apa yang diperlukan oleh jambatan, dan berikan kunci itu kepadanya.

Apa yang tidak diberikan oleh kunci API

Ini ialah had sebenar bagi pelaksanaan semasa, bukan perkara yang tertinggal daripada halaman ini. Jika semakan keselamatan anda bergantung pada mana-mana daripadanya, rancanglah jalan keluarnya sekarang dan bukan selepas pembinaan siap.

  • Tiada senarai modul bagi setiap kunci. Sesebuah kunci membaca dan menulis apa yang dibenarkan oleh peranan pemiliknya — untuk menyempitkannya, berikan kunci kepada pemilik yang peranannya lebih sempit. Di samping itu, hanya tiga tahap capaian terpakai: anda tidak boleh menyenaraikan, pada kunci itu sendiri, modul yang boleh digunakannya.
  • Tiada senarai benarkan IP. Sesebuah kunci sah dari mana-mana sahaja di internet. Anggaplah ia rahsia: peti besi atau simpanan rahsia platform anda, jangan sekali-kali repositori kod, pemacu kongsi atau tiket sokongan.
  • Tiada log penggunaan bagi setiap kunci. Hanya lastUsedAt disimpan. Tiada sejarah panggilan bagi setiap kunci, tiada kuota bagi setiap kunci dan tiada rekod tentang kunci mana yang melakukan operasi mana. Pembilang kuota harian adalah bagi setiap SYARIKAT dan dikongsi oleh semua kunci, jadi satu penyepaduan yang terlepas kawalan boleh menghabiskan kuota semua yang lain.
  • Tiada kelulusan bagi pihak orang lain. Kunci tidak sekali-kali meluluskan langkah aliran kerja, walaupun pemiliknya boleh berbuat demikian: kelulusan kekal sebagai tindakan manusia dalam aplikasi.
  • Satu syarikat bagi setiap kunci. Kunci terikat kepada syarikat tempat ia dicipta dan tidak boleh mencapai data syarikat lain: rekod syarikat lain dianggap tidak dijumpai.

Apa yang boleh anda baca

GraphQL menyediakan 16 pertanyaan bacaan: whoami, workOrders, workOrder(id), assets, asset(id), assetDowntimes, meters(assetId), parts, part (mengikut id atau kod bar), stockMovements, locations, vendors, customers, purchaseOrders, purchaseOrder(id | reference | erpReference) dan floorPlans(locationId). Setiap senarai boleh dilalui halaman demi halaman hingga ke penghujung: workOrders, assets, assetDowntimes, meters, parts, purchaseOrders, locations, vendors dan customers semuanya menerima limit (1 hingga 200) serta offset, dan workOrders, assets, parts, purchaseOrders, locations, vendors dan customers juga menerima updatedSince untuk penyegerakan tokokan. Saiz halaman lalai ialah 50 baris, kecuali locations, vendors dan customers, yang mengekalkan nilai lalai lama mereka iaitu 200. Setiap senarai disusun dengan id sebagai pemutus seri, jadi sempadan halaman tidak sesekali melangkau atau mengulang sesuatu baris. stockMovements ialah lejar stok yang menjadi asas penyesuaian rekod anda: ia dibaca dari yang terlama dan dihalamankan dengan afterId — hantar id pergerakan terakhir yang anda terima — yang kekal tepat walaupun pergerakan baharu sedang ditulis, dan since membolehkan anda memulakan pengisian semula data sejarah dari satu tarikh. Perintah kerja dalam Tong Kitar Semula tidak sesekali dipulangkan. purchaseOrders juga boleh ditapis mengikut status dan vendorId; amaun dalam mata wang syarikat, yang dibawa setiap pesanan dalam medan currency.

Sahkan kunci dan baca perintah kerja dalam satu panggilan: curl -X POST https://freemaint.com/api/v1/graphql -H "Authorization: Bearer $FMK" -H "Content-Type: application/json" -d '{"query":"{ whoami { companyId tier } workOrders(limit: 5, status: \"OPEN\") { id reference title status priority dueDate } }"}'

Apa yang boleh anda tulis

Dua belas mutasi: mencipta, mengemas kini dan memadam pada perintah kerja, aset dan alat ganti, serta adjustStock untuk pergerakan inventori bertanda. Kesemuanya berjalan melalui perkhidmatan yang sama seperti yang digunakan oleh aplikasi itu sendiri, jadi rujukan (WO-…, ASS-…, PART-…), baris audit dan pemberitahuan berkelakuan tepat seperti dalam antara muka. Untuk stok, utamakan adjustStock: ia menulis satu baris audit StockMovement dalam transaksi yang sama dan enggan menurunkan quantity ke bawah sifar, manakala updatePart(quantity) menetapkan nilai mutlak dan merekodkan perbezaannya sebagai pelarasan. Pada alat ganti yang stoknya dijejaki mengikut lokasi, hantar locationId kepada adjustStock; di situ updatePart(quantity) ditolak. Yang kesebelas, addMeterReading, merekod bacaan meter melalui perkhidmatan yang sama seperti skrin meter, jadi pencetus meter dan penyelenggaraan pencegahan berasaskan meter bertindak tepat seperti bacaan yang ditaip dalam aplikasi. Yang kedua belas, setPurchaseOrderErpReference, menyimpan nombor dokumen ERP anda pada pesanan belian supaya kedua-dua rekod boleh dipadankan kemudian dengan purchaseOrder(erpReference: …). Ia memerlukan kunci akses FULL dan sengaja tidak mencetuskan sebarang webhook: ERP anda tidak pernah menerima tulisannya sendiri sebagai peristiwa.

Apa yang langsung tidak diliputi oleh API

Skema GraphQL mengandungi perintah kerja, aset, pemberhentian mesin, alat ganti berserta pergerakan stoknya, meter, pesanan belian, lokasi, pembekal, pelanggan dan pelan lantai. Tiada yang lain. Berikut ialah bahagian FreeMaint yang berfungsi sepenuhnya tetapi hari ini TIDAK mempunyai sebarang permukaan API: ia tidak boleh dibaca, ditulis atau dilanggan daripada sesuatu integrasi, dan tiada gabungan pertanyaan sedia ada yang mencapainya.

  • Pemeriksaan — bukan templatnya, bukan larian berjadualnya, bukan keputusan yang direkodkan mahupun kod tindakannya. Tiada pertanyaan pemeriksaan, tiada mutasi pemeriksaan dan tiada peristiwa webhook pemeriksaan.
  • Pengguna, peranan dan pasukan — anda tidak boleh menyenaraikan, mencipta atau menyahaktifkan pengguna melalui API ini. Peruntukan pengguna berlaku di dalam aplikasi; pada pelan Enterprise ia boleh diautomasikan dengan SCIM, iaitu mekanisme berasingan dan bukan sebahagian daripada API ini.
  • Projek — tiada pertanyaan dan tiada mutasi.
  • Permohonan belian — tiada pertanyaan dan tiada mutasi. Pesanan belian boleh dibaca (purchaseOrders, purchaseOrder), ERP anda boleh menulis semula rujukannya (setPurchaseOrderErpReference) dan webhook purchase_order.* mengumumkannya, tetapi pesanan tidak boleh dicipta, diubah atau diterima melalui API: itu kekal dalam aplikasi.
  • Fail, foto dan lampiran — anda tidak boleh memuat naik dokumen atau foto, dan tidak boleh membacanya semula. Foto perintah kerja, imej alat ganti dan bukti pemeriksaan kesemuanya berada di luar API. Sesuatu URL yang muncul dalam respons, seperti imageUrl bagi sesebuah alat ganti, bukanlah laluan muat naik.
  • Jadual penyelenggaraan pencegahan, log masa, tugas dan senarai semak — tidak didedahkan.

Penting

Tentukan skop pembinaan anda berdasarkan senarai ini, bukan berdasarkan apa yang mampu dilakukan oleh produk ini di dalam pelayar. Aplikasi web dan mudah alih FreeMaint sendiri berjalan di atas API REST dalaman yang tidak dapat dicapai oleh kunci API, jadi sesuatu ciri yang kelihatan pada skrin bukanlah bukti bahawa sesebuah penyepaduan boleh memacunya.

Webhook — katalog peristiwa

Webhook ialah bahagian tolak bagi sesebuah penyepaduan: bukannya menyoal berulang kali, FreeMaint menghantar POST ke URL anda sebaik sahaja sesuatu berlaku. Anda mengkonfigurasinya di Tetapan syarikat > Webhook (/company-settings/webhooks) dan melanggankan setiap webhook kepada peristiwa yang anda perlukan. Katalognya ialah satu senarai tetap.

  • work_order.created — sebuah perintah kerja telah dicipta
  • work_order.completed — sebuah perintah kerja telah mencapai status Selesai
  • work_order.status_changed — sesuatu perintah kerja bertukar ke mana-mana status; muatan membawa new_status. Dipicu bersama work_order.completed, yang kekal tidak berubah
  • request.created — sebuah permintaan penyelenggaraan telah dihantar
  • request.status_changed — sebuah permintaan telah diluluskan, ditolak atau dibatalkan
  • part.low_stock — sesuatu alat ganti jatuh ke paras minimumnya atau ke bawah
  • part.out_of_stock — sesuatu alat ganti mencapai sifar; ia peristiwa berasingan, bukan varian low_stock
  • part.low_stock_summary — satu ringkasan harian bagi setiap syarikat yang menyenaraikan alat ganti pada titik pesanan semula atau ke bawah, termasuk yang tidak pernah bergerak
  • part.out_of_stock_summary — ringkasan harian yang sama, untuk alat ganti yang berada pada sifar
  • part.consumed — sesuatu alat ganti telah digunakan pada, atau dipulangkan daripada, sesebuah perintah kerja; quantity bertanda
  • compliance.chain_divergence — rantaian cincangan audit telah terputus (Enterprise)
  • asset.downtime_started — satu pemberhentian mesin telah dibuka
  • asset.downtime_ended — satu pemberhentian mesin telah ditutup; tempohnya kini boleh dikira
  • report.daily_summary — kerja yang selesai pada hari itu, sekali sehari pada jam pilihan anda
  • purchase_order.created — pesanan belian dicipta; muatan membawa pesanan (reference, status, total_cost, currency, expected_date, erp_reference) dan pembekalnya
  • purchase_order.status_changed — status pesanan belian berubah (diluluskan, dipesan, dibatalkan…); muatan membawa previous_status dan new_status
  • purchase_order.received — satu penghantaran telah diterima bagi pesanan pembelian (dihantar untuk setiap penghantaran, termasuk sebahagian); payload menyenaraikan setiap baris dengan quantity_ordered, quantity_received (penghantaran ini), quantity_received_total dan quantity_remaining, serta receipt_id, fully_received dan closed_short; new_status ialah PARTIALLY_RECEIVED selagi barangan masih dijangka dan RECEIVED apabila pesanan lengkap atau ditutup

Amaran

Tiada peristiwa pemeriksaan, dan tiada peristiwa kecacatan atau penemuan. Jika proses anda berbunyi «sesuatu pemeriksaan gagal, lalu ERP saya bertindak balas», tiada apa pun yang tercetus untuknya pada hari ini. Rancanglah jurang itu secara jelas dan bukannya menganggap ada peristiwa yang cukup hampir.

Sampul penghantaran

Setiap penghantaran GENERIC ialah POST yang badannya menggunakan sampul tiga kunci yang sama: event, timestamp dan data, dengan data diindeks mengikut entiti. Tiga pengepala menyertainya. X-FreeMaint-Signature berbentuk t=<saat unix>,v1=<hex>, dengan v1 ialah HMAC-SHA256 bagi rentetan tepat "<t>.<badan mentah>" yang ditandatangani menggunakan rahsia webhook tersebut; X-FreeMaint-Event mengulangi nama peristiwa; X-FreeMaint-Delivery-Id mengenal pasti penghantaran itu. Sahkan tandatangan terhadap badan MENTAH, sebelum sebarang penghuraian — menyirikan semula JSON mengubah baitnya dan tandatangan tidak akan sepadan lagi.

{ "event": "work_order.created", "timestamp": "2026-09-05T08:14:02.371Z", "data": { "work_order": { "id": 5521, "title": "Kebocoran pam #3", "status": "OPEN", "priority": "HIGH", "dueDate": "2026-09-08T00:00:00.000Z" } } }

Kebolehpercayaan dan pemantauan

Sesuatu penghantaran dicuba 3 kali dengan undur eksponen berasaskan 2 saat — lebih kurang 2 saat, kemudian 4 saat, kemudian 8 saat — dan setiap percubaan tamat masa selepas 10 saat. Respons 2xx menandakannya telah dihantar. Respons 5xx dan ralat rangkaian akan dicuba semula. Respons 4xx dianggap sebagai penolakan kekal dan langsung TIDAK dicuba semula: jika titik akhir anda menjawab 400 atau 401 kerana pepijat di pihak anda, penghantaran itu berhenti di situ dan hanya main semula secara manual yang dapat memulihkannya.

  • Setiap penghantaran disimpan: peristiwanya, muatan tepat yang dihantar, statusnya, kod HTTP yang anda pulangkan, kira-kira 500 aksara pertama badan respons anda, bilangan percubaan dan mesej ralatnya.
  • Statusnya ialah PENDING, DELIVERED, FAILED, RATE_LIMITED (had Starter iaitu 100 penghantaran sehari telah dicapai) dan SKIPPED_TIER (pelan itu tidak lagi melayakkan destinasi tersebut).
  • Sesuatu penghantaran yang tersimpan boleh dimain semula daripada sejarah webhook. Muatan yang disimpan dihantar semula tanpa diubah, jadi kunci perniagaan di dalamnya kekal serupa dan penerima yang menyahduplikasi dengan betul tidak akan mencatatnya dua kali.
  • Setiap webhook membawa lastTriggeredAt, lastSuccessAt, lastFailureAt dan satu failureCount, yang sudah memadai untuk pemeriksaan kesihatan tanpa membuka sejarah penuhnya.
  • Senarai webhook dan log penghantarannya boleh dibaca pada semua pelan, jadi penyepaduan yang terhenti akibat penurunan pelan kekal kelihatan dan tidak mati secara senyap.
  • Tiada apa pun yang memberi amaran apabila penghantaran mula gagal — tiada e-mel, tiada pemberitahuan. Jika gangguan senyap akan menjadi masalah, soallah log penghantaran daripada sistem pemantauan anda sendiri.

Keselamatan

URL disahkan semasa anda menyimpan webhook, dan peraturannya sengaja dibuat ketat: webhook ialah permintaan keluar yang dibuat oleh pelayan kami, jadi peraturan yang longgar akan menjadi vektor SSRF.

  • Kunci disimpan sebagai cincangan SHA-256 — nilai mentahnya tidak boleh dipulihkan daripada FreeMaint selepas penciptaan.
  • URL webhook mesti menggunakan https. http biasa dan setiap skema lain ditolak.
  • Hanya port 443 dan 8443 diterima.
  • Hos gelung balik, pautan tempatan dan julat persendirian (127.x, 10.x, 192.168.x, 172.16–31.x, ::1 dan seumpamanya) ditolak: penerima mesti boleh dicapai daripada internet awam. Sistem yang hanya wujud di dalam kilang anda memerlukan geganti awam atau terowong.
  • Kelayakan di dalam URL (https://user:pass@host) ditolak.
  • Ubah hala tidak diikuti — titik akhir yang anda daftarkan ialah titik akhir yang menerima POST.
  • Setiap webhook mempunyai rahsia penandatanganannya sendiri dan terdapat tindakan putar rahsia. Putaran berkuat kuasa serta-merta, jadi laksanakan rahsia baharu di pihak anda dalam tetingkap masa yang sama.
  • Destinasi SLACK dan TEAMS menerima mesej yang diformatkan untuk platform berkenaan dan TIADA pengepala HMAC FreeMaint: bagi kedua-duanya, kerahsiaan URL itulah satu-satunya pengesahan. Gunakan GENERIC untuk apa jua yang perlu anda sahkan secara kriptografi.

Corak yang berfungsi dengan baik pada hari ini

Inilah penyepaduan yang disokong dengan kemas oleh permukaan semasa, berserta butiran yang menjadikan setiap satu selamat dijalankan dalam pengeluaran.

Mencerminkan penggunaan ke dalam ERP

Langganlah part.consumed. quantity bertanda — negatif apabila dikeluarkan kepada kerja, positif apabila dipulangkan — dan muatannya membawa satu stock_movement_id yang kekal stabil merentas percubaan semula dan main semula, jadi gunakannya sebagai kunci idempoten anda. Mutasi adjustStock sengaja TIDAK membangkitkan peristiwa ini, dan itulah yang menghalang tulisan anda sendiri bergema kembali kepada anda dalam satu gelung.

Menolak pembetulan stok masuk

Panggil adjustStock dengan delta bertanda dari pihak anda. Sesebuah kunci READ_STOCK boleh melakukan tepat ini dan tiada yang lain, menjadikannya padanan yang ketat untuk jambatan stok sehala.

Mencipta perintah kerja daripada sistem lain

createWorkOrder daripada penggera SCADA, tiket meja bantuan atau notis kerosakan daripada ERP. Perintah kerja itu menerima rujukan biasanya dan membangkitkan work_order.created seperti mana-mana yang lain.

Mengekalkan katalog alat ganti sentiasa selaras

parts(updatedSince:) hanya memulangkan apa yang berubah sejak saat yang anda pilih. createPart dan updatePart menerima customReference — kod anda sendiri bagi alat ganti itu — dan part(barcode:) kemudian memadankannya, jadi anda boleh mencari alat ganti melalui pengecam yang telah pun digunakan oleh ERP anda. Keunikannya tidak dikuatkuasakan; andalah yang perlu menjaminnya.

Menutup gelung apabila kerja selesai

work_order.completed membawa perintah kerja itu berserta status sebelumnya, yang sudah memadai untuk menutup notis penyelenggaraan di sebelah sana.

Pelan yang anda perlukan

Dua pintu yang berasingan: satu untuk API, satu untuk webhook. Syarikat pada pelan Starter boleh menerima webhook tanpa mempunyai API.

API GraphQL dan kunci API

Business dan ke atas. Core dan Starter langsung tidak boleh mencipta kunci.

Kuota harian

5,000 panggilan sehari pada Business, 100,000 pada Enterprise. Dikira mengikut syarikat dan mengikut operasi, ditetapkan semula pada 00:00 UTC — menggabungkan beberapa operasi ke dalam satu permintaan HTTP menjimatkan perjalanan pergi-balik, bukan kuota.

Webhook

Starter dan ke atas, dihadkan kepada 100 penghantaran sehari; tanpa had mulai Business.

Destinasi Slack dan Teams

Enterprise. Webhook generik tersedia mulai Starter.

Petua

Merancang sesuatu yang terlanggar salah satu jurang di atas? Beritahu kami apa yang sedang anda bina di contact@freemaint.com. Keupayaan mana yang keluar seterusnya ditentukan oleh apa yang benar-benar menyekat pelanggan.

Adakah halaman ini membantu?