الفواتير والإيصالات تشترك في نفس المدخل. كيفية تجنب الخلط بين الهيكلين؟

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

غالبًا ما يتم وضع الفواتير والإيصالات في نفس الواجهة للمعالجة، ولكن إذا تم استخدام كائن عريض به "جميع الحقول اختيارية" لاستلامه، فيمكنه استيعاب أي إدخال، لكنه لا يمكنه معرفة نوع المستند الذي تم استلامه. هذه المقالة مخصصة للمطورين وموظفي الأعمال الذين يحتاجون إلى تصميم واجهة استلام المستندات أو الحفاظ على قواعد التحقق من صحة مخطط JSON. بعد قراءة هذا، ستتعلم كيفية الاحتفاظ بعقدين مستقلين، واختيار أحدهما بحقل نوع واضح، والتعامل مع تعارضات الفروع والأنواع غير المعروفة.

تستخدم الأمثلة الموجودة في هذه المقالة العينات الاصطناعية لتوضيح طرق المعالجة. تم فحص الكود باستخدام أمثلة في بيئة معزولة، لكن هذا لا يضمن جميع الملفات الحقيقية أو أداء المنتج. قبل معالجة المستندات المهمة، يرجى الاحتفاظ بالنسخ الأصلية ومراجعتها وفقًا للحدود وبنود القبول في النص.

كيفية التعامل مع الدخول المشترك للفواتير والإيصالات؟ استنتاج جملة واحدة

عند استلام مستندين من نفس البوابة، يكون من الواضح الاحتفاظ بعقدين منفصلين واستخدام حقل kind المطلوب لاختيار أحدهما، بدلاً من استخدام كائن واسع يمكنه الاحتفاظ بكل شيء.

حالتكالممارسات الموصى بهاسبب
تحتاج نفس الواجهة لتلقي الفواتير والإيصالاتاحتفظ بعقدين منفصلين، تم تحديدهما بحقل النوع المطلوبيمكن لكائن كبير به جميع الحقول الاختيارية أن يحتوي على أي شيء، ولكن من الصعب شرح ما يتم استلامه.
تنظيم الفروع مع واحديستخدم كل فرع const لإصلاح النوعيتطلب oneOf فرعًا واحدًا بالضبط ليتم مطابقته. سيؤدي تداخل الحقول الفرعية إلى فشل الإدخال القانوني.
أدخل النوع المفقود أو تعارض الحقلقم بإرجاع رسالة خطأ واضحة توضح الحقول والمصادر المتضاربةإن إظهار "لا يوجد تطابق" فقط لا يمكن أن يساعد في تحديد المشكلة
لا يستطيع المصنف التمييز بين أنواع المستنداتاحتفظ بالحالة غير المعروفة وأدخل قائمة الانتظار المستقلة ليتم تصنيفهااختيار فرع عشوائيًا لن يؤدي إلا إلى "نجاح" زائف
تم التحقق من الهيكلولا يعني ذلك أن التصنيف صحيح، ولا يعني أن الوثائق صحيحة.ثقة التصنيف والتحقق من البنية وأصالة الأعمال هي ثلاثة مستويات مختلفة

لماذا لا يمكنك استخدام كائن عريض؟

خطورة جعل كافة الحقول اختيارية

عندما تقبل الواجهة كلا من الفواتير والإيصالات، فمن السهل كتابة كائنات كبيرة مع "جميع الحقول اختيارية". يمكن لمثل هذا الكائن بالفعل أن يتلقى مجموعة متنوعة من المدخلات، ولكن على حساب:

  • من المستحيل معرفة الوثيقة التي تم استلامها من الهيكل.
  • تختلط العناصر المطلوبة والعناصر الاختيارية في الوثيقتين مع بعضها البعض، وتزداد ضبابية قواعد التحقق.
  • عند حدوث خطأ، يكون من الصعب توضيح مكان الإدخال ليس كما هو متوقع.

سيكون من الواضح الاحتفاظ بعقدين منفصلين واختيار أحدهما بحقل نوع واضح.

