تكامل الفروع داخل موديول المعامل — Multi-Branch LIS

نموذج المعامل الكبرى (Hub & Spoke) · الصلاحيات ومجموعات الموظفين · ما هو موجود · الفجوات · التصميم · كله من جوّه المعمل

1 اللي طلبته (تأكيد الفهم)

2 المعامل الكبرى بتعمل ايه؟ (Hub & Spoke — نموذج المعمل المرجعي)

ده بالظبط اللي إنت بتوصفه — المعيار العالمي للسلاسل والمعامل متعددة الفروع:

🏪 الفرع (Spoke)
تجميع + تحاليل بسيطة
→ يحوّل ← 🏛️ المركزي (Hub)
كل التحاليل المعقّدة
→ النتيجة ترجع ← 🏪 الفرع يشوف النتيجة + يطبع
المبدأإزاي بيشتغل في المعامل الكبرى
الفرع = موقع تجميع + منيو محدوديسجّل المريض، يجمع العينة، يحلل منيو صغير محليًا (CBC, بول, براز, سكر) بأجهزة صغيرة.
المركزي = المعمل المرجعييحلل المنيو الكامل (كيمياء، هرمونات، باثولوجي…) لكل الفروع.
توجيه العينات (Routing)التحاليل اللي الفرع ما يقدرش يعملها تتحوّل للمركزي مع مانيفست/سلسلة عهدة وتتبّع الحالة (بالفرع → في الطريق → وصل المركزي → اتحلّل).
مستودع نتائج مركزيالنتيجة تظهر في الفرع الأصلي ومركزيًا. التقرير يوضّح فرع السحب + الفرع المُنفّذ (مطلوب اعتماديًا).
وورك-ليست لكل فرعكل فرع يشوف شغله المعلّق؛ المركزي يشوف الطابور المجمّع.
تشغيل لكل فرعمخزون/كواشف، خزنة/كاش، QC، وصلاحيات لكل فرع على حدة.
الخلاصة: رؤيتك مطابقة 100% لنموذج Hub & Spoke. وعندنا بالفعل بنية الـ الإحالات (Referrals) اللي نقدر نوسّعها لتكون إحالة داخلية للفرع المركزي بدل معمل خارجي.

3 اللي موجود فعلًا في النظام (الأساس)

العنصرالحالةالتفاصيل
موديل الفرعموجودis_main (الفرع المركزي)، is_active. لكنه مسطّح (مفيش parent/هرمية).
ربط اليوزر بالفروعموجودMany-to-many branch_user + is_primaryuser->primaryBranch().
branch_id على الكياناتجزئيموجود على: الريكوست، العينة (بتتختم تلقائي ✓)، الزيارة، الفاتورة. ناقص: المدفوعات، النتيجة.
الأدمن = يشوف الكلموجود (FE)سوبر أدمن = أدوار وصلاحيات فاضية. permissionService.isSuperAdmin().
نمط فلتر الفرع (FE)موجودBranchContextService + نمط مجرّب في الخزن/الأصول (dropdown مفلتر بفروع اليوزر).
نمط الإعداداتموجودصفحة «إعدادات المعمل» التبويبية — نضيف تبويب/سويتش بسهولة.

4 الفجوات (الناقص)

1) مفيش فلترة تلقائية بالفرع: كل اليوزرز بيشوفوا كل الفروع (الفلترة بالشركة بس). مفيش «اليوزر يشوف فرعه».
2) branch_id مش بيتختم في كل مكان: الريكوست/المدفوعات/النتيجة مش بتتختم بفرع اليوزر تلقائيًا (العينة بس).
3) مفيش منيو فرع (قدرات): مفيش تعريف «الفرع ده يعمل أنهي تحاليل». مفيش ربط جهاز↔فرع ولا تحليل↔فرع.
4) مفيش توجيه داخلي بين الفروع: الإحالات الموجودة للمعامل الخارجية بس — مفيش «حوّل للفرع المركزي» داخليًا.
5) مفيش فلتر فرع في شاشات المعمل ولا selector في الهيدر، ومفيش صلاحية «شوف كل الفروع».

5 التصميم المقترح — ركيزتان، كله جوّه المعمل

الركيزة (أ): نطاق ورؤية الفروع — Branch Scoping

الركيزة (ب): منيو الفرع + التوجيه الداخلي — Hub & Spoke

Order @ Branch "Maadi" → tests: [Stool, CBC, TSH] Stool → in Maadi worklist (branch can do it) CBC → INTERNAL REFERRAL → Hub (not in Maadi menu) TSH → INTERNAL REFERRAL → Hub ───────────────────────────────────────────── Hub resolves CBC, TSH → results flow back to Maadi Report: Collected at Maadi · Performed at Central Lab

فين بيتعمل ده؟ (كله جوّه المعمل)

6 الصلاحيات ومجموعات الموظفين — من جوّه المعمل

