خطة إصلاح باركود B2B: تحليل ABO لا يظهر على الليبل

تحليل وتشخيص فقط، بدون تنفيذ. المطلوب موافقة المالك على الخطة قبل أي تعديل في السورس أو build أو release.

قرار التشغيل

لن يتم تعديل staging أو نسخ ملفات إليه. أي إصلاح بعد الموافقة سيكون في السورس على moonui، ثم tests، ثم changelog، ثم commit/push. تحديث staging يتم لاحقا بواسطة المالك عبر MoonStack.

الحالة التي تم فحصها

البيئة s-elmadina.elbaset.com قراءة فقط من قاعدة selmadina_stg
المريض MRN-011876، الاسم في الداتا: test، أنثى، 30 سنة تقريبا
الطلب داخليا في الداتا: LR-2026-00094، وليس LI-2026-00059 في هذا الـstaging snapshot
العينة 26070700105، specimen: Whole Blood EDTA، section: Hematology، section code: HEM
التحليل ABO موجود ومربوط بالعينة في lab_sample_investigations، والحالة collected
إعداد الليبل الحالي lis.barcode_config.test_label_mode = "code"، لذلك ظهور ABO ككود هو السلوك المتوقع حاليا. لو المطلوب الاسم الكامل يصبح الإعداد name.

الخلاصة الفنية

الداتا سليمة: ABO موجود على الطلب والعينة. المشكلة في payload الخاص بطباعة باركود B2B. endpoint GET /api/lis/external-lab-portal/requests/{id}/barcodes يرجع داخل samples[].tests[] بيانات التحليل بدون id. بعد توحيد طباعة الباركود، الـFrontend يستخدم فلتر حماية يمنع طباعة أي investigation بلا id. النتيجة: الليبل يتبني، لكن قائمة التحاليل تصبح فاضية، فيختفي ABO.

الدليل من الكود

Backend: payload ناقص id

في Modules/LIS/app/Http/Controllers/ExternalLabPortalRequestController.php داخل barcodes():

->map(fn (LabInvestigation $inv) => [
    'code' => $inv->code,
    'name' => $inv->name,
    'name_en' => $inv->name_en ?? $inv->name,
    'is_panel' => (bool) $inv->is_panel,
])

لا يوجد id في test payload، ولا يوجد id للعينة نفسها في sample payload.

Frontend: الفلتر يرفض أي test بلا id

في src/app/core/services/lis-label-row.util.ts:

export function isLabelVisibleInvestigation(inv, memberIds): boolean {
  if (!inv?.id) return false;
  if (memberIds.has(inv.id)) return false;
  if (inv.is_searchable === false) return false;
  return true;
}

وفي portal-barcode-builder.ts يتم تحويل test كالتالي:

id: inv.id ?? t.id,
code: (inv.code || t.code || '').trim(),
nameEn: (inv.name_en || t.name_en || '').trim(),

بما أن الـBackend لا يرسل id، يصبح id فاضي، فيتم حذف ABO من الليبل.

مهم: مشكلتان متداخلتان وليستا نفس الشيء

المشكلة الحالة الأثر
يطبع الكود بدل الاسم تم لها إصلاح سابق في السورس: الـB2B endpoint يرجع label_config والـFE يمرره إلى renderer. لو الإعداد test_label_mode=name سيطبع الاسم الإنجليزي بدلا من الكود.
لا يطبع ABO أصلا المشكلة الحالية الـtests في payload بلا id. الـunified builder يحذف التحليل، فتظهر عينة بلا تحليل على الليبل.

الخطة المقترحة للموافقة

الاختيار الموصى به: إصلاح Backend payload مع الحفاظ على فلتر الـFrontend

لا نفتح فلتر الـFrontend لقبول tests بلا id، لأن هذا الفلتر موجود لمنع رجوع مشكلة قديمة: ظهور أعضاء البانل على الليبل. الحل الصحيح أن الـBackend يرسل payload كامل يطابق عقد الـunified barcode builder.

  1. تعديل ExternalLabPortalRequestController::barcodes() في السورس فقط لإضافة id إلى كل test: 'id' => $inv->id.
  2. إضافة حقول routing المفيدة لنفس test payload: specimen_type_id وlab_section_id وis_searchable.
  3. إضافة id للعينة في sample payload: 'id' => $s->id. هذا يعالج عيب جانبي: طباعة عينة واحدة بعد recollect تستخدم x.id === sampleId، لكن endpoint لا يرجع sample id حاليا.
  4. إبقاء label_config كما هو، لأنه حل مشكلة code/name في B2B portal.
  5. إضافة test في Modules/LIS/tests/Feature/ExternalLabPortalB2bTest.php يؤكد أن: data.samples.0.id موجود، وdata.samples.0.tests.0.id موجود، وcode=ABO لا يضيع.
  6. إضافة test ثاني أو توسيع test موجود يؤكد أن label_config.test_label_mode يرجع من إعداد الشركة، حتى لا ترجع مشكلة الكود/الاسم.
  7. تشغيل اختبار Backend محدد: /usr/local/bin/php vendor/bin/phpunit Modules/LIS/tests/Feature/ExternalLabPortalB2bTest.php أو أمر الاختبار المتبع في repo لو phpunit route مختلف.
  8. تشغيل php -l على الملفات المعدلة، ثم build للواجهة فقط لو احتجنا تعديل FE. في الخطة الموصى بها لا يوجد تعديل FE.
  9. إضافة release note ثنائي اللغة تحت [Unreleased] في docs/moonstack/CHANGELOG.md.
  10. commit/push على hazemdev. بعد ذلك المالك يقرر merge/release/update staging عبر MoonStack.

بدائل غير موصى بها

البديل لماذا ليس الأفضل
تعديل FE ليقبل test بلا id سيطبع ABO، لكنه يضعف حماية البانل وقد يعيد ظهور panel members على الليبل. هذا علاج عرض وليس جذر المشكلة.
تعديل staging مباشرة مرفوض كفلو طبيعي: يخلق drift بين staging والسورس والـrelease package، ويتخطى GitHub/MoonStack/changelog.
تغيير إعداد test_label_mode فقط لا يحل اختفاء ABO؛ هذا الإعداد يحدد code vs name بعد أن يكون test موجودا أصلا.

تحسين اختياري أقوى

بعد حل الـid يمكن لاحقا جعل endpoint يقرأ tests من lab_sample_investigations مباشرة، لأنها مصدر الحقيقة لما يوجد على كل عينة. هذا أقوى من إعادة مطابقة التحاليل بالـspecimen_type_id وlab_section_id. لكنه تغيير أوسع، لذلك لا أقترحه كأول خطوة إلا لو المالك يريد تقوية المسار بالكامل الآن.

معايير القبول بعد التنفيذ

الملفات المتوقع تعديلها بعد الموافقة

الملف نوع التعديل
/home/moonui/moon-erp-be/Modules/LIS/app/Http/Controllers/ExternalLabPortalRequestController.php إضافة sample.id وtests[].id وحقول routing في barcodes().
/home/moonui/moon-erp-be/Modules/LIS/tests/Feature/ExternalLabPortalB2bTest.php اختبار payload يمنع رجوع المشكلة.
/home/moonui/moon-erp-be/docs/moonstack/CHANGELOG.md Release note عربي/إنجليزي تحت [Unreleased].

مطلوب موافقة

أحتاج موافقة المالك على الخطة الموصى بها: Backend payload fix فقط، مع tests وchangelog، بدون تعديل staging مباشر. بعد الموافقة أبدأ التنفيذ في السورس.