خطة الإيكونات الثلاث + Patient History — Worklist & Validation

الهدف: توحيد سلوك Re-run / Reject / Send Out في الصفحتين /lab/worklist و /lab/validation مع إضافة عمود Patient History جديد. كل الإيكونات تشتغل على مستوى التحليل أو على مستوى البنل كاملاً.

1) زرار Re-run (إعادة قراءة)

اللي عايزه المستخدم

الموجود حالياً

الطبقةالحالة
BE — POST /lis/results/{id}/retest مع reuse_sample=true موجود بيعمل:
  • يحدّث الـ original بـ is_retested=true
  • يعمل LabResult جديد بـ status=pending
  • ينسخ previous_result = original.result_value
  • يحط الـ reason جوه comment بكلمة "إعادة فحص: ..."
  • يكتب سطر في lab_result_audit_logs
FE — openReturnDialog + confirmReturn موجود بيستدعي retestReread. الـ reason مطلوب (required) ✗
FE — Previous column موجود ومعمول clickable بيفتح openHistoryDialog
FE — History dialog موجود لكن غلط بيجيب كل النتائج من كل الـ requests للمريض (يعني Patient History) مش history الـ rerun-chain للنتيجة دي. لازم يتفصل ✗

الفجوات

الفجوةالحل
الـ reason مطلوب حالياً، المستخدم عايزه اختياريBE + FE
BE: reason يبقى nullable في validate
FE: dialog يقبل comment فاضي + ميسموش "reason" يبقى "comment"
الـ history dialog بيعرض كل النتائج بدل rerun-chainBE + FE
BE: endpoint جديد GET /lis/results/{id}/rerun-history بيرجع سلسلة الـ retest_of حتى الأصل: كل نسخة معاها (value, comment, entered_by, entered_at)
FE: openRerunHistoryDialog بدل openHistoryDialog الحالي
الـ previousResult كحقل بيظهر القيمة الأخيرة بس، مش كل التاريخFE — العرض في الـ cell يبقى القيمة الأخيرة + Badge عدد المرات (مثلاً ×3) لو فيه أكتر من واحدة. Click يفتح Dialog كامل

2) زرار Reject

اللي عايزه المستخدم

الموجود حالياً

الطبقةالحالة
BE — POST /lis/results/{id}/reset مع reason موجود بيرجع الـ result لـ status=pending ويصفّر القيمة
BE — flow الـ recollect من Reception موجود الـ SampleInvestigationService::moveTo بيدعم رفض + إعادة تجميع، ولما الـ sample يتجمع تاني الـ listener بيعمل LabResult جديد فاضي
BE — قائمة Rejection Reasons موجود GET /lis/rejection-reasons?is_active=true — مفيش شك
FE — Reject dialog جزئي فيه dialog لكن بيكتب reason كنص حر — مفيش dropdown للأسباب المحفوظة
FE — locked row indicator موجود الـ lockedGroupsForRequest section بتظهر التحاليل المرفوضة فوق الجدول
FE — منع إدخال نتيجة في صف rejected موجود via isEditable + notReceivable

الفجوات

الفجوةالحل
الـ reject dialog مفيهوش dropdown للأسباب المحفوظةFE استخدام test-action-dialog الموجود (الـ shared component) بدل الـ dialog المحلي — هو فعلاً عنده reason picker + text box
لما الصف يكون مرفوض، التحاليل تظهر في "Locked" فوق الجدول مش جنب اسمه في الجدول نفسهFE إضافة badge "Rejected" + lock icon على الصف نفسه في الجدول، مع تمييز بصري (خط بيشطب الـ value، خلفية رمادية)
لما الـ panel كله يترفض، الـ status بتعت البنل لازم تبقى RejectedFE الـ rollupPanelStatus الحالي ميعرفش rejected — لازم يضاف للترتيب

3) زرار Send Out

اللي عايزه المستخدم

الموجود حالياً

الطبقةالحالة
BE — POST /lis/referralsموجود بيعمل referral للتحليل
BE — GET /lis/external-labsموجود
BE — GET /lis/external-labs/{id}/pricingموجود بيرجع {investigation_id, price, tat_hours}
FE — Send Out dialog جزئي dropdown للمعامل بس — بدون سعر أو TAT
FE — Send Out at panel-level جزئي بيشتغل بس بيفتح dialog للعضو الأول فقط
FE — Result entry لـ external row موجود الـ isExternalLab flag موجود ومش بيمنع الإدخال

الفجوات

