صلاحيات المستخدمين في المعمل — لماذا يرى الكاشير أكثر مما مُنح؟

تشخيص حالة emad.ghali@yahoo.com (دور reception) · أين تُطبَّق الصلاحيات · المشاكل الحقيقية · خطة العلاج — دراسة قبل التنفيذ

1 الخلاصة في 4 نقاط (اقرأها الأول)

① الباك إند آمن. اختبرنا الحساب فعليًا: أي endpoint مالوش صلاحية فيه رجّع 403 (الأقسام، الأجهزة، QC، الخزائن، التقارير، المعامل الخارجية…). مفيش تسريب بيانات.
② المشكلة الأساسية = إعداد الدور، مش باج في الكود. دور "reception" ماخد 46 صلاحية على ~15 مورد. القائمة الجانبية بتعرض بالظبط اللي الدور بيسمح بيه — فهو "شايف كتير" لأن الدور نفسه واسع، مش لأن في خلل في الفلترة. ده أسرع حاجة تتظبط: من شاشة الأدوار.
③ الخطير مش "بيشوف" — الخطير "بيقدر يعمل". الدور فيه صلاحيات مدمّرة الكاشير المفروض ميكونش معاه: payments.void (إلغاء دفعات)، invoices.cancel، invoices.delete، requests.delete، patients.delete، doctors.delete. دي قدرات حقيقية (الباك إند بينفّذها لأنها ممنوحة)، مش مجرد شاشة فاضية.
④ تسريب شكلي (UX): راوتس /lab/* مفيهاش أي حارس صلاحيات — لو اليوزر كتب لينك شاشة ممنوعة بإيده، هيكل الشاشة بيظهر (عنوان + جدول فاضي + زرار «جديد») والداتا بترجع 403. منظر مزعج لكن مش تسريب بيانات.

2 إزاي الصلاحيات بتتطبّق؟ (3 طبقات)

الطبقةالمكانالحالةالتقييم
1. الباك إند (الحماية الحقيقية) كل Controller فيه permission:lis.X.action على كل أكشن (view/create/update/delete/post/cancel…) دقيقة ومُفعّلة — بترجع 403 سليمة ✓
2. فلترة القائمة (Sidebar) lis-layoutfilteredNavGroupsPermissionService.hasAnyPermission(prefix) بتخفي العناصر اللي مفيش ليها صلاحية (مجموعات External Labs / Costing / Quality اختفت كلها لـ emad) شغّالة بس بالـ prefix الخشن
3. حُرّاس الراوت (Route Guards) lis-standalone.routes.ts (مسارات /lab/*) 57 راوت — صفر حارس صلاحيات. الأب عليه authGuard بس (تسجيل دخول فقط) مفقودة ✗
المسارات المدمجة /core/lis/* عليها حارس واحد عام على الأب: data: { permissions: ['lis.'] } — يعني أي يوزر عنده أي صلاحية lis.* يقدر يفتح كل شاشات المعمل المدمجة. خشن جدًا.

3 حالة emad بالتفصيل — "بيشوف" مقابل "بيقدر يعمل"

الدور reception عنده 46 صلاحية. التقسيم:

أ) صلاحيات مدمّرة / مرتفعة — الأخطر — راجِعها فورًا

الصلاحيةبتسمح بإيهكاشير المفروض يكون معاه؟
lis.payments.voidإلغاء/تصفير دفعة متسجّلةلأ
lis.invoices.cancelإلغاء فاتورة (قيد عكسي محاسبي)لأ
lis.invoices.deleteحذف فاتورةلأ
lis.requests.delete / requests.cancelحذف/إلغاء طلبلأ (الإلغاء ربما بصلاحية منفصلة)
lis.patients.deleteحذف مريضلأ
lis.doctors.delete / create / updateإدارة الأطباء بالكامللأ (يكفي view)
lis.visits.deleteحذف زيارةلأ
دي قدرات تنفيذية حقيقية — مش شاشات فاضية. لو الكاشير ضغط الزرار، الباك إند هينفّذ لأن الصلاحية ممنوحة فعلاً. دي أهم نقطة في الدراسة.

ب) صلاحية واحدة بتفتح أكتر من شاشة (الـ prefix الخشن)

الفلترة بتقارن بـ "يبدأ بـ" (startsWith)، فالصلاحية الواحدة بتكشف كل الشاشات اللي بتشترك في نفس البادئة:

عند emadالشاشات اللي بتظهر بسببهاملاحظة
lis.results.view فقطWorklist + Review & Release (الاعتماد/الإصدار)شاشة الإصدار حساسة — تفتح بصلاحية «عرض» فقط
lis.payments.*Payments + Cashier Shift + Cashier Reconciliation + Cash Flowمنحة واحدة → 4 شاشات (منها إدارية)
lis.invoices.*Invoices + Receivablesمقبول للكاشير

ج) تسريب شكلي بالـ URL المباشر (دليل من اختبار حقيقي على جلسة emad)

القائمة الجانبية بتخفي الشاشات دي صح، لكن لو فتحتها بالـ URL مباشرة الهيكل بيظهر:

الشاشةالنتيجة عند الفتح المباشرالداتا
/lab/machinesظهر الهيكل كامل (عنوان «Lab Machines» + أعمدة + زر «New Machine»)7 × 403
/lab/sectionsظهر الهيكل5 × 403
/lab/treasuriesظهر الهيكل4 × 403
/lab/reports · /lab/external-labs · /lab/qcكلها ظهر هيكلها403
بيانات محمية الباك إند بيرجع 403 هيكل ظاهر عنوان + جدول فاضي + أزرار

4 المشاكل وأماكنها في الكود

#المشكلةالمكانالخطورة
1دور "reception" واسع جدًا (46 صلاحية فيها مدمّرة)إعداد الدور (شاشة الأدوار / السيدر)عالية (قدرة فعلية)
2صفر حُرّاس صلاحيات على /lab/*lis-standalone.routes.tsمتوسطة (هيكل فقط)
3حارس /core/lis/* عام بـ ['lis.']app.routes.ts سطر 186متوسطة
4prefix خشن: صلاحية «عرض» تكشف شاشات إجراءاتpermission.service.ts (startsWith) + nav prefixesمنخفضة (تصميم)
5لينك «Settings» ظاهر دايمًا بدون صلاحيةهيدر lis-layoutمنخفضة

5 خطة العلاج — مرتبة بالأثر والسرعة

① فورًا (بدون كود): ظبط دور reception من شاشة الأدوار
شيل الصلاحيات المدمّرة (void / cancel / delete / إدارة الأطباء) — يحل «بيشوف» و«بيقدر يعمل» مرة واحدة. ده تغيير بيانات تعمله إنت دلوقتي.
② تحصين (كود FE): حارس صلاحيات على كل راوت /lab/*
نضيف lisPermissionGuard يقرأ صلاحية الشاشة (نفس اللي في الـ nav) ويمنع الفتح المباشر — يوديه للداشبورد أو يعرض «لا تملك صلاحية» بدل الهيكل الفاضي. ونظبّط /core/lis/* بصلاحية لكل شاشة بدل ['lis.'].
③ تحسين (طويل المدى): فصل صلاحيات العرض عن الإجراء
صلاحية مستقلة للإصدار (lis.results.release)، وللكاشير-شيفت/التسويات/التدفق النقدي (بدل lis.payments العامة) — في الـ nav والباك إند.
④ اختياري: دور «cashier» جاهز ومُصغّر
نعمل دور مخصص للكاشير بصلاحيات الحد الأدنى، ونحوّل عماد ليه.

اقتراح مجموعة صلاحيات «كاشير» مصغّرة (للنقاش — مش نهائي)

يبقىيتشال
patients.view/create/update requests.view/create/update samples.view/collect/receive invoices.view/create payments.view/create results.view investigations/packages/price-lists.view doctors.view payments.void invoices.cancel/delete requests.cancel/delete patients.delete doctors.create/update/delete visits.delete
تنبيه على invoices.post: ميزة «التحصيل بضغطة» اللي عملناها بترحّل الفاتورة المسودة تلقائيًا قبل الدفع. فلو الكاشير هيحصّل، محتاج invoices.post (نسيبها) — بس نشيل invoices.cancel/delete. قرار رقم 4.

6 قرارات محتاج رأيك فيها

قرار 1 — تنفيذ ظبط الدور
أظبّط دور "reception" دلوقتي بإزالة الصلاحيات المدمّرة؟ (توصيتي: نعم فورًا) — ولا تفضّل نعمل دور "cashier" جديد ونحوّل عماد ليه؟
قرار 2 — حُرّاس الراوت
أضيف lisPermissionGuard على كل شاشات /lab/* و/core/lis/* عشان أمنع الفتح المباشر للهيكل؟ (توصيتي: نعم — تحصين مهم)
قرار 3 — فصل صلاحيات الإجراء
أفصل صلاحية الإصدار (Release) والكاشير-شيفت عن البادئات العامة؟ (توصيتي: مرحلة تانية بعد التحصين)
قرار 4 — مجموعة الكاشير المصغّرة
أعتمد المجموعة المقترحة فوق (مع إبقاء invoices.post عشان التحصيل)؟ أنت تحدد القائمة النهائية.

7 الخلاصة

بياناتك محمية (الباك إند بيرجع 403). اللي محتاج تحرّك: (١) ظبط دور reception فورًا — يشيل القدرات المدمّرة ويقلّل اللي بيتعرض. (٢) حُرّاس راوت على شاشات المعمل — تمنع تسريب الهيكل. الباقي تحسينات granularity على مهل.
دراسة فنية — Moon ERP / LIS · يونيو 2026 · للمراجعة والموافقة قبل التنفيذ