Skip to main content
الحقل المحسوب يخزن قيمة يشتقها KayanOS من بيانات أخرى بدلاً من مطالبة شخص بإدخالها مراراً. يمكنه تمثيل مبلغ أو درجة أو علامة أو جزء من تسمية أو عدد علاقات أو نتيجة أخرى تتبع قاعدة معتمدة. تبقى النتيجة في السجل لكي تراجع وتصفّى وتظهر في التقارير وتستخدم في الخطوات اللاحقة من دون إعادة الحساب يدوياً. الحقل المحسوب ليس عنصراً مستقلاً في قائمة أنواع حقول الكيان. إنه حقل عادي ليس من نوع إجراء ولا حالة، وله calculation_code غير فارغ. اختر نوع حقل الناتج بحسب القيمة: استخدم الرقم للمبلغ أو العدد، والمنطقية لنتيجة نعم أو لا واضحة، والنص لقيمة عرض قصيرة، وهكذا. أما المرجع التسلسلي فيستخدم إعداد التسلسل المخصص له بدلاً من حساب يقلد عملية الإصدار. تُظهر لقطة أداة الإنشاء الآتية حقل الرقم الرسوم التقديرية في كيان طلب خدمة مواطن مع تعبير حسابه. وهي مثال على اختيار نوع الناتج العادي أولاً ثم ربط قاعدة الحساب بذلك الحقل. إعداد الحقل المحسوب للرسوم التقديرية في KayanOS لكيان طلب خدمة مواطن.

متى تستخدمه

استخدم الحقل المحسوب عندما تكون النتيجة محددة تماماً من بيانات موجودة في السجل أو من علاقات مهيأة ليحلها النظام. من الأمثلة المناسبة: رسم خدمة محسوب من مبلغ ونسبة، أو علامة اكتمال مبنية على بيانات استلام منظمة، أو عدد معاينات، أو درجة عبء عمل، أو تصنيف تقريري مشتق من مدخلات معتمدة. استخدم آلية أخرى عندما يحتاج العمل إلى حكم بشري أو صلاحية أو حدث خارجي: حافظ على ظهور المدخلات وسمّها باسم معناها في العمل. فالحقلان requested_amount وfee_rate يجعلان القاعدة قابلة للمراجعة، أما حمولة JSON غامضة فلا تفعل. لا تطلب من الناس إدخال قيمة سيستبدلها الحساب مباشرة. وإذا كانت البيانات المصدر غير مكتملة، فقرر هل يجب أن تكون النتيجة null، أو هل ينبغي لتحقق أن يمنع حفظ السجل، أو هل يلزم قرار بشري منفصل.

الإعداد

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

السياق وسلوك الناتج

يعتمد سياق التقييم على مسار التنفيذ. لا تفترض أن اسماً متاحاً عند إنشاء السجل أو تحديثه سيكون متاحاً أيضاً في التحديث الخلفي؛ فلكل من المسارين بيانات مختلفة عن قصد: في المسار المتزامن قد يجري KayanOS تمريراً واحداً لكل حقل محسوب كحد أقصى، ويتوقف عندما لا يغير تمرير أي قيمة. تقارن النتيجة بالقيمة الحالية؛ فإذا اختلفت وكانت معرفة توضع القيمة المحدثة في بيانات السجل المستخدمة في مسار الإنشاء أو التحديث ذلك. أما النتيجة undefined أو خطأ التقييم فيتجاوزان الكتابة بدلاً من تخزين قيمة جديدة. تسلك المهمة الخلفية نهجاً مختلفاً: تقيم كل حقل محسوب مرة واحدة من سياق المصدر فقط، ثم تكتب النتائج المتغيرة معاً. لهذا تعد معالجة القيم الفارغة مهمة: قد يكون الفراغ الدفاعي أكثر أماناً من مبلغ خاطئ، لكنه قد يبقي نتيجة أقدم إلى أن تصلح بيانات المصدر. ابدأ بحساب محلي لا يعتمد على علاقة:
عندما تكون requested_amount مساوية لـ 250000 وfee_rate مساوية لـ 0.03، فالنتيجة الرقمية المتوقعة هي 7500. ينبغي أن يكون الحقلان المصدران من نوع رقم. وإذا كانت النسبة اختيارية، فاختر بوضوح قيمة بديلة بدلاً من ضرب نص أو null أو قيمة مفقودة من غير قصد.

