# مصادر الطلبات

كل طلب جديد من واجهة المتجر يحفظ `orders.platform` مستقلاً عن مصدر تسجيل العميل. القيم هي `ios` و`android` و`web` و`app` و`unknown`.

## ربط التطبيقات

أرسل الهيدر الموجود بالفعل `X-Client` مع طلب إنشاء الطلب `POST /api/v1/stores/{store}/checkout`:

```http
X-Client-Id: 3lcost
X-Store-ID: 24
X-Client: ios
```

- تطبيق آيفون/آيباد: `X-Client: ios` (يقبل أيضًا `iphone` و`ipad`).
- تطبيق أندرويد: `X-Client: android`.
- الموقع، بما فيه متصفح الموبايل: `X-Client: web`، أو اترك الهيدر غائبًا.
- طلب الشراء الذي يعرّف نفسه كعميل Dart أصلي عبر `User-Agent` يظهر ضمن «تطبيق (النظام غير محدد)» إذا غاب معرّف آيفون أو أندرويد.
- القيمة غير المعروفة تُسجل `unknown`.

يعمل للعملاء المسجلين والضيوف. إعادة الطلب بنفس مفتاح idempotency لا تغير المنصة الأصلية. لا نستنتج التطبيق من User-Agent أو منصة تسجيل العميل، ولا نحفظ User-Agent. هذا وصف يرسله العميل للتحليل وليس إثباتًا موثوقًا لنوع الجهاز.

## التقرير

لوحة التحكم: التقارير ← مصادر الطلبات (`/admin/reports/order-platforms`).

```http
GET /api/v1/admin/reports/order-platforms?date_from=2026-10-01&date_to=2026-10-19
```

الصلاحية: `reports.order_platforms.view`. نطاق التاريخ حسب منطقة المتجر، والحد الأقصى 366 يومًا. البيانات معزولة بالمتجر والتينانت. التقرير يعرض عدد الطلبات والعملاء، النسبة من الطلبات، عدد المدفوع والملغي، وقيمة الطلبات بثلاث خانات مع فصل العملات. يشمل جميع حالات طلبات الواجهة ونقطة البيع ويستبعد الطلبات المحذوفة. إجمالي العملاء فريد عبر كل المصادر؛ العميل قد يظهر ضمن أكثر من مصدر. قيمة الطلبات ليست الإيراد المحصل.

طلبات نقطة البيع (`orders.source = admin_pos`) تظهر ضمن `pos` في التقرير، حتى لو كانت قديمة أو كانت قيمة `platform` فيها فارغة أو مختلفة. لا نغير قيمة `platform` المحفوظة. إضافتها للتقرير لا تحتاج migration جديدًا.

طلبات الواجهة السابقة تبقى `NULL` وتظهر «غير محدد»؛ لا نخمّن مصادرها أو نعدّلها.

## التحديث على السيرفر لتينانت واحد

بعد رفع ملفات API والـbuild الجديد للوحة التحكم، نفّذ من مجلد `api` الأمر التالي. يفعّل تينانت `3lcost` ويتحقق من الاتصال، ثم يشغّل ملفي الإضافة فقط. لا يشغّل migrations لباقي التينانت أو أي seeder:

```bash
php artisan tinker --execute='(function () { $manager = app(\App\Services\Store\TenantDatabaseManager::class); $client = $manager->activateByCode("3lcost"); $manager->assertConnectedTo($client); $status = \Illuminate\Support\Facades\Artisan::call("migrate", ["--database" => config("database.default"), "--path" => ["database/migrations/2026_10_19_200000_add_platform_to_orders_table.php", "database/migrations/2026_10_19_200100_add_order_platform_report_permission.php"], "--force" => true]); echo \Illuminate\Support\Facades\Artisan::output(); if ($status !== 0) { throw new \RuntimeException("Order platform migration failed"); } })();'
```

شغّل الإضافة على التينانت قبل استقبال طلبات checkout بالكود الجديد. تحديث الصلاحية يحافظ على الأدوار المخصصة أو المعدلة، ويضيفها فقط للأدوار النظامية التي ما زالت مطابقة للكتالوج السابق. حدّث جلسة لوحة التحكم بعد التحديث لقراءة صلاحيات الشاشة الجديدة.
