Update: 2026-06-26 17:29:23

This commit is contained in:
Hamza-Ayed
2026-06-26 17:29:23 +03:00
parent a323da29aa
commit 9ded734e38
139 changed files with 1815 additions and 2676 deletions

View File

@@ -0,0 +1,704 @@
# دراسة نظام أتمتة السوق الذكي - Siro
**التاريخ: 26 يونيو 2026**
**إعداد: فريق التطوير**
---
## فهرس المحتويات
1. [توحيد السناك بار (Snackbar System)](#1-توحيد-السناك-بار-snackbar-system)
2. [نظرة عامة على نظام أتمتة السوق الذكي](#2-نظرة-عامة-على-نظام-أتمتة-السوق-الذكي)
3. [مكونات النظام بالتفصيل](#3-مكونات-النظام-بالتفصيل)
4. [تدفق البيانات (Data Flow)](#4-تدفق-البيانات-data-flow)
5. [قاعدة البيانات وجداولها](#5-قاعدة-البيانات-وجدولها)
6. [خريطة مفاتيح Redis](#6-خريطة-مفاتيح-redis)
7. [الخدمات الخارجية المستخدمة](#7-الخدمات-الخارجية-المستخدمة)
8. [ملفات الخلفية - مراجعة أمنية شاملة](#8-ملفات-الخلفية---مراجعة-أمنية-شاملة)
9. [قائمة الملفات المطلوب حذفها فوراً](#9-قائمة-الملفات-المطلوب-حذفها-فوراً)
10. [ثغرات SQL Injection](#10-ثغرات-sql-injection)
11. [التوصيات النهائية](#11-التوصيات-النهائية)
---
## 1. توحيد السناك بار (Snackbar System)
### الوضع الحالي - 4 تطبيقات و 4 طرق مختلفة
يوجد حاليًا 4 تطبيقات Flutter ولكل منها نظام سناك بار مختلف تمامًا:
---
### 1.1 siro_admin - الإصدار القديم (GetX)
**الملف:** `siro_admin/lib/views/widgets/snackbar.dart`
- يستخدم `Get.snackbar()` حصريًا
- يوجد دالتان فقط: `mySnackeBarError()` و `mySnackbarSuccess()`
- **لا يوجد** `mySnackbarWarning()` ولا `mySnackbarInfo()`
- الألوان: أحمر للخطأ (`AppColor.redColor`)، أخضر للنجاح (`AppColor.greenColor`)
- يستخدم `SnackbarConfig` للثوابت (مدة 3 ثوان، زوايا 12، ظل)
- التوقيع: `SnackbarController mySnackeBarError(String message)`
- النصوص بالإنكليزية: `'Error'.tr`, `'Success'.tr`
- 30+ استخدامًا في التطبيق
### 1.2 siro_service - الإصدار القديم (GetX)
**الملف:** `siro_service/lib/views/widgets/mycircular.dart`
- يستخدم `Get.snackbar()` حصريًا
- يوجد 3 دوال: `mySnackbarError()` و `mySnackbarWarning()` و `mySnackbarSuccess()`
- الألوان: أحمر (`AppColor.redColor`)، أصفر (`AppColor.yellowColor` + نص أسود)، أخضر (`AppColor.greenColor`)
- نفس `SnackbarConfig` للثوابت
- 70+ استخدامًا في التطبيق
### 1.3 siro_driver - الإصدار الحديث (Custom Widget)
**الملف:** `siro_driver/lib/views/widgets/error_snakbar.dart`
- ويج محسّن مخصص مع `_SnackContent` و `AnimationController`
- يوجد 4 دوال: `mySnackbarSuccess()` و `mySnackeBarError()` و `mySnackbarInfo()` و `mySnackbarWarning()`
- **4 متغيرات (variants):** success, error, info, warning
- ألوان: أخضر (`#1A9E5C`)، أحمر (`#D93025`)، أزرق (`#1A73E8`)، برتقالي (`#F29900`)
- ألوان السطح: `#F0FBF5`, `#FEF2F1`, `#F0F6FF`, `#FFF8E6`
- تأثيرات: `ScaleTransition` مع `Curves.elasticOut`، شريط تقدم تنازلي
- إخفاء يدوي مع زر Close + Haptic Feedback
- يتحقق أولاً من `Overlay`، فإن لم يجده يستخدم `ScaffoldMessenger`
- **مشكلة:** يستخدم `Get.snackbar()` الذي يرمي `FlutterError` إذا لم يكن `Overlay` جاهزًا
- 100+ استخدامًا في التطبيق
### 1.4 siro_rider - الإصدار الحديث المحسّن (ScaffoldMessenger)
**الملف:** `siro_rider/lib/views/widgets/error_snakbar.dart`
- نفس تصميم `siro_driver` مع تحسينات جوهرية
- **يستخدم فقط `ScaffoldMessenger`** بدلاً من `Get.snackbar()` (لتجنب أخطاء `Overlay`)
- يحتوي على آلية إعادة محاولة (retry) تصل إلى 3 مرات
- `messenger.clearSnackBars()` قبل العرض (يمنع التراكم)
- يعيد `SnackbarController?` (nullable) لأن `Get.snackbar` لم يعد مستخدمًا
- التوقيع: `SnackbarController? mySnackbarSuccess(String message)` - ملاحظة: الرجوع `?`
- 100+ استخدامًا في التطبيق
### 1.5 دوال Toast البسيطة
- **siro_driver** و **siro_rider** لديهما `lib/controller/functions/toast.dart`
- `Toast.show(BuildContext context, String message, Color color)` - دالة بسيطة جدًا
- تستخدم `ScaffoldMessenger.of(context).showSnackBar()` مع `SnackBar` مادة
- 10+ استخدامات في كل تطبيق
---
### الفروقات بين الإصدارين (القديم والحديث)
| الخاصية | siro_admin (قديم) | siro_driver (حديث) | siro_rider (حديث) | siro_service (قديم) |
|---------|:-----------------:|:------------------:|:-----------------:|:-------------------:|
| عدد الدوال | 2 | 4 | 4 | 3 |
| `mySnackbarWarning` | ❌ | ✅ | ✅ | ✅ |
| `mySnackbarInfo` | ❌ | ✅ | ✅ | ❌ |
| `mySnackbarSuccess` | ✅ | ✅ | ✅ | ✅ |
| `mySnackeBarError` | ✅ | ✅ | ✅ | ✅ |
| آلية العرض | `Get.snackbar()` | `Get.snackbar()` + `ScaffoldMessenger` | `ScaffoldMessenger` فقط | `Get.snackbar()` |
| التصميم | نص فقط | أيقونة + نص + زر إغلاق + شريط تقدم | أيقونة + نص + زر إغلاق + شريط تقدم | نص فقط |
| Retry | ❌ | ❌ | ✅ (3 مرات) | ❌ |
| Null Safety | `SnackbarController` | `SnackbarController` | `SnackbarController?` | `SnackbarController` |
| أخطاء `Overlay` | ✅ (GetX آمن) | ⚠️ (قد يحدث) | ✅ (متفادي) | ✅ (GetX آمن) |
---
### خطة التوحيد المقترحة
#### الهدف: إنشاء package مشترك واحد لجميع التطبيقات الأربعة
**الخطوة 1:** إنشاء مجلد مشترك (shared package) في المسار:
```
siro_admin/lib/shared/widgets/snackbar/
```
**الخطوة 2:** توحيد الواجهة (API) لتصبح:
```dart
// الاستخدام الموحد - نفس التوقيع في كل التطبيقات
void mySnackbarSuccess(String message);
void mySnackbarError(String message);
void mySnackbarWarning(String message);
void mySnackbarInfo(String message);
```
**الخطوة 3:** الاعتماد على `ScaffoldMessenger` فقط (مثل siro_rider) لتجنب مشاكل `Overlay` في GetX.
**الخطوة 4:** توحيد الألوان والثوابت:
| المتغير | اللون الأساسي | لون السطح | الأيقونة |
|---------|:------------:|:---------:|:--------:|
| success | `#1A9E5C` (أخضر) | `#F0FBF5` | `check_circle_rounded` |
| error | `#D93025` (أحمر) | `#FEF2F1` | `error_rounded` |
| info | `#1A73E8` (أزرق) | `#F0F6FF` | `info_rounded` |
| warning | `#F29900` (برتقالي) | `#FFF8E6` | `warning_amber_rounded` |
**الخطوة 5:** تحويل ملفات `toast.dart` في `siro_driver` و `siro_rider` لاستخدام دالة واحدة موحدة بدلاً من التكرار.
**الخطوة 6:** إزالة دوال `Get.snackbar()` المباشرة من جميع ملفات التحكم (controllers) والاستعاضة عنها بالدوال الموحدة.
---
## 2. نظرة عامة على نظام أتمتة السوق الذكي
### ما هو النظام؟
**"أتمتة السوق الذكي"** هو نظام متكامل لذكاء السوق والتسعير الديناميكي في Siro. يقوم النظام بـ:
1. **جمع بيانات المنافسين** تلقائيًا عبر Android Bot
2. **تحليل الفجوات السعرية** بين Siro والمنافسين (YallaGo, Zaken, Tufaddal)
3. **تعديل أسعار Siro تلقائيًا** بناءً على تحليل السوق
4. **كشف فرص رفع الأسعار** (Surge Opportunities) في المناطق التي يرتفع فيها الطلب
5. **توليد حملات تسويقية ذكية** باستخدام AI (Google Gemini)
6. **تقديم تقارير أسبوعية** عن صحة السوق (Market Health Reports)
7. **محاكاة "What-If"** لمعرفة أثر تغيير الأسعار
### طبقات النظام
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ طبقة العرض (Admin Dashboard) │
│ siro_admin → لوحة تحكم المدير → Flutter Web │
│ endpoints: Admin/marketing/*.php │
├─────────────────────────────────────────────────────────────────────────────┤
│ طبقة API (PHP Backend) │
│ cron_jobs → bot/*.php │ pricing → ride/pricing/*.php │
│ heatmap → ride/heatmap/*.php │ marketing → Admin/marketing/*.php │
├─────────────────────────────────────────────────────────────────────────────┤
│ طبقة الذكاء والتحليل │
│ Google Gemini AI │ SiroGeminiService │ Redis Analytics │
├─────────────────────────────────────────────────────────────────────────────┤
│ طبقة جمع البيانات │
│ Android Bot ←→ worker.php ←→ competitor_prices (MySQL) │
│ generate_price_tasks.php (cron) → Redis Queue → Bot │
├─────────────────────────────────────────────────────────────────────────────┤
│ قاعدة البيانات والذاكرة المؤقتة │
│ MySQL (main, tracking, ride) │ Redis (مفاتيح surge, demand) │
└─────────────────────────────────────────────────────────────────────────────┘
```
### الدول المدعومة
| الدولة | رمز البلد | المنطقة الزمنية | عملة |
|:------:|:--------:|:--------------:|:----:|
| سوريا | SY | Asia/Damascus | ل.س |
| الأردن | JO | Asia/Amman | د.أ |
| مصر | EG | Africa/Cairo | ج.م |
| العراق | IQ | Asia/Baghdad | د.ع |
---
## 3. مكونات النظام بالتفصيل
### 3.1 نظام البوت (Bot System) - `backend/bot/`
#### 3.1.1 `generate_price_tasks.php`
- **الجدولة:** كل 15 دقيقة
- **الوظيفة:** يولد مهام فحص أسعار المنافسين ويدفعها إلى Redis Queue
- **آلية العمل:**
- ينشئ جدول `competitor_prices` تلقائيًا إذا لم يكن موجودًا
- يحتوي على 10 مناطق رئيسية في دمشق (ساحة الأمويين، المزة، المالكي، كفرسوسة، الميدان، باب توما، ركن الدين، دمر، برامكة، المهاجرين)
- المنافسون: `['yallago', 'zaken', 'tufaddal']`
- لكل منطقة يولد نقطة انطلاق عشوائية ضمن 2km، ثم رحلة قصيرة (2-5km) وأخرى طويلة (10-15km)
- يضغط المهام في Redis list: `queue:bot:tasks`
- **الملفات المكتوبة:** Redis key `queue:bot:tasks`
- **ملاحظة:** إنشاء الجدول داخل cron job أمر غير محبذ - يجب أن يكون في migration
#### 3.1.2 `worker.php`
- **الوظيفة:** نقطة نهاية API لبوت Android لسحب المهام وإرسال النتائج
- **الأمان:** HMAC-SHA256 مع نافذة 5 دقائق + `BOT_SECRET_KEY` من البيئة
- **الأجهزة المسموحة:** `['SHAM_CASH_BOT_01', 'PRICE_SCRAPER_BOT_01']`
- **GET:** يسحب مهمة من قائمة Redis (`RPOP`)
- **POST:** يستقبل النتيجة:
- `price_check`: يحسب `pricePerKm` ويدرج في جدول `competitor_prices` و Redis `competitor:price_history`
- `payment`: يسجل نجاح الدفع
- `failed`: يسجل الخطأ
- **Redis:** `queue:bot:tasks` (قراءة)، `competitor:price_history:{app}` (كتابة)
- **MySQL:** إدراج في `competitor_prices`
#### 3.1.3 `standalone_worker.php`
- **الوظيفة:** نسخة بديلة كاملة بذاتها بدون Redis أو MySQL - تستخدم ملفات JSON
- **الاستخدام:** اختبار محلي / تطوير
- **الميزات:** لوحة تحكم HTML داكنة مع Bootstrap، منشئ مهام، سجل مهام
- **الأمان:** HMAC-SHA256 مع نافذة 15 دقيقة
- **لا يشكل خطرًا أمنيًا في الإنتاج طالما لا يمكن الوصول إليه عبر الويب**
#### 3.1.4 `cron_surge_opportunity.php` (قلب النظام)
- **الجدولة:** كل 10 دقائق
- **الوظيفة:** محرك كشف فرص رفع الأسعار (Surge Detection)
- **آلية العمل:**
1. يستعلم من `competitor_prices` ويجمّع البيانات بخلايا جغرافية (~1.5km)
2. يحسب خط الأساس (baseline): متوسط سعر كل منافس لآخر 7 أيام
3. يحسب السعر الحالي: متوسط لكل منافس في آخر ساعتين
4. يشترط وجود 2 عينة على الأقل لكل منافس في كل خلية
5. يكتشف الفرصة عندما **جميع** المنافسين في الخلية رفعوا أسعارهم
6. يقترح مضاعف السعر: `1.0 + (avg_competitor_surge_ratio - 1.0) * 0.6` (يقلل عن المنافسين بـ 40%)
7. يحفظ في Redis: `surge:opportunities` مع TTL 10 دقائق
- **SQL الرئيسي:**
```sql
SELECT ROUND(lat * 74) / 74 AS lat_group, ROUND(lng * 74) / 74 AS lng_group,
competitor_name, country_code,
AVG(CASE WHEN created_at < DATE_SUB(NOW(), INTERVAL 6 HOUR)
THEN price_per_km END) AS baseline_avg,
AVG(CASE WHEN created_at >= DATE_SUB(NOW(), INTERVAL 2 HOUR)
THEN price_per_km END) AS current_avg,
COUNT(CASE WHEN created_at >= DATE_SUB(NOW(), INTERVAL 2 HOUR)
THEN 1 END) AS recent_samples
FROM competitor_prices
GROUP BY lat_group, lng_group, competitor_name, country_code
HAVING recent_samples >= 2
```
#### 3.1.5 `cron_kazan_adjuster.php`
- **الجدولة:** كل 10 دقائق
- **الوظيفة:** يخفف عمولة Siro (Kazan) في المناطق التي يرتفع فيها سعر المنافسين
- **آلية العمل:**
- يقرأ `surge:opportunities:{country}` من Redis
- للخلايا ذات surge > 1.2: يطبق تخفيض 30% على العمولة (0.70x)
- للخلايا ذات surge 1.05-1.2: يطبق تخفيض 15% (0.85x)
- يحفظ في Redis: `surge:kazan_discounts:{country}` مع TTL 20 دقيقة
- **ملاحظة:** يستدعي دالة `getRedisConnection()` غير المعرّفة - سيفشل في وقت التشغيل
#### 3.1.6 `cron_seasonal_pricing.php`
- **الجدولة:** كل 30-60 دقيقة
- **الوظيفة:** يطبق مضاعفات موسمية (رمضان، عيد، طقس سيء)
- **القواعد:**
- `ramadan_iftar` (18:00-20:00): 1.25x
- `eid`: 1.15x (غير نشط حاليًا)
- `severe_weather`: 1.30x (غير نشط حاليًا)
- **ملاحظة:** نفس مشكلة `getRedisConnection()` غير المعرّفة
#### 3.1.7 `cron_weekly_health_report.php`
- **الجدولة:** أسبوعيًا (ليلة الأحد)
- **الوظيفة:** ينشئ تقرير صحة السوق الأسبوعي
- **المقاييس:**
- **PCI (Price Competitiveness Index):** `siroPrice / compPrice`
- **حصة السوق:** % من الرحلات التي Siro فيها أرخص
- **عدد الشذوذ (anomalies):** من جدول `price_anomalies`
- **عدد الحملات:** من جدول `marketing_campaigns_log`
- **Redis:** لا يستخدم
- **MySQL:** يدرج في `market_health_reports`
---
### 3.2 نظام التسعير الديناميكي - `backend/ride/pricing/`
#### 3.2.1 `auto_adapt.php`
- **الجدولة:** كل 30-60 دقيقة
- **الوظيفة:** يعدل جميع أسعار Siro بناءً على أدنى متوسط سعر للمنافسين
- **المعادلة:** `new_price_per_km = lowest_competitor_avg * 0.92` (أقل من المنافسين بـ 8%)
- **النطاق:** بين 85% و 115% من السعر الحالي
- **الأعمدة المحدثة:** speedPrice, comfortPrice, ladyPrice, electricPrice, vanPrice, deliveryPrice, mishwarVipPrice, fixedPrice, awfarPrice
- **الدول:** SY, JO, EG, IQ
- **SQL الرئيسي:**
```sql
SELECT competitor_name, AVG(price_per_km) AS avg_ppm
FROM competitor_prices
WHERE country_code = :cc AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
AND price_per_km > 0
GROUP BY competitor_name
ORDER BY avg_ppm ASC
```
#### 3.2.2 `get.php` (نقطة تسعير الرحلة - 511 سطرًا)
- **الوظيفة:** يحسب سعر الرحلة عند الطلب (أثناء تشغيل التطبيق)
- **آلية العمل المعقدة:**
1. **حساب الخلية الجغرافية:** من إحداثيات الراكب (~1.5km)
2. **قراءة الطلب:** `$redis->get("demand:grid:" . $grid_id)`
3. **قراءة surge المنافسين:** من `surge:opportunities` في Redis
4. **حساب توفر السائقين:** `$redisLocation->georadius()` ضمن 0.75km
5. **Surge Calculation:** إذا `طلب/سائقين > 1.2`، يطبق مضاعف يصل إلى 3.0x
6. **التسعير الزمني:** الليل (21:00-01:00) ← `latePrice`، الفجر (01:00-05:00) ← مضاعف، الظهر (14:00-17:00) ← `heavyPrice`
7. **تخفيضات المسافات الطويلة:** 40km+ و 100km+
8. **مطابقة المنافسين:** مستويين من المطابقة:
- المستوى 1: يطابق نقطة البداية والنهاية معًا
- المستوى 2: يطابق نقطة البداية فقط
- يخفض السعر بنسبة 8% إذا كان السعر المحسوب أعلى من متوسط المنافسين
9. **العمولة:** `price * (1 + kazanPercent / 100)`
10. **التحقق من العروض:** يتحقق من جدول `promos`
11. **ديون الراكب:** يقرأ من Redis `passenger_debt_{id}`
12. **توليد توكن:** يشفر حمولة السعر بانتهاء صلاحية 7 دقائق لمنع التلاعب
- **المفاتيح الأساسية:** `kazan`, `promos`, `competitor_prices`
- **Redis:** `demand:grid:{id}`, `surge:opportunities`, `passenger_debt_{id}`
---
### 3.3 نظام الخريطة الحرارية (Heatmap) - `backend/ride/heatmap/`
#### 3.3.1 `log_demand.php`
- **الوظيفة:** يسجل الطلب عند كل خلية جغرافية
- **Redis:** `INCR` على `demand:grid:{grid_id}` مع TTL 60 ثانية
- **يُستدعى من:** تطبيق الراكب عند طلب رحلة
#### 3.3.2 `get_surge_heatmap.php`
- **الوظيفة:** يعرض بؤر surge لتطبيق السائق (Driver App)
- **المصادقة:** يتطلب دور `driver`
- **Redis:** يقرأ `surge:opportunities:{countryCode}`
- **الفلترة:** فقط الخلايا ذات مضاعف > 1.05
#### 3.3.3 `heatmap_live.php`
- **الوظيفة:** خريطة حية لتطبيق الكابتن - تجمع بين الطلب وتوفر السائقين
- **تحذير:** يستخدم `$redis->keys("demand:grid:*")` - أمر `KEYS` بطيء مع عدد كبير من المفاتيح
- **التصنيف:** عالي (نسبة > 2.0 أو عدد ≥ 5)، متوسط (نسبة > 1.2 أو عدد ≥ 3)، منخفض
---
### 3.4 نقط نهاية التسويق - `backend/Admin/marketing/`
#### 3.4.1 `trigger_campaign.php` (200 سطر - الأكثر تعقيدًا)
- **الوظيفة:** يطلق حملة تسويقية مدعومة بالذكاء الاصطناعي
- **الخطوات:**
1. يجلب آخر 10 أسعار منافسين من MySQL
2. يستدعي `SiroGeminiService->analyzeMarketAndDraftCampaign()` مع بيانات السوق
3. إذا تم اكتشاف فرصة (`opportunity_detected`):
- يجد الركاب المستهدفين من `passenger_opening_locations`
- ينشئ كود خصم في جدول `promos` (صالحة 7 أيام)
- لكل راكب:
- إذا لديه FCM token: يرسل إشعار دفع
- إذا لا: يتحقق من anti-spam (24 ساعة)، ثم WhatsApp → SMS
4. يسجل في `admin_audit_log`
- **الخدمات الخارجية:** Google Gemini, WhatsApp Bot, Firebase Cloud Messaging
- **الحماية:** Anti-spam (24h cooldown للـ SMS/WhatsApp)
#### 3.4.2 `ai_price_prediction.php`
- **الوظيفة:** يتوقع ساعات الذروة بناءً على بيانات 14 يومًا
- **المنطق:** `SELECT HOUR(created_at) FROM price_anomalies WHERE anomaly_type = 'opportunity' GROUP BY HOUR ORDER BY COUNT(*) DESC LIMIT 3`
- **النتيجة:** أفضل 3 ساعات متوقعة + نسبة ثقة 85%
#### 3.4.3 `what_if_simulator.php`
- **الوظيفة:** محاكي "ماذا لو" - يقترح السعر الأمثل
- **المنطق:**
- يأخذ `speed_price` مقترح
- يحاكي السعر لآخر 500 رحلة منافس
- يحسب PCI الجديد وحصة السوق المتوقعة
- التوصية: PCI < 0.8 تحذير (ربح قليل)، 0.9-0.95 ممتاز، > 1.0 خطر
#### 3.4.4 `surge_opportunity_index.php`
- **الوظيفة:** نسخة Admin من `cron_surge_opportunity.php` - استعلام فوري
- **الفرق:** يُستدعى عبر HTTP، يعرض تفاصيل كل منطقة ومنافس
#### 3.4.5 `winback_hotspot_targets.php`
- **الوظيفة:** يجد الركاب الخاملين (30 يوم بدون رحلة) في مناطق surge
- **Redis:** يقرأ `surge:opportunities:{countryCode}`
- **MySQL:** `users JOIN passenger_opening_locations`
#### 3.4.6 `get_price_gap_heatmap.php`
- **الوظيفة:** خريطة حرارية توضح أين Siro أرخص/أغلى من المنافسين
- **المنطق:** لكل خلية جغرافية يحسب `pci = currentSpeedPrice / avg_competitor_price` و `weight = pci - 1.0` مقيد بـ [-1, 1]
#### 3.4.7 باقي نقاط النهاية
| الملف | الوظيفة |
|-------|---------|
| `get_campaigns_log.php` | سجل الحملات التسويقية |
| `get_market_anomalies.php` | الشذوذ السعري + آخر أسعار المنافسين |
| `get_market_share_analytics.php` | بيانات حصة السوق للرسوم البيانية (آخر 12 أسبوع) |
| `get_price_comparison.php` | مقارنة الأسعار: متوسطات الساعة، PCI حسب المنطقة، أسعار Siro |
| `get_telemetry.php` | إحصائيات استخدام النظام: عدد الحملات، التكلفة التقديرية |
---
### 3.5 خدمة الذكاء الاصطناعي - `backend/core/Services/SiroGeminiService.php`
- **النموذج:** `gemini-1.5-flash`
- **الوظيفة:** تحليل السوق وكتابة الحملات التسويقية بالعربية
- **المخرجات:** JSON يحتوي على `opportunity_detected`, `campaign_text`, `discount_percent`, `message_type`
- **التكيف:** يضبط اللهجة حسب البلد (سوري، أردني، مصري، عراقي)
---
## 4. تدفق البيانات (Data Flow)
```
generate_price_tasks.php (cron/15min)
│ LPUSH → queue:bot:tasks (Redis)
Android Bot (Scraper) ←→ worker.php (API)
│ POST result → INSERT competitor_prices
┌────────────────────────────────────────────────────────────┐
│ competitor_prices (MySQL) │
│ country_code | lat | lng | price_per_km | competitor_name │
└─────────────────────────────────────────────────────────────┘
├─── cron_surge_opportunity.php (cron/10min)
│ │ SELECT baseline vs current
│ │ WRITE surge:opportunities (Redis)
│ ▼
├─── cron_kazan_adjuster.php (cron/10min)
│ │ READ surge:opportunities:{CC}
│ │ WRITE surge:kazan_discounts:{CC}
│ ▼
├─── cron_seasonal_pricing.php (cron/30-60min)
│ │ WRITE surge:seasonal:{CC}
│ ▼
├─── auto_adapt.php (cron/30-60min)
│ │ SELECT AVG(price_per_km) → UPDATE kazan
│ ▼
├─── cron_weekly_health_report.php (cron/weekly)
│ │ SELECT → INSERT market_health_reports
│ ▼
├─── ride/pricing/get.php (API - عند طلب رحلة)
│ │ READ Redis (surge, demand, debt)
│ │ SELECT (competitor_prices, kazan, promos)
│ ▼
└─── Admin/marketing/*.php (API - لوحة التحكم)
│ READ (competitor_prices, anomalies, etc.)
│ WRITE (promos, campaigns_log, audit_log)
│ CALL Gemini API
```
---
## 5. قاعدة البيانات وجداولها
| الجدول | العمليات (SELECT) | العمليات (INSERT/UPDATE) |
|--------|:-----------------:|:------------------------:|
| `competitor_prices` | cron_surge_opportunity, cron_weekly_health, surge_opportunity_index, get_price_comparison, get_price_gap_heatmap, what_if_simulator, trigger_campaign, auto_adapt, pricing/get | worker.php (INSERT), generate_price_tasks (CREATE TABLE) |
| `kazan` | cron_weekly_health, get_price_comparison, get_price_gap_heatmap, what_if_simulator, pricing/get | auto_adapt (UPDATE) |
| `price_anomalies` | ai_price_prediction, get_market_anomalies, cron_weekly_health, get_telemetry | (خارج نطاق هذه الدراسة) |
| `market_health_reports` | get_market_share_analytics | cron_weekly_health (INSERT) |
| `marketing_campaigns_log` | get_campaigns_log, cron_weekly_health, get_telemetry | trigger_campaign (INSERT) |
| `passenger_opening_locations` | trigger_campaign, winback_hotspot_targets | (خارج النطاق) |
| `promos` | pricing/get | trigger_campaign (INSERT) |
| `passengers` | get_campaigns_log, trigger_campaign | (خارج النطاق) |
| `tokens` | trigger_campaign | (خارج النطاق) |
| `users` | winback_hotspot_targets | (خارج النطاق) |
| `admin_audit_log` | - | trigger_campaign (INSERT via logAudit) |
---
## 6. خريطة مفيكات Redis
| نمط المفتاح | يُكتب بواسطة | يُقرأ بواسطة | TTL |
|:-----------:|:------------:|:------------:|:---:|
| `surge:opportunities` | cron_surge_opportunity, surge_opportunity_index | pricing/get, get_surge_heatmap | 600s |
| `surge:opportunities:{CC}` | cron_kazan_adjuster | winback_hotspot_targets, get_surge_heatmap | 1200s |
| `surge:kazan_discounts:{CC}` | cron_kazan_adjuster | (ride logic) | 1200s |
| `surge:seasonal:{CC}` | cron_seasonal_pricing | (ride logic) | 3600s |
| `queue:bot:tasks` | generate_price_tasks | worker.php (RPOP) | list |
| `competitor:price_history:{app}` | worker.php | (تحليلات مستقبلية) | list/50 |
| `demand:grid:{grid}` | log_demand | pricing/get, heatmap_live | 60s |
| `passenger_debt_{id}` | (من نظام المحفظة) | pricing/get | متغير |
---
## 7. الخدمات الخارجية المستخدمة
| الخدمة | الاستخدام | الملف المرتبط |
|--------|:---------:|:-------------:|
| **Google Gemini AI** | إنشاء محتوى الحملات التسويقية | `SiroGeminiService.php`, `trigger_campaign.php` |
| **Firebase Cloud Messaging** | إشعارات الدفع للركاب | `trigger_campaign.php`, `FcmService.php` |
| **WhatsApp Bot Servers** | إرسال رسائل واتساب | `trigger_campaign.php` |
| **Android Bot (Scraper)** | جمع أسعار المنافسين | `worker.php`, `generate_price_tasks.php` |
| **Location Socket Server** | مواقع السائقين اللحظية | `heatmap_live.php`, `pricing/get.php` |
---
## 8. ملفات الخلفية - مراجعة أمنية شاملة
### 8.1 ملفات اختبار/تجربة عالية الخطورة (يجب حذفها فورًا)
#### `backend/test_add_driver_and_car.php`
- **الوصف:** سكربت اختبار يُنشئ سائق وسيارة في قاعدة البيانات مباشرة
- **الخطر:** لا يتطلب أي مصادقة - أي زائر يمكنه إنشاء حسابات سائقين وهمية
- **التصنيف:** **🚨 عالي جدًا - احذف فورًا**
#### `backend/test_signed_pricing.php`
- **الوصف:** سكربت اختبار يتحايل على المصادقة (`define('TESTING_BYPASS_AUTH', true)`)
- **الخطر:** يمكنه إنشاء رحلات حقيقية ببيانات مزيفة
- **التصنيف:** **🚨 عالي جدًا - احذف فورًا**
#### `backend/diagnose_fingerprint.php`
- **الوصف:** أداة تشخيص تفضي ببيانات البصمات المخزنة
- **الخطر:** يعرض البيانات مفككة التشفير بدون مصادقة
- **التصنيف:** **🚨 عالي جدًا - احذف فورًا**
#### `backend/diagnose_login.php`
- **الوصف:** أداة تشخيص تسجيل الدخول - تعرض أرقام الهواتف والأسماء
- **الخطر:** يعرض PII (معلومات شخصية) مفككة التشفير
- **التصنيف:** **🚨 عالي جدًا - احذف فورًا**
#### `backend/auth/Tester/getTesterApp.php` و `updateTesterApp.php`
- **الوصف:** نقاط نهاية اختبار بدون مصادقة مع SQL Injection
- **الخطر:** SQL Injection صريح + لا مصادقة
- **التصنيف:** **🚨 عالي جدًا - احذف فورًا**
#### `backend/migration_create_table.php`
- **الوصف:** سكربت إنشاء جدول (كان يجب حذفه بعد الاستخدام)
- **الخطر:** يمكن إعادة تنفيذه لتعديل schema قاعدة البيانات
- **التصنيف:** **🚨 عالي جدًا - احذف فورًا**
#### `backend/migrate_driver_passwords.php`
- **الوصف:** سكربت ترحيل كلمات المرور
- **الخطر:** يحتوي على بيانات اعتماد قاعدة بيانات في الكود
- **التصنيف:** **🚨 عالي جدًا - احذف فورًا**
#### `backend/Admin/auth/migration_cryptography.php`
- **الوصف:** يعيد تشفير جميع الأعمدة المشفرة (أكثر من 15 جدول)
- **الخطر:** إعادة تنفيذه قد تفسد جميع البيانات المشفرة
- **التصنيف:** **🚨 عالي - احذف فورًا**
#### `backend/Admin/auth/migrate_db.php`
- **الوصف:** سكربت ترحيل بنية قاعدة البيانات
- **الخطر:** يمكنه تعديل schema الإنتاج
- **التصنيف:** **🚨 عالي - احذف فورًا**
#### `backend/Admin/Staff/add_super_admin.php`
- **الوصف:** إضافة مشرف (Admin) جديد
- **الخطر:** التحقق من الصلاحية معلّق (commented out) - أي زائر يمكنه إنشاء super admin
- **التصنيف:** **🚨 عالي جدًا - احذف فورًا**
#### `backend/Admin/Staff/setup.php`
- **الوصف:** سكربت إعداد الموظفين الأولي
- **الخطر:** يمكنه إعادة تعيين جميع صلاحيات المشرفين
- **التصنيف:** **🚨 عالي - احذف بعد التأكد من الإعداد**
### 8.2 ملفات ترحيل البصمات - مفتاح مشفر مكشوف
#### `siro_admin/lib/views/admin/enceypt/fingerprint_migration.dart`
#### `siro_admin/lib/views/admin/enceypt/driver_fingerprint_migration.dart`
- **الوصف:** أدوات Flutter لترحيل البصمات
- **الخطر:** يحتويان على مفتاح المشرف (admin key) بشكل نصي صريح:
```
'iuyweiruinakjbfkajkjlkmalkcxnlahd'
```
- **التصنيف:** **🔥 خطير جدًا - احذف فورًا وغيّر المفتاح في السيرفر**
### 8.3 ملفات "ggg" - أدوات التشفير
| الملف | الوظيفة | المصادقة | التصنيف |
|-------|:-------:|:--------:|:-------:|
| `backend/ggg.php` | تشفير/فك تشفير للمشرف | JWT admin/super_admin | ⚠️ متوسط |
| `backend/Admin/ggg.php` | تشفير/فك تشفير | ADMIN_PHONE_NUMBERS | ⚠️ متوسط |
**التوصية:** احذف بعد انتهاء الترحيل. هذه أدوات خطيرة لأنها تسمح بفك تشفير أي بيانات.
### 8.4 ملفات الترحيل (Migration Files)
| الملف | الوظيفة | التصنيف |
|-------|:-------:|:-------:|
| `backend/migration/get_all_fingerprints.php` | تصدير بصمات الركاب | ⚠️ متوسط |
| `backend/migration/get_all_driver_fingerprints.php` | تصدير بصمات السائقين | ⚠️ متوسط |
| `backend/migration/update_fingerprint_admin.php` | تحديث بصمة راكب | ⚠️ متوسط |
| `backend/migration/update_driver_fingerprint_admin.php` | تحديث بصمة سائق | ⚠️ متوسط |
**التوصية:** احذف جميع ملفات الترحيل بعد التأكد من اكتمال الترحيل في الإنتاج.
### 8.5 ملفات أخرى
#### `backend/intaleq_v1_secure_latest.md`
- **الوصف:** ملف توثيق ضخم (33,608 سطر) يحتوي على كود المصدر الكامل
- **الخطر:** إذا كان الوصول إليه ممكنًا عبر الويب، فإنه يسرب كامل قاعدة الشفرة
- **التصنيف:** ⚠️ متوسط - انقل خارج جذر الويب أو احذف
#### `siro_admin/lib/debug_jwt.dart`
- **الوصف:** سكربت Flutter لاختبار JWT
- **الخطر:** يكشف بنية JWT ومنهجية التشفير
- **التصنيف:** ⚠️ منخفض - احذف من بنية الإنتاج
---
## 9. قائمة الملفات المطلوب حذفها فوراً
### أولوية قصوى - خطر أمني مباشر 🔴
| الملف | السبب |
|:------|:-----:|
| `backend/test_add_driver_and_car.php` | إنشاء سائقين بدون مصادقة |
| `backend/test_signed_pricing.php` | تجاوز المصادقة |
| `backend/diagnose_fingerprint.php` | كشف بيانات حساسة بدون مصادقة |
| `backend/diagnose_login.php` | كشف PII بدون مصادقة |
| `backend/migration_create_table.php` | تعديل schema بدون مصادقة |
| `backend/migrate_driver_passwords.php` | بيانات اعتماد DB في الكود |
| `backend/Admin/auth/migration_cryptography.php` | إعادة تشفير شامل |
| `backend/Admin/auth/migrate_db.php` | تعديل schema الإنتاج |
| `backend/Admin/Staff/add_super_admin.php` | صلاحية المشرِف معلّقة |
| `backend/Admin/Staff/setup.php` | إعادة تعيين الصلاحيات |
| `backend/auth/Tester/getTesterApp.php` | SQL Injection + لا مصادقة |
| `backend/auth/Tester/updateTesterApp.php` | SQL Injection + لا مصادقة |
| `siro_admin/lib/views/admin/enceypt/fingerprint_migration.dart` | مفتاح مكشوف 🔥 |
| `siro_admin/lib/views/admin/enceypt/driver_fingerprint_migration.dart` | مفتاح مكشوف 🔥 |
### أولوية متوسطة - أمان أو تنظيف 🟡
| الملف | السبب |
|:------|:-----:|
| `backend/ggg.php` | أداة تشفير للمشرفين - احذف بعد الترحيل |
| `backend/Admin/ggg.php` | أداة تشفير - احذف بعد الترحيل |
| `backend/migration/get_all_fingerprints.php` | ترحيل بصمات - احذف بعد التأكد |
| `backend/migration/get_all_driver_fingerprints.php` | ترحيل بصمات - احذف بعد التأكد |
| `backend/migration/update_fingerprint_admin.php` | ترحيل بصمات - احذف بعد التأكد |
| `backend/migration/update_driver_fingerprint_admin.php` | ترحيل بصمات - احذف بعد التأكد |
| `backend/Admin/auth/register.php` | مراجعة - هل ما زال مستخدمًا؟ |
| `siro_admin/lib/debug_jwt.dart` | تصحيح JWT - احذف من الإنتاج |
| `backend/intaleq_v1_secure_latest.md` (33k سطر) | كود مصدر كامل - انقل أو احذف |
### أولوية منخفضة - تحسين أمني 🟢
| الملف | السبب |
|:------|:-----:|
| `walletintaleq.intaleq.xyz/v2/main/ride/payment/delete.php` | ملف فارغ تمامًا |
| `backend/logo.png` | (تحقق ما إذا كان ضروريًا) |
---
## 10. ثغرات SQL Injection
### 10.1 ملفات ذات SQL Injection مباشر
هذه الملفات تستخدم `prepare()` بعد `$sql = "... WHERE id = '$var'"` مما يبطل تمامًا حماية prepared statements:
| الملف | السطر | الكود المخترق |
|:------|:-----:|:--------------|
| `wallet/ride/passengerWallet/delete.php` | `$sql = "DELETE FROM passengerWallet WHERE id = '$id'"` |
| `wallet/ride/passengerWallet/update.php` | `$sql = "UPDATE passengerWallet SET balance = '$balance' WHERE id = '$id'"` |
| `wallet/ride/passengerWallet/getAllPassengerTransaction.php` | `WHERE passenger_id = '$passenger_id'` |
| `wallet/ride/passengerWallet/getPassengerWalletArchive.php` | `WHERE passenger_id = '$passenger_id'` |
| `wallet/ride/driverPayment/delete.php` | `DELETE FROM paymentsDriverPoints WHERE id = '$id'` |
| `wallet/ride/driverPayment/update.php` | `UPDATE ... SET amount = '$amount', ...` |
| `wallet/ride/driverPayment/add.php` | `INSERT INTO paymentsDriverPoints VALUES ('$amount', '$paymentMethod', '$driverID')` |
| `wallet/ride/driverWallet/get.php` | `WHERE driverID = '$driverID'` (في subquery) |
| `wallet/ride/payment/update.php` | بناء `SET` ديناميكي + SQL Injection |
| `backend/Admin/adminUser/get.php` | `WHERE device_number = '$device_number'` |
### 10.2 الإجراء المطلوب
1. **فوري:** استبدال `$sql = "... WHERE id = '$var'"` بـ `$sql = "... WHERE id = :id"` مع `bindParam(':id', $id)`
2. **مراجعة:** جميع ملفات `walletintaleq/` لديها مشكلة أمنية منهجية - تحتاج مراجعة كاملة
3. **تحذير:** ملفات `driverPayment/` لا تملك أي مصادقة JWT - يمكن لأي زوار الوصول إليها
---
## 11. التوصيات النهائية
### أولاً - فوري (خلال 24 ساعة)
1. **حذف جميع الملفات عالية الخطورة (القسم 9 - 🔴)**
2. **تغيير مفتاح `MIGRATION_ADMIN_KEY`** في جميع السيرفرات (المفتاح `iuyweiruinakjbfkajkjlkmalkcxnlahd` أصبح مكشوفًا)
3. **إصلاح ثغرات SQL Injection** في ملفات المحفظة (القسم 10)
### ثانيًا - قصير المدى (خلال أسبوع)
4. **توحيد السناك بار** حسب الخطة في القسم 1
5. **حذف ملفات الترحيل** بعد التأكد من اكتمال الترحيل
6. **نقل أو حذف `intaleq_v1_secure_latest.md`** من جذر الويب
7. **مراجعة جميع ملفات `walletintaleq/`** - معظمها يفتقر إلى مصادقة JWT
### ثالثًا - طويل المدى (شهر)
8. **تبسيط الـ Redis architecture** - حاليًا يوجد اتصالان منفصلان (main + location)
9. **استبدال `KEYS` command** في `heatmap_live.php` بـ `SCAN`
10. **إصلاح الدوال غير المعرّفة** `getRedisConnection()` و `resolveAdminCountry()`
11. **فصل إنشاء الجداول** من ملفات cron إلى migration scripts
12. **توسيع التغطية الجغرافية** - حاليًا تتركز على دمشق فقط
### رابعًا - تحسينات إضافية
13. **إضافة مزيد من التوثيق** للـ cron jobs (جدولة، مخرجات، مراقبة)
14. **إضافة نظام إنذار** عند فشل أحد cron jobs
15. **تشفير جميع مفاتيح API** في ملف `.env` فقط
16. **تطبيق pipeline CI/CD** يستبعد ملفات الاختبار والترحيل من الإنتاج
---
*تم إعداد هذه الدراسة بتاريخ 26 يونيو 2026 بناءً على تحليل شامل للكود المصدري لمشروع Siro.*