العلاقات المباشرة والعلاقات العكسية

لا ترى صيغة العلاقة المباشرة $relations في الإنشاء أو التحديث المعتاد إلا إذا كان مسار التحقق المحيط قد حل سياق العلاقة. أما المهمة الخلفية فلا تحل إلا حقول العلاقات المباشرة المهيأة لتحديث الحقول المحسوبة. لعلاقة مفردة مثل service_category تكون $relations.service_category إما كائن السجل المرتبط أو null. أما علاقة المصفوفة فتحل المفتاح نفسه كمصفوفة. احمِ الوصول إلى العلاقة بشرط:
مع فئة خدمة مرتبطة تحتوي fee_rate بقيمة 0.03 ومبلغ مطلوب 250000، تكون النتيجة المتوقعة 7500. ومن دون فئة أو نسبة تكون النتيجة null. استخدم مفاتيح الحقول المخزنة في الكيان المرتبط لا العناوين التي يراها الموظف. تجيب العلاقة العكسية عن سؤال مختلف: ما السجلات الأخرى التي تشير إلى هذا السجل؟ وهي بيانات لمسار الخلفية وليست سياقاً متزامناً مضموناً: أثناء الإنشاء والتحديث المعتاد يكون $inverseRelations فارغاً. هيئ تعريف العلاقة العكسية على الكيان قبل الاعتماد عليها، ثم استخدم التعبير فقط حيث يكون التحديث الخلفي المهيأ جزءاً من التصميم. في هذا المسار الخلفي تكون القيم مصفوفات تحت مفتاح الكيان العكسي ومفتاح حقل علاقته. استخدم الدالة المسجلة length(...) لعد عناصر المصفوفة:
إذا كانت ثلاث سجلات معاينة تشير إلى الطلب الحالي من خلال request_reference، فالنتيجة الرقمية المتوقعة هي 3 بعد التحديث الخلفي المهيأ. يجب أن يطابق المفتاحان inspections وrequest_reference في المثال مفتاح الكيان وحقل العلاقة العكسية المهيأين تماماً. لا تكتب تجميعاً على مسار عكسي قبل التحقق من الإعداد المحفوظ وسجل الأصل المحدّث. هناك مساران مهمان للتوقيت. أثناء الإنشاء والتحديث المعتاد، يحسب KayanOS البيانات المحلية وأي علاقات مباشرة محلولة و$value وسياق قالب الحالة المنطبق؛ ولا يملك مجموعة سجلات عكسية. أما مهمة calculate_entity_fields الخلفية فتقرأ العلاقات المباشرة والعكسية المهيأة، ولا توفر $value أو $statusTemplates، وتعيد حساب كل ناتج مرة واحدة من بيانات المصدر وتسجل أخطاء التقييم. يجب التحقق من قاعدة تعتمد سجلات عكسية بعد إعادة الحساب الخلفية؛ لا تفترض أن إضافة سجل تابع تحدث عداد الأصل فوراً في كل مسار.

التبعيات والدورات وسياق الحالة

قد تبدو سلسلة قصيرة من حقل محسوب إلى آخر مستقرة خلال إنشاء أو تحديث متزامن واحد: فهذا المسار قد يكرر التمريرات بحد أقصى يساوي عدد الحقول المحسوبة. لكنه ليس عقد تبعية صالحاً للإنتاج. يزيل التحديث الخلفي كل النواتج المحسوبة من $ ويجري تمريرة واحدة، وقد يكتب لاحقاً قيماً مشتقة من بيانات المصدر وحدها. ابنِ السياسة الدائمة من حقول مصدر معتمدة بدلاً من الاعتماد على إتاحة ناتج محسوب لحقل آخر. لا تنشئ قواعد دائرية مثل اعتماد a على b واعتماد b على a، ولا صيغاً تغير مدخلاتها باستمرار. يمكن للخادم تزويد سياق قالب الحالة أثناء المسار المتزامن عندما يستخدم الحقل إعداد قالب الحالة المناسب، لكنه لا يقدمه إلى المهمة الخلفية. اعتبره بيانات سياقية لا اختصاراً للأذونات. وإذا اعتمدت القاعدة على قالب حالة، فاختبر اختيار القالب وحالة السجل وسلوك التحديث الدقيقين اللذين سيستخدمان وقت التنفيذ.

