# Beta Testing Checklist — `smk_customer`

**الإصدار:** Beta (commit `stabilize-smk-customer-beta`)  
**المنصة المستهدفة:** Android (أولوية) — iOS لاحقاً  
**اسم التطبيق:** SMK  

---

## معلومات جلسة الاختبار

| الحقل | القيمة |
|-------|--------|
| المختبر | |
| التاريخ | |
| الجهاز / الموديل | |
| Android / iOS | |
| حجم الشاشة | |
| نوع الاتصال | Emulator / LAN / Wi‑Fi |
| Backend | WAMP / Production |
| Build | Debug / Release |
| حساب الاختبار | |

---

## تهيئة البيئة (قبل أي اختبار)

- [ ] Laravel يعمل: `php artisan config:clear`
- [ ] قاعدة البيانات `smk_db` متصلة وبها بيانات (أقسام، منتجات، متاجر)
- [ ] **Emulator:** `cd smk_customer && flutter run`
- [ ] **جهاز حقيقي:** `flutter run --dart-define=USE_LAN_HOST=true` (أو `--dart-define=API_HOST=http://IP`)
- [ ] Firebase Android مُعدّ (`docs/FIREBASE_SETUP.md`)
- [ ] `.env` — البريد وFCM مضبوطان
- [ ] حساب عميل جديد + حساب عميل موجود للاختبار

**API Base المتوقع:**

- Emulator: `http://10.0.2.2/smk/public/api/v1`
- LAN: `http://192.168.1.118/smk/public/api/v1` (عدّل IP حسب شبكتك)

---

## مفتاح النتائج

| الرمز | المعنى |
|-------|--------|
| ✅ | نجح |
| ❌ | فشل — سجّل bug |
| ⚠️ | يعمل جزئياً |
| ➖ | غير قابل للاختبار |
| N/A | لا ينطبق |

---

## 1. التسجيل والدخول

### Splash & Auth Flow

- [ ] Splash → ينتقل للرئيسية (زائر) أو Home بعد login
- [ ] **تسجيل حساب جديد** — كل الحقول الإلزامية تُتحقق (اسم، هاتف، بريد، محل، محافظة، منطقة، عنوان، كلمة مرور)
- [ ] اختيار المحافظة من القائمة يعمل
- [ ] بعد التسجيل → دخول تلقائي → الرئيسية
- [ ] **تسجيل الدخول** — بريد أو هاتف + كلمة مرور
- [ ] «تذكرني» لا يسبب crash
- [ ] **نسيت كلمة المرور** → إدخال البريد → رسالة نجاح
- [ ] **OTP يصل للبريد** (تحقق Inbox + Spam) — **لا يظهر OTP داخل التطبيق**
- [ ] **إعادة تعيين كلمة المرور** → دخول بالكلمة الجديدة
- [ ] محاولة دخول ببيانات خاطئة → رسالة خطأ واضحة
- [ ] تبويبا **الطلبات** و**السلة** يطلبان تسجيل الدخول للزائر
- [ ] **Privacy / Terms / About** من More أو Register

**معايير القبول:** مسار تسجيل → دخول → استعادة كلمة المرور بدون تسريب OTP.

---

## 2. الرئيسية (`HomeScreen`)

### Header & Navigation

- [ ] Header: logo SMK، أيقونة إشعارات، أيقونة سلة
- [ ] عداد السلة يتحدث بعد إضافة منتج
- [ ] عداد الإشعارات غير المقروءة (مسجّل دخول)
- [ ] **الموقع:** يظهر فقط إذا محافظة المستخدم من API — **لا** «بغداد» افتراضية
- [ ] شريط البحث → `SearchScreen`
- [ ] أيقونة Barcode → `BarcodeScannerScreen`

### المحتوى

- [ ] Banner slider — تحميل / fallback / swipe
- [ ] أقسام رئيسية → `CategoryDetailsScreen`
- [ ] «عرض الكل» للأقسام → `CategoriesScreen`
- [ ] تجار موثقون → `VendorStoreScreen` — **بدون تقييم وهمي**
- [ ] شبكة/قوائم منتجات — تحميل Skeleton ثم بيانات
- [ ] «العروض» → `OffersScreen`
- [ ] Pull-to-refresh يعمل
- [ ] فشل API → رسالة خطأ (ليس شاشة فارغة صامتة)

**معايير القبول:** لا بيانات وهمية (تقييمات، موقع، أوقات إغلاق).

---

## 3. المتاجر

### قائمة المتاجر (`StoresScreen`)