إنت عايز تظبط صلاحيات المعمل من جوّه المعمل: تعمل مجموعات موظفين (أدوار) كل واحدة بخواصها، وكل زرّ/فنكشن في كل شاشة بصلاحية، وكل دور له نطاق بيانات وصفحة رئيسية.

الأدوار اللي إنت ذكرتها

الاستقبال (Reception) فني التجميع (Collector) الكيميائي / منفّذ التحليل فني المعمل مدير المعمل

كل فنكشن في كل شاشة = صلاحية (مصفوفة الصلاحيات)

الشاشةالفنكشنات (كل واحدة صلاحية مستقلة)
الطلبات (Requests)عرض · إضافة · تعديل · حذف · طباعة · إلغاء
التجميع (Collection)تجميع · طباعة باركود · تأجيل
الاستلام (Receiving)استلام · رفض
الورك-ليست (Worklist)إدخال نتيجة · ري-رن · طباعة
الفاليديشن (Validation)اعتماد (Validate) · إطلاق (Release) · طباعة
عامكل شاشة view مستقل + الأزرار محكومة بالصلاحية (تختفي/تتعطّل لو ملوش صلاحية)

نطاق البيانات لكل دور (Data Scope) — مرتبط بالفروع 👇

ده بالظبط نفس محور الفروع — نطاق واحد موحّد لكل دور:
النطاقيشوف ايه
own — بياناته بساللي هو أنشأه فقط (مثلاً ريسبشن يشوف طلباته هو).
branch — بيانات الفرعكل بيانات اليوزرز جوّه فرعه.
all — كل الفروعالمدير/الأدمن — كل حاجة + فلتر بالفرع.
يعني سؤالك «يتحكم في بياناته هو بس ولا كل بيانات الفرع» = خاصية data_scope على الدور، وهي نفسها اللي بتحدد رؤية الفروع.

صفحة رئيسية لكل دور (Home Page)

كل دور يختار صفحته الرئيسية من الشاشات الموجودة — أول ما اليوزر يفتح يروح عليها. مثلاً فني التجميع → صفحة «التجميع» تفتح أول.

اللي موجود مقابل الناقص

العنصرالحالةالتفاصيل
أدوار وصلاحيات (Spatie)موجودنظام أدوar/صلاحيات كامل + شاشة Roles في الموديول الرئيسي.
صلاحيات LISموجود (139)139 صلاحية lis.* متفصّلة (طلبات، عينات، نتائج، كانبان…). معظم فنكشناتك موجودة (collect/receive/reject/enter/validate/release).
شاشة أدوار جوّه المعملناقصمحتاجين نسخة LIS-only تعرض صلاحيات lis.* بس، مجمّعة حسب الشاشة.
نطاق البيانات (own/branch/all)ناقصمفهوم جديد على الدور — data_scope (موحّد مع الفروع).
صفحة رئيسية للدورناقصحقل home_page جديد على الدور + توجيه عند الدخول.
بعض الفنكشنات الدقيقةجزئيزي طباعة/تأجيل/ري-رن/طباعة-باركود — نضيف اللي ناقص لإكمال المصفوفة.
ليه مع الفروع؟ النطاق (own/branch/all) هو نفسه محور رؤية الفروع — فالأدوار والفروع بيشتركوا في نفس الآلية: الدور بيحدد الصلاحيات + النطاق، والفرع بيحدد الـ branch_id. عشان كده بنعملهم مع بعض.

7 خطة على مراحل

المرحلة 1 — النطاق + الصلاحيات (تسلّم الرؤية بالفرع + أدوار المعمل):
  • ختم branch_id في كل العمليات + إضافته للمدفوعات/النتيجة.
  • data_scope على الدور (own/branch/all) + فلترة سيرفر.
  • شاشة أدوار المعمل (مصفوفة صلاحيات lis.* حسب الشاشة) + home_page.
  • الأزرار في كل شاشة محكومة بالصلاحية (تختفي/تتعطّل) + selector الفرع.
المرحلة 2 — Hub & Spoke (براز هنا، CBC للمركزي):
  • منيو الفرع (قدرات التحاليل لكل فرع).
  • زر «حوّل للمركزي» (يدوي) + رجوع النتيجة.
  • تقرير «سُحب في / نُفّذ في».

8 القرارات المؤكَّدة ✓

القرارالمؤكَّد
رؤية الفروعقابلة للتحكم لكل دور عبر data_scope (own / branch / all) — مش binary صارم. الأدمن: all.
منيو الفرعمنيو لكل فرع — كل فرع يختار تحاليله؛ المركزي يعمل الكل افتراضيًا.
التوجيه الداخلييدوي — زر «حوّل للمركزي» (مش تلقائي).
إظهار الفروعتلقائي حسب عدد الفروع + إمكانية override.
الصلاحياتشاشة أدوار جوّه المعمل، مصفوفة lis.* حسب الشاشة/الفنكشن، + data_scope + home_page لكل دور.
Moon ERP · LIS · تكامل الفروع + الصلاحيات — القرارات مؤكَّدة. التنفيذ بادئ بالمرحلة 1.