الفجوةالحل
الـ dialog بيعرض اسم المعمل بس، مفيش سعر أو TATFE الـ dialog يجيب external-labs/{id}/pricing لكل معمل مرة واحدة عند الفتح. يعرض جدول: اسم المعمل · السعر · TAT بالساعات · زرار "اختار"
العرض كقائمة فيها radio button لكل معمل، اللي مالوش سعر للتحليل ده يظهر "—" بدل السعر
الـ panel-level send out بيبعت العضو الأول فقطFE + BE اختياري
الـ dialog يبقى فيه checkboxes للأعضاء (مفعّلين كلهم بشكل افتراضي)، والـ submit يبعت referral لكل عضو متشاك
الـ External badge على الصف مش واضح بصرياًFE badge أصفر/برتقالي صغير "EXT · LabName" جنب الـ test code، مع tooltip فيه TAT والـ status

4) عمود جديد — Patient History (تاريخ المريض)

اللي عايزه المستخدم

الموجود حالياً

الطبقةالحالة
BE — fetch previous results across requests موجود ممكن يتجاب عبر GET /lis/results?patient_id=X&investigation_id=Y&statuses=released
FE — fetch logic موجود لكن للسبب الغلط الـ fetchPreviousResultsForRows الحالي بيجيب previous results للمريض ويحطها في حقل previousResult — وده اللي بيظهر في عمود Previous حالياً. المنطق ده مكانه الـ Patient History الجديد، مش Previous

الفجوات

الفجوةالحل
الـ Previous والـ Patient History مدموجين في حقل واحدFE فصل المنطق:
previousResult: القيمة قبل آخر rerun داخل نفس الـ request (من الـ retest_of chain)
patientHistory: نتائج released للمريض في requests أخرى
عمودين منفصلين في الجدول، كلاهما clickable يفتح dialog مختلف
الـ patient history بيتجاب صف بصف (N+1)FE bulk fetch: قائمة (patient_id, investigation_id) فريدة → request واحد بيرجع كل الـ history → mapping محلي. اللي عمل بالفعل في fetchPreviousResultsForRows

5) صفحة Validation — نفس الـ 3 إيكونات + إضافات

القاعدة: صفحة /lab/validation فيها كل اللي في /lab/worklist + إيكونات إضافية للـ approval workflow.

الإيكونات اللي في Validation وليست في Worklist

الإيكونةمتى تظهرالـ BE endpoint
Validate ✓status = enteredPOST /lis/sample-investigations/{id}/validate — موجود
Approvestatus = validatedPOST /lis/sample-investigations/{id}/approve — موجود
Releasestatus = approvedPOST /lis/sample-investigations/{id}/release — موجود
Print 🖨status = releasedPOST /lis/sample-investigations/{id}/print — موجود
Publish 📡status = printed أو releasedPOST /lis/sample-investigations/{id}/publish — موجود
Unpublish (Retract)status = released/printed/publishedPOST /lis/sample-investigations/{id}/unpublish — موجود

اللي موجود في الـ Validation حالياً

الخطة التنفيذية المقترحة

المرحلة 1 — BE

المرحلة 2 — FE Re-run

المرحلة 3 — FE Reject

المرحلة 4 — FE Send Out

المرحلة 5 — FE Patient History

المرحلة 6 — Validation Page

تحذيرات وقرارات محتاجة منك

  1. الـ rerun-history endpoint — أعمله جديد ولا أعتمد على lab_result_audit_logs الموجود؟ الـ audit logs فيها كل التغييرات (مش بس rerun) فمحتاجة فلترة.
  2. الـ panel-level Send Out — لو الأعضاء في تخصصات مختلفة (مثلاً CBC نصه دم ونصه biochemistry)، المعامل اللي بتقدم سعر للأعضاء كلها هتكون قليلة. أعرض المعامل اللي بتدعم على الأقل عضو واحد ولا اللي بتدعم كل الأعضاء؟
  3. الـ Patient History column — هيتعرض ازاي لما يبقى فيه 5 نتائج سابقة؟ آخر قيمة + count؟ ولا 3 قيم + ...؟
  4. الكومنت في Re-run — لو فاضي، يتسجل ايه في الـ audit log؟ "Re-run (no reason)" ولا فاضي؟

ترتيب التنفيذ المقترح

  1. المرحلة 5 (Patient History) — أبسط، مش بتأثر على endpoints موجودة
  2. المرحلة 2 (Re-run) — بناء على audit log أو endpoint جديد
  3. المرحلة 3 (Reject) — استبدال dialog فقط
  4. المرحلة 4 (Send Out) — أكتر تعقيداً (pricing + TAT + multi-select)
  5. المرحلة 6 (Validation page) — نقل وتعميم

الملف ده مرجع للنقاش قبل البدء في التنفيذ. اقرأه وقولي:
1) الإجابة على التحذيرات الأربعة فوق
2) لو الترتيب يناسبك ولا تحب نبدأ بحاجة معينة
3) لو فيه فيتشر زودته