- [ ] تحميل قائمة المتاجر
- [ ] Empty state عند عدم وجود متاجر
- [ ] الضغط → `VendorStoreScreen`

### صفحة المتجر (`VendorStoreScreen`)

- [ ] Banner + شعار + اسم + موقع (من API)
- [ ] **لا** ratingCount / openNow / closesAt وهمية
- [ ] **لا** زر مفضلة في الـ banner
- [ ] مشاركة المتجر → «تم نسخ رابط المتجر»
- [ ] **4 تبويبات:** الرئيسية | المنتجات | العروض | معلومات — **بدون تقييمات**
- [ ] إحصائيات: **عدد المنتجات فقط** (لا سنوات خبرة / عملاء وهميين)
- [ ] «عن المتجر»: وصف حقيقي أو «غير متوفر حالياً»
- [ ] أقسام المتجر → فلترة المنتجات
- [ ] شريط سفلي: السلة + «تسوق من المتجر»
- [ ] Pull-to-refresh
- [ ] فشل تحميل → Error + «إعادة المحاولة»

---

## 4. المنتجات

### الأقسام (`CategoriesScreen` / `CategoryDetailsScreen`)

- [ ] قائمة الأقسام + عدد المنتجات
- [ ] تفاصيل قسم — banner + عدد منتجات (**بدون وصف marketing ثابت**)
- [ ] Grid/List toggle + فلتر «متوفر فقط» + ترتيب
- [ ] Sidebar الأقسام (شاشات >400px) / مخفي (≤400px)
- [ ] Grid: 2 أعمدة على ≤360px، 3 على الأكبر
- [ ] Empty: «لا توجد منتجات» بعد فلتر
- [ ] Error + retry عند فشل API

### البحث (`SearchScreen`)

- [ ] بحث نصي → نتائج
- [ ] لا نتائج → empty state
- [ ] Barcode scan → منتج أو رسالة

### تفاصيل المنتج (`ProductDetailsScreen`)

- [ ] صور / gallery / SKU / سعر / كمية / توفر
- [ ] **لا** reviewCount / displayRating وهمي
- [ ] وصف: «غير متوفر حالياً» (حتى يُضاف حقل API)
- [ ] **لا** WholesaleBanner
- [ ] مشاركة → «تم نسخ رابط المنتج»
- [ ] مفضلة + إضافة للسلة + selector كمية
- [ ] منتجات مشابهة
- [ ] Error عند فشل تحميل المنتج

### بطاقات المنتج (`HomeProductCard`)

- [ ] **لا** نجمة/تقييم وهمي — brand + سعر فقط

---

## 5. السلة (`CartScreen`)

- [ ] تحميل السلة (Skeleton)
- [ ] عرض البنود: صورة، اسم، سعر، كمية
- [ ] تعديل الكمية / حذف بند
- [ ] ملخص: subtotal, shipping, commission, total
- [ ] Empty: «سلتك فارغة»
- [ ] **Error + retry** عند فشل API (لا empty مضلل)
- [ ] Pull-to-refresh
- [ ] زر «إتمام الطلب» → Checkout

---

## 6. Checkout (`CheckoutScreen`)

- [ ] يتطلب تسجيل دخول
- [ ] تحميل العناوين المحفوظة
- [ ] اختيار عنوان للتوصيل
- [ ] «إضافة عنوان» → `AddressFormScreen`
- [ ] ملخص الطلب والأسعار
- [ ] تأكيد الطلب → نجاح
- [ ] بعد الطلب → تبويب الطلبات (أو رسالة نجاح)
- [ ] السلة تُفرغ بعد الطلب
- [ ] فشل الطلب → رسالة خطأ واضحة

---

## 7. الطلبات (`CustomerOrdersScreen`)

- [ ] تحميل قائمة الطلبات
- [ ] Empty: «لا توجد طلبات»
- [ ] كل بطاقة: رقم، حالة، تاريخ، مبلغ
- [ ] الضغط → `OrderTrackingScreen`
- [ ] Pull-to-refresh
- [ ] فلاتر/حالات مختلفة (pending, delivered, cancelled…)

---

## 8. التتبع (`OrderTrackingScreen`)

- [ ] Timeline حالات الطلب
- [ ] تفاصيل: عنوان، منتجات، أسعار
- [ ] حالة «قيد التجهيز / في الطريق / تم التسليم» منطقية
- [ ] Pull-to-refresh / تحديث الحالة
- [ ] Error أو retry عند فشل التحميل