واحد ليس مجرد أي واحد

سيؤدي تداخل الفروع إلى فشل الإدخال القانوني.

يتطلب oneOf أن يتطابق الإدخال مع فرع واحد تمامًا. إذا مر كلا الفرعين في نفس الوقت، فسوف يفشل التحقق الشامل.

إذا كانت الفروع تحتوي على عدد قليل فقط من الحقول الاختيارية، فمن المحتمل أن تتداخل بشكل كبير. في هذا الوقت، فشل الإدخال القانوني في اجتياز عملية التحقق.

استخدم اللطف والاستمرار لإزالة التداخل

باستخدام حقل kind المطلوب بالإضافة إلى const لتثبيت القيم، يمكنك تحديد حدود واضحة بين الفروع وإزالة مثل هذه التداخلات مسبقا.

لمزيد من التفاصيل حول قواعد التركيب، يرجى الرجوع إلى قواعد تركيبة مخطط JSON.

بروتوكول تحويل تنفيذي

from jsonschema import Draft202012Validator

def branch(kind, identity):
    return {
        "type": "object", "additionalProperties": False,
        "required": ["kind", identity],
        "properties": {"kind": {"const": kind},
                       identity: {"type": "string", "minLength": 1}}
    }

schema = {"oneOf": [branch("invoice", "invoice_number"),
                    branch("receipt", "receipt_number")]}
v = Draft202012Validator(schema)
valid = lambda x: not list(v.iter_errors(x))
assert valid({"kind": "invoice", "invoice_number": "I-1"})
assert valid({"kind": "receipt", "receipt_number": "R-1"})
assert not valid({"kind": "invoice", "receipt_number": "R-1"})
assert not valid({"kind": "receipt", "receipt_number": ""})
assert not valid({"kind": "invoice", "invoice_number": "I-1",
                  "receipt_number": "R-1"})
assert not valid({"kind": "unknown"})

هذا نموذج سجل مبسط، وليس نموذج ميداني كامل لفاتورة حقيقية. يوضح الكود اختيار الفروع ورفض الحقول الزائدة؛ يجب تعريف معدلات الضرائب، والرؤوس، والمبالغ بشكل منفصل.

إذا سمح العمل بإضافة حقول، يجب أن تكون مساحات الأسماء لهذه الحقول محددة بوضوح بدلا من إزالة جميع القيود بهدوء.

لا تعرض فقط رسائل خطأ "عدم تطابق"

يتم عرض "عدم التوافق" فقط، ولا يمكن للمستخدمين أو موظفي الصيانة معرفة مكان المشكلة. الجدول أدناه يسرد عدة ميزات إدخال شائعة وطرق تغذية راجعة مقابلة:

ميزات الإدخالشكوك حقيقيةاقترح ملاحظات
نوع من النقصلا يمكن اختيار الاتفاقيةيرجى تقديم نوع الوثيقة
تعارض حقول النوع والأرقامالهيكلان مختلطانعرض الحقول المتضاربة ومصادرها
سلاسل فارغة مرقمةالمفتاح موجود لكنه لا قيمة لهأنظر إلى المنطقة المرقمة
نوع غير معروفالاتفاقية الحالية لا تغطي هذاادخل قائمة الانتظار المستقلة ليتم تصنيفك

الأنواع غير المؤكدة تحتاج أيضا إلى مخرج

إذا لم يستطع المصنف التمييز بين الفواتير والإيصالات، يجب الاحتفاظ بالحالة المجهولة بدلا من اختيار فرع عشوائيا لتحقيق "نجاح".

هناك ثلاثة مستويات مختلفة هنا يجب النظر فيها بشكل منفصل:

  • ثقة الفئة: مدى ثقة النظام في تقييم أنواع المستندات.
  • التحقق من الهيكل: أدخل ما إذا كان العقد المختار قد تم تحقيقه.
  • أصالة الأعمال: ما إذا كانت الوثائق نفسها أصلية وصحيحة.

