قبل أن تبدؤوا
تعمل واجهة برمجة التطبيقات دون حساب عبر جلسة ضيف. واجهة برمجة التطبيقات في عنوان الموقع الخاص تحت /api. اضبطوه مرة واحدة:
API=https://dev.uliketechnology.com/api
F=board.zip
board.zip هو zip مسطح لملفات Gerber والحفر الخاصة بكم. لما يدخل فيه، راجعوا ملفات للتصنيع والتجميع. الأمثلة تحتاج curl وjq.
كل طلب إلى واجهة برمجة التطبيقات بعد جلسة الضيف يأخذ Authorization: Bearer <token>. كل خطأ له الشكل نفسه:
{ "error": { "code": "VALIDATION_FAILED", "message": "…", "details": {}, "requestId": "…" } }
تفرّعوا على code. message للمطورين.
- جلسة ضيف: يُظهر الرمز مرة واحدة.
- الرفع:
PUTzip إلى العنوان الذي تسمّيه واجهة برمجة التطبيقات، بالرؤوس التي تسمّيها. - الإكمال، ثم الاستقصاء حتى ينتهي التحليل.
- التقرير: الملاحظات، أي عمليات فحص عملت وأيها لم تعمل.
- معاينة عرض السعر.
التدفق مع curl
اقرؤوا ما يمكن طلبه. هذا لا يحتاج رمزًا:
curl -s $API/v1/capabilities | jq '.options[].id'
افتحوا جلسة ضيف. يُظهر الرمز مرة واحدة ويدوم 30 يومًا:
T=$(curl -s -X POST $API/v1/guest-sessions | jq -r .token)
أعلنوا الملف. الإجابة فيها uploadId وdesignId وuploadUrl وrequiredHeaders:
J=$(curl -s -X POST $API/v1/uploads -H "authorization: Bearer $T" -H 'content-type: application/json' \
-d "{\"fileName\":\"board.zip\",\"sizeBytes\":$(stat -c %s $F),\"sha256\":\"$(sha256sum $F | cut -d' ' -f1)\",\"purpose\":\"design\"}")
أرسلوا الملف إلى العنوان الذي تسمّيه الإجابة، مع كل رأس في requiredHeaders (نوع المحتوى والطول والمجموع الاختباري؛ دونها يُرفض الرفع بـ 403). ثم أكملوا الرفع:
curl -s -X PUT --data-binary @$F \
$(echo $J | jq -r '.requiredHeaders | to_entries[] | "-H \(.key):\(.value)"') \
"$(echo $J | jq -r .uploadUrl)"
curl -s -X POST $API/v1/uploads/$(echo $J | jq -r .uploadId)/complete -H "authorization: Bearer $T" | jq .design.status
الحالة هي analysing في البداية. اقرؤوا التصميم حتى يتغير. عندما يكون ready، التقرير في الإجابة:
D=$(echo $J | jq -r .designId)
curl -s $API/v1/designs/$D -H "authorization: Bearer $T" | jq '.design.status, .report.headline, .report.counts'
العنوان هو no_problems_in_checks_run أو problems_found أو could_not_check. اقرؤوا checksRun وchecksNotRun أيضًا: فحص لم يعمل ليس نجاحًا. الحالات الأخرى هي needs_mapping (اضبطوا الطبقات بـ PUT /v1/designs/{designId}/layer-mapping) وneeds_engineer وrejected.
اطلبوا معاينة سعر. selection وdestinationCountry مطلوبان؛ selection فارغ يأخذ الافتراضيات:
curl -s -X POST $API/v1/quote-previews -H "authorization: Bearer $T" -H 'content-type: application/json' \
-d "{\"designId\":\"$D\",\"quantities\":{\"boardsFabricated\":10,\"boardsAssembled\":0},\"selection\":{},\"destinationCountry\":\"DE\"}" \
| jq '.mode, .reviewReasons, .totalMinor'
mode هو instant (السعر قائم كما يُظهر) أو review (يؤكده مهندس)؛ reviewReasons يقول لماذا. totalMinor بوحدات صغرى من currency الإجابة، وغائب عندما يجب على مهندس تسعير العمل. لحفظ عرض سعر، POST /v1/quotes يأخذ الجسم نفسه.
التدفق نفسه مع عميل JavaScript
يغلّف عميل @ulike/sdk هذه المسارات. لم يُنشر كحزمة بعد؛ هذا شكله، بحيث تستطيعون كتابة الاستدعاءات نفسها بـ fetch. أسماء الطرق:
import { createClient } from '@ulike/sdk';
let token;
const api = createClient({ baseUrl: 'https://dev.uliketechnology.com/api', token: () => token });
const caps = await api.capabilities();
token = (await api.createGuestSession()).token;
const started = await api.uploadDesign({ name: 'board.zip', bytes }); // announce, PUT, complete
const view = await api.waitForDesign(started.design.id); // polls getDesign
const preview = await api.previewQuote({
designId: view.design.id,
quantities: { boardsFabricated: 10, boardsAssembled: 0 },
selection: {},
destinationCountry: 'DE',
});
الطرق الأخرى هي createUpload وcompleteUpload وgetDesign وsetLayerMapping وvalidateDesign وgetValidation وwaitForValidation وcreateQuote وgetQuote وreviseQuote. تُلقى الأخطاء كـ ApiClientError مع status وcode.
فحص طلب
التقرير الذي تحصلون عليه بعد الرفع مصنوع على الملفات وحدها. لفحص الملفات مقابل طلب، استدعوا POST /v1/designs/{designId}/validations (validateDesign) مع order يحمل quantities وselection. الإجابة حالة: running أو failed أو done. بينما running، اقرؤوا GET /v1/validations/{reportId} (getValidation) كل ثانية أو ثانيتين حتى يكون done.
- رفع zip.
- قراءة التقرير.
- إصلاح ورفع كتصميم جديد. توقفوا واسألوا الشخص عندما يغيّر إصلاح الوظيفة أو السعر أو زمن التسليم.
- ملفات نظيفة: شغّلوا فحص الطلب.
عرض سعر أو معاينة بخيارات تجلب حدودًا أخرى (نحاس أسمك، سماكة أخرى) يحتاج فحصًا لذلك الاختيار. إن لم يوجد واحد، يُبدأ واحد، وتحمل المعاينة سبب المراجعة file_check_pending وcheck مع reportId الخاص به. يُظهر السعر فورًا، لكن عرض السعر يبقى في review حتى ينتهي ذلك الفحص. اقرؤوا الفحص كما أعلاه، ثم اطلبوا المعاينة مرة أخرى.
أخطاء ستواجهونها
| الرمز | الحالة | ماذا يعني | ماذا تفعلوا |
|---|---|---|---|
DESIGN_NOT_READY |
422 | التصميم لا يزال يُقرأ (details.status يقول أي حالة)، أو لا تقرير له بعد. |
اقرؤوا التصميم حتى لا تكون الحالة analysing، ثم اسألوا مرة أخرى. |
VALIDATION_FAILED |
400 | الطلب ليس له الشكل المتوقع، أو يسمّي خيارًا أو قيمة لا يملكها الكتالوج. details يسرد المشاكل أو القضايا. |
أصلحوا الحقل المسمّى في details وأرسلوا مرة أخرى. خذوا معرّفات الخيارات وقيمها من GET /v1/capabilities. |
NOT_MANUFACTURABLE |
422 | الاختيار شيء لا نصنعه. details.because يحمل الأسباب. |
غيّروا الاختيار؛ لا تعيدوا المحاولة نفسه. اسألوا الشخص إن كان التغيير سيغيّر اللوحة. |
ANONYMOUS_BUDGET_SPENT |
429 | مخصص اليوم دون حساب مستهلك. details.resetsOn هو التاريخ. |
توقفوا. أخبروا الشخص؛ يستطيع تسجيل الدخول أو الانتظار حتى ذلك التاريخ. |
REVISION_CONFLICT |
409 | سمّت مراجعة قاعدة لم تعد رأس عرض السعر. details يحمل كلا الرأسين. |
اقرؤوا الرأس بـ GET /v1/quotes/{quoteId}، أعيدوا تطبيق تغييركم عليه، وأرسلوا مرة أخرى. |
ممكن أيضًا DESIGN_REJECTED (رُفض الرفع؛ راجعوا details.reason) وUNAUTHENTICATED لرمز مفقود أو خاطئ (رمز خاطئ يُرفض حتى على مسارات عامة)، وFEATURE_DISABLED لمسار غير مفتوح بعد.
مخصص اليوم دون حساب
جلسة ضيف لها مخصص يومي للحوسبة. الرفوع وعمليات الفحص المبدوءة تكلف أكثر من قراءة عادية، وفتح جلسات ضيف عديدة من عنوان شبكة واحد يُحسب أيضًا. فحص يبدأه الموقع بنفسه لاختيار جديد يُحسب على المخصص نفسه. عندما يُستهلك، تحصلون على ANONYMOUS_BUDGET_SPENT مع تاريخ إعادة ضبطه. المتصلون مسجّلو الدخول لا يُحسبون هكذا.
ما لا تستطيع واجهة برمجة التطبيقات فعله اليوم: الطلب والدفع ومفاتيح واجهة برمجة التطبيقات وتسجيل دخول الوكلاء مخطّطة وغير متاحة. خادم MCP المخطّط موصوف في ما هو MCP وكيف تطلب الوكلاء.