### Push → التتبع

- [ ] إشعار push (Android) عند تغيير حالة الطلب
- [ ] الضغط على الإشعار → `OrderTrackingScreen` (إذا `order_id` في payload)
- [ ] إشعار بدون `order_id` → لا crash

---

## 9. العناوين (`AddressesScreen`)

- [ ] قائمة العناوين + badge «افتراضي»
- [ ] Empty: «لا توجد عناوين»
- [ ] **Error + retry** عند فشل API
- [ ] FAB «إضافة عنوان»
- [ ] إضافة: محافظة، منطقة، عنوان، هاتف اختياري
- [ ] تعديل عنوان موجود
- [ ] حذف مع تأكيد
- [ ] «تعيين افتراضي»
- [ ] العنوان الافتراضي يظهر في Checkout

---

## 10. المفضلة (`FavoritesScreen`)

- [ ] تحميل المفضلة
- [ ] Empty: «لم تضف منتجات…»
- [ ] **Error + retry** عند فشل API
- [ ] الضغط → تفاصيل المنتج
- [ ] إزالة من المفضلة
- [ ] إضافة للسلة من المفضلة
- [ ] Pull-to-refresh
- [ ] toggle مفضلة من بطاقات المنتج يتزامن

---

## 11. النقاط (`MyPointsScreen`)

- [ ] زائر → «يجب تسجيل الدخول»
- [ ] Header: نقاط الشهر + الشهر/السنة
- [ ] بطاقة الأهلية (مؤهل / غير مؤهل)
- [ ] المكافآت المتاحة + زر «استبدال»
- [ ] سجل النقاط + طلبات الاستبدال
- [ ] Empty sections: «لا توجد مكافآت / حركات»
- [ ] **Error + retry** عند فشل تحميل الملخص
- [ ] Pull-to-refresh

---

## 12. الإشعارات

### Header + Screen

- [ ] أيقونة الجرس → `NotificationsScreen`
- [ ] Badge بعدد غير المقروء
- [ ] قائمة إشعارات + pagination
- [ ] Empty / Loading / **Error + retry**
- [ ] «تعليم الكل كمقروء»
- [ ] الضغط على إشعار طلب → تتبع

### Push (FCM)

- [ ] Token يُسجّل بعد login
- [ ] استلام push في foreground / background
- [ ] لا crash عند إشعار بدون payload كامل

---

## 13. الدعم

### Hub (`SupportHubScreen`)

- [ ] FAQ / تذاكري / اتصال / تذكرة جديدة
- [ ] بيانات الاتصال من API

### FAQ (`SupportFaqScreen`)

- [ ] تحميل + بحث
- [ ] Empty: «لا توجد نتائج» (بحث)
- [ ] **Error + retry** (فشل API)
- [ ] Expansion tiles تعمل

### التذاكر (`SupportTicketsScreen`)

- [ ] قائمة تذاكر + حالات ملونة
- [ ] Empty + زر «تذكرة جديدة»
- [ ] **Error + retry**
- [ ] FAB + AppBar add → `CreateTicketScreen`
- [ ] تفاصيل تذكرة → `TicketDetailScreen` + رسائل

---

## 14. More & Profile

- [ ] `MoreScreen` — كل الروابط تعمل
- [ ] الملف الشخصي — تعديل + محافظة
- [ ] حذف الحساب (إن وُجد)
- [ ] Privacy / Terms / About
- [ ] تسجيل خروج → Splash/Home

---

## 15. حالات الخطأ (Error States) — **اختبار إلزامي**

**الطريقة:** أوقف WAMP أو قطع Wi‑Fi، افتح الشاشة، ثم أعد الاتصال واضغط «إعادة المحاولة».

| الشاشة | يظهر «حدث خطأ…» + retry | Empty فقط بعد نجاح API |
|--------|-------------------------|-------------------------|
| المفضلة | [ ] | [ ] |
| السلة | [ ] | [ ] |
| العناوين | [ ] | [ ] |
| نقاطي | [ ] | [ ] |
| تذاكر الدعم | [ ] | [ ] |
| FAQ | [ ] | [ ] |
| تفاصيل قسم | [ ] | [ ] |
| صفحة متجر | [ ] | [ ] |
| العروض | [ ] | [ ] |
| الإشعارات | [ ] | [ ] |

**فشل:** إذا ظهر «لا توجد بيانات» بدل رسالة خطأ → **Bug P1**

---

## 16. الشاشات الصغيرة (≤360px)

