ERP ও অন্যান্য সিস্টেমের সঙ্গে ইন্টিগ্রেশন গাইড

তৈরি করার আগে ইন্টিগ্রেশনের পরিধি নির্ধারণ করুন: API কী কী নাগালে পায়, কী পায় না, আর সীমারেখা কোথায়

9 মিনিট পড়ার সময়
এই বিভাগটি প্রিন্ট করুন

এই গাইডটি সেই ডেভেলপারের জন্য, যিনি FreeMaint-এর সঙ্গে অন্য কোনো সিস্টেমের — একটি ERP, একটি SCADA হিস্টোরিয়ান, একটি গুদাম বা হিসাবরক্ষণ প্যাকেজের — ইন্টিগ্রেশনের পরিধি ঠিক করছেন। এই বিভাগের অন্য নিবন্ধগুলো বলে কীভাবে কল করতে হয়; এটি ইচ্ছাকৃতভাবে সীমারেখা নিয়ে। কারণ ব্যয়বহুল ভুলটি কখনোই ভুল হেডার নয় — বরং কাজের মাঝপথে আবিষ্কার করা যে আপনি যে সক্ষমতা ধরে নিয়েছিলেন তা আসলে নেই। নিচের প্রতিটি সীমাবদ্ধতা ইচ্ছে করেই লেখা হয়েছে।

একটি কী, তিনটি দরজা

একটি API কী (এটি fmk_ দিয়ে শুরু হয়) একজন অ্যাডমিন কোম্পানি সেটিংস > API (/company-settings/api)-তে তৈরি করেন, অথবা কেউ নিজের জন্য প্রোফাইল > নিরাপত্তা > API কী-তে তৈরি করেন, এবং এটি Authorization: Bearer fmk_... আকারে পাঠানো হয়। এটি ঠিক তিনটি জিনিস প্রমাণীকরণ করে: POST /api/v1/graphql-এ থাকা GraphQL এন্ডপয়েন্ট, এনার্জি ইনজেস্ট এন্ডপয়েন্ট, এবং /public-api/whoami ও /public-api/ping। এটি /api/v1/{resource}-এর অধীন REST রুটগুলো প্রমাণীকরণ করে না — ওগুলো অ্যাপ্লিকেশনের নিজস্ব API এবং সেগুলোর জন্য ব্যবহারকারীর সেশন (JWT) লাগে। আপনার ইন্টিগ্রেশন GraphQL-এর উপর গড়ুন: কী যে পৃষ্ঠতলে পৌঁছায়, সেটিই।

একটি API কী আপনাকে যা দেয়

কাঁচা কী কেবল একবারই, তৈরির সময়, দেখানো হয় এবং তারপর আর কখনোই উদ্ধার করা যায় না: কেবল একটি SHA-256 হ্যাশ সংরক্ষিত হয়, সঙ্গে fmk_-এর পরের ৬টি অক্ষর, যাতে তালিকায় কী-টি পর্দায় চেনা যায়।

নাম

মানুষের পড়ার মতো একটি লেবেল — 'Oracle ERP ব্রিজ', 'লাইন ২ কিয়স্ক'। প্রতিটি ব্যবহারকারী সিস্টেমের জন্য আলাদা কী ইস্যু করুন, যাতে একটি বাতিল করলে বাকিগুলোতে হাত না পড়ে।

অ্যাক্সেস স্তর

READ, READ_STOCK বা FULL — মালিকের অনুমতির ওপর একটি ক্রমানুসারী স্তরবিন্যাস। READ কেবল কোয়েরি চালায় এবং এটিই ডিফল্ট। READ_STOCK এর সঙ্গে adjustStock মিউটেশন যোগ করে। FULL মালিকের ভূমিকা যে সব অপারেশনের অনুমতি দেয় তার সবই অনুমোদন করে — তৈরি, হালনাগাদ ও মুছে ফেলা সহ — এবং মালিক শক্তির রিডিং তৈরি করতে পারলে এনার্জি ইনজেস্ট এন্ডপয়েন্টও।

মেয়াদ

expiresAt ঐচ্ছিক। ওই মুহূর্তের পর কী আর প্রমাণীকরণ করে না। স্থায়ী সার্ভিস ইন্টিগ্রেশনের জন্য ফাঁকা রাখুন; ঠিকাদার বা পাইলটের জন্য নির্ধারণ করুন।

