# خطة اختبار ونشر الإشعارات

## نطاق الضمان

يغطي النظام 46 سيناريو إشعار آلي بالعربية والإنجليزية عبر Database وRedis وFCM/APNs والبريد وSMS. يتم إنشاء النص من `message_key` وبيانات محايدة لغويًا، ثم يُعرض حسب `locale` الخاص بالمستلم.

الاستثناء المقصود هو إشعار الأدمن اليدوي: ما دام `SendNotificationRequest` يستقبل `title` و`body` كنص واحد، فلا يمكن ترجمة النص الحر تلقائيًا بصورة مضمونة. لم يتغير هذا العقد.

## التغطية المنفذة

- تطابق كتالوجي العربية والإنجليزية، وتطابق المتغيرات وعدم وجود نص إنجليزي ثابت في القالب العربي.
- اختبار كل الحالات الـ46، والجمهور الصحيح لكل حالة.
- اختبار القيم الديناميكية: الخدمة، العنوان، نوع الموعد، التاريخ والسبب الحر.
- اختبار API والحقول التي تعتمد عليها الواجهة، والقراءة والحذف وإعداد اللغة.
- اختبار Database وRedis وFCM/APNs وQueue وtransaction commit/rollback.
- اختبار البريد وSMS ورمز التحقق باللغتين.
- اختبار مسارات الطلبات والمحفظة والشركات والفنيين.
- اختبار endpoints العقود الحقيقية: الإنشاء والتوقيع والقبول والرفض والإنهاء وقبول/رفض التجديد.
- اختبار أوامر إصدار الفواتير، قرب الاستحقاق، التأخير وقرب انتهاء العقود.
- تسجيل `contracts:check-expiring` و`invoices:check-due` يوميًا في Scheduler.
- منع تكرار الإشعارات المجدولة بعلامات دائمة في قاعدة البيانات و`lockForUpdate`، مع اختبار تشغيل كل أمر مرتين.
- اختبار تقديم الفني الحقيقي بعد التحقق من OTP ووصول إشعار الطلب إلى الأدمن.
- اختبار إصلاح lazy loading في إضافة عنصر للسلة.

## أمثلة قبل وبعد

- قبل: `تم إسناد طلب Plumbing في Home والموعد scheduled.`
- بعد: `تم إسناد طلب السباكة في المنزل والموعد مجدول.`

- قبل: `تم تحديث الموعد إلى 26 August 2026.`
- بعد: `تم تحديث الموعد إلى 26 أغسطس 2026.`

- قبل: `تعذر رد المبلغ: Order is not eligible.`
- بعد: `تعذر رد المبلغ: تم توضيح السبب في التفاصيل.`

## الواجهة الأمامية

لا يوجد تغيير في أسماء حقول الاستجابة أو طلب إرسال إشعار الأدمن. يجب على الواجهة حفظ `locale` بقيمة `ar` أو `en`. الخادم يعيد `title` و`body` جاهزين ولا تحتاج الواجهة إلى ترجمة `message_key`.

عقد الأدمن الذي ينشئه الخادم يبقى بحالة `draft`. أصبح توقيع الشركة يقبل `draft` أو `pending_signature`، ثم ينقله إلى `pending_approval`؛ هذا يغلق مسار التوقيع دون تغيير response schema.

## ترتيب النشر

1. أخذ نسخة احتياطية من قاعدة البيانات.
2. نشر الكود والم migrations معًا.
3. تشغيل `php artisan migrate --force`.
4. مسح كاش الإعدادات بالطريقة المعتمدة في السيرفر.
5. إعادة تشغيل queue workers.
6. التأكد من تشغيل cron الخاص بـ `php artisan schedule:run` كل دقيقة.
7. تنفيذ smoke test على مستخدم عربي وإنجليزي وجهاز FCM/APNs فعلي لكل منهما.

## بوابات Go/No-Go

يسمح بالنشر النهائي عند:

- صفر failures في حزمة الإشعارات.
- نجاح migrations على نسخة staging حديثة.
- وصول إشعار push فعلي بالعربية والإنجليزية.
- تطابق محتوى الجهاز وinbox وRedis.
- عدم التكرار عند إعادة تشغيل الأوامر المجدولة.
- عدم وجود queue exceptions أو backlog غير طبيعي.

## نتيجة الاختبار الحالية

- حزمة الإشعارات: **51 اختبارًا ناجحًا، 2,493 تحققًا، صفر failures**.
- حزمة الانحدار المرتبطة: **168 اختبارًا ناجحًا، 2,758 تحققًا، صفر failures**.
- المشروع كاملًا: **385 اختبارًا ناجحًا و65 failure خارج الإشعارات**.
- الـ65 failure هي المجموعة نفسها من التشغيل السابق: fixtures أدمن بلا صلاحيات RBAC، اختبار `/` لمسار غير موجود، وثلاث حالات SupportChat في شكل `closed_at` وفلترة entity.

بوابة كود الإشعارات خضراء. اعتماد الإنتاج النهائي يبقى مشروطًا باختبار الخدمات الخارجية الحقيقية على staging.