**أجهزة مقترحة:** 320×640, 360×640

| المنطقة | الاختبار | ✅/❌ |
|---------|----------|------|
| `home_header` | Logo + أيقونات بدون تداخل | [ ] |
| `home_header` | موقع لا يكسر التخطيط | [ ] |
| `home_banner_slider` | ارتفاع banner مناسب | [ ] |
| `home_products_grid` | بطاقتان + نص غير مقطوع | [ ] |
| `category_details` | 2 أعمدة، sidebar مخفي | [ ] |
| `category_details` | banner مضغوط بدون overflow | [ ] |
| `vendor_store` | TabBar scrollable | [ ] |
| Checkout / Forms | حقول قابلة للاستخدام | [ ] |
| Bottom Nav | 5 تبويبات واضحة | [ ] |

**فحص Overflow:** لا خطوط صفراء/حمراء «RenderFlex overflowed»

---

## 17. الأداء

| الاختبار | المعيار | ✅/❌ |
|----------|---------|------|
| فتح التطبيق (cold start) | < 5 ثوانٍ على mid-range | [ ] |
| الرئيسية أول تحميل | Skeleton ≤ 3 ثوانٍ | [ ] |
| صفحة متجر — تبويب منتجات | Scroll سلس (50 منتج) | [ ] |
| تفاصيل قسم — 100+ منتج | لا تجمّد UI > 2 ثانية | [ ] |
| IndexedStack (5 tabs) | تبديل tabs ≤ 300ms | [ ] |
| صور الشبكة | تحميل تدريجي بدون crash OOM | [ ] |
| Barcode dialog | إغلاق بدون memory leak | [ ] |
| Background → Foreground | استئناف بدون crash | [ ] |

**ملاحظة:** قوائم طويلة بدون pagination — راقب بطء الشبكة على أقسام كبيرة.

---

## 18. العروض (`OffersScreen`)

- [ ] تحميل / Empty / Error + retry
- [ ] بطاقة بـ `productId` → تفاصيل منتج
- [ ] بطاقة بـ `categoryId` → تفاصيل قسم
- [ ] بطاقة بدون رابط → **غير قابلة للضغط**

---

## 19. Regression — ما يجب ألا يعود

- [ ] **لا** OTP في التطبيق أو API response
- [ ] **لا** `ratingCount = 50 + id`
- [ ] **لا** «يغلق الساعة 11:00 م» ثابت
- [ ] **لا** SnackBar «قريباً» على أزرار ظاهرة
- [ ] **لا** onTap فارغ على عناصر تبدو قابلة للضغط

---

## 20. الأمان (Smoke)

- [ ] `.env` غير موجود في Git
- [ ] HTTPS في production (لاحقاً)
- [ ] Session/token يُمسح بعد logout
- [ ] لا بيانات حساسة في logs Flutter

---

## نموذج تسجيل Bug

```
ID:
الأولوية: P1 / P2 / P3
القسم:
الجهاز:
الخطوات:
المتوقع:
الفعلي:
Screenshot/Video:
Commit: stabilize-smk-customer-beta
```

| الأولوية | التعريف |
|----------|---------|
| P1 | يمنع إتمام طلب / crash / بيانات مضللة |
| P2 | feature معطّل / UX سيء |
| P3 | تجميلي / نادر |

---

## ملخص الجلسة

| القسم | Passed | Failed | N/A |
|-------|--------|--------|-----|
| تسجيل ودخول | | | |
| الرئيسية | | | |
| المتاجر | | | |
| المنتجات | | | |
| السلة | | | |
| Checkout | | | |
| الطلبات | | | |
| التتبع | | | |
| العناوين | | | |
| المفضلة | | | |
| النقاط | | | |
| الإشعارات | | | |
| الدعم | | | |
| Error States | | | |
| شاشات صغيرة | | | |
| الأداء | | | |

**الحكم النهائي:** ☐ Go Beta  ☐ No-Go  ☐ Go with known issues  

**توقيع المختبر:** _______________  **التاريخ:** _______________

---

## أوامر سريعة للمختبر

```bash
# Backend
cd c:\wamp64\www\smk && php artisan config:clear

# Emulator
cd smk_customer && flutter run

# Physical device (LAN)
cd smk_customer && flutter run --dart-define=USE_LAN_HOST=true

# Analyze
cd smk_customer && flutter analyze lib
```

---

**مرجع الحالة:** [`docs/reports/CUSTOMER_APP_STATUS.md`](reports/CUSTOMER_APP_STATUS.md)
