إنتقل إلى المحتوى الرئيسي

رفع بيانات أعمالك

يمكن لـ Kaleidr الإجابة عن الأسئلة بالاعتماد على بيانات مؤسستك الخاصة — مثل العقارات، والقوائم، والغرف، والأسعار، وساعات العمل، والمستندات — إلى جانب معرفتها الأساسية بالعالم.

هناك أمران مهمان يجب توضيحهما قبل أي شيء آخر، لأنهما يؤثران في كل قرار أدناه.

يتم تقديم بياناتك إلى مؤسستك فقط. وهي معزولة على مستوى قاعدة البيانات، وليس بمنطق التطبيق، ولا تصل أبدًا إلى إجابة في Kaleidr Map المخصص للمستهلكين. وهي متاحة ضمن واجهات B2B الخاصة بك فقط ولا تظهر في أي مكان آخر.

لا يقوم نموذج لغوي بكتابة بياناتك أبدًا. فهو يقرأ header الخاص بملف التصدير وعددًا قليلًا من sample rows ويقترح column mapping؛ ثم تقوم deterministic code بتطبيق ذلك mapping على كل row. إذا كان mapping خاطئًا، تقوم بتصحيحه في نموذج. أما جعل النموذج ينسخ 500 row فيعني 500 فرصة لاختراع سعر قد يُقتبس لاحقًا بثقة مع timestamp، ولا يمكن تمييز السعر المختلق عن السعر الحقيقي.

التوفر

رفع vendor data هو ميزة ضمن خطة Enterprise-tier. كل من upload UI و API يتحققان من VENDOR_UPLOAD_TIERS = {"enterprise"} — وسيحصل owner أو admin ضمن Pro-tier على 403 vendor_data_requires_enterprise في أي upload call.

واجهة vendor-data UI معطلة حاليًا في production (vendorDataEnabled config flag). تواصل مع دعم Kaleidr إذا كنت على Enterprise وتحتاج إلى تفعيلها لمؤسستك.

بالإضافة إلى ذلك، يلزم دور owner أو admin ضمن Enterprise — فهذه بيانات على مستوى المؤسسة وليست لكل project.

طريقتان للإدخال

صفحة الرفع. سجّل الدخول في kaleidr.com وافتح Your Data في منطقة حسابك (مسار nav /vendor-data، بجانب Billing وAPI keys). تتبع الصفحة الخطوات الأربع نفسها التي يتبعها API: اختر ملفًا، وراجع mapping المقترح، وعاين ما تم فهمه، ثم انشر. وهذا هو المسار المناسب لـ spreadsheet.

الـ API، موثق أدناه. استخدمه عندما تكون بياناتك موجودة بالفعل في نظام يمكنه push، أو عندما تريد عمليات رفع مجدولة.

المصادقة

تأخذ جميع الاستدعاءات Cognito access token كـ bearer، وهو نفس الرمز الذي تحتفظ به جلستك بالفعل:

Authorization: Bearer <access token>

وليس platform API key. فمفاتيح Platform تحدد integration؛ أما رفع البيانات فهو فعل من أفعال إدارة المؤسسة، ولذلك تتم المصادقة كشخص لديه role. جميع المسارات أدناه تقع تحت https://api.kaleidr.com.

بنية عملية الرفع

ينتج عن كل upload ingest واحد (الـ job) وrelease واحد (النتيجة ذات الإصدار). يكون release في حالة draft حتى يتم نشره، ويستبدل النشر الإصدار السابق atomically — لذلك لا يرى القراء تحديثًا مطبقًا جزئيًا، ولا توجد فترة تكون فيها مؤسستك بلا بيانات.

1. اقتراح mapping

أرسل بداية ملفك — header row وعددًا قليلًا من data rows، وليس كامل export.

MethodPathBodyReturns
POST/inference-api/vendor/mapping/propose{ csv_head }{ mapping_spec, columns, sample_result, notes, errors[] }

