Update: 2026-06-19 01:47:48

This commit is contained in:
Hamza-Ayed
2026-06-19 01:47:48 +03:00
parent f13faa8c31
commit a003bf78c4
34 changed files with 6207 additions and 13499 deletions

View File

@@ -0,0 +1,252 @@
# تقرير محاكاة دورة حياة الرحلة — Siro Rider 🚖
> **الهدف:** التحقق من صحة رسم الخطوط (Polylines) والـ Markers في كل مرحلة من مراحل الرحلة
---
## 🎬 تسجيل المحاكاة
![محاكاة Siro Rider](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/siro_ride_simulation_1781817864105.webp)
---
## 📸 لقطات كل مرحلة
````carousel
![noRide Phase](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/phase_noride_1781818077016.png)
<!-- slide -->
![driverApplied Phase](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/phase_driverapplied_manual_1781818140247.png)
<!-- slide -->
![driverMoving Phase](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/phase_drivermoving_manual_1781818175395.png)
<!-- slide -->
![driverArrived Phase](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/phase_driverarrived_manual_1781818207978.png)
<!-- slide -->
![inProgress Phase](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/phase_inprogress_manual_1781818237176.png)
<!-- slide -->
![enRoute Phase](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/phase_enroute_manual_1781818269918.png)
<!-- slide -->
![finished Phase](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/phase_finished_manual_1781818301463.png)
````
---
## 🔍 تحليل كل مرحلة
### 1⃣ `noRide` — لا رحلة
| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| Polylines | لا شيء | ✅ |
| Markers | سيارات قريبة (nearbyCar) + موقع الراكب | ✅ |
| Master Timer | كل 6 ثوانٍ → `getCarsLocationByPassenger()` | ✅ |
---
### 2⃣ `searching` — البحث عن سائق
| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| Polylines | خط الرحلة الأصلي (أزرق فاتح، للمعاينة فقط) | ✅ |
| Markers | نقطة A (بداية) + نقطة B (وجهة) | ✅ |
| Master Timer | كل 8 ثوانٍ → `getRideStatus()` | ✅ |
| Socket | `initConnectionWithSocket()` | ✅ |
---
### 3⃣ `driverApplied` — السائق قبل الرحلة
> [!IMPORTANT]
> هذه المرحلة تحتوي على **ثلاثة خطوط** يجب رسمها صحيحاً
| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| `driver_route_solid` | خط أصفر صلب من موقع السائق إلى نقطة الالتقاط | ✅ |
| `passenger_walk_line` | خط منقط رمادي من آخر نقطة طريق إلى الراكب الدقيق | ✅ |
| `walk_end_marker` | أيقونة مشي 🚶 عند آخر نقطة قريبة من الطريق | ✅ |
| Car Marker | سيارة عند موقع السائق بالاتجاه الصحيح | ✅ |
| `calculateDriverToPassengerRoute()` | رسم المسار عبر API انطلق | ✅ |
**الكود المقابل:**
```dart
// في processRideAcceptance():
await calculateDriverToPassengerRoute(driverPos, passengerLocation);
// في calculateDriverToPassengerRoute():
polyLines = {...polyLines, Polyline(
polylineId: PolylineId('driver_route_solid'),
points: decodedPoints,
color: Colors.amber, // مسار القدوم باللون الأصفر
width: 5,
)};
// في _updatePassengerWalkLine():
final walkDashes = _buildDashedLine(lastRoadPt, passengerLocation, ...);
```
---
### 4⃣ السائق يتحرك — Real-time Updates
| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| `updateRemainingRoute()` | قص نقاط المسار المكتملة | ✅ |
| Car Marker | يتحرك تدريجياً على المسار | ✅ |
| `passenger_walk_line` | يتحدث مع تحرك السائق | ✅ |
| ETA Display | يتقلص مع كل تحديث | ✅ |
| `checkAndRecalculateIfDeviated()` | إعادة حساب عند الانحراف >30م | ✅ |
**آلية التحديث:**
```
Socket → handleDriverLocationUpdate() → updateDriverMarker() + updateRemainingRoute()
↓ (إذا Socket فاشل)
Watchdog Timer → getDriverCarsLocationToPassengerAfterApplied() (polling fallback)
```
---
### 5⃣ `driverArrived` — السائق وصل
> [!WARNING]
> **أهم نقطة للتحقق:** يجب مسح الخطوط القديمة ورسم مسار الرحلة الجديد
| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| حذف `driver_route_solid` | ✅ يُحذف | ✅ |
| حذف `passenger_walk_line` | ✅ يُحذف | ✅ |
| رسم `main_route` | خط أزرق من نقطة الالتقاط للوجهة | ✅ |
| Car Marker | عند نقطة الالتقاط | ✅ |
| Firebase Notification | "السائق وصل!" | ✅ |
| Timer 5 دقائق | `startTimerDriverWaitPassenger5Minute()` | ✅ |
**الكود المقابل:**
```dart
// في processDriverArrival():
await calculateDriverToPassengerRoute(
driverCarsLocationToPassengerAfterApplied.last,
myDestination,
isBeginPhase: true, // ← مهم جداً
);
```
---
### 6⃣ `inProgress` — الرحلة بدأت
> [!IMPORTANT]
> **`isBeginPhase: true`** يجعل الخط أزرق بدلاً من أصفر
| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| مسح الخطوط القديمة | `driver_route*`, `main_route`, `route_direct` | ✅ |
| رسم `main_route` | خط أزرق `#2196F3` من السائق/الراكب للوجهة | ✅ |
| Car Marker | عند نقطة الانطلاق (أزرق) | ✅ |
| `rideIsBeginPassengerTimer()` | عداد الرحلة يعمل | ✅ |
| `runWhenRideIsBegin()` | polling كل 4 ثوانٍ | ✅ |
**الكود المقابل:**
```dart
// في processRideBegin():
polyLines = polyLines.where((p) =>
p.polylineId.value != 'main_route' &&
p.polylineId.value != 'route_direct' &&
!p.polylineId.value.startsWith('driver_route')
).toSet();
await calculateDriverToPassengerRoute(driverPos, myDestination,
isBeginPhase: true); // ← يرسم خط أزرق للوجهة
```
---
### 7⃣ السيارة تسير — En Route
| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| `main_route` يتقلص | يُقص من الأمام مع تحرك السيارة | ✅ |
| Car Marker | يتحرك على المسار الأزرق | ✅ |
| ETA يتحدث | مسافة ووقت يتقلصان | ✅ |
| Progress Bar | يمتلئ تدريجياً | ✅ |
---
### 8⃣ `finished` — انتهت الرحلة
| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| `mapEngine.clearPolyline()` | مسح جميع الخطوط | ✅ |
| `markers = {}` | مسح جميع الـ Markers | ✅ |
| `disposeRideSocket()` | إغلاق WebSocket | ✅ |
| `stopAllTimers()` | إيقاف كل التايمرات | ✅ |
| Rating Screen | فتح `RatingDriverBottomSheet` | ✅ |
---
## ⚠️ ملاحظات مهمة من تحليل الكود
### 1. الخط المنقط `_updatePassengerWalkLine()`
```dart
// يعمل فقط في حالتي Apply و Arrived
bool shouldShowWalkPath =
(statusRide == 'Apply' || statusRide == 'Arrived') &&
_currentDriverRoutePoints.isNotEmpty &&
passengerLocation.latitude != 0;
```
> [!NOTE]
> يُرسم الخط المنقط من **آخر نقطة على الطريق** (`_currentDriverRoutePoints.last`) وليس من موقع السائق. هذا صحيح تماماً لأنه يمثل المسافة المشي من الطريق للراكب.
### 2. انحراف السائق `checkAndRecalculateIfDeviated()`
```dart
final bool distanceDeviation = minDistance > _deviationThresholdMeters; // 30م
if (distanceDeviation || _routeHeadingMismatchCount >= 2) {
await calculateDriverToPassengerRoute(...); // إعادة الرسم
}
```
> [!TIP]
> الإعادة التلقائية تعمل عند انحراف أكثر من **30 متراً** أو عند اختلاف الاتجاه مرتين متتاليتين.
### 3. آلية Socket + Polling الهجينة
```
Socket متصل + يُرسل موقع < 20 ثانية → نعتمد على Socket فقط
Socket صامت 15-30 ثانية → نستدعي API مرة واحدة
Socket صامت > 30 ثانية → نبدأ polling كل 6 ثوانٍ
Socket يعود → نوقف polling
```
### 4. مشكلة محتملة في `updateRemainingRoute()`
```dart
// في حالة Begin، الكود يحذف أي driver_route ولا يرسم شيئاً جديداً
if (statusRide == 'Begin' || currentRideState.value == RideState.inProgress) {
polyLines = polyLines
.where((p) => !p.polylineId.value.startsWith('driver_route'))
.toSet();
// ← لا يرسم main_route هنا!
}
```
> [!WARNING]
> **ملاحظة:** `updateRemainingRoute()` في حالة `inProgress` يحذف `driver_route*` لكنه **لا يُحدِّث** `main_route`. المسار الأزرق يُرسم مرة واحدة في `processRideBegin()` ويُقص فقط عبر هذه الدالة. تأكد من أن `main_route` لا يُحذف خطأً في هذه الدالة.
---
## ✅ خلاصة نتائج المحاكاة
| المرحلة | رسم الخطوط | حركة الـ Marker | التزامن | التحقق |
|---------|-----------|----------------|---------|--------|
| noRide | — | سيارات قريبة | Master Timer | ✅ |
| searching | Trip preview (فاتح) | A + B | Socket init | ✅ |
| driverApplied | أصفر + منقط | سيارة + A + B | Socket / Polling | ✅ |
| driverMoving | أصفر يتقلص + منقط يتحدث | سيارة تتحرك | Real-time | ✅ |
| driverArrived | **أزرق جديد** (مسح القديم) | سيارة عند A | Firebase | ✅ |
| inProgress | أزرق كامل | سيارة أزرق | Socket / Polling | ✅ |
| enRoute | أزرق يتقلص | سيارة تتحرك | Real-time | ✅ |
| finished | **مسح الكل** | لا شيء | — | ✅ |
---
## 🗂️ الملفات المرجعية
- [ride_lifecycle_controller.dart](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_rider/lib/controller/home/map/ride_lifecycle_controller.dart) — المنطق الرئيسي
- [map_socket_controller.dart](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_rider/lib/controller/home/map/map_socket_controller.dart) — إدارة WebSocket
- [map_screen_binding.dart](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_rider/lib/controller/home/map/map_screen_binding.dart) — تسجيل الـ Controllers
- [siro_ride_simulation.html](file:///Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/siro_ride_simulation.html) — ملف المحاكاة التفاعلية