تعريف مجموعة الخيارات المبنية على البيانات
معرّف المخطط: model-driven-option-set@1
المخطط القابل للقراءة آليًا: model-driven-option-set.schema.json
التمثيل المرجعي لمجموعة خيارات — وهي قائمة مسمّاة وقابلة لإعادة الاستخدام من القيم المسموح بها لحقل ما (القسم 6.14). ويسمّي Dataverse المفهوم نفسه Choice. ويجري التحقق منه بالطريقة نفسها سواء جاء من المصمّم، أو من استدعاء API، أو من مساعد ذكاء اصطناعي، أو من استيراد حل.
الشكل
| الحقل | النوع | مطلوب | ملاحظات |
|---|---|---|---|
logicalName | string | نعم | مسبوق ببادئة الناشر، بصيغة snake_case صغيرة (مثل par_invoicestatus). |
displayName | string | نعم | اسم مقروء. |
description | string | لا | الغرض من المجموعة. |
publisherPrefix | string | لا | بادئة الناشر المالك. تُحمل كي يسمّي التعريف ناشره بنفسه بدل ترك المستورد يستنتجه من الاسم المنطقي. |
optionValueBase | integer | نعم | أساس قيم الخيارات لدى الناشر المالك، وvalue كل خيار مطلق ضمنه — 110000001 لا 1. مطلوب منذ 2026-09-12: التعريف الذي يفتقده يُرفض عند الاستيراد، وهكذا كُتب أول حل للمنتج واجتاز كل الاختبارات. |
nextOptionValue | integer | لا | علامة المجموعة العليا — أي القيمة التالية التي ستمنحها. تُخزَّن بدل اشتقاقها من options، فلا يُعاد إصدار رقم خيار متقاعد أبدًا. انظر أدناه. |
options | array | نعم | الخيارات، بترتيب العرض. خيار واحد على الأقل — فالمجموعة التي لا يستطيع أحد الاختيار منها ليست مجموعة. |
الخيار
| الحقل | النوع | مطلوب | ملاحظات |
|---|---|---|---|
value | integer | نعم | القيمة المخزّنة. تخصصها المنصة من أساس الناشر المالك وتصبح غير قابلة للتغيير بمجرد إسنادها. الحد الأدنى 1 — انظر أدناه. |
displayName | string | نعم | ما يختاره المستخدم. |
description | string | لا | معنى الخيار. |
لماذا القيم أرقام كبيرة، لا 0/1/2
القيمة value هي ما تخزّنه قاعدة البيانات فعليًا. ويملك كل ناشر نطاقًا من الأرقام
(مثل 270150000–270159999)، وتُرقَّم خيارات المجموعة تصاعديًا من أساسها:
270150000, 270150001, 270150002, …
ولو بدأ كل ناشر من 0، لكان استيراد ح لول من ناشرَين إلى بيئة واحدة يجعل "مسودة" لدى
أحدهما تعني "ملغى" لدى الآخر بصمت — لأن كلتيهما ستُخزَّن على أنها 0. والنطاق لكل ناشر
يجعل ذلك مستحيلًا. وهو النظير الرقمي لبادئة الناشر، التي تؤدي الدور نفسه بالنسبة
للأسماء.
وتنبثق من ذلك قاعدتان، وكلتاهما مفروضة:
- أنت لا تختار القيم. فواجهة الإنشاء لا تأخذ قيمة؛ بل تخصص المنصة القيمة التالية من نطاق الناشر. وعند التحديث، الخيار الذي يحمل قيمة هو خيار تُبقيه — والقيمة غير المعروفة تُرفض، لا تُقبل.
- القيمة لا تتغير أبدًا. فإعادة تسمية خيار مجانية وآمنة؛ أما إعادة ترقيمه فتعيد توجيه كل سجل يخزّنه سلفًا. ورقم الخيار المحذوف يتقاعد بدل أن يُعاد إصداره.
الاستيراد والتصدير
تنتقل القيم مع التعريف؛ ولا يُعاد تخصيصها عند الاستيراد. فسجلات البيئة المصدر
تحملها سلفًا، ومن ثم على الحل المستورَد إلى Test أو Prod أن يتفق مع Dev على معنى
270150001.
وتنتقل nextOptionValue للسبب نفسه، بدرجة واحدة أبعد. فهي القيمة التالية التي ستمنحها
المجموعة، وهي مخزّنة بدل أن تُحسب من الخيارات الموجودة. فإذا حُذف خيار، تبقى العلامة فوق
الرقم الذي كان يحمله — فيتقاعد الرقم بدل أن يُمنح للخيار الجديد التالي، وهذا مهم لأن
سجلًا ما في مكان ما قد يظل يحمله. والبيئة المستوردة التي تعيد اشتقاق العلامة من
الخيارات التي تلقتها ستنقض تلك الحماية بالضبط. أما التعريف الذي لا يحمل
nextOptionValue فيعود إلى العلامة المشتقة، وهي أفضل جواب متاح لمستند لم يسجّل واحدة قط.
ويفحص الاستيراد ما كان التخصيص سيضمنه لولاه: فيجب أن تقع كل قيمة داخل نطاق الناشر، ولا يجوز أن يتشارك خياران قيمةً أو تسميةً، ويجب أن يكون الاسم المنطقي متاحًا في البيئة الهدف. أما القيمة الآتية من نطاق ناشر آخر فتُرفض بدل أن تُخزَّن — إذ إن قبولها يزرع التصادم ذاته الذي وُجد نظام النطاقات لمنعه.
ربط حقل بمجموعة
يشير حقل الجدول إلى المجموعة بـالاسم، في تعريف الجدول:
{ "logicalName": "par_status", "displayName": "Status", "dataType": "OptionSet", "optionSet": "par_invoicestatus" }
والعمود من نوع bigint يحمل قيمة الخيار المختار. ويرفض الخادم أي كتابة قيمتها ليست من
خيارات المجموعة.
مثال
{
"logicalName": "par_invoicestatus",
"displayName": "Invoice Status",
"description": "The lifecycle of an invoice",
"publisherPrefix": "par",
"optionValueBase": 270150000,
"nextOptionValue": 270150003,
"options": [
{ "value": 270150000, "displayName": "Draft", "description": "Not yet sent to the customer" },
{ "value": 270150001, "displayName": "Sent" },
{ "value": 270150002, "displayName": "Paid" }
]
}