csv_head محدود بـ 16 KB، ويتم تقطيع sample server-side — لذا فإن إرسال ملف أكبر لا يزيد ما يمكن للنموذج رؤيته.

sample_result هو الجزء الذي يجب قراءته. يتم تنفيذ dry-run للـ mapping المقترح على sample rows الخاصة بك قبل أن تراه أصلًا، ويعرض sample_result ما الذي تم إنتاجه لكل section. أما mapping الذي يبدو منطقيًا لكنه لا ينتج شيئًا فقد لا تكتشفه إلا بعد الرفع.

إذا لم يكن بالإمكان تطبيق الاقتراح، فستظل تحصل على 200 مع تعبئة errors، وليس 5xx. الـ mapping قابل للتعديل، وتصحيح column واحد هو كامل التفاعل، كما تعرض errors كل ما يمكن معرفته في تمريرة واحدة — فالحقل المطلوب المفقود واسم column غير الموجود في sheet يصلا معًا بدلًا من خطأ واحد لكل round trip.

ما يتم اكتشافه قبل الرفع: section يفتقد field مطلوبًا في كل row (stay_date, price_amount, units_available, أو name أو timezone لمكان)، أو timezone بصيغة {"const": …} ليست IANA zone حقيقية، أو currency const ليست ثلاثة أحرف، أو أي object rule ليست const container. وإلا فسيفشل كل واحد منها مرة لكل row بعد الرفع.

الحد هو 30 اقتراحًا لكل مستخدم في الساعة.

2. تجهيز preview

MethodPathBodyReturns
POST/shared-api/vendor-data/ingests{ filename, artifact, source, mapping_spec?, preview?, org_id? }{ ingest_id, release_id, status, status_url, dispatched }
  • يجب أن ينتهي filename بـ .json أو .csv.
  • artifact هو النص الخام للملف.
  • source هو csv أو json أو manual.
  • mapping_spec هو ما أعادته الخطوة 1، ويمكن تعديله اختياريًا. احذفه إذا كنت ترسل JSON bundle مطبعًا مسبقًا أو CSV يحتوي على places فقط.
  • preview: true يجهز البيانات دون نشرها — ويوصى به بشدة لأول upload، وكذلك لأي تغيير في mapping.
  • org_id اختياري؛ والقيمة الافتراضية هي المؤسسة التي تديرها.

Idempotency-Key مطلوب في هذا الاستدعاء (من 8 إلى 128 حرفًا)، وهو محدد النطاق لكل مؤسسة. إعادة المحاولة بالمفتاح نفسه تعيد ingest الموجود بدلًا من إنشاء ingest ثانٍ. استخدم مفتاحًا جديدًا عندما تقوم عمدًا بإعادة التجهيز بعد تعديل mapping — فهذا طلب مختلف فعليًا، وأي مفتاح مشتق من الملف سيعيد ingest المبني باستخدام mapping القديم.

3. متابعة العملية

MethodPathReturns
GET/shared-api/vendor-data/ingests/{ingest_id}{ status, attempts, row_counts, error_report, created_at, started_at, finished_at }

يتغير status من pendingrunningsucceeded أو failed. عند النجاح، يحمل row_counts ما تم فهمه — "47 places, 312 rates" — بينما يحمل error_report الصفوف التي تعذر قراءتها، مع سبب كل منها.

4. النشر

MethodPathReturns
POST/shared-api/vendor-data/ingests/{ingest_id}/publish{ ingest_id, release_id, status, status_url, dispatched }

فقط لـ ingest تم تجهيزه باستخدام preview: true ونجح.

يعيد النشر تشغيل الـ job بدلًا من تغيير flag. فهو يعيد قراءة artifact نفسه ويطبق mapping نفسه من جديد، ولذلك تتطابق counts وidentifiers بحكم البنية — لكن geocoding هو live call، لذا قد تختلف coordinate إذا قام provider بتصحيحها منذ preview.

