فحوصات جودة النظام
وحدة فحوصات جودة النظام هي الشبكة الأمان الشاملة لبنية السلامة في أمل. تحتفظ بسجل إصدارات لـ38 فحصاً مُسمَّى، وتوجِّه حالات الفشل في وقت التشغيل بشكل حتمي، وتكشف عن ثلاث نقاط نهاية قراءة للمراقبة، دون تكرار سطر واحد من منطق التطبيق من وحدات المحرك التي تمتلكه أصلاً.
ما تفعله هذه الوحدة وما لا تفعله
هذه الوحدة تُسجِّل وتُوجِّه. لا تُعيد التطبيق. تطبيق كل فحص موجود في الوحدة التي تمتلك القاعدة (محرك حالة المهارات، وحدة التجمعات، كتالوج الحزم، طبقة سلامة اللغة، إلخ). توفر وحدة QA مكاناً واحداً لاكتشاف الفحوصات الموجودة، وشدتها، ومتى أُطلقت في وقت التشغيل.
المسؤوليات الثلاث:
- التسجيل: جدول إعداد مُصدَر ومجمَّد (
qa_check_definition، 38 صفاً، عالمي بدون نطاق مستأجر) يصف كل فحص: معرِّفه (QA_001..QA_038)، أمر lint الخاص بـCI الذي يُطبِّقه، رسالة فشل مقروءة باللغة العربية، وشدته. - التوجيه: حين يرصد وحدة المحرك انتهاكاً، يستدعي
routeQaFailure({ qaCheckId }). يُطابق الموجِّه شدة الفحص ويُطبِّق مصفوفة التوجيه الحتمية. - القراءة: ثلاث نقاط نهاية HTTP للمديرين/المهندسين فقط تكشف السجل وسجل تنبيهات وقت التشغيل.
السجل (38 فحصاً)
تغطي الفحوصات الـ38 (31 فحصاً من الشريك v5 + QA_032 حارس الإفراط في الاختبار + QA_033..QA_038 حواجز إعادة هيكلة الحزم في R12 Tier-D، بمصدرية new_in_wp_qac_be) الفئات الشاملة الرئيسية:
| الفئة | أمثلة |
|---|---|
| كفاية البيانات | QA_001 قاعدة التعادل / حارس do_not_decide_yet |
| الانحدار الحاد | QA_002 مراجعة انخفاض ≥20%؛ لا فشل تلقائي أبداً |
| سلامة التنشيط الجماعي | QA_003 استثناء DATA_INCOMPLETE، QA_004 استثناء الانحدار الحاد |
| اتساق التجمع | QA_005 هوية التجمع بالمفتاح الخماسي |
| سلامة مستوى التدرج | QA_006 فريدية (طالب × مهارة × حزمة × نوع مهمة) |
| تأكيد المعلم | QA_007 التأكيد الصريح مطلوب للتنشيط الجماعي |
| اللغة الحساسة | QA_022 تطبيق مرشِّح اللغة، QA_023 سلامة تقرير الوالدين |
| الاتفاق العربي | QA_008 فحص قواعدي عند الاستيراد |
| البيانات المقارنة | QA_009 المسابير المقارنة فقط تُقارَن |
| الحفاظ على المرساة | QA_020 وزن المرساة يجب أن يبقى الأكبر |
| منع التحميل الزائد | QA_021 حد أقصى خيطَين داعمَين |
| صحة المحتوى | QA_010 أسئلة الاستنتاج تحتاج evidence_sentence |
| نطاق الميزات العربية | QA_011 لا تُصعِّد ميزة عربية منفردة وحدها |
| تدقيق وقت التشغيل | QA_012 تثبيت إصدار القواعد على جميع القرارات |
| سلامة تقرير الوالدين | QA_023 لا ملصقات داخلية في ملف PDF الوالدين |
| حارس الإفراط في الاختبار | QA_032 تنبيه عند تجاوز المسابير الحد في فترة زمنية (جديد) |
| حواجز إعادة هيكلة الحزم (R12 Tier-D) | QA_033 حزمة أساسية واحدة لكل دورة، QA_034 التوجيه للمرحلة النشطة فقط (لا FUTURE_INACTIVE)، QA_035 لا توجيه لحزمة وهمية (رفض غير الحزمة في recommended_bundle_id)، QA_036 لا استنتاج نوع خطأ من ORF، QA_037 لا توجيه لميزة غير نشطة، QA_038 ملاءمة المحتوى / لا مسبار كتعليمات |
QA_027 (بوابة أمانة RTI) وQA_030 (تحقق متقاطع مع متتبع الأمانة) مسجَّلان وجاهزان للتوجيه لكنهما غير موصولَين بعد بحزم العمل المستهلِكة (WP-RTI-BE / متتبع الأمانة). سيُطلَقان عند ربط تلك الحزم بـrouteQaFailure.
مصفوفة توجيه الشدة
التوجيه حتمي بحقل severity في السجل؛ لا يمكن لموقع الاستدعاء تجاوزه:
| الشدة | ما يحدث |
|---|---|
critical | writeQaAlert (تُسجَّل التنبيه، surfacedToTeacher=true) + notifier.notifyCritical |
high | writeQaAlert + notifier.notifyEngineering (لا يُعرَض للمعلم) |
medium | writeQaAlert فقط |
low | تسجيل في runtimeLogTarget الخاص بالصف فقط؛ لا تنبيه يُكتَب، لا مُنبِّه |
في الموجة الأولى، المُنبِّه هو واجهة تسجيل فقط (logOnlyQaNotifier). لا اتصال شبكي. تكامل Slack مع #amal-alerts مُقرَّر لما بعد الإطلاق (Q-QAC-1).
تصل تنبيهات وقت التشغيل إلى جدول platform_alert_log الموجود (لا جدول جديد). الصفوف التي وجَّهها QA تضع alertKind = "qa_NNN" (بأحرف صغيرة) وعموداً severity، مما يجعل القراءات المُفلتَرة مسحاً بفهرس مُغطَّى.
حارس الإفراط في الاختبار (QA_032)
QA_032 فحص جديد أضافته هذه الحزمة (ليس من مواصفات الشريك v5). يُطلَق حين يجمع طالب أكثر من over_testing_threshold مسباراً في نافذة over_testing_window يوماً.
نقاط التصميم الرئيسية:
- لا يحظر أبداً. المسبار يُسجَّل دائماً. يُطلَق الحارس بعد الكتابة كتوصية إرشادية.
- الإعدادات الافتراضية: الحد = 8 مسابير، النافذة = 14 يوماً (للتأكيد مع الشريك في جلسة 25 يونيو).
- يُحقَن الحارس في
monitoring/repository/evidence-writer.tsعند بدء التشغيل؛ لا دورة استيراد بينmodules/qaوmodules/monitoring.
إصدار السجل
يُصدر المديرون مجموعة فحوصات جديدة بـPOST /api/admin/qa/checks-set. تُطبِّق نقطة النهاية:
- يجب توفير موافقة الشريك (
partnerApprovedBy+partnerApprovedAt). - يجب الإقرار بالفرق صراحةً (
acknowledgeDiff: true). - يجب أن تكون جميع الفحوصات الـ38 موجودة في الحمولة.
ciLintCommandلكل صف يجب أن يكون أمر مساحة عمل قابلاً للتشغيل.failureMessageArلكل صف يجب أن يجتاز مرشِّح سلامة اللغة (لا سلاسل فرعية محظورة).
يُعاد 422 عند أي ثغرة. البذرة (v1) هي المسار المستخدَم عند النشر الأولي؛ نقطة النهاية هذه تحكم النشرات اللاحقة.
نقاط نهاية الAPI
نقاط القراءة الثلاث ونقطة نشر الإصدار تتطلب صلاحيات مرتفعة؛ لا يمكن للمعلم أو الطالب الوصول إليها (تُعيد 403):
| نقطة النهاية | الصلاحية | ما تُعيده |
|---|---|---|
GET /api/qa/checks | VIEW_QA_REGISTRY أو RUN_BACKOFFICE أو SUPER_ADMIN | السجل الكامل (عالمي، بدون تصفية مستأجر، لكن يتطلب requireTenantContext لاشتقاق الصلاحيات) |
GET /api/qa/runtime-alerts | نفسه | التنبيهات المُقيَّدة بالمنظمة حيث alertKind LIKE 'qa_%'؛ يدعم ?severity=، ?from=، ?to=، ?qaCheckId= |
GET /api/admin/qa/audit-summary | RUN_BACKOFFICE أو SUPER_ADMIN | أعداد حسب الفحص والشدة لنطاق زمني (تغذية جولة الشريك قبل الإطلاق) |
POST /api/admin/qa/checks-set | RUN_BACKOFFICE أو SUPER_ADMIN | نشر إصدار سجل جديد |
VIEW_QA_REGISTRY هو رمز الصلاحية الخامس والعشرون في التعداد المغلق ذي 25 قيمة.
اتفاقية test:qa:NNN
ciLintCommand لكل صف في السجل هو أمر مساحة العمل الفعلي الذي يُطبِّقه. يضيف package.json اسماً مستعاراً رقيقاً test:qa:NNN لكل صف يُفوِّض إلى ذلك الأمر الأصلي (مثل test:qa:003 → test:cluster:exclusions)، بالإضافة إلى مجموع pnpm test:qa المُزال فيه التكرار. مهمة CI qa-registry تُشغِّل pnpm test:qa وpnpm lint:qa وتحجب طلب التغيير عند الفشل.
صفحات ذات صلة
- قواعد السلامة: بنية السلامة الشاملة التي تُشكِّل شبكة الأمان لهذه الوحدة
- سلامة اللغة: QA_022 وQA_023 يشيران إلى التطبيق هنا
- التجميع الذكي: QA_003 وQA_004 تُطبَّق في وحدة التجمع
- مراقبة التقدم: QA_032 تُطلَق من كاتب الأدلة