في طلب LR-2026-00308، تحاليل الغدة الدرقية (TSH / FT4 / FT3) ظاهرة في Collect كأكواد منفصلة بدل ما تتجمّع تحت اسم «Thyroid Panel». الملف ده بيشرح إيه اللي حصل بالظبط بالأدلة، السبب الجذري، والحل المعتمد على الباك إند (مش الفرونت) عشان يتعالج نهائياً لكل البنلات والباكدچات.
🗓️ 2026-06-08🧬 LIS — Collect / Reception / WorklistBackend-first · Plan before implement
1 العرض (اللي إنت شفته)
❌ الحاصل
تيوب واحد فيه أكواد مفكوكة:
TSH, FT4, FT3 (وكمان CHOL, TG, HDL, LDL, VLDL) — كل واحد لوحده.
✅ المتوقّع
تتجمّع تحت اسم الباكدج/البنل:
Thyroid Panel (TSH · FT4 · FT3) — مجموعة واحدة.
2 التشخيص — بالأدلة من قاعدة البيانات
أ. الطلب فيه الأعضاء بس — مفيش «أب بنل» مربوط
lab_request_investigations لـ LR-2026-00308
الكود
is_panel
investigation 17
TSH
0 (عضو)
investigation 18
FT4
0 (عضو)
investigation 19
FT3
0 (عضو)
مفيش صف للـ«أب البنل» (THYROID id=87 أو Thyroid Profile id=137).
ب. التحاليل دي فعلاً أعضاء بنل — بس في بنلين!
البنل (is_panel=1)
أعضاؤه
THYROID (87) «هرمونات الغدة الدرقية»
TSH · FT4 · FT3
THYROI (137) «Thyroid Profile»
TSH · FT4 · FT3
كمان فيه باكدجPKG-THYR (2) «باقة الغدة الدرقية» محتوياته = نفس التلاتة (17/18/19). يعني نفس التحاليل تنتمي لـبنلين + باكدج.
ج. إنشاء الطلب بيفكّ البنل/الباكدج لأعضائه — ويرمي الأصل
// LabRequestController@store (سطر 285)
if ($investigation->is_panel) {
foreach ($investigation->panelMembers as $member) {
// بيضيف صف request_investigation لكل عضو فقط
// ❌ «أب البنل» ما بيتربطش، وما بيتسجّلش العضو ده جه من أنهي بنل
}
}
// الباكدج (سطر 309): بيضيف الأفراد كمان — من غير ما يسجّل إنهم من باكدج معيّن
د. منطق التجميع في العرض بيحتاج «أب البنل» يكون مربوط
🎯 الطلب بيخزّن «تحاليل فردية» بس — من غير أي ذاكرة إنها اتطلبت كبنل/باكدج
جدول lab_request_investigationsمفيهوش أي عمود يتتبّع أصل المجموعة (لا panel_id ولا package_id).
وقت الطلب، البنل/الباكدج بيتفكّ لأعضائه، والأصل (الاسم «Thyroid Panel») بيضيع.
منطق العرض بيحاول يجمّع بشرط إن «أب البنل» يكون مربوط — وهو مش مربوط أبداً → بيظهروا مفكوكين.
وحتى لو حاولنا نجمّع بالعافية: العضو في بنلين (87 و137) → مبهم نختار أنهي اسم.
الخلاصة
المشكلة مش في الفرونت ولا في منطق العرض — المشكلة إن الباك مش بيحفظ المعلومة من الأساس: إن التلات تحاليل دول اتطلبوا كمجموعة «Thyroid Panel». من غير المعلومة دي، أي عرض (Collect/Reception/Worklist) مستحيل يجمّعهم صح.
4 الحل الجذري (معتمد على الباك إند)
نخلّي الطلب يفتكر المجموعة: نسجّل على كل تحليل إنه اتطلب كجزء من أنهي بنل/باكدج، والباك يجمّع العرض بناءً عليها. الفرونت يرسم الجاهز بس.
قبل: lab_request_investigations(investigation_id) → تحاليل فردية، الأصل ضايع → عرض مفكوك
بعد: lab_request_investigations(investigation_id, source_panel_id?, source_package_id?, group_label?)
└─ وقت الطلب: نختم على كل عضو المجموعة اللي جه منها
└─ وقت العرض: الباك يجمّع تحت اسم البنل/الباكدج → تيوب فيه "Thyroid Panel (TSH, FT4, FT3)"
بيحلّ غموض «العضو في بنلين» — لأننا بنسجّل المجموعة الفعلية اللي اتطلبت.
مفيش صفوف وهمية ولا تأثير على التسعير/العدّ.
مصدر واحد للحقيقة (الباك) — كل الشاشات تتجمّع نفس الطريقة.
بديل أبسط (وأضعف)
إننا نربط «أب البنل» في الطلب → التجميع الحالي يشتغل. بس ده مايغطّيش الباكدچات (واللي إنت طلبته باكدج)، وبيضيف صف غير قابل للفوترة. فمش كافي.
5 خطة التنفيذ (آمنة، بالترتيب)
مرحلة 1
تتبّع المصدر في قاعدة البيانات DBBackend
الهدف: الطلب يفتكر المجموعة.
migration: إضافة source_panel_id + source_package_id (nullable) على lab_request_investigations.
تعديل إنشاء الطلب: وقت فكّ البنل/الباكدج، نختم المصدر على كل عضو.
مرحلة 2
تجميع العرض في الباك Backend
الهدف: الباك يرجّع المجموعات جاهزة.
تحديث LabSampleResource + endpoints (reception-worklist / collection / worklist): يجمّعوا التحاليل تحت اسم البنل/الباكدج المسجّل (بدل شرط «أب البنل مربوط»).
fallback: لو مفيش مصدر مسجّل (طلبات قديمة)، نرجع للسلوك الحالي.
مرحلة 3
الفرونت يرسم الجاهز Frontend
الهدف: صفر منطق تجميع في الفرونت.
Collect/Reception يعرضوا المجموعة بالاسم اللي الباك بيرجّعه — من غير حسابات.
مرحلة 4
تحقّق Backend
طلب باكدج Thyroid → Collect يعرض «Thyroid Panel (TSH, FT4, FT3)» مجموعة واحدة.
طلب تحليل مفرد (TSH لوحده) → يفضل مفرد (مش يتجمّع غلط).
طلبات قديمة → السلوك زي ما هو.
6 قرار / ملاحظة
التحاليل دي تنتمي لـبنلين (THYROID 87, Thyroid Profile 137) + باكدج (PKG-THYR). تأكيد: اللي بتطلبه هو الباكدج «باقة الغدة الدرقية»؟ (عشان نختار اسم العرض الصح).
موافق على الحل المعتمد على تتبّع المصدر (source_panel_id/source_package_id)؟ ده الأصحّ والأشمل.
أنا جاهز أبدأ بمرحلة 1 (الـmigration + ختم المصدر وقت الطلب) أول ما توافق. كل الشغل في الباك، والفرونت يرسم الجاهز — زي ما عملنا في الورك ليست و Reception.