🔬 تحليل رحلة TSH على LR-2026-00147

الـ Request: LR-2026-00147 — Patient: فاطمة حسن إبراهيم (MRN-000002)
التحليل المتتبَّع: TSH (investigation_id = 17) على الـ external lab "Mokattam Lab"

١. ما الذي حدث فعلياً (Timeline)

الخطوة ١ — إنشاء الـ Request
الـ request اتعمل بـ TSH كـ outsourced (external_lab_id = 1) + Lipid Panel internal.
الخطوة ٢ — التجميع
اتعمل sample 22 = 260526EVM3P9 للـ TSH (external) + sample 23 = 26052631DJCC-BIO للـ Lipid (internal). الـ pivot rows اتعملت: pivot #44 (TSH على sample 22) بـ status=pending.
الخطوة ٣ — الاستلام في الـ Lab
الـ technician عمل scan لـ 260526EVM3P9 → sample 22 → status=delivered. الـ GenerateResultsOnSampleReceived listener اشتغل وأنشأ LabResult #13 للـ TSH بـ status=pending.
⚠️ ملاحظة: الـ pivot row 44 transitioned to status=received.
الخطوة ٤ — الرفض من Reception History
المستخدم فتح Reception → History → اختار TSH → ضغط رفض → اختار سبب.
POST /samples/22/reject + investigation_ids=[17] اشتغل:
الخطوة ٥ — Recollect من الـ Requests page
المستخدم فتح /lab/requests، شاف ايكونة الرفض الحمراء، ضغط عليها، اختار TSH، ضغط Recollect.
POST /requests/10/recollect + source=rejected, investigation_ids=[17] اشتغل:
الخطوة ٦ — الاستلام الجديد + المشكلة الفعلية
sample 24 ظهر في /lab/reception → To Receive، الـ technician استلمها → status=delivered. الـ pivot row 45 transition من pending → collected → received.

الـ GenerateResultsOnSampleReceived listener اشتغل، شاف الـ pivot row 45 (received) — وحاول ينشئ LabResult لـ TSH على sample 24...
❌ لكن الـ existence check وجد LabResult #13 موجود بالفعل (الـ original المرفوض)
الكود الحالي:
$existing = LabResult::query()
    ->where('lab_request_id', $request->id)
    ->where('lab_request_investigation_id', $pivot->lab_request_investigation_id)
    ->first();
if ($existing) {
    if ($existing->sample_id !== $sample->id) {
        $existing->update(['sample_id' => $sample->id]);  // ← يعمل re-bind
    }
    continue;
}
الـ listener عمل re-bind للـ LabResult #13 من sample 22 إلى sample 24. الـ result نفسها pending — فضلت قابلة للإدخال.

٢. الحالة النهائية في الـ DB

Entityidstatus / state
sample (original outsourced)22 — 260526EVM3P9delivered (orphaned — pivot 44 deleted)
sample (recollect)24 — SMP-2026-05-00109delivered
pivot (TSH on 22)44rejected → soft-deleted
pivot (TSH on 24)45received
lab_result (TSH)13pending — مربوط بـ sample 24

٣. ليه التحليل ظهر في الـ Validation وقابل لإدخال نتيجة؟

لأن الـ LabResult #13 رجع بـ status=pending بعد ما الـ recollect اتعمل، والـ GenerateResultsOnSampleReceived listener عمل re-bind للـ result من الـ original sample 22 → الـ recollect sample 24.

الـ FE behavior الحالي مقبول لو هو ده اللي عايزه: بعد ما الـ recollect يحصل، الـ test يبقى من جديد قابل لإدخال نتيجة — لأن الـ user قال "أنا عايز أرجع أعمله".

لكن المستخدم يطلب: طول ما الـ test في حالة "rejected" أو "awaiting recollect"، يبقى عنده **lock indicator** في الـ Validation/Workflow + مفيش إمكانية إدخال نتيجة لحد ما يتسلم تاني فعلاً.

٤. الفجوة الفعلية في الـ UX

الـ FE حالياً مفيش فيه أي حالة intermediate توضح للفني إن التحليل في رحلة re-collection:

٥. اللي محتاج يتعمل (التوصية)

على مستوى الـ Validation Screen

  1. Filter rows by pivot status — مش بس result.status:
    • لو الـ pivot الـ associated بـ status rejected أو recollected → show row as locked
    • لو الـ pivot في status pending/collected → block result entry
    • لو الـ pivot في status received أو بعدها → result entry متاحة
  2. Visual badge per row:
    • 🚫 Rejected — Awaiting recollect (red)
    • ♻️ Recollected — Awaiting receive (orange)
    • 📥 Received — Ready for result (green) ← الحالة الحالية اللي بتشتغل
  3. Tooltip with history يعرض كل الـ rejection cycles مع تواريخهم + الفني المسؤول

على مستوى الـ BE

  1. عند الـ partial rejection، الـ LabResult المرتبط بالـ rejected pivot لازم يتم setting بـ status=invalidated أو status=retracted (مش يفضل pending).
  2. عند الـ recollect، الـ Listener يـ create LabResult جديد بدل ما يعمل re-bind للقديم — الـ القديم يفضل في الـ DB كـ audit trail.

٦. اقتراح Implementation

Phase 1 — BE Fix (minor)

Phase 2 — FE Indicator (small)

٧. السؤال للمستخدم

  1. هل التوصية أعلاه مقبولة؟ (الـ LabResult invalidated عند الـ rejection + result جديد لكل recollect cycle)
  2. ولا تفضل approach أبسط: الـ FE فقط يخفي الـ row من الـ Validation طول ما الـ pivot في حالة rejected/deferred/cancelled — مع indicator واضح في الـ requests page؟