لا يمكن إثبات صحة التحقق الهيكلي عكسيا، ولا يمكن إثبات صحة المستند.

يجب أيضا الاحتفاظ بنوع المستند أثناء عملية الترجمة

قد يتطلب نفس المجال مصطلحات مختلفة في وثائق مختلفة. عند استخدام مصطلحات OmniDoc وسير عمل المراجعة ثنائي اللغة، يساعد توفير قوائم التسليم لأنواع المستندات المراجعين على فهم سياق العدد والمبلغ.

لا تدع كائن JSON واسع يمحو هذه الاختلافات.

📊 مقارنة النواة

الطريقةهل يمكن تحديد نوع الوثيقة بوضوح؟المظاهر عندما تتداخل الفروعالتعامل مع الأنواع المجهولة
الكائنات العريضة مع جميع الحقول اختياريةمن الصعب شرح ما تم استلامهغير قابل للتطبيق؛ لا توجد حدود فروع بين الحقوليسهل ابتلاعه من أهداف واسعة ويصعب ملاحظته
عقدان مستقلان + نوع مطلوباختر بوضوح باستخدام حقل النوعاستخدم Const لتثبيت القيم لتقليل التداخلاترك الحالة المجهولة وادخل قائمة الانتظار للفرز

🎯 أي طريقة تناسبك؟

إذا كنت بحاجة لاستلام الفواتير والإيصالات في نفس الوقت

احتفظ بعقدين منفصلين وحدد kind كحقل مطلوب.

إذا تداخلت حقول الفروع لديك بشكل كبير

قم بتثبيت kind مع const في كل فرع لتجنب مطابقة المدخلات الشرعية لعدة فروع في نفس الوقت.

إذا كان نظامك يسمح بحقول إضافية

أولا، أوضح مساحة أسماء الحقل الإضافي، ثم قرر كيفية تخفيف القيود.

إذا لم يكن مصنفك متأكدا بما فيه الكفاية

احتفظ بالحالة المجهولة وأرسل المستندات إلى قائمة الانتظار للفرز؛ لا تختار الفروع بالقوة.

❓ الأسئلة الشائعة (الأسئلة الشائعة)

1. لماذا لا تستخدم كائنا حيث تكون جميع الحقول اختيارية؟

مثل هذا الشريك يمكنه التظاهر بأي شيء، لكن من الصعب معرفة ما الذي يتلقاه بالضبط.

2. لماذا يسبب oneOf فشل دخول صحيح؟

يتطلب oneOf مطابقة فرع بدقة. إذا اجتاز كلا الفرعين في نفس الوقت، سيفشل الفحص الكلي. من المرجح أن يحدث هذا الوضع عندما تتداخل الحقول الفرعية بشكل كبير.

3. ما الذي يجب أن تنتبه له عند السماح بإضافة حقول إضافية؟

يجب تعريف مساحة الاسم للحقل الإضافي بوضوح، بدلا من إزالة جميع القيود بهدوء.

4. ماذا لو لم يتمكن المصنف من تحديد نوع المستند؟

احتفظ بحالة المجهول ودخل طابور مستقل ليتم تصنيفه؛ لا تختار فرعا عشوائيا لتجميع فرع ناجح.

5. هل يثبت اجتياز التحقق الهيكلي صحة الوثائق؟

لا. الثقة في التصنيف، والتحقق الهيكلي، وأصالة الأعمال هي ثلاثة مستويات مميزة؛ لا يمكن للتحقق الهيكلي إثبات أصالة الوثائق.

📝 ملخص

عند وضع الفواتير والإيصالات في نفس الإدخال، احتفظ بعقدين منفصلين واختارهما باستخدام حقل kind المطلوب، مما يجعل نوع المستند المدخل واضحا بوضوح. يجب أيضا تصميم التحقق من الفروع، وردود الفعل على الأخطاء، وتصدير النوع المجهول معا.

اختبر الآن: ارفع مستندك لتبدأ الترجمة، مع الحفاظ على التنسيق الأصلي

تاريخ التحديث: 2026-11-15