41 KiB
دراسة نظام أتمتة السوق الذكي - Siro
التاريخ: 26 يونيو 2026
إعداد: فريق التطوير
فهرس المحتويات
- توحيد السناك بار (Snackbar System)
- نظرة عامة على نظام أتمتة السوق الذكي
- مكونات النظام بالتفصيل
- تدفق البيانات (Data Flow)
- قاعدة البيانات وجداولها
- خريطة مفاتيح Redis
- الخدمات الخارجية المستخدمة
- ملفات الخلفية - مراجعة أمنية شاملة
- قائمة الملفات المطلوب حذفها فوراً
- ثغرات SQL Injection
- التوصيات النهائية
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. يقوم النظام بـ:
- جمع بيانات المنافسين تلقائيًا عبر Android Bot
- تحليل الفجوات السعرية بين Siro والمنافسين (YallaGo, Zaken, Tufaddal)
- تعديل أسعار Siro تلقائيًا بناءً على تحليل السوق
- كشف فرص رفع الأسعار (Surge Opportunities) في المناطق التي يرتفع فيها الطلب
- توليد حملات تسويقية ذكية باستخدام AI (Google Gemini)
- تقديم تقارير أسبوعية عن صحة السوق (Market Health Reports)
- محاكاة "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و Rediscompetitor:price_historypayment: يسجل نجاح الدفع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)
- آلية العمل:
- يستعلم من
competitor_pricesويجمّع البيانات بخلايا جغرافية (~1.5km) - يحسب خط الأساس (baseline): متوسط سعر كل منافس لآخر 7 أيام
- يحسب السعر الحالي: متوسط لكل منافس في آخر ساعتين
- يشترط وجود 2 عينة على الأقل لكل منافس في كل خلية
- يكتشف الفرصة عندما جميع المنافسين في الخلية رفعوا أسعارهم
- يقترح مضاعف السعر:
1.0 + (avg_competitor_surge_ratio - 1.0) * 0.6(يقلل عن المنافسين بـ 40%) - يحفظ في 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.25xeid: 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
- PCI (Price Competitiveness Index):
- 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.5km)
- قراءة الطلب:
$redis->get("demand:grid:" . $grid_id) - قراءة surge المنافسين: من
surge:opportunitiesفي Redis - حساب توفر السائقين:
$redisLocation->georadius()ضمن 0.75km - Surge Calculation: إذا
طلب/سائقين > 1.2، يطبق مضاعف يصل إلى 3.0x - التسعير الزمني: الليل (21:00-01:00) ←
latePrice، الفجر (01:00-05:00) ← مضاعف، الظهر (14:00-17:00) ←heavyPrice - تخفيضات المسافات الطويلة: 40km+ و 100km+
- مطابقة المنافسين: مستويين من المطابقة:
- المستوى 1: يطابق نقطة البداية والنهاية معًا
- المستوى 2: يطابق نقطة البداية فقط
- يخفض السعر بنسبة 8% إذا كان السعر المحسوب أعلى من متوسط المنافسين
- العمولة:
price * (1 + kazanPercent / 100) - التحقق من العروض: يتحقق من جدول
promos - ديون الراكب: يقرأ من Redis
passenger_debt_{id} - توليد توكن: يشفر حمولة السعر بانتهاء صلاحية 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 سطر - الأكثر تعقيدًا)
- الوظيفة: يطلق حملة تسويقية مدعومة بالذكاء الاصطناعي
- الخطوات:
- يجلب آخر 10 أسعار منافسين من MySQL
- يستدعي
SiroGeminiService->analyzeMarketAndDraftCampaign()مع بيانات السوق - إذا تم اكتشاف فرصة (
opportunity_detected):- يجد الركاب المستهدفين من
passenger_opening_locations - ينشئ كود خصم في جدول
promos(صالحة 7 أيام) - لكل راكب:
- إذا لديه FCM token: يرسل إشعار دفع
- إذا لا: يتحقق من anti-spam (24 ساعة)، ثم WhatsApp → SMS
- يجد الركاب المستهدفين من
- يسجل في
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 الإجراء المطلوب
- فوري: استبدال
$sql = "... WHERE id = '$var'"بـ$sql = "... WHERE id = :id"معbindParam(':id', $id) - مراجعة: جميع ملفات
walletintaleq/لديها مشكلة أمنية منهجية - تحتاج مراجعة كاملة - تحذير: ملفات
driverPayment/لا تملك أي مصادقة JWT - يمكن لأي زوار الوصول إليها
11. التوصيات النهائية
أولاً - فوري (خلال 24 ساعة)
- حذف جميع الملفات عالية الخطورة (القسم 9 - 🔴)
- تغيير مفتاح
MIGRATION_ADMIN_KEYفي جميع السيرفرات (المفتاحiuyweiruinakjbfkajkjlkmalkcxnlahdأصبح مكشوفًا) - إصلاح ثغرات SQL Injection في ملفات المحفظة (القسم 10)
ثانيًا - قصير المدى (خلال أسبوع)
- توحيد السناك بار حسب الخطة في القسم 1
- حذف ملفات الترحيل بعد التأكد من اكتمال الترحيل
- نقل أو حذف
intaleq_v1_secure_latest.mdمن جذر الويب - مراجعة جميع ملفات
walletintaleq/- معظمها يفتقر إلى مصادقة JWT
ثالثًا - طويل المدى (شهر)
- تبسيط الـ Redis architecture - حاليًا يوجد اتصالان منفصلان (main + location)
- استبدال
KEYScommand فيheatmap_live.phpبـSCAN - إصلاح الدوال غير المعرّفة
getRedisConnection()وresolveAdminCountry() - فصل إنشاء الجداول من ملفات cron إلى migration scripts
- توسيع التغطية الجغرافية - حاليًا تتركز على دمشق فقط
رابعًا - تحسينات إضافية
- إضافة مزيد من التوثيق للـ cron jobs (جدولة، مخرجات، مراقبة)
- إضافة نظام إنذار عند فشل أحد cron jobs
- تشفير جميع مفاتيح API في ملف
.envفقط - تطبيق pipeline CI/CD يستبعد ملفات الاختبار والترحيل من الإنتاج
تم إعداد هذه الدراسة بتاريخ 26 يونيو 2026 بناءً على تحليل شامل للكود المصدري لمشروع Siro.