كل الأدلة

مساعدو AI

بدء سريع لواجهة برمجة التطبيقات: الرفع والفحص وعرض السعر

الاستدعاءات التي تأخذ ملف لوحة إلى تقرير فحص ملفات ومعاينة سعر، مع curl وعميل JavaScript، إضافة إلى الأخطاء التي ستواجهونها.

لمساعدي AIتم التحديث 2026-11-104 دقيقة للقراءةنص Markdown الخام لمساعدي AI

قبل أن تبدؤوا

تعمل واجهة برمجة التطبيقات دون حساب عبر جلسة ضيف. واجهة برمجة التطبيقات في عنوان الموقع الخاص تحت /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 للمطورين.

خمس صور صغيرة بالترتيب: مفتاح، ملف يذهب إلى عنوان رفع، ساعة رملية، صفحة تقرير بملاحظات، وبطاقة سعر
  1. جلسة ضيف: يُظهر الرمز مرة واحدة.
  2. الرفع: PUT zip إلى العنوان الذي تسمّيه واجهة برمجة التطبيقات، بالرؤوس التي تسمّيها.
  3. الإكمال، ثم الاستقصاء حتى ينتهي التحليل.
  4. التقرير: الملاحظات، أي عمليات فحص عملت وأيها لم تعمل.
  5. معاينة عرض السعر.

التدفق مع 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.

حلقة من ثلاث خطوات: رفع الملفات وقراءة التقرير والإصلاح والرفع مرة أخرى؛ سهم يغادر الحلقة إلى علامة عندما تكون الملفات نظيفة
  1. رفع zip.
  2. قراءة التقرير.
  3. إصلاح ورفع كتصميم جديد. توقفوا واسألوا الشخص عندما يغيّر إصلاح الوظيفة أو السعر أو زمن التسليم.
  4. ملفات نظيفة: شغّلوا فحص الطلب.

عرض سعر أو معاينة بخيارات تجلب حدودًا أخرى (نحاس أسمك، سماكة أخرى) يحتاج فحصًا لذلك الاختيار. إن لم يوجد واحد، يُبدأ واحد، وتحمل المعاينة سبب المراجعة 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 وكيف تطلب الوكلاء.

جرّب ذلك على لوحة حقيقية

ارفع لوحة وشاهد عمليات الفحص الـ25 عليها.

ارفع لوحة