বাতিলকরণ

isActive হলো প্রতিটি কী-এর নিজস্ব সুইচ, যা কয়েক সেকেন্ডের মধ্যে কার্যকর হয়। নিরীক্ষার জন্য সারিটি রেখে দেওয়া হয়, তাই বাতিল করা কী মুছে না গিয়ে অনুসন্ধানযোগ্য থাকে।

সর্বশেষ ব্যবহার

lastUsedAt সর্বশেষ প্রমাণীকৃত কলটি নথিভুক্ত করে — কোন কী আর কেউ ব্যবহার করছে না তা ধরার জন্য যথেষ্ট।

মালিক

যে ব্যক্তির হয়ে কী কাজ করে। প্রতিটি কল তাঁর অনুমতি ও ডেটা দেখার পরিসর বহন করে, এবং কী যা লেখে তাতে তাঁর নামই স্বাক্ষর হিসেবে থাকে। ERP-এর জন্য একটি নিবেদিত ব্যবহারকারী তৈরি করুন — “ERP ইন্টিগ্রেশন” — এমন একটি ভূমিকা দিয়ে যা ব্রিজের ঠিক যতটুকু দরকার ততটুকুই কভার করে, এবং কী-টি তাকেই দিন।

একটি API কী আপনাকে যা দেয় না

এগুলো বর্তমান বাস্তবায়নের প্রকৃত সীমাবদ্ধতা, এই পাতার বাদ পড়া অংশ নয়। আপনার নিরাপত্তা পর্যালোচনা যদি এগুলোর কোনোটির উপর নির্ভর করে, তবে নির্মাণের পরে নয় — এখনই সেই অনুযায়ী নকশা করুন।

  • প্রতি কী-এর জন্য কোনো মডিউল তালিকা নেই। একটি কী তার মালিকের ভূমিকা যা অনুমোদন করে তা-ই পড়ে ও লেখে — পরিসর সংকুচিত করতে, কী-টি এমন মালিককে দিন যাঁর ভূমিকা সংকীর্ণতর। এর ওপরে শুধু তিনটি অ্যাক্সেস স্তর প্রযোজ্য: কী-এর মধ্যেই আপনি সেটি কোন কোন মডিউল ব্যবহার করতে পারবে তা তালিকাভুক্ত করতে পারবেন না।
  • কোনো IP অনুমোদন-তালিকা নেই। একটি কী ইন্টারনেটের যেকোনো জায়গা থেকে বৈধ। একে গোপন তথ্য হিসেবেই গণ্য করুন: ভল্ট বা আপনার প্ল্যাটফর্মের সিক্রেট স্টোর — কখনোই রিপোজিটরি, শেয়ার্ড ড্রাইভ বা সাপোর্ট টিকিট নয়।
  • প্রতি কী-এর কোনো ব্যবহার-লগ নেই। কেবল lastUsedAt রাখা হয়। প্রতি কী-এর কল ইতিহাস নেই, প্রতি কী-এর কোটা নেই, এবং কোন কী কোন কাজটি করেছে তার কোনো নথি নেই। দৈনিক কোটার গণনা কোম্পানিভিত্তিক এবং সব কী মিলে ভাগ করে নেয়, তাই একটি বেসামাল ইন্টিগ্রেশন বাকি সবার কোটা নিঃশেষ করে দিতে পারে।
  • অন্যের পক্ষে অনুমোদন নয়। মালিক নিজে পারলেও কোনো কী কখনো ওয়ার্কফ্লো ধাপ অনুমোদন করে না: অনুমোদন অ্যাপে মানুষেরই কাজ হয়ে থাকে।
  • প্রতি কী-তে একটি কোম্পানি। কী যে কোম্পানিতে তৈরি হয়েছে তার সঙ্গেই বাঁধা এবং অন্য কোম্পানির ডেটায় পৌঁছাতে পারে না: অন্য কোম্পানির কোনো রেকর্ড কেবল পাওয়া যায় না।

আপনি যা পড়তে পারেন