إسقاط العميل ليس مرجع الحساب

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

مثال عملي

تدير مديرية خدمات عامة في سوريا طلبات مواطنين لخدمة محلية. يتضمن كل طلب requested_amount وfee_rate وعلاقة إلى service_category وسجلات معاينة مرتبطة. يريد مالك الخدمة أن يرى الموظفون الرسم التقديري وعلامة المراجعة وعدد سجلات المعاينة من دون إعادة كتابة أي نتيجة. أنشئ حقول الناتج التالية: في النسخة الأولى، احتفظ بالنسبة مباشرة في الطلب واستخدم حساباً بسيطاً:
لطلب فيه requested_amount بقيمة 250000 وfee_rate بقيمة 0.03 تصبح قيمة estimated_fee هي 7500. ضع النتيجة قرب مبلغ المصدر في تخطيط المراجعة، وأبق المدخلين ظاهرين حتى يستطيع المراجع تفسير الرقم. ثم عرّف حد مراجعة منطقي واضحاً مباشرة من قيم المصدر نفسها:
في المثال السابق تكون needs_fee_review مساوية لـ false، أما عندما ينتج المبلغ والنسبة رسماً قدره 12500 فتكون true. الصيغة متعمدة وليست $.estimated_fee >= 10000: فقد يظهر estimated_fee المحسوب متزامناً خلال تمرير تحقق واحد، لكن مسار الخلفية يزيل النواتج المحسوبة قبل تقييم الحد. هيئ مسار العمل بحيث تقود العلامة الحقيقية إلى مهمة مراجعة ظاهرة أو خطوة حالة. الحقل نفسه لا يعيّن مراجعاً ولا يمنح موافقة. إذا كانت سياسة الرسم مخزنة في سجل service_category المرتبط، فاستبدل الصيغة الأولى بصيغة العلاقة المباشرة المحمية الواردة في قسم الإعداد. اختبر طلباً بلا فئة، وفئة بلا نسبة، وفئة ذات نسبة رقمية صحيحة. وإذا تغيرت العلاقة لاحقاً، فشغّل أو تحقق من إعادة الحساب ذات الصلة وافحص الرسم المخزن قبل إصدار مستند قرار. وأخيراً هيئ العلاقة العكسية inspections.request_reference فقط إذا كانت المديرية تحتاج العدد المخزن للوحة معلومات أو تقرير. أنشئ طلباً واحداً، واربط به ثلاث سجلات معاينة، ثم شغّل أو انتظر إعادة الحساب الخلفية، وتأكد أن inspection_count يساوي 3. العدد معلومة تشغيلية وليس دليلاً على قبول كل معاينة. احتفظ بنتيجة المعاينة وحالة القرار في حقول مضبوطة مستقلة.

الاختبار

اختبر الحسابات بمجموعة غير إنتاجية صغيرة تتضمن الحالات العادية والفارغة والمتغيرة وحالات العلاقات. دوّن قيم المصدر والنتائج المخزنة المتوقعة. اختبر سجلاً محفوظاً لا مؤشر المحرر فقط، إذ يمكن للمحرر أن يقبل الصياغة بينما تملك البيانات الفعلية شكل علاقة مختلفاً أو قيمة مفقودة. استخدم تعبير علاقة محافظاً قبل إضافة الحساب:
مع فئة مرتبطة تملك fee_rate بقيمة 0.03 فالنتيجة المتوقعة هي 0.03؛ ومن دون فئة مرتبطة تكون null. بعد نجاح ذلك أضف الضرب وحد المراجعة تعبيراً واحداً في كل مرة. وللعدد العكسي اختبر الإعداد المحفوظ ذاته بدلاً من تخمين مفتاح الكيان أو الحقل من عنوانه على الشاشة.

استكشاف الأخطاء وإصلاحها

الأذونات وحدود جودة البيانات

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

أدلة ذات صلة