Files
Siro/docs/دراسة_نظام_أتمتة_السوق_الذكي.md
2026-06-26 17:29:23 +03:00

41 KiB

دراسة نظام أتمتة السوق الذكي - Siro

التاريخ: 26 يونيو 2026
إعداد: فريق التطوير


فهرس المحتويات

  1. توحيد السناك بار (Snackbar System)
  2. نظرة عامة على نظام أتمتة السوق الذكي
  3. مكونات النظام بالتفصيل
  4. تدفق البيانات (Data Flow)
  5. قاعدة البيانات وجداولها
  6. خريطة مفاتيح Redis
  7. الخدمات الخارجية المستخدمة
  8. ملفات الخلفية - مراجعة أمنية شاملة
  9. قائمة الملفات المطلوب حذفها فوراً
  10. ثغرات SQL Injection
  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) لتصبح:

// الاستخدام الموحد - نفس التوقيع في كل التطبيقات
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 الرئيسي:
    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 الرئيسي:
    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)

ثانيًا - قصير المدى (خلال أسبوع)

  1. توحيد السناك بار حسب الخطة في القسم 1
  2. حذف ملفات الترحيل بعد التأكد من اكتمال الترحيل
  3. نقل أو حذف intaleq_v1_secure_latest.md من جذر الويب
  4. مراجعة جميع ملفات walletintaleq/ - معظمها يفتقر إلى مصادقة JWT

ثالثًا - طويل المدى (شهر)

  1. تبسيط الـ Redis architecture - حاليًا يوجد اتصالان منفصلان (main + location)
  2. استبدال KEYS command في heatmap_live.php بـ SCAN
  3. إصلاح الدوال غير المعرّفة getRedisConnection() و resolveAdminCountry()
  4. فصل إنشاء الجداول من ملفات cron إلى migration scripts
  5. توسيع التغطية الجغرافية - حاليًا تتركز على دمشق فقط

رابعًا - تحسينات إضافية

  1. إضافة مزيد من التوثيق للـ cron jobs (جدولة، مخرجات، مراقبة)
  2. إضافة نظام إنذار عند فشل أحد cron jobs
  3. تشفير جميع مفاتيح API في ملف .env فقط
  4. تطبيق pipeline CI/CD يستبعد ملفات الاختبار والترحيل من الإنتاج

تم إعداد هذه الدراسة بتاريخ 26 يونيو 2026 بناءً على تحليل شامل للكود المصدري لمشروع Siro.