GraphQL 16টি পঠন-কোয়েরি উন্মুক্ত করে: whoami, workOrders, workOrder(id), assets, asset(id), assetDowntimes, meters(assetId), parts, part (id বা বারকোড দিয়ে), stockMovements, locations, vendors, customers, purchaseOrders, purchaseOrder(id | reference | erpReference) এবং floorPlans(locationId)। প্রতিটি তালিকা শেষ পর্যন্ত পাতায় পাতায় পড়া যায়: workOrders, assets, assetDowntimes, meters, parts, purchaseOrders, locations, vendors ও customers — সবগুলোই limit (1 থেকে 200) সঙ্গে offset নেয়, এবং workOrders, assets, parts, purchaseOrders, locations, vendors ও customers ইনক্রিমেন্টাল সিঙ্কের জন্য updatedSince-ও নেয়। ডিফল্ট পাতা 50 সারির; ব্যতিক্রম কেবল locations, vendors ও customers, যেগুলো তাদের আগের ডিফল্ট 200 ধরে রাখে। প্রতিটি তালিকার ক্রমে সমান মানের সারিগুলোর মধ্যে id দিয়ে নিষ্পত্তি করা হয়, তাই পাতার সীমানায় কোনো সারি কখনো বাদ পড়ে না বা দুবার আসে না। stockMovements হলো সেই স্টক খতিয়ান, যার ভিত্তিতে আপনি হিসাব মেলান: এটি পুরোনো থেকে নতুন ক্রমে পড়া হয় এবং afterId দিয়ে পাতা বদলায় — সর্বশেষ প্রাপ্ত চলাচলের id দিন —, যা নতুন চলাচল লেখা চলতে থাকলেও নির্ভুল থাকে, আর since দিয়ে একটি নির্দিষ্ট তারিখ থেকে পুরোনো ডেটা টেনে আনা শুরু করা যায়। আবর্জনায় থাকা কাজের নির্দেশনা কখনো ফেরত দেওয়া হয় না। purchaseOrders status ও vendorId দিয়েও ছাঁকা যায়; অঙ্কগুলো কোম্পানির মুদ্রায় থাকে, যা প্রতিটি ক্রয়াদেশ currency ঘরে বহন করে।

একটি কলেই কী যাচাই করুন এবং কাজের নির্দেশনা পড়ুন: 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 } }"}'

আপনি যা লিখতে পারেন

বারোটি মিউটেশন: কাজের নির্দেশনা, সম্পদ ও যন্ত্রাংশে তৈরি, হালনাগাদ ও মুছে ফেলা, সেই সঙ্গে চিহ্নযুক্ত মজুত-চলাচলের জন্য adjustStock। এগুলো ঠিক সেই সার্ভিসগুলোর মধ্য দিয়েই যায় যেগুলো অ্যাপ্লিকেশন নিজে ব্যবহার করে, তাই রেফারেন্স (WO-…, ASS-…, PART-…), নিরীক্ষা সারি ও বিজ্ঞপ্তি ইন্টারফেসের মতোই আচরণ করে। মজুতের ক্ষেত্রে adjustStock-কেই প্রাধান্য দিন: এটি একই লেনদেনে একটি StockMovement নিরীক্ষা সারি লেখে এবং পরিমাণ শূন্যের নিচে নামাতে অস্বীকার করে, যেখানে updatePart(quantity) একটি পরম মান বসায় এবং পার্থক্যটিকে একটি সমন্বয় হিসেবে লিখে রাখে। যে যন্ত্রাংশের মজুত অবস্থান অনুযায়ী রাখা হয়, সেখানে adjustStock-এ locationId দিন; সেখানে updatePart(quantity) প্রত্যাখ্যাত হয়। একাদশটি, addMeterReading, মিটার স্ক্রিনের একই সার্ভিসের মাধ্যমে মিটার রিডিং রেকর্ড করে, তাই মিটার ট্রিগার ও মিটার-ভিত্তিক প্রতিরোধমূলক রক্ষণাবেক্ষণ অ্যাপে লেখা রিডিংয়ের মতোই সাড়া দেয়। দ্বাদশটি, setPurchaseOrderErpReference, আপনার ERP-এর নথি নম্বর একটি ক্রয়াদেশে সংরক্ষণ করে, যাতে পরে purchaseOrder(erpReference: …) দিয়ে দুটি রেকর্ড মেলানো যায়। এর জন্য FULL অ্যাক্সেসের কী লাগে এবং এটি ইচ্ছাকৃতভাবে কোনো webhook চালু করে না: আপনার ERP কখনো নিজের লেখা ইভেন্ট হিসেবে পায় না।