لا ترسل Idempotency-Key هنا. هذا endpoint لا يقبله، ولا يحتاج إليه: لا يمكن حدوث نشر ثانٍ للـ ingest نفسه. إذا انتهت مهلة الطلب الأول من جهتك لكنه نجح لدينا، فستعيد المحاولة 409ingest_is_not_a_preview، أو publish_already_in_progress إذا تداخلت محاولتان تمامًا. كلتاهما تعني أن عملية النشر جارية بالفعل. تعامل معهما كنجاح، وليس كخطأ يستوجب إعادة المحاولة.

عرض releases

MethodPathReturns
GET/shared-api/vendor-data/releases[{ id, status, published_at, superseded_at, created_at }]

يمكن تصفيتها اختياريًا باستخدام ?status=. يوجد release واحد فقط لكل مؤسسة بحالة published في أي وقت.

انتهاء صلاحية previews

أي preview لا توافق عليه يتم إيقافه بعد 14 يومًا، محسوبة من وقت انتهاء staging. يتم وضع علامة superseded عليه بدلًا من حذفه، لذلك يبقى upload في السجل — لكنه لا يعود قابلًا للنشر، وستحتاج إلى الرفع مرة أخرى. نشر preview منتهي يعيد 409 no_previewed_release_to_publish.

ملاحظات حول الحقول

timezone مطلوب لكل place، وهو مهم. يتم حساب إجابات rate وavailability وفق التقويم المحلي للعقار — فـ "tonight" في فندق في Sydney هو يوم مختلف عن "tonight" على server. إذا كان export الخاص بك فعلًا لا يحتوي على timezone column، فقم بربط ثابت بشكل صريح:

{ "timezone": { "const": "UTC" } }

اكتب ذلك عمدًا بدلًا من تركه على default. UTC إجابة صحيحة لعقار يعمل وفق ساعات UTC، لكنها إجابة خاطئة بشكل دقيق لعقار لا يفعل ذلك، ولا يظهر الخطأ إلا عند أطراف stay window.

يتم رفض حذف timezone، أو استخدام zone غير موجودة، في خطوة propose بدلًا من بعد upload.

قدم coordinates عندما تكون متوفرة لديك. أي place يحتوي على lat/lng يُستخدم كما هو — coordinates الخاصة بك هي المرجع ولن نعيد اشتقاقها. أما place الذي يحتوي على address فقط فيتم geocode له، وإذا لم نكن واثقين من المطابقة فسيتم رفضها بدلًا من التخمين: وضع عقار في موقع خاطئ على الخريطة أسوأ من الإبلاغ عن تعذر تحديد موقعه. وجود نصف coordinate يُعامل كخطأ مطبعي وليس كقيمة ناقصة.

إعادة الرفع منخفضة التكلفة وآمنة. يتم اشتقاق identifiers من الأعمدة التي يحددها mapping كأعمدة تعريف، ولذلك ينتج export نفسه المراجع نفسها — إعادة الرفع تقوم بالتحديث بدلًا من التكرار.

الأخطاء

StatusMeaning
401Access token مفقود أو منتهي
403 vendor_data_requires_enterpriseالمؤسسة ليست على Enterprise tier
403مؤسستك غير مفعلة لرفع البيانات
404لا يوجد ingest كهذا لمؤسستك
409ingest ليس في حالة تسمح بهذا الاستدعاء — راجع ملاحظات النشر أعلاه
413الملف يتجاوز حد الرفع
422تعذر قراءة الملف أو mapping؛ body يحدد الصفوف والأسباب
429Rate limited — أعد المحاولة بعد فترة توقف

ما هو قادم

يقبل API حاليًا bundle كاملًا. وبمجرد أن يصبح mapping كائنًا مخزنًا وقابلًا لإعادة الاستخدام، سيقبل أيضًا export الخاص بك بالإضافة إلى mapping id، بحيث يتمكن integration من إرسال الملف الذي ينتجه بالفعل دون إعادة تشكيله أولًا. وسيتبع ذلك delta API — upsert وdelete حسب natural key، مع cursor باسم since — ضمن المسار نفسه.