Files
Siro/knowledge/full_system_simulation_ar.html
T

1056 lines
42 KiB
HTML

<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>محاكاة نظام Siro الكاملة - اليوم 2026-06-21</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;600;700;800&display=swap');
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Cairo', sans-serif;
background: #0a0e17;
color: #e2e8f0;
padding: 2rem 1rem;
direction: rtl;
}
.container { max-width: 1300px; margin: 0 auto; }
h1 {
font-size: 2.5rem;
font-weight: 800;
background: linear-gradient(135deg, #3b82f6, #10b981, #f59e0b);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-align: center;
margin-bottom: 0.5rem;
}
.subtitle {
text-align: center;
color: #64748b;
margin-bottom: 2.5rem;
font-size: 1.1rem;
}
.stats-bar {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
margin-bottom: 2rem;
}
.stat-card {
background: linear-gradient(135deg, rgba(30, 41, 59, 0.8), rgba(15, 23, 42, 0.8));
border: 1px solid rgba(255,255,255,0.05);
border-radius: 16px;
padding: 1.25rem;
text-align: center;
backdrop-filter: blur(12px);
}
.stat-value { font-size: 2rem; font-weight: 800; color: #3b82f6; }
.stat-label { font-size: 0.85rem; color: #64748b; margin-top: 0.25rem; }
.flow-section {
background: linear-gradient(135deg, rgba(30, 41, 59, 0.5), rgba(15, 23, 42, 0.5));
border: 1px solid rgba(255,255,255,0.05);
border-radius: 20px;
padding: 1.5rem;
margin-bottom: 1.5rem;
backdrop-filter: blur(12px);
}
.flow-title {
font-size: 1.4rem;
font-weight: 700;
margin-bottom: 1.25rem;
display: flex;
align-items: center;
gap: 0.75rem;
padding-bottom: 0.75rem;
border-bottom: 1px solid rgba(255,255,255,0.05);
}
.flow-title .icon { font-size: 1.5rem; }
.step {
display: flex;
gap: 1rem;
padding: 0.75rem 0;
border-bottom: 1px solid rgba(255,255,255,0.03);
position: relative;
}
.step:last-child { border-bottom: none; }
.step-num {
width: 32px;
height: 32px;
min-width: 32px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: 800;
font-size: 0.85rem;
background: rgba(59, 130, 246, 0.15);
color: #3b82f6;
border: 1px solid rgba(59, 130, 246, 0.3);
}
.step-desc { flex: 1; }
.step-desc .title { font-weight: 700; font-size: 1rem; color: #f1f5f9; }
.step-desc .detail { font-size: 0.9rem; color: #94a3b8; margin-top: 0.25rem; }
.step-desc .code {
background: rgba(0,0,0,0.3);
border: 1px solid rgba(255,255,255,0.05);
border-radius: 8px;
padding: 0.75rem;
margin-top: 0.5rem;
font-family: 'Courier New', monospace;
font-size: 0.8rem;
color: #a5b4fc;
direction: ltr;
text-align: left;
overflow-x: auto;
white-space: pre-wrap;
word-break: break-all;
}
.tag {
display: inline-block;
padding: 0.15rem 0.5rem;
border-radius: 6px;
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
margin-left: 0.5rem;
}
.tag-success { background: rgba(16,185,129,0.15); color: #34d399; border: 1px solid rgba(16,185,129,0.3); }
.tag-warning { background: rgba(245,158,11,0.15); color: #fbbf24; border: 1px solid rgba(245,158,11,0.3); }
.tag-info { background: rgba(59,130,246,0.15); color: #60a5fa; border: 1px solid rgba(59,130,246,0.3); }
.tag-error { background: rgba(239,68,68,0.15); color: #f87171; border: 1px solid rgba(239,68,68,0.3); }
.tag-purple { background: rgba(139,92,246,0.15); color: #a78bfa; border: 1px solid rgba(139,92,246,0.3); }
.arrow-connector {
display: flex;
justify-content: center;
padding: 0.25rem;
color: #334155;
font-size: 1.5rem;
}
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
@media (max-width: 768px) { .grid-2 { grid-template-columns: 1fr; } }
.timeline-bar {
background: rgba(0,0,0,0.2);
border-radius: 99px;
padding: 0.75rem 1.25rem;
margin-bottom: 1rem;
display: flex;
align-items: center;
gap: 1rem;
font-size: 0.85rem;
color: #64748b;
}
.timeline-bar .time { color: #3b82f6; font-weight: 700; font-family: monospace; }
.highlight { color: #fbbf24; font-weight: 700; }
.highlight-green { color: #34d399; font-weight: 700; }
.highlight-blue { color: #60a5fa; font-weight: 700; }
.data-table {
width: 100%;
border-collapse: collapse;
margin-top: 0.75rem;
font-size: 0.85rem;
}
.data-table th {
background: rgba(59,130,246,0.1);
padding: 0.5rem 0.75rem;
text-align: right;
color: #94a3b8;
font-weight: 700;
border-bottom: 1px solid rgba(255,255,255,0.05);
}
.data-table td {
padding: 0.5rem 0.75rem;
border-bottom: 1px solid rgba(255,255,255,0.03);
color: #cbd5e1;
}
.json-block {
background: rgba(0,0,0,0.3);
border: 1px solid rgba(255,255,255,0.05);
border-radius: 12px;
padding: 1rem;
margin: 0.75rem 0;
font-family: 'Courier New', monospace;
font-size: 0.8rem;
color: #a5b4fc;
direction: ltr;
text-align: left;
overflow-x: auto;
white-space: pre-wrap;
word-break: break-all;
}
</style>
</head>
<body>
<div class="container">
<h1>🚀 محاكاة نظام Siro الكاملة</h1>
<p class="subtitle">جميع الإضافات والتغييرات التي تم العمل عليها بتاريخ 2026-06-21</p>
<div class="stats-bar">
<div class="stat-card">
<div class="stat-value" style="color:#3b82f6;">5</div>
<div class="stat-label">Commits رئيسية</div>
</div>
<div class="stat-card">
<div class="stat-value" style="color:#10b981;">74</div>
<div class="stat-label">ملف معدل/مضاف</div>
</div>
<div class="stat-card">
<div class="stat-value" style="color:#f59e0b;">8</div>
<div class="stat-label">أنظمة فرعية</div>
</div>
<div class="stat-card">
<div class="stat-value" style="color:#a78bfa;">2</div>
<div class="stat-label">لغات (Dart/Kotlin)</div>
</div>
</div>
<!-- ============================== -->
<!-- PHASE 1: CRON JOB GENERATES TASKS -->
<!-- ============================== -->
<div class="flow-section">
<div class="flow-title">
<span class="icon">⏰</span>
<span>المرحلة الأولى: Cron Job يولد مهام تسعير المنافسين</span>
<span class="tag tag-warning">backend/bot/generate_price_tasks.php</span>
</div>
<div class="timeline-bar">
<span>كل <span class="time">15 دقيقة</span></span>
<span>|</span>
<span>المناطق: <span class="highlight">10 مناطق في دمشق</span></span>
<span>|</span>
<span>المنافسون: <span class="highlight">YallaGo • Zaken • Tfadal</span></span>
</div>
<div class="step">
<div class="step-num">1</div>
<div class="step-desc">
<div class="title">الاتصال بقاعدة البيانات و Redis</div>
<div class="detail">يتم تحميل <span class="highlight-blue">boostrap.php</span> لإنشاء اتصال MySQL و Redis</div>
</div>
</div>
<div class="step">
<div class="step-num">2</div>
<div class="step-desc">
<div class="title">إنشاء جدول competitor_prices إن لم يكن موجوداً</div>
<div class="code">
CREATE TABLE IF NOT EXISTS competitor_prices (
id INT AUTO_INCREMENT PRIMARY KEY,
competitor_name VARCHAR(50),
from_latitude VARCHAR(30), from_longitude VARCHAR(30),
to_latitude VARCHAR(30), to_longitude VARCHAR(30),
distance_km DECIMAL(8,2), total_price DECIMAL(10,2),
price_per_km DECIMAL(8,2), country_code VARCHAR(5) DEFAULT 'SY',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
</div>
</div>
</div>
<div class="step">
<div class="step-num">3</div>
<div class="step-desc">
<div class="title">توليد نقاط عشوائية لـ 10 مناطق رئيسية في دمشق</div>
<div class="detail">
<span class="tag tag-info">ساحة الأمويين</span>
<span class="tag tag-info">المزة</span>
<span class="tag tag-info">المالكي</span>
<span class="tag tag-info">كفرسوسة</span>
<span class="tag tag-info">الميدان</span>
<span class="tag tag-info">باب توما</span>
<span class="tag tag-info">ركن الدين</span>
<span class="tag tag-info">دمر</span>
<span class="tag tag-info">برامكة</span>
<span class="tag tag-info">المهاجرين</span>
</div>
<div class="detail" style="margin-top:0.5rem;">لكل منطقة: نقطة بداية عشوائية ضمن <span class="highlight">2 كم</span> + رحلة قصيرة <span class="highlight-green">(2-5 كم)</span> + رحلة طويلة <span class="highlight-green">(10-15 كم)</span></div>
</div>
</div>
<div class="step">
<div class="step-num">4</div>
<div class="step-desc">
<div class="title">إدراج المهام في Redis Queue</div>
<div class="detail">استخدام <span class="highlight-blue">LPUSH</span> إلى <span class="highlight">queue:bot:tasks</span></div>
<div class="code">
// 10 مناطق × رحلتين × 3 منافسين = 60 مهمة كل 15 دقيقة
$redis->lpush('queue:bot:tasks', json_encode($taskData));
echo "Successfully generated and queued $tasksCreated pricing tasks.";
</div>
</div>
</div>
</div>
<!-- ============================== -->
<!-- PHASE 2: BOT FETCHES TASKS -->
<!-- ============================== -->
<div class="flow-section">
<div class="flow-title">
<span class="icon">🤖</span>
<span>المرحلة الثانية: Android Bot يسحب المهام وينفذها</span>
<span class="tag tag-success">android_bot/</span>
</div>
<div class="timeline-bar">
<span>آلية السحب: <span class="time">Polling كل 15 ثانية</span></span>
<span>|</span>
<span>الأجهزة المسجلة: <span class="highlight">SHAM_CASH_BOT_01 • PRICE_SCRAPER_BOT_01</span></span>
</div>
<div class="grid-2">
<div>
<div class="step">
<div class="step-num">1</div>
<div class="step-desc">
<div class="title">WorkerClient.kt — التوقيع HMAC-SHA256</div>
<div class="code">
fun generateSignature(deviceId: String, ts: Long): String {
val message = "$deviceId$ts"
val algorithm = "HmacSHA256"
val mac = Mac.getInstance(algorithm)
val secretKeySpec = SecretKeySpec(SECRET_KEY.toByteArray(), algorithm)
mac.init(secretKeySpec)
val hashBytes = mac.doFinal(message.toByteArray())
return hashBytes.joinToString("") { "%02x".format(it) }
}
</div>
</div>
</div>
<div class="step">
<div class="step-num">2</div>
<div class="step-desc">
<div class="title">إرسال GET إلى standalone_worker.php</div>
<div class="code">
GET /standalone_worker.php?device_id=ANDROID_ID&ts=1718970000&sig=abc123...
→ Response (JSON):
{
"status": "success",
"has_task": true,
"task": {
"task_id": "prc_667b8e2f",
"type": "price_check",
"app": "com.zakinn.app",
"payload": {
"start_lat": 33.5138, "start_lng": 36.2765,
"end_lat": 33.5350, "end_lng": 36.2950
}
}
}
</div>
</div>
</div>
</div>
<div>
<div class="step">
<div class="step-num">3</div>
<div class="step-desc">
<div class="title">ScraperAccessibilityService.kt — نقر آلي</div>
<div class="detail">آلة حالة متكاملة لتطبيقات المنافسين:</div>
<div class="code">
IDLE → LAUNCHING_APP → SEARCHING_START → SEARCHING_END → READING_PRICE → SUBMITTING
</div>
<div class="detail" style="margin-top:0.5rem;">
<span class="tag tag-success">YallaGo</span> البحث عن "Where to" أو "أين تريد الذهاب" والنقر عليه
<br>
<span class="tag tag-success">Zakinn</span> استخدام <span class="highlight-blue">findAccessibilityNodeInfosByViewId</span> للـ TextInput
<br>
<span class="tag tag-success">Tfadal</span> البحث بـ 7 لغات مختلفة (AR/EN/TR) عن حقول الإدخال
</div>
</div>
</div>
<div class="step">
<div class="step-num">4</div>
<div class="step-desc">
<div class="title">قراءة السعر وإرسال النتيجة</div>
<div class="code">
// قراءة السعر من النصوص التي تحتوي على SYP, ل.س, AED, SP
searchPriceByCurrency(node) → "ل.س 12,500"
→ submitPriceToServer → POST /standalone_worker.php
{
"device_id": "...", "ts": 1718970000, "sig": "...",
"task_id": "prc_667b8e2f", "type": "price_check",
"status": "success",
"result_data": {
"app": "com.zakinn.app",
"distance_km": 4.8,
"price": 12500,
"start_lat": 33.5138, "start_lng": 36.2765,
"end_lat": 33.5350, "end_lng": 36.2950
}
}
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ============================== -->
<!-- PHASE 3: WORKER PROCESSES RESULTS -->
<!-- ============================== -->
<div class="flow-section">
<div class="flow-title">
<span class="icon">⚙️</span>
<span>المرحلة الثالثة: Worker يستقبل النتائج ويخزنها</span>
<span class="tag tag-purple">backend/bot/worker.php</span>
</div>
<div class="step">
<div class="step-num">1</div>
<div class="step-desc">
<div class="title">استقبال POST مع التحقق من HMAC-SHA256</div>
<div class="code">// التحقق من التوقيع + منع Replay Attacks (صلاحية 5 دقائق)
if (abs(time() - $ts) > 300) → رفض الطلب
$expected_sig = hash_hmac('sha256', $device_id . $ts, $SECRET_KEY);
hash_equals($expected_sig, $sig) → تحقق آمن من التوقيع</div>
</div>
</div>
<div class="step">
<div class="step-num">2</div>
<div class="step-desc">
<div class="title">تخزين السعر في MySQL + Redis</div>
<div class="code">
// MySQL: حفظ البيانات للتقارير اللاحقة
$stmt = $con->prepare("INSERT INTO competitor_prices (...) VALUES (...?)");
$stmt->execute([$app_name, $start_lat, $start_lng, $end_lat, $end_lng, $distance_km, $price, $pricePerKm, $country_code]);
// Redis: حفظ آخر 50 سعر لكل تطبيق للتسعير الديناميكي
$redis->lpush("competitor:price_history:$app_name", $pricePerKm);
$redis->ltrim("competitor:price_history:$app_name", 0, 49);
</div>
</div>
</div>
</div>
<!-- ============================== -->
<!-- PHASE 4: STANDALONE DASHBOARD -->
<!-- ============================== -->
<div class="flow-section">
<div class="flow-title">
<span class="icon">📊</span>
<span>المرحلة الرابعة: Standalone Worker Dashboard (واجهة تحكم)</span>
<span class="tag tag-warning">standalone_worker.php</span>
</div>
<div class="step">
<div class="step-num">1</div>
<div class="step-desc">
<div class="title">واجهة مدير متكاملة (HTML/CSS)</div>
<div class="detail">نظام ملفات JSON (tasks.json / results.json) — بدون حاجة لقاعدة بيانات</div>
<div class="detail">
<span class="tag tag-info">قائمة المهام المعلقة</span>
<span class="tag tag-success">سجل النتائج المنجزة</span>
<span class="tag tag-warning">نموذج إضافة مهمة يدوية</span>
</div>
</div>
</div>
<div class="step">
<div class="step-num">2</div>
<div class="step-desc">
<div class="title">عينة من البيانات المعروضة</div>
<table class="data-table">
<tr><th>#</th><th>التطبيق</th><th>المسار</th><th>السعر</th><th>الحالة</th></tr>
<tr><td>1</td><td>YallaGo</td><td>المزة → مطار دمشق</td><td>12,500 SYP</td><td><span style="color:#34d399;">✅ نجاح</span></td></tr>
<tr><td>2</td><td>Zakinn</td><td>ساحة الأمويين → دمر</td><td>8,200 SYP</td><td><span style="color:#34d399;">✅ نجاح</span></td></tr>
<tr><td>3</td><td>Tfadal</td><td>المالكي → كفرسوسة</td><td>—</td><td><span style="color:#f87171;">❌ فشل</span></td></tr>
<tr><td>4</td><td>YallaGo</td><td>برامكة → المهاجرين</td><td>15,000 SYP</td><td><span style="color:#34d399;">✅ نجاح</span></td></tr>
<tr><td>5</td><td>Zakinn</td><td>الميدان → باب توما</td><td>6,750 SYP</td><td><span style="color:#34d399;">✅ نجاح</span></td></tr>
</table>
</div>
</div>
</div>
<!-- ============================== -->
<!-- PHASE 5: MARKETING + AI -->
<!-- ============================== -->
<div class="flow-section">
<div class="flow-title">
<span class="icon">🧠</span>
<span>المرحلة الخامسة: نظام التسويق الذكي بالذكاء الاصطناعي (Gemini AI)</span>
<span class="tag tag-purple">SiroGeminiService.php + trigger_campaign.php</span>
</div>
<div class="step">
<div class="step-num">1</div>
<div class="step-desc">
<div class="title">المدير يضغط "إطلاق حملة استعادة ذكية فوراً"</div>
<div class="detail">من <span class="highlight-blue">siro_admin → Marketing Page</span></div>
<div class="code">
// Flutter Controller: marketing_controller.dart
Future<void> triggerAICampaign() async {
var res = await CRUD().post(link: AppLink.triggerCampaign, payload: params);
// → POST /Admin/marketing/trigger_campaign.php
}
</div>
</div>
</div>
<div class="step">
<div class="step-num">2</div>
<div class="step-desc">
<div class="title">PHP يسحب آخر أسعار المنافسين ويرسلها إلى Gemini AI</div>
<div class="code">
$sqlPrices = "SELECT competitor_name, total_price, distance_km
FROM competitor_prices WHERE country_code = :country
ORDER BY created_at DESC LIMIT 10";
// البيانات تسحب من جدول competitor_prices الذي ملأه البوت!
$geminiService = new SiroGeminiService();
$aiCampaign = $geminiService->analyzeMarketAndDraftCampaign(
$competitorPrices, $siroBasePrice, $regionName, $countryCode
);
</div>
</div>
</div>
<div class="step">
<div class="step-num">3</div>
<div class="step-desc">
<div class="title">Gemini AI يحلل ويكتب حملة تسويقية كاملة</div>
<div class="code">
// SiroGeminiService.php — إرسال prompt إلى Gemini API
$prompt = "
أنت خبير تسويق ذكي لتطبيق Siro...
1. أسعار المنافسين: " . json_encode($competitorPrices) . "
2. سعر Siro الأساسي: 10000 SYP
الخرج المطلوب JSON:
{
\"opportunity_detected\": true,
\"recommended_price\": 8500,
\"discount_percentage\": 15,
\"promo_code\": \"SIRODM15\",
\"push_title\": \"🔥 وفر 15% على رحلتك!\",
\"push_body\": \"خصم خاص لسكان دمشق! استخدم كود SIRODM15\",
\"sms_body\": \"اشتقنا لك يا ${passenger_name}! عد إلينا ووفر 15% مع كود SIRODM15\"
}"
</div>
</div>
</div>
<div class="step">
<div class="step-num">4</div>
<div class="step-desc">
<div class="title">إرسال الإشعارات والحملات الترويجية</div>
<div class="detail">
<span class="tag tag-success">FCM Push</span> للمستخدمين النشطين (بدون حدود سبام)
<br>
<span class="tag tag-warning">WhatsApp</span> للمستخدمين المنقطعين (مع anti-spam 24 ساعة)
<br>
<span class="tag tag-info">SMS</span> كخيار احتياطي إذا فشل WhatsApp
</div>
<div class="code">
// trigger_campaign.php
foreach ($targets as $target) {
if ($fcmToken) {
sendFcmNotification($fcmToken, $pushTitle, $pushBody, $fcmData);
$sentFcm++;
} else {
if ($spamCount === 0) { // anti-spam
sendWhatsAppFromServer($decryptedPhone, $smsBody);
$sentWhatsApp++;
}
}
}
</div>
</div>
</div>
<div class="step">
<div class="step-num">5</div>
<div class="step-desc">
<div class="title">تسجيل الحملة في سجل التدقيق</div>
<div class="code">
// Audit Log
logAudit($con, $user_id, 'trigger_marketing_campaign', 'promos', $promoCode, [
'promo_code' => $promoCode,
'targets_count' => count($dispatchedPassengers)
]);
// Response للمدير:
{
"campaign_created": true,
"promo_code": "SIRODM15",
"push_notification": { "sent_count": 34 },
"whatsapp_sms": { "whatsapp_sent_count": 12, "sms_sent_count": 5 },
"total_dispatched": 51
}
</div>
</div>
</div>
</div>
<!-- ============================== -->
<!-- PHASE 6: PRICING ENGINE -->
<!-- ============================== -->
<div class="flow-section">
<div class="flow-title">
<span class="icon">💰</span>
<span>المرحلة السادسة: محرك التسعير الديناميكي يستخدم بيانات المنافسين</span>
<span class="tag tag-warning">backend/ride/pricing/get.php</span>
</div>
<div class="step">
<div class="step-num">1</div>
<div class="step-desc">
<div class="title">حساب السعر مع الـ Surge Multiplier من Redis</div>
<div class="code">
// قراءة الطلب (demand) من Redis الرئيسي
$demandCount = (int)$redis->get("demand:grid:" . $grid_id);
// قراءة السائقين المتاحين من Redis الموقع
$drivers = $redisLocation->georadius('geo:drivers:available', $lng, $lat, 0.75, 'km');
if ($demandCount > 0 && $availableDrivers > 0) {
$surgeRatio = $demandCount / $availableDrivers;
if ($surgeRatio > 1.2) {
$surgeMultiplier = 1.0 + ($surgeRatio - 1.2) * 0.5; // Capped at 3.0
}
}
</div>
</div>
</div>
<div class="step">
<div class="step-num">2</div>
<div class="step-desc">
<div class="title">تطبيق التسعير التنافسي (Competitor Undercut — أقل بـ 8%)</div>
<div class="code">
// البحث عن أسعار منافسين لنفس المنطقة الجغرافية
SELECT total_price, distance_km FROM competitor_prices
WHERE country_code = 'SY'
AND (from_latitude + 0.0) BETWEEN :min_flat AND :max_flat
AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
// إذا وجدنا تطابق → نخفض سعرنا ليكون أقل من المنافس بـ 8%
if ($competitorTarget !== null) {
$undercutPrice = $competitorTarget * 0.92; // أقل بــ 8% 🎯
if ($price > $targetAdjustedPrice) {
$price = $targetAdjustedPrice; // تطبيق السعر التنافسي
}
}
</div>
</div>
</div>
<div class="step">
<div class="step-num">3</div>
<div class="step-desc">
<div class="title">تطبيق الخصم (Promo Code) + الديون السابقة + التوقيع المشفر</div>
<div class="code">
// التحقق من صلاحية الكود الترويجي
$sqlPromo = "SELECT amount FROM promos WHERE promo_code = :code AND ...";
$discount = (float) $promoData['amount'];
// إضافة الديون السابقة
$redisDebt = $redisInstance->get("passenger_debt_" . $passenger_id);
$finalPrice += (float) $redisDebt;
// توقيع السعر بشكل مشفر لمنع التلاعب
$priceToken = $encryptionHelper->encryptData(json_encode([
'passenger_id' => $passenger_id,
'distance' => $distance, 'duration' => $duration,
'expires' => time() + 420, // 7 دقائق فقط
'prices' => $pricesRaw
]));
</div>
</div>
</div>
</div>
<!-- ============================== -->
<!-- PHASE 7: SOCKET SYSTEM -->
<!-- ============================== -->
<div class="flow-section">
<div class="flow-title">
<span class="icon">🔌</span>
<span>المرحلة السابعة: WebSocket — الاتصال المباشر مع السائقين</span>
<span class="tag tag-purple">socket_intaleq/driver_socket.php</span>
</div>
<div class="timeline-bar">
<span>🚀 المستوى الثاني (Level 2 Architecture)</span>
<span>|</span>
<span>بورت <span class="highlight">2020</span> WebSocket</span>
<span>|</span>
<span>بورت <span class="highlight">2021</span> HTTP Internal</span>
</div>
<div class="step">
<div class="step-num">1</div>
<div class="step-desc">
<div class="title">اتصال السائق بالـ Socket</div>
<div class="code">
// siro_driver → background_service.dart → Socket.IO
socket = IO.io(AppLink.locationSocketUrl, OptionBuilder()
.setQuery({'driver_id': driverId, 'token': token}));
// server side: driver_socket.php
$socket->join('driver_' . $driverId);
$connectedDrivers[$driverId] = ['conn' => $socket, 'platform' => $platform, 'token' => $token];
</div>
</div>
</div>
<div class="step">
<div class="step-num">2</div>
<div class="step-desc">
<div class="title">تحديث الموقع مع Redis Pipeline Buffering (Level 2)</div>
<div class="code">
// السائق يرسل موقعه ← يتم تجميع الأحداث كل 500ms
$socket->on('update_location', function($data) use (&$eventBuffer) {
// حساب التغيير الفعال (تجنب عمليات Redis غير الضرورية)
if (!$didMove && !$speedChanged && !$headingChanged && !$statusChanged) return;
// التخزين المؤقت → Redis Pipeline
$eventBuffer[$driverId] = [
'hmset' => ['heading' => $heading, 'speed' => $speed, 'status' => $status],
'geoadd' => ['status' => $status, 'lng' => $lng, 'lat' => $lat],
'status_change' => ['old' => $oldStatus, 'new' => $newStatus]
];
});
// Timer كل 500ms: تنفيذ Pipeline
Timer::add(0.5, function() {
$pipe = $redis->pipeline();
foreach ($eventBuffer as $driverId => $ops) { /* تنفيذ مجمع */ }
$pipe->execute();
$eventBuffer = [];
});
</div>
<div class="detail" style="margin-top:0.5rem;">
<span class="tag tag-success">تحسين أداء</span> بدلاً من 3 عمليات Redis لكل تحديث → <span class="highlight">عملية واحدة كل 500ms</span> لكل السائقين
</div>
</div>
</div>
<div class="step">
<div class="step-num">3</div>
<div class="step-desc">
<div class="title">إرسال الطلبات الجديدة (Dispatch + Market)</div>
<div class="code">
// HTTP Internal → dispatch_order
$io->to('driver_' . $driverId)->emit('new_ride_request', $payload);
if ($platform === 'ios') sendFCM_Async($token, 'طلب جديد', 'لديك رحلة جديدة');
// Market New Ride
$redis->geoadd('geo:rides:waiting', $lng, $lat, $rideId);
$nearbyDrivers = $redis->georadius('geo:drivers:available', $lng, $lat, 50, 'km');
foreach ($nearbyDrivers as $driverId) {
$io->to('driver_' . $driverId)->emit('market_new_ride', $payload);
}
</div>
</div>
</div>
<div class="step">
<div class="step-num">4</div>
<div class="step-desc">
<div class="title">تحديث موقع السائق إلى الراكب (Forward to Passenger Socket)</div>
<div class="code">
// Throttle: إرسال الموقع للراكب فقط إذا تحرك >15 متر أو مر >3 ثواني
function forwardLocationToPassengerSocket(...) {
if ($dist < FORWARD_MIN_METERS && $timeDiff < FORWARD_MAX_SECONDS) return;
$http = new AsyncHttp();
$http->request($passengerSocketUrl, ['method' => 'POST', 'data' => $payload,
'headers' => ['x-internal-key' => $internalKey]]);
}
</div>
</div>
</div>
</div>
<!-- ============================== -->
<!-- PHASE 8: DRIVER APP -->
<!-- ============================== -->
<div class="flow-section">
<div class="flow-title">
<span class="icon">📍</span>
<span>المرحلة الثامنة: تطبيق السائق — الوجهة المقترحة والخلفية</span>
<span class="tag tag-info">siro_driver/</span>
</div>
<div class="grid-2">
<div>
<div class="step">
<div class="step-num">1</div>
<div class="step-desc">
<div class="title">DestinationController — إدارة الوجهة</div>
<div class="code">
// حفظ الوجهة (حد أقصى مرتين في اليوم)
Future<void> saveDestination(LatLng position, String name) async {
final response = await CRUD().post(link: AppLink.saveDriverDestination, payload: {
'action': 'set',
'destination_lat': position.latitude.toString(),
'destination_lng': position.longitude.toString(),
'destination_name': name,
});
// تحقق من رسالة "الحد الأقصى لتعديل الوجهة"
if (msg.contains("الحد الأقصى") || msg.contains("limit")) {
mySnackbarWarning('You have reached the daily limit');
}
}
// جلب الوجهة الحالية + مسحها
fetchActiveDestination() / clearDestination()
</div>
</div>
</div>
</div>
<div>
<div class="step">
<div class="step-num">2</div>
<div class="step-desc">
<div class="title">Background Service — استقبال الطلبات في الخلفية</div>
<div class="code">
// Socket في الخلفية ← عند وصول new_ride_request
socket.on('new_ride_request', (data) async {
if (isAppInForeground || overlayActive) return; // لا نكرر
// أندرويد: نعرض Overlay فوق أي تطبيق
await FlutterOverlayWindow.showOverlay(
overlayTitle: "طلب جديد 🚖",
overlayContent: "لديك طلب رحلة جديد!",
flag: OverlayFlag.focusPointer,
);
// iOS: نعرض Local Notification
flutterLocalNotificationsPlugin.show(1002, "طلب رحلة جديد 🚖", ...);
});
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ============================== -->
<!-- PHASE 9: ADMIN APP -->
<!-- ============================== -->
<div class="flow-section">
<div class="flow-title">
<span class="icon">📱</span>
<span>المرحلة التاسعة: Admin App — لوحة التسويق الذكي</span>
<span class="tag tag-info">siro_admin/</span>
</div>
<div class="step">
<div class="step-num">1</div>
<div class="step-desc">
<div class="title">MarketingController — التحكم بالأسواق والحملات</div>
<div class="detail">يدير كل من:
<span class="tag tag-warning">Anomalies</span>
<span class="tag tag-success">Campaigns Log</span>
<span class="tag tag-purple">Telemetry</span>
<span class="tag tag-info">Price Comparison</span>
<span class="tag tag-error">What-If Simulator</span>
</div>
<div class="code">
// دوال رئيسية:
fetchAnomalies() // شواذ الأسعار
fetchCampaignsLog() // سجل الحملات
fetchTelemetry() // استهلاك API والتكاليف
fetchPriceComparison() // مقارنة الأسعار + PCI
fetchPriceGapHeatmap() // خارطة الفجوات السعرية
fetchMarketShareAnalytics() // تطور الحصة السوقية
fetchAiPricePrediction() // توقعات AI
fetchWinbackTargets() // أهداف الاستعادة
triggerAICampaign() // إطلاق حملة AI
runWhatIfSimulation(price) // محاكي تغيير الأسعار
</div>
</div>
</div>
<div class="step">
<div class="step-num">2</div>
<div class="step-desc">
<div class="title">واجهة MarketingPage متكاملة بـ 3 تبويبات</div>
<div class="detail">
<span class="tag tag-info">التبويب 1: شواذ الأسعار والمنافسين</span><br>
- بطاقة التحكم بالـ AI (Gemini)<br>
- توقعات الذكاء الاصطناعي (Siro AI Prediction)<br>
- محاكي تغيير الأسعار الذكي (What-If Simulator)<br>
- رسم بياني لتطور الحصة السوقية (آخر 12 أسبوع)<br>
- رسم بياني لمقارنة تقلبات الأسعار اللحظية<br>
- خارطة الفجوات ومؤشر التنافسية السعري (PCI)<br>
- أهداف استعادة العملاء (Win-Back)
<br><br>
<span class="tag tag-success">التبويب 2: سجل الحملات المنجزة</span><br>
- عرض الحملات المرسلة (Push / WhatsApp / SMS)
<br><br>
<span class="tag tag-warning">التبويب 3: إعدادات الأتمتة والتحكم</span><br>
- مراقب استهلاك الرموز API Telemetry<br>
- تفعيل/تعطيل الـ Autopilot<br>
- تعديل System Prompt للذكاء الاصطناعي
</div>
</div>
</div>
<div class="step">
<div class="step-num">3</div>
<div class="step-desc">
<div class="title">What-If Simulator — محاكي السيناريوهات</div>
<div class="code">
// مثلاً: المدير يقترح سعر 8500 لكل كم
POST /Admin/marketing/what_if_simulator.php?speed_price=8500&country_code=SY
→ Response:
{
"simulated_pci": 0.89,
"market_share_percent": 72.5,
"recommendation_status": "success",
"recommendation_message": "✅ السعر المقترح 8500 SYP/كم سيجعلنا أرخص من جميع المنافسين!"
}
</div>
</div>
</div>
</div>
<!-- ============================== -->
<!-- PHASE 10: RIDER APP -->
<!-- ============================== -->
<div class="flow-section">
<div class="flow-title">
<span class="icon">🗣️</span>
<span>المرحلة العاشرة: تطبيق الراكب — الملاحة والـ TTS</span>
<span class="tag tag-info">siro_rider/</span>
</div>
<div class="step">
<div class="step-num">1</div>
<div class="step-desc">
<div class="title">NavigationView + NavigationController — الملاحة</div>
<div class="detail">واجهة ملاحة كاملة مع: معلومات المسار، وقت الوصول، المسافة المتبقية</div>
</div>
</div>
<div class="step">
<div class="step-num">2</div>
<div class="step-desc">
<div class="title">TTS (Text-to-Speech) Controller</div>
<div class="detail">تحويل إرشادات الملاحة إلى صوت بالعربية — إعلانات صوتية للمنعطفات</div>
<div class="code">
// siro_rider/lib/controller/functions/tts.dart
class TextToSpeechController extends GetxController {
Future<void> speakText(String text) async {
await flutterTts.setLanguage("ar-SA");
await flutterTts.setSpeechRate(0.5);
await flutterTts.speak(text);
}
}
</div>
</div>
</div>
</div>
<!-- ============================== -->
<!-- DATA FLOW DIAGRAM -->
<!-- ============================== -->
<div class="flow-section">
<div class="flow-title">
<span class="icon">🔁</span>
<span>مخطط تدفق البيانات الكامل — دورة متكاملة</span>
</div>
<div style="text-align:center; padding:1rem; font-size:0.95rem; line-height:2;">
<span style="color:#fbbf24;">⏰ Cron Job (15 دقيقة)</span><br>
<span style="color:#334155;">↓ يولد</span><br>
<span style="color:#60a5fa;">📋 60 مهمة تسعير → Redis Queue</span><br>
<span style="color:#334155;">↓ يسحب</span><br>
<span style="color:#34d399;">🤖 Android Bot (Accessibility Service)</span><br>
<span style="color:#334155;">↓ يفتح التطبيق وينقر آلياً ويقرأ</span><br>
<span style="color:#a78bfa;">📱 YallaGo • Zakinn • Tfadal</span><br>
<span style="color:#334155;">↓ يرسل النتائج</span><br>
<span style="color:#60a5fa;">📊 Worker → MySQL (competitor_prices) + Redis</span><br>
<span style="color:#334155;">↓ يستخدم في</span><br>
<span style="color:#34d399;">💰 محرك التسعير الديناميكي (Undercut 8%)</span><br>
<span style="color:#334155;">↓ ويستخدم في</span><br>
<span style="color:#f59e0b;">🧠 Gemini AI Campaign Generator</span><br>
<span style="color:#334155;">↓ يرسل</span><br>
<span style="color:#10b981;">📣 FCM Push + WhatsApp + SMS → الركاب</span><br>
<span style="color:#334155;">↓ وأيضاً</span><br>
<span style="color:#f87171;">📊 Admin Dashboard يعرض التحليلات</span><br>
</div>
</div>
<!-- ============================== -->
<!-- FILE STRUCTURE -->
<!-- ============================== -->
<div class="flow-section">
<div class="flow-title">
<span class="icon">📁</span>
<span>هيكلية الملفات المضافة والمعدلة اليوم</span>
</div>
<div class="grid-2">
<div>
<div style="font-weight:700; margin-bottom:0.5rem; color:#3b82f6;">📱 siro_driver/</div>
<div style="font-size:0.8rem; color:#94a3b8; line-height:1.8;">
├── lib/constant/links.dart<br>
├── lib/controller/functions/background_service.dart<br>
├── lib/controller/functions/location_controller.dart<br>
├── lib/controller/home/captin/<br>
│ ├── destination_controller.dart<br>
│ ├── home_captain_controller.dart<br>
│ └── order_request_controller.dart<br>
├── lib/controller/local/ar_eg.dart<br>
├── lib/controller/local/ar_jo.dart<br>
├── lib/controller/local/ar_sy.dart<br>
├── lib/controller/local/en.dart<br>
├── lib/views/home/Captin/home_captain/<br>
│ ├── home_captin.dart<br>
│ └── widget/destination_bottom_sheet.dart<br>
└── lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart
</div>
</div>
<div>
<div style="font-weight:700; margin-bottom:0.5rem; color:#10b981;">⚙️ backend/</div>
<div style="font-size:0.8rem; color:#94a3b8; line-height:1.8;">
├── bot/<br>
│ ├── generate_price_tasks.php (Cron Job)<br>
│ ├── worker.php (Redis Worker Endpoint)<br>
│ └── standalone_worker.php (Dashboard)<br>
├── core/Services/SiroGeminiService.php<br>
├── Admin/marketing/<br>
│ ├── trigger_campaign.php<br>
│ ├── get_price_comparison.php<br>
│ ├── get_market_anomalies.php<br>
│ ├── get_telemetry.php<br>
│ └── get_campaigns_log.php<br>
├── ride/pricing/get.php<br>
├── ride/location/save_driver_destination.php<br>
└── ride/rides/add_ride.php, acceptRide.php, cancel*.php
</div>
<div style="font-weight:700; margin-top:1rem; margin-bottom:0.5rem; color:#a78bfa;">🤖 android_bot/</div>
<div style="font-size:0.8rem; color:#94a3b8; line-height:1.8;">
├── service/ScraperAccessibilityService.kt<br>
├── service/AppLauncher.kt<br>
├── network/WorkerClient.kt<br>
└── MainActivity.kt
</div>
</div>
</div>
</div>
<!-- ============================== -->
<!-- FINAL REMARKS -->
<!-- ============================== -->
<div class="flow-section" style="border-color: rgba(16,185,129,0.3);">
<div class="flow-title" style="border-bottom-color: rgba(16,185,129,0.15);">
<span class="icon">✅</span>
<span>الخلاصة — ماذا أنجزنا اليوم؟</span>
</div>
<div style="padding:0.5rem 0; line-height:2;">
<span class="tag tag-success">مكتمل</span> <span class="highlight-green">Android Bot</span> — نقر آلي ذكي (Accessibility Service) مع آلة حالة متكاملة لـ 3 تطبيقات منافسة<br>
<span class="tag tag-success">مكتمل</span> <span class="highlight-green">Cron Job</span> — توليد 60 مهمة تسعير كل 15 دقيقة لـ 10 مناطق في دمشق<br>
<span class="tag tag-success">مكتمل</span> <span class="highlight-green">Worker Endpoint</span> — استقبال نتائج البوت مع HMAC Authentication + MySQL/Redis<br>
<span class="tag tag-success">مكتمل</span> <span class="highlight-green">Gemini AI</span> — خدمة تحليل أسعار وصياغة حملات تسويقية بالعربية (لهجات محلية)<br>
<span class="tag tag-success">مكتمل</span> <span class="highlight-green">Marketing Campaign</span> — إطلاق حملات عبر FCM + WhatsApp + SMS مع Anti-Spam<br>
<span class="tag tag-success">مكتمل</span> <span class="highlight-green">Pricing Engine</span> — تسعير ديناميكي مع Undercut 8% عن المنافسين + Surge Pricing<br>
<span class="tag tag-success">مكتمل</span> <span class="highlight-green">WebSocket Level 2</span> — Redis Pipeline Buffering كل 500ms + Forward للموقع<br>
<span class="tag tag-success">مكتمل</span> <span class="highlight-green">Destination System</span> — وجهة السائق مع حد يومي + خلفية مع Overlay للطلبات<br>
<span class="tag tag-success">مكتمل</span> <span class="highlight-green">Admin Dashboard</span> — لوحة تسويق ذكية مع PCI, Heatmap, What-If Simulator, Telemetry<br>
<span class="tag tag-success">مكتمل</span> <span class="highlight-green">Standalone Dashboard</span> — واجهة تحكم كاملة للبوت بدون حاجة Redis/MySQL
</div>
</div>
</div>
</body>
</html>