API যা মোটেই আওতাভুক্ত করে না

GraphQL স্কিমায় আছে কাজের নির্দেশনা, সম্পদ, যন্ত্র বন্ধ, যন্ত্রাংশ ও তাদের স্টক চলাচল, মিটার, ক্রয়াদেশ, অবস্থান, সরবরাহকারী, গ্রাহক ও ফ্লোর প্ল্যান। এর বাইরে কিছু নয়। নিচেরগুলি FreeMaint-এর পুরোপুরি কার্যকর অংশ, অথচ আজ এগুলির কোনো API পৃষ্ঠ নেই: কোনো ইন্টিগ্রেশন থেকে এগুলি পড়া, লেখা বা সাবস্ক্রাইব করা যায় না, এবং বিদ্যমান কোয়েরির কোনো সমন্বয়েই এগুলিতে পৌঁছানো যায় না।

  • পরিদর্শন — টেমপ্লেট, নির্ধারিত রান, নথিভুক্ত ফলাফল কিংবা অ্যাকশন কোড, কোনোটিই নয়। পরিদর্শনের কোনো কোয়েরি নেই, কোনো মিউটেশন নেই এবং কোনো ওয়েবহুক ইভেন্টও নেই।
  • ব্যবহারকারী, ভূমিকা ও দল — এই API দিয়ে আপনি কোনো ব্যবহারকারীর তালিকা করতে, তৈরি করতে বা নিষ্ক্রিয় করতে পারবেন না। ব্যবহারকারী প্রভিশনিং অ্যাপেই হয়; Enterprise প্ল্যানে SCIM দিয়ে তা স্বয়ংক্রিয় করা যায়, যা একটি পৃথক ব্যবস্থা এবং এই API-এর অংশ নয়।
  • প্রকল্প — কোনো কোয়েরি নেই, কোনো মিউটেশনও নেই।
  • ক্রয়ের অনুরোধ — কোনো কোয়েরি নেই, কোনো মিউটেশনও নেই। ক্রয়াদেশ পড়া যায় (purchaseOrders, purchaseOrder), আপনার ERP সেগুলোতে নিজের রেফারেন্স লিখে দিতে পারে (setPurchaseOrderErpReference) এবং purchase_order.* webhook সেগুলোর খবর দেয়, কিন্তু API দিয়ে কোনো ক্রয়াদেশ তৈরি, সম্পাদনা বা গ্রহণ করা যায় না: সেটি অ্যাপেই থাকে।
  • ফাইল, ছবি ও সংযুক্তি — আপনি কোনো নথি বা ছবি আপলোড করতে পারবেন না, আবার সেগুলো পড়েও আনতে পারবেন না। কাজের নির্দেশনার ছবি, যন্ত্রাংশের ছবি ও পরিদর্শনের প্রমাণ — সবই API-এর বাইরে। প্রতিক্রিয়ায় দেখা কোনো URL, যেমন একটি যন্ত্রাংশের imageUrl, আপলোডের পথ নয়।
  • প্রতিরোধমূলক রক্ষণাবেক্ষণের সূচি, সময়ের হিসাব, কাজ ও চেকলিস্ট — উন্মুক্ত নয়।

গুরুত্বপূর্ণ

আপনার নির্মাণের পরিধি এই তালিকা ধরে ঠিক করুন, ব্রাউজারে পণ্যটি যা করে তা ধরে নয়। FreeMaint-এর নিজের ওয়েব ও মোবাইল অ্যাপ চলে একটি অভ্যন্তরীণ REST API-এর উপর, যেখানে API কী পৌঁছাতে পারে না; তাই পর্দায় কোনো বৈশিষ্ট্য দেখা যাওয়া মানেই এই নয় যে কোনো ইন্টিগ্রেশন সেটি চালাতে পারবে।

ওয়েবহুক — ইভেন্ট ক্যাটালগ

ওয়েবহুক হলো ইন্টিগ্রেশনের 'পুশ' অংশ: আপনি বারবার জিজ্ঞেস করার বদলে, কিছু ঘটামাত্র FreeMaint আপনার URL-এ POST পাঠায়। কোম্পানি সেটিংস > Webhooks (/company-settings/webhooks)-এ এগুলো কনফিগার করুন এবং প্রতিটি ওয়েবহুককে প্রয়োজনীয় ইভেন্টে সাবস্ক্রাইব করান। ক্যাটালগটি একটি নির্দিষ্ট তালিকা।

  • work_order.created — একটি কাজের নির্দেশনা তৈরি হয়েছে
  • work_order.completed — একটি কাজের নির্দেশনা সম্পন্ন অবস্থায় পৌঁছেছে
  • work_order.status_changed — একটি কাজের নির্দেশনা যেকোনো স্ট্যাটাসে গেছে; পেলোডে new_status থাকে। অপরিবর্তিত work_order.completed-এর পাশাপাশি এটিও ট্রিগার হয়
  • request.created — একটি রক্ষণাবেক্ষণ অনুরোধ জমা পড়েছে
  • request.status_changed — একটি অনুরোধ অনুমোদিত, প্রত্যাখ্যাত বা বাতিল হয়েছে
  • part.low_stock — একটি যন্ত্রাংশ তার ন্যূনতম সীমায় বা তার নিচে নেমেছে
  • part.out_of_stock — একটি যন্ত্রাংশ শূন্যে পৌঁছেছে; এটি পৃথক ইভেন্ট, low_stock-এর কোনো রূপভেদ নয়
  • part.low_stock_summary — প্রতি কোম্পানিতে দিনে একটি সারসংক্ষেপ, যাতে পুনঃক্রয় সীমায় বা তার নিচে থাকা যন্ত্রাংশগুলি থাকে — যেগুলি কখনও নড়েনি সেগুলিও
  • part.out_of_stock_summary — শূন্যে থাকা যন্ত্রাংশের জন্য সেই একই দৈনিক সারসংক্ষেপ
  • part.consumed — একটি কাজের নির্দেশনায় যন্ত্রাংশ ব্যবহৃত হয়েছে, বা সেখান থেকে ফেরত এসেছে; quantity চিহ্নযুক্ত
  • compliance.chain_divergence — নিরীক্ষার হ্যাশ-চেইন ভেঙেছে (Enterprise)
  • asset.downtime_started — একটি যন্ত্র বন্ধের রেকর্ড খোলা হয়েছে
  • asset.downtime_ended — একটি যন্ত্র বন্ধের রেকর্ড বন্ধ করা হয়েছে; সময়কাল এখন হিসাবে তোলা যাবে
  • report.daily_summary — দিনের সম্পন্ন কাজ, আপনার বেছে নেওয়া সময়ে দিনে একবার
  • purchase_order.created — একটি ক্রয়াদেশ তৈরি হয়েছে; পেলোডে ক্রয়াদেশটি (reference, status, total_cost, currency, expected_date, erp_reference) ও তার সরবরাহকারী থাকে
  • purchase_order.status_changed — একটি ক্রয়াদেশের স্ট্যাটাস বদলেছে (অনুমোদিত, অর্ডার করা, বাতিল…); পেলোডে previous_status ও new_status থাকে
  • purchase_order.received — একটি ক্রয় আদেশের বিপরীতে একটি ডেলিভারি গ্রহণ করা হয়েছে (আংশিকসহ প্রতিটি ডেলিভারিতে পাঠানো হয়); পেলোডে প্রতিটি লাইন quantity_ordered, quantity_received (এই ডেলিভারি), quantity_received_total ও quantity_remaining সহ তালিকাভুক্ত থাকে, সঙ্গে receipt_id, fully_received ও closed_short; পণ্য প্রত্যাশিত থাকা পর্যন্ত new_status হলো PARTIALLY_RECEIVED এবং সম্পূর্ণ বা বন্ধ হলে RECEIVED

সতর্কতা

পরিদর্শনের কোনো ইভেন্ট নেই, ত্রুটি বা পর্যবেক্ষণেরও কোনো ইভেন্ট নেই। আপনার প্রক্রিয়াটি যদি হয় 'একটি পরিদর্শন ব্যর্থ হলে আমার ERP সাড়া দেবে', তবে আজ তার জন্য কিছুই চালু হয় না। কাছাকাছি কোনো ইভেন্ট আছে ধরে না নিয়ে এই ঘাটতির জন্য স্পষ্টভাবে পরিকল্পনা করুন।

ডেলিভারি এনভেলপ

প্রতিটি GENERIC ডেলিভারি এমন একটি POST যার বডি সেই একই তিন-কী এনভেলপ: event, timestamp এবং data — যেখানে data সত্তা অনুযায়ী সাজানো। এর সঙ্গে তিনটি হেডার যায়। X-FreeMaint-Signature-এর রূপ t=<ইউনিক্স সেকেন্ড>,v1=<hex>, যেখানে v1 হলো ঠিক "<t>.<কাঁচা বডি>" স্ট্রিংটির HMAC-SHA256, ওই ওয়েবহুকের সিক্রেট দিয়ে স্বাক্ষরিত; X-FreeMaint-Event ইভেন্টের নাম পুনরাবৃত্তি করে; X-FreeMaint-Delivery-Id ডেলিভারিটি শনাক্ত করে। স্বাক্ষর যাচাই করুন কাঁচা বডির বিপরীতে, পার্স করার আগে — JSON পুনরায় সিরিয়ালাইজ করলে বাইট বদলে যায় এবং স্বাক্ষর আর মিলবে না।

{ "event": "work_order.created", "timestamp": "2026-09-05T08:14:02.371Z", "data": { "work_order": { "id": 5521, "title": "৩ নম্বর পাম্পে লিক", "status": "OPEN", "priority": "HIGH", "dueDate": "2026-09-08T00:00:00.000Z" } } }

নির্ভরযোগ্যতা ও পর্যবেক্ষণ

একটি ডেলিভারি ২ সেকেন্ড ভিত্তিক সূচকীয় ব্যাকঅফসহ ৩ বার চেষ্টা করা হয় — মোটামুটি ২ সে., তারপর ৪ সে., তারপর ৮ সে. — এবং প্রতিটি চেষ্টা ১০ সেকেন্ড পর টাইম আউট হয়। ২xx এলে সেটি ডেলিভার হিসেবে চিহ্নিত হয়। ৫xx প্রতিক্রিয়া ও নেটওয়ার্ক ত্রুটি পুনরায় চেষ্টা করা হয়। ৪xx-কে স্থায়ী প্রত্যাখ্যান ধরা হয় এবং একেবারেই পুনরায় চেষ্টা করা হয় না: আপনার প্রান্তে কোনো ত্রুটির কারণে এন্ডপয়েন্ট যদি ৪০০ বা ৪০১ দেয়, ওই ডেলিভারি সেখানেই থেমে যায় এবং কেবল হাতে করে পুনঃপ্রেরণ করলেই তা উদ্ধার হবে।

  • প্রতিটি ডেলিভারি সংরক্ষিত হয়: ইভেন্ট, ঠিক যে পেলোডটি পাঠানো হয়েছিল, স্ট্যাটাস, আপনি যে HTTP কোড ফেরত দিয়েছেন, আপনার প্রতিক্রিয়া বডির প্রথম ~৫০০ অক্ষর, চেষ্টার সংখ্যা এবং ত্রুটির বার্তা।
  • স্ট্যাটাসগুলো হলো PENDING, DELIVERED, FAILED, RATE_LIMITED (দিনে ১০০ ডেলিভারির Starter সীমায় পৌঁছে গেছে) এবং SKIPPED_TIER (সাবস্ক্রিপশন আর ওই গন্তব্যের অধিকার দেয় না)।
  • সংরক্ষিত যেকোনো ডেলিভারি ওয়েবহুকের ইতিহাস থেকে পুনরায় চালানো যায়। এটি সংরক্ষিত পেলোড অপরিবর্তিত অবস্থায় আবার পাঠায়, তাই ভেতরের ব্যবসায়িক কী-গুলো একই থাকে এবং যে গ্রাহক ঠিকমতো ডিডুপ্লিকেট করে সে দুবার হিসাব করবে না।
  • প্রতিটি ওয়েবহুক বহন করে lastTriggeredAt, lastSuccessAt, lastFailureAt এবং failureCount — পুরো ইতিহাস না খুলেই স্বাস্থ্য পরীক্ষার জন্য যা যথেষ্ট।
  • ওয়েবহুকের তালিকা ও তার ডেলিভারি লগ সব প্ল্যানেই পড়া যায়, তাই প্ল্যান কমার কারণে থেমে যাওয়া ইন্টিগ্রেশন নীরবে মরে না গিয়ে চোখে পড়ে।
  • ডেলিভারি ব্যর্থ হতে শুরু করলে কিছুই আপনাকে সতর্ক করে না — কোনো ইমেইল নয়, কোনো বিজ্ঞপ্তিও নয়। নীরব বিভ্রাট যদি সমস্যা হয়, তবে নিজের পর্যবেক্ষণ ব্যবস্থা থেকেই ডেলিভারি লগ পড়ে নিন।

