318 lines
12 KiB
Markdown
318 lines
12 KiB
Markdown
# DRIVER_JOURNEY.md — Complete Driver (Captain) Lifecycle
|
|
|
|
## Stage 1: App Launch & Authentication
|
|
|
|
### Screen
|
|
- **Route**: `/` → `SplashScreen`
|
|
- **File**: `siro_driver/lib/splash_screen_page.dart`
|
|
- **Controllers**: `SplashScreenController`, `LocaleController`, `BackgroundServiceHelper`
|
|
|
|
### State Flow
|
|
- GetX-based auth check → JWT validation → Splash → Map or Login
|
|
|
|
### Variables
|
|
| Variable | Storage | Key |
|
|
|----------|---------|-----|
|
|
| jwt (driver) | GetStorage | `BoxName.jwt` |
|
|
| driverID | GetStorage | `BoxName.driverID` |
|
|
| isAppInForeground | GetStorage | `BoxName.isAppInForeground` |
|
|
| statusDriverLocation | GetStorage | `BoxName.statusDriverLocation` |
|
|
| rideStatus | GetStorage | `BoxName.rideStatus` |
|
|
|
|
### APIs (Driver Auth)
|
|
| Endpoint | Method | Input | Output |
|
|
|----------|--------|-------|--------|
|
|
| `$authCaptin/login.php` | POST | phone, password, fingerprint | JWT + driver data |
|
|
| `$authCaptin/register.php` | POST | driver data | account created |
|
|
| `$server/loginJwtDriver.php` | POST | refresh token | new JWT |
|
|
| `$server/loginJwtWalletDriver.php` | POST | refresh token | wallet JWT |
|
|
| `$authCaptin/loginFromGoogle.php` | POST | google token | JWT + driver data |
|
|
|
|
### Database Tables
|
|
- `driver` — driver records
|
|
- `driverToken` — FCM tokens
|
|
|
|
## Stage 2: Go Online
|
|
|
|
### Screen
|
|
- **File**: `siro_driver/lib/views/home/Captin/driver_map_page.dart` → `PassengerLocationMapPage`
|
|
- **Controller**: `HomeCaptainController`, `MapSocketController`
|
|
|
|
### State Flow
|
|
1. Driver presses "Go Online" button
|
|
2. `HomeCaptainController.startOnlineStatus()`
|
|
3. Location service begins continuous GPS updates
|
|
4. WebSocket connects to receive ride offers
|
|
|
|
### Background Service
|
|
- **File**: `siro_driver/lib/controller/functions/background_service.dart`
|
|
- `BackgroundServiceHelper.initialize()` — starts Android foreground service
|
|
- Location updates sent every few seconds to location server
|
|
|
|
### APIs
|
|
| Endpoint | Method | Input | Output |
|
|
|----------|--------|-------|--------|
|
|
| `$location/add.php` | POST | driver_id, lat, lng, heading, speed, status, carType | success |
|
|
| `$server/ride/notificationCaptain/addWaitingRide.php` | POST | driver_id | waiting status |
|
|
| `$endPoint/ride/notificationCaptain/getRideWaiting.php` | POST | driver_id | pending rides |
|
|
|
|
### Database Tables
|
|
- `car_locations` — real-time driver GPS (SPATIAL index)
|
|
- `car_tracks` — historical location tracks
|
|
- `notificationCaptain` — pending ride notifications
|
|
|
|
### Real-time Operations
|
|
- **WebSocket Connect**: `socket_intaleq/driver_socket.php`
|
|
- **Publish**: `driver_online`, `driver_location`
|
|
- **Subscribe**: `ride_offer`, `ride_accepted`, `ride_cancelled`
|
|
|
|
## Stage 3: Ride Offer Reception
|
|
|
|
### Screen
|
|
- **Widget**: `order_request_page.dart`
|
|
- **Overlay**: `TripOverlayPlugin` (native Android overlay showing incoming trip)
|
|
|
|
### State Flow
|
|
1. FCM push received with `category=Order` or `category=OrderSpeed`
|
|
2. `backgroundMessageHandler()` processes push data
|
|
3. Extracts `DriverList` array from message data
|
|
4. Shows overlay via `TripOverlayPlugin.showOverlay(tripData, autoCloseSeconds: 15)`
|
|
5. Stores pending trip in secure storage: `pending_driver_list`
|
|
|
|
### Data Package (DriverList array indices)
|
|
| Index | Field |
|
|
|-------|-------|
|
|
| 0 | passengerLat |
|
|
| 1 | passengerLng |
|
|
| 2 | paymentAmount |
|
|
| 3 | destLat |
|
|
| 4 | destLng |
|
|
| 5 | distance |
|
|
| 7 | passengerId |
|
|
| 8 | passengerName |
|
|
| 9 | passengerToken |
|
|
| 10 | phone |
|
|
| 11 | distance (dup) |
|
|
| 13 | walletChecked |
|
|
| 15 | durationToPassenger |
|
|
| 16 | orderId |
|
|
| 18 | driverId |
|
|
| 19 | durationOfRide |
|
|
| 20-25 | steps (waypoints) |
|
|
| 26 | fare/totalCost |
|
|
| 28 | email |
|
|
| 29 | startNameLocation |
|
|
| 30 | endNameLocation |
|
|
| 31 | carType |
|
|
| 32 | kazan |
|
|
|
|
### Notifications
|
|
- **Local**: Custom notification with "ding.wav" sound, accept/reject buttons
|
|
- **Overlay**: Android system overlay with trip info + accept/reject
|
|
|
|
## Stage 4: Accept Ride
|
|
|
|
### Screen
|
|
- **Function**: `_processAcceptOrder(List<dynamic> data)` in `siro_driver/lib/main.dart`
|
|
|
|
### State Flow
|
|
1. Overlay accept button → `TripOverlayPlugin.onTripAccepted` fires
|
|
2. Or in-app accept button → `HomeCaptainController.acceptOrder()`
|
|
3. Shows loading dialog
|
|
4. Calls API to accept:
|
|
```
|
|
POST {$rideServerSide}/rides/acceptRide.php
|
|
payload: { id: orderId, rideTimeStart, status: 'Apply', passengerToken, driver_id }
|
|
```
|
|
5. On success → navigate to `PassengerLocationMapPage` with ride args
|
|
6. On failure (already taken) → show "طلب أخذه سائق آخر" dialog
|
|
|
|
### Variables Written
|
|
| Variable | Value |
|
|
|----------|-------|
|
|
| `BoxName.statusDriverLocation` | `'on'` |
|
|
| `BoxName.rideStatus` | `'Apply'` |
|
|
| `BoxName.rideArguments` | ride args map |
|
|
|
|
### APIs
|
|
| Endpoint | Method | Input | Output |
|
|
|----------|--------|-------|--------|
|
|
| `$rideServerSide/rides/acceptRide.php` | POST | orderId, rideTimeStart, status, passengerToken, driver_id | ride accepted |
|
|
| `$server/ride/driver_order/add.php` | POST | driver_id, order_id, status='applied' | log |
|
|
|
|
### GIS Operations
|
|
- Route from driver → passenger pickup
|
|
- Google Maps directions URL generated
|
|
|
|
## Stage 5: Navigate to Pickup
|
|
|
|
### Screen
|
|
- **File**: `siro_driver/lib/views/home/Captin/driver_map_page.dart`
|
|
- **Navigation**: `siro_driver/lib/controller/home/navigation/navigation_controller.dart`
|
|
|
|
### State Flow
|
|
- `RideStatus: 'Apply'` → navigate to passenger
|
|
- **Timer**: `startTimerFromDriverToPassengerAfterApplied()` — ETA countdown
|
|
|
|
### GIS Operations
|
|
- **Route Drawing**: Polyline from driver → passenger pickup
|
|
- **Voice Navigation**: TTS navigation instructions
|
|
- **Deviation Detection**: Re-route if off path
|
|
|
|
### Real-time
|
|
- **WebSocket Publish**: `driver_location` with ride context
|
|
- **WebSocket Subscribe**: `passenger_location`, `ride_cancelled`
|
|
|
|
## Stage 6: Arrived at Pickup
|
|
|
|
### Action
|
|
- Driver presses "I've Arrived" button
|
|
- API call updates ride status to `Arrived`
|
|
- 5-minute passenger waiting timer starts
|
|
|
|
### APIs
|
|
| Endpoint | Method | Input | Output |
|
|
|----------|--------|-------|--------|
|
|
| `$rideServerSide/ride/rides/updateStausFromSpeed.php` | POST | ride_id, status='Arrived' | success |
|
|
|
|
### Notifications
|
|
- **Push**: FCM sent to passenger "Driver has arrived"
|
|
- **In-App**: Navigation state changes to "Waiting for passenger"
|
|
|
|
## Stage 7: Start Ride
|
|
|
|
### Action
|
|
- Driver presses "Start Ride" button
|
|
- API call updates ride status to `Begin`
|
|
- Trip officially begins
|
|
|
|
### APIs
|
|
| Endpoint | Method | Input | Output |
|
|
|----------|--------|-------|--------|
|
|
| `$rideServerSide/ride/rides/updateStausFromSpeed.php` | POST | ride_id, status='Begin' | success |
|
|
|
|
### GIS Operations
|
|
- Route updates from current position → passenger destination
|
|
- Live ETA recalculated
|
|
|
|
## Stage 8: Active Ride
|
|
|
|
### Screen
|
|
- **File**: `driver_map_page.dart` (same screen, different state)
|
|
|
|
### State Flow
|
|
- `RideStatus: 'Begin'` → navigating to destination
|
|
- Live trip timer and fare counter displayed
|
|
|
|
### GIS Operations
|
|
- **Route Drawing**: Blue polyline to destination
|
|
- **ETA Updates**: Continuous recalculation
|
|
- **Driver Behavior**: Speed, hard brakes, distance monitored
|
|
|
|
### Database Tables
|
|
- `driver_behavior` — speed, brakes, score per trip
|
|
|
|
## Stage 9: End Ride
|
|
|
|
### Action
|
|
- Driver presses "End Ride" button
|
|
- API call updates ride status to `Finished`
|
|
- Payment screen shown
|
|
|
|
### APIs
|
|
| Endpoint | Method | Input | Output |
|
|
|----------|--------|-------|--------|
|
|
| `$rideServerSide/ride/rides/updateStausFromSpeed.php` | POST | ride_id, status='Finished' | success |
|
|
| `$paymentServer/ride/payment/add.php` | POST | amount, payment_method, passengerID, rideId, driverID | payment record |
|
|
|
|
### GIS Operations
|
|
- **Stop Location Tracking**: End ride location published
|
|
- **Route Cleanup**: Clear map route
|
|
|
|
### Real-time
|
|
- **WebSocket Publish**: `ride_finished` event
|
|
- **WebSocket Disconnect**: Ride room cleanup
|
|
|
|
## Stage 10: Rating & Payment
|
|
|
|
### Screen
|
|
- **Rate**: Rate passenger bottom sheet
|
|
- **Payment**: Cash confirmation or digital payment
|
|
|
|
### APIs
|
|
| Endpoint | Method | Input | Output |
|
|
|----------|--------|-------|--------|
|
|
| `$server/ride/rate/addRateToPassenger.php` | POST | passenger_id, driverID, rideId, rating, comment | success |
|
|
| `$server/ride/payment/get.php` | POST | driver_id | today's earnings |
|
|
|
|
## Stage 11: Go Offline & Earnings
|
|
|
|
### Screen
|
|
- **Wallet**: `siro_driver/lib/views/home/Captin/wallet_page.dart`
|
|
- **Earnings**: `earnings_page.dart`
|
|
|
|
### APIs
|
|
| Endpoint | Method | Input | Output |
|
|
|----------|--------|-------|--------|
|
|
| `$walletDriver/getWalletByDriver.php` | POST | driver_id | wallet balance |
|
|
| `$paymentServer/ride/driverPayment/get.php` | POST | driver_id | payment history |
|
|
| `$server/ride/payment/getCountRide.php` | POST | driver_id | ride count today |
|
|
|
|
### Go Offline Flow
|
|
1. Driver presses "Go Offline"
|
|
2. `HomeCaptainController.stopOnlineStatus()`
|
|
3. Location stops updating
|
|
4. WebSocket disconnects
|
|
5. `car_locations.status` set to `'off'`
|
|
|
|
---
|
|
|
|
## Navigation Route Map (Driver)
|
|
|
|
```
|
|
SplashScreen (/)
|
|
→ [JWT exists?]
|
|
→ Yes → PassengerLocationMapPage (/passenger-location-map)
|
|
→ No → LoginPage → OTPPage → PassengerLocationMapPage
|
|
PassengerLocationMapPage
|
|
→ [Online] → WebSocket connects, location streaming starts
|
|
→ [Ride Offer via Overlay/FCM] → Accept → PassengerLocationMapPage (with ride)
|
|
→ Navigate to pickup → Arrived → Start Ride → Active Ride → End Ride
|
|
→ [After Ride] → Rate page → Earnings update → Back to map
|
|
→ [Offline] → WebSocket disconnects, location stops
|
|
```
|
|
|
|
## Driver App Background Service Architecture
|
|
|
|
```
|
|
┌──────────────────────────────────────────────────────┐
|
|
│ Driver App (siro_driver) │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────┐ │
|
|
│ │ Main Isolate (flutter) │ │
|
|
│ │ - AppBindings, GetX Controllers │ │
|
|
│ │ - TripOverlayPlugin.listen() │ │
|
|
│ │ - _processAcceptOrder / Reject │ │
|
|
│ └──────────────────┬───────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌──────────────────┴───────────────────────────┐ │
|
|
│ │ Background Isolate (FCM Handler) │ │
|
|
│ │ - backgroundMessageHandler() │ │
|
|
│ │ - Shows TripOverlay (autoClose: 15s) │ │
|
|
│ │ - Writes pending_driver_list to SecureStore │ │
|
|
│ └──────────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌──────────────────┴───────────────────────────┐ │
|
|
│ │ Android Foreground Service │ │
|
|
│ │ - BackgroundServiceHelper.initialize() │ │
|
|
│ │ - LocationService: continuous GPS updates │ │
|
|
│ │ - Channels: driver_service, location_service │ │
|
|
│ └──────────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌──────────────────┴───────────────────────────┐ │
|
|
│ │ Native Overlay (Android, Kotlin/Swift) │ │
|
|
│ │ - TripOverlayPlugin (custom native plugin) │ │
|
|
│ │ - Shows incoming trip data overlay │ │
|
|
│ │ - Accept/Reject buttons → MethodChannel │ │
|
|
│ └──────────────────────────────────────────────┘ │
|
|
└──────────────────────────────────────────────────────┘ |