নিরাপত্তা

আপনি ওয়েবহুক সংরক্ষণ করার সময়েই URL যাচাই করা হয়, আর নিয়মগুলো ইচ্ছাকৃতভাবেই কড়া: ওয়েবহুক হলো আমাদের সার্ভার থেকে যাওয়া একটি বহির্গামী অনুরোধ, তাই শিথিল নিয়ম হতো একটি SSRF ভেক্টর।

  • কী সংরক্ষিত হয় SHA-256 হ্যাশ হিসেবে — তৈরির পর FreeMaint থেকে কাঁচা মান আর উদ্ধার করা যায় না।
  • ওয়েবহুক URL অবশ্যই https হতে হবে। সাধারণ http এবং অন্য সব স্কিম প্রত্যাখ্যাত।
  • কেবল ৪৪৩ ও ৮৪৪৩ পোর্ট গ্রহণ করা হয়।
  • লুপব্যাক, লিংক-লোকাল ও ব্যক্তিগত পরিসরের হোস্ট (127.x, 10.x, 192.168.x, 172.16–31.x, ::1 এবং অনুরূপ) প্রত্যাখ্যাত: গ্রাহককে অবশ্যই পাবলিক ইন্টারনেট থেকে নাগালযোগ্য হতে হবে। যে সিস্টেম কেবল আপনার কারখানার ভেতরেই আছে, তার জন্য একটি পাবলিক রিলে বা টানেল দরকার।
  • URL-এর ভেতরে ক্রেডেনশিয়াল (https://user:pass@host) প্রত্যাখ্যাত।
  • রিডাইরেক্ট অনুসরণ করা হয় না — আপনি যে এন্ডপয়েন্ট নিবন্ধন করেন, সেটিই POST পায়।
  • প্রতিটি ওয়েবহুকের নিজস্ব স্বাক্ষর-সিক্রেট থাকে এবং সিক্রেট ঘোরানোর একটি ব্যবস্থা আছে। ঘোরানো সঙ্গে সঙ্গে কার্যকর হয়, তাই একই সময়সীমার মধ্যে নতুন সিক্রেটটি নিজের প্রান্তে স্থাপন করুন।
  • SLACK ও TEAMS গন্তব্য প্ল্যাটফর্ম-অনুযায়ী সাজানো বার্তা পায় এবং FreeMaint-এর কোনো HMAC হেডার পায় না: ওগুলোর ক্ষেত্রে URL-এর গোপনীয়তাই একমাত্র প্রমাণীকরণ। যা কিছু ক্রিপ্টোগ্রাফিকভাবে যাচাই করা দরকার, তার জন্য GENERIC ব্যবহার করুন।

আজ যেসব ধরন ভালো কাজ করে

বর্তমান পৃষ্ঠতল যেসব ইন্টিগ্রেশন পরিচ্ছন্নভাবে সমর্থন করে, এবং যে খুঁটিনাটি প্রতিটিকে প্রোডাকশনে নিরাপদ করে তোলে।

ERP-তে ব্যবহারের প্রতিফলন

part.consumed-এ সাবস্ক্রাইব করুন। quantity চিহ্নযুক্ত — কাজে ইস্যু করলে ঋণাত্মক, ফেরত এলে ধনাত্মক — আর পেলোডে থাকে একটি stock_movement_id, যা পুনঃচেষ্টা ও পুনঃপ্রেরণ জুড়ে অপরিবর্তিত থাকে; তাই একেই আপনার আইডেমপোটেন্সি কী হিসেবে ব্যবহার করুন। adjustStock মিউটেশন ইচ্ছাকৃতভাবেই এই ইভেন্ট তোলে না, আর সেটিই আপনার নিজের লেখাগুলোকে প্রতিধ্বনি হয়ে ফিরে এসে অন্তহীন চক্র তৈরি করা থেকে ঠেকায়।

মজুতের সংশোধন ভেতরে পাঠানো

আপনার দিক থেকে চিহ্নযুক্ত ডেল্টা দিয়ে adjustStock কল করুন। একটি READ_STOCK কী কিছু তৈরি, হালনাগাদ বা মুছে ফেলার ক্ষমতা ছাড়াই ঠিক এই কাজটি করতে পারে, যা একমুখী স্টক সেতুর জন্য নিখুঁতভাবে মানানসই।

অন্য সিস্টেম থেকে কাজের নির্দেশনা তৈরি

একটি SCADA অ্যালার্ম, হেল্পডেস্ক টিকিট বা ERP-র ব্রেকডাউন নোটিশ থেকে createWorkOrder চালান। কাজের নির্দেশনাটি তার স্বাভাবিক রেফারেন্স পায় এবং বাকি সবার মতোই work_order.created তোলে।

যন্ত্রাংশের ক্যাটালগ মিলিয়ে রাখা

parts(updatedSince:) কেবল আপনার বেছে নেওয়া মুহূর্তের পর যা বদলেছে তা-ই ফেরত দেয়। createPart ও updatePart গ্রহণ করে customReference — যন্ত্রাংশটির জন্য আপনার নিজের কোড — আর তারপর part(barcode:) সেটির সঙ্গেই মেলায়; ফলে আপনার ERP-তে ইতিমধ্যে ব্যবহৃত শনাক্তকারী দিয়েই যন্ত্রাংশ খুঁজে নিতে পারবেন। এর স্বতন্ত্রতা বাধ্যতামূলক করা হয় না; সেটি নিশ্চিত করার দায়িত্ব আপনার।

সমাপ্তিতে বৃত্ত সম্পূর্ণ করা

work_order.completed কাজের নির্দেশনাটি এবং তার আগের স্ট্যাটাস বহন করে, যা অপর প্রান্তে একটি রক্ষণাবেক্ষণ নোটিশ বন্ধ করার জন্য যথেষ্ট।

আপনার যে প্ল্যান দরকার

দুটি আলাদা ফটক: একটি API-এর, আরেকটি ওয়েবহুকের। Starter প্ল্যানের কোনো কোম্পানি API ছাড়াই ওয়েবহুক পেতে পারে।

GraphQL API ও API কী

Business ও তার উপরে। Core ও Starter কোনোভাবেই কী তৈরি করতে পারে না।

দৈনিক কোটা

Business-এ দিনে ৫,০০০ কল, Enterprise-এ ১,০০,০০০। গণনা হয় প্রতি কোম্পানি ও প্রতি অপারেশন অনুযায়ী, রিসেট হয় ০০:০০ UTC-তে — একাধিক অপারেশন এক HTTP অনুরোধে জড়ো করলে যাতায়াত বাঁচে, কোটা নয়।

ওয়েবহুক

Starter ও তার উপরে, দিনে ১০০ ডেলিভারিতে সীমাবদ্ধ; Business থেকে সীমাহীন।

Slack ও Teams গন্তব্য

Enterprise। একটি সাধারণ ওয়েবহুক Starter থেকেই পাওয়া যায়।

টিপ

উপরের কোনো ঘাটতিতে গিয়ে আটকে যাচ্ছে এমন কিছু পরিকল্পনা করছেন? আপনি কী বানাচ্ছেন তা contact@freemaint.com-এ জানান। পরবর্তীতে কোন সক্ষমতা আসবে তা ঠিক হয় গ্রাহকেরা আসলে কোথায় আটকে আছেন তার ভিত্তিতে।

এই পেজটি কি সহায়ক ছিল?