32 KiB
Intaleq Driver App — Complete Ride Lifecycle Analysis Report
Table of Contents
- System Architecture Overview
- Ride State Machine
- Phase 1: Ride Request Ingress (Socket → Order Request)
- Phase 2: Accept Order & Navigation to Pickup
- Phase 3: Arrival & Begin Ride
- Phase 4: In-Ride Navigation & Polyline System
- Phase 5: Finish Ride & Payment
- Phase 6: Post-Ride (Rating, Review)
- Pricing Engine
- Socket.IO Communication
- HTTP Backend API Endpoints
- Polyline Engine Deep Dive
- Location Tracking System
- Voice Call Signaling
- Key Architectural Patterns & Fixes
- Data Flow Diagrams
1. System Architecture Overview
High-Level Component Map
graph TB
subgraph "Driver App sefer_driver"
A[LocationController] -->|Socket.IO| B[Location Server]
C[OrderRequestController] -->|HTTP| D[Ride Server]
E[MapDriverController] -->|HTTP| D
F[NavigationController] -->|HTTP| G[Map SaaS Server]
H[SignalingService] -->|WebSocket| I[Call Server]
J[WalletController] -->|HTTP| K[Payment Server]
end
subgraph "Passenger App Intaleq"
L[RideLifecycleController] -->|Polling/HTTP| D
M[MapEngineController] -->|HTTP| G
end
B -->|Socket.IO Events| A
B <-->|update_location| A
D <-->|Ride CRUD| E
D <-->|Ride CRUD| L
subgraph "Backend Servers"
B[Location Server: location.intaleq.xyz]
D[Ride Server: rides.intaleq.xyz]
G[Map SaaS: map-saas.intaleqapp.com]
I[Call Server: calls.intaleqapp.com]
K[Payment Server: walletintaleq.intaleq.xyz]
end
style A fill:#4a90d9,color:#fff
style C fill:#4a90d9,color:#fff
style E fill:#4a90d9,color:#fff
style F fill:#4a90d9,color:#fff
style L fill:#e67e22,color:#fff
style M fill:#e67e22,color:#fff
Server Infrastructure
| Server | Base URL | Purpose |
|---|---|---|
| API Server | https://api.intaleq.xyz/intaleq_v3 |
Auth, CRUD operations, ride management |
| Ride Server | https://rides.intaleq.xyz/intaleq/ride |
Ride-specific CRUD |
| Location Server | https://location.intaleq.xyz |
Socket.IO real-time location, batch uploads, behavior recording |
| Map SaaS | https://map-saas.intaleqapp.com/api/maps/route |
Route/polyline generation |
| Payment Server | https://walletintaleq.intaleq.xyz/v1/main |
Wallet management, payment processing |
| Call Server | wss://calls.intaleqapp.com/ws |
WebRTC signaling for voice/video calls |
Key Technologies
- State Management: GetX (
GetxController) - Real-time: Socket.IO (
socket_io_client: 1.0.2) athttps://location.intaleq.xyz - Map: Custom
intaleq_mapspackage (local path:../map-saas/packages/flutter-sdk/) - Routing API: OSRM-compatible response format via SaaS
- Navigation: Step-by-step with TTS (
flutter_tts: ^4.0.2) - Background:
flutter_background_service: ^5.1.0,flutter_overlay_window: ^0.5.0
2. Ride State Machine
The driver app uses an implicit state machine managed via a master status variable in map_driver_controller.dart.
stateDiagram-v2
[*] --> NoRide: App start / Return to home
NoRide --> Searching: Socket new_ride_request received
Searching --> DriverApplied: Driver taps Accept Order
DriverApplied --> Searching: Ride taken by another driver
DriverApplied --> DriverArrived: Driver arrives at pickup point
DriverArrived --> InProgress: Driver taps Start Ride / Begin
InProgress --> Finished: Driver taps Finish Ride
Finished --> PreCheckReview: Driver begins review process
PreCheckReview --> NoRide: Review complete / Rate passenger
Finished --> NoRide: Skip review
note right of NoRide: Location streaming active, listening for orders
note right of Searching: OrderRequestPage shown, route calculation
note right of DriverApplied: Navigation to passenger pickup point
note right of DriverArrived: Waiting timer counting, passenger notified
note right of InProgress: Navigation to destination, pricing timer active
State Management Pattern: The status is stored as a string variable (status) and checked throughout with switch/if blocks. Additionally, a Box (GetStorage) is used for persistence across app restarts. Key fields in Box include box.read('status'), box.read('ride_id'), box.read('tokenPassenger').
3. Phase 1: Ride Request Ingress
Flow Diagram
sequenceDiagram
participant S as Location Server Socket.IO
participant LC as LocationController
participant ORC as OrderRequestController
participant UI as OrderRequestPage
S->>LC: new_ride_request event
Note over LC: Data format: List or Map
LC->>LC: handleIncomingOrder()
Note over LC: Validate key '16' exists
LC->>LC: Extract DriverList structure
LC->>LC: Sort by distance
LC->>UI: Get.to OrderRequestPage
UI->>ORC: initState -> _initializeData()
ORC->>ORC: Parse List or Map format
ORC->>ORC: _calculateFullJourney()
ORC->>MapSaaS: getRoute for pickup + trip
MapSaaS-->>ORC: Return polylines + distance + duration
ORC->>UI: Update UI with routes
Socket Event: new_ride_request
Received in location_controller.dart (lines ~230-323).
Data Payload (supports two formats):
Format A — List (original):
[
"lat,lng", // [0] start coordinates
"lat,lng", // [1] end coordinates
"price", // [2]
"duration_sec", // [3] trip duration
"total_sec", // [4] total duration
"distance_m", // [5] trip distance
"unknown", // [6]
"passenger_id", // [7]
"customer_name", // [8]
"customer_token", // [9]
"phone", // [10]
"unknown", // [11]
"dist_to_driver_m", // [12] distance to driver
"unknown", // [13]
"unknown", // [14]
"duration_to_driver_sec", // [15]
"ride_id", // [16] - Validation key
...
"start_address", // [29]
"end_address", // [30]
"ride_type", // [31] Speed/Comfort/Lady/etc
"passenger_rate", // [33]
]
Format B — Map (newer):
{
'myListString': { ... },
'DriverList': [
{ lat, lng, price, duration, ... },
...
]
}
Validation Gate (location_controller.dart, lines 327-399)
void handleIncomingOrder(dynamic data) {
// Check if data has key '16' (ride_id) — if so, treat as List format
// Otherwise, extract from myListString/DriverList
// Convert all to sorted DriverList format
// Navigate to OrderRequestPage
}
Ride Taken Prevention (order_request_controller.dart, lines 624-649)
A dedicated socket listener prevents double-accept:
socket.on('ride_taken', (data) {
// Check if ride_id matches current displayed order
// If so, show "ride taken" dialogue and return to home
});
4. Phase 2: Accept Order & Navigation to Pickup
Accept Flow (order_request_controller.dart, lines 672-783)
sequenceDiagram
participant D as Driver
participant ORC as OrderRequestController
participant API as Ride Server
participant Box as GetStorage
participant PDP as PassengerLocationMapPage
participant MDC as MapDriverController
D->>ORC: Tap Accept
ORC->>API: GET acceptRide.php?ride_id=X&driver_id=Y
API-->>ORC: Success response
ORC->>Box: Write rideArgs: ride_id, status=applied, tokenPassenger, carType, kazan, etc.
ORC->>PDP: Get.to(PassengerLocationMapPage, arguments: rideArgs)
PDP->>MDC: argumentLoading() parses rideArgs
MDC->>Box: Persist all ride data
MDC->>MapSaaS: getRoute(for pickup location)
MapSaaS-->>MDC: Polyline + steps for driver->passenger route
MDC->>MDC: Draw polyline on map
MDC->>MDC: Start GPS tracking, step-by-step navigation
Ride Arguments Map (map_driver_controller.dart, lines 2212-2279)
The complete rideArgs map written to Box:
| Field | Source | Description |
|---|---|---|
passenger_lat, passenger_lng |
From order data | Passenger pickup location |
passenger_destination_lat, passenger_destination_lng |
From order data | Trip destination |
ride_id |
From order data | Unique ride identifier |
tokenPassenger |
From order data | Passenger auth token |
carType |
Driver profile | Speed/Fixed/Comfort/Lady/Electric/Van/Delivery |
kazan |
From order data | Commission percentage |
status |
Set to applied |
Current ride state |
price |
From order data | Trip price |
customerName |
From order data | Passenger name |
tripDistance |
From order data | Total trip distance |
tripDurationMin |
Calculated | Trip duration in minutes |
5. Phase 3: Arrival & Begin Ride
Arrival Detection
The driver's GPS is continuously monitored. When the driver reaches within ~150m of the passenger, the "Arrived" UI state activates.
Begin Ride (map_driver_controller.dart, lines 838-952)
sequenceDiagram
participant D as Driver
participant MDC as MapDriverController
participant API as Ride Server
participant Box as GetStorage
participant PSGR as Passenger App
D->>MDC: Tap "Begin Ride" / startRideFromDriver()
MDC->>MDC: Validate distance from passenger < 150m
MDC->>API: GET start_ride.php?ride_id=X&driver_id=Y&passenger_id=Z×tamp=...
API-->>MDC: Success
MDC->>Box: Update status to 'begin'
MDC->>PSGR: Socket emit update_location with status=begin
MDC->>MapSaaS: getRoute(for destination, from current location)
MapSaaS-->>MDC: New polyline from current pos -> destination
MDC->>MDC: Redraw polyline on map
MDC->>MDC: Start pricing timer (rideIsBeginPassengerTimer)
MDC->>MDC: Start step-by-step navigation
Key Validation: Distance from passenger must be <150m before ride can begin. This prevents starting the ride prematurely.
6. Phase 4: In-Ride Navigation & Polyline System
Full Navigation Stack
graph TB
subgraph "Navigation System"
GPS[Geolocator Stream] --> Filter[Jitter Filter <2m]
Filter --> NavCtrl[NavigationController]
Filter --> MDC[MapDriverController]
NavCtrl --> RouteMatch[RouteMatcherWorker Isolate]
NavCtrl --> PolylineDecode[DecodePolylineIsolate]
RouteMatch --> SmartSnap[Smart Sliding Window Snapping]
SmartSnap --> SplitPoly[Split Traveled vs Upcoming]
PolylineDecode --> RouteCoords[Full Route Coordinates]
RouteCoords --> StepNav[Step-by-Step Instructions]
StepNav --> TTS[Flutter TTS Voice]
SplitPoly --> GreyPoly[Grey Traveled Polyline]
SplitPoly --> ColorPoly[Colored Upcoming Polyline]
end
GPS --> Camera[Adaptive Camera]
Camera --> Zoom[Speed-Based Zoom: 15-19]
Camera --> Tilt[Speed-Based Tilt: 0-55deg]
MDC --> Pricing8[Pricing Timer: 1s interval]
Polyline Rendering (Dual Polyline System)
The driver app renders two polylines simultaneously:
- Upcoming Route (
polylineinMapDriverController): Colored polyline from the driver's current snapped position to the destination - Traveled Route (
polyline2inMapDriverController): Grey polyline showing the path already driven
Smart Sliding Window Snapping (map_driver_controller.dart, lines 2563-2622)
void _updateTraveledPolylineSmart(LatLng currentLocation) {
// 1. Define sliding window of 60 points around last known index
// 2. Find closest point on the original route polyline within that window
// 3. Split the original route at the matched index:
// - Points [0..matchedIndex] -> traveled (grey polyline)
// - Points [matchedIndex..end] -> upcoming (colored polyline)
// 4. Update map with both polylines
}
Isolate-Based Route Matching (route_matcher_worker.dart)
The heavy computation of finding the closest point on the route polyline is offloaded to a dedicated isolate:
Messages: init, match, dispose
Response: matchResult { index, lat, lng, dist }
- Uses Float64List for zero-copy memory sharing
- Sliding window search (default: 120 points, configurable)
- Haversine distance for accurate meter-level distance calculation
- Projection onto line segments for sub-point accuracy
Step-by-Step Navigation (map_driver_controller.dart, lines 211-273)
void startListeningStepNavigation() {
// 1. Subscribe to Geolocator stream with jitter filter (<2m ignore)
// 2. Smooth animation via AnimationController
// 3. Snap to route (update traveled polyline)
// 4. Check proximity to next step waypoint
// 5. If near next waypoint:
// - Speak next instruction via TTS
// - Update currentStepIndex
// - Show next instruction distance
// 6. Update camera position (adaptive zoom/tilt based on speed)
}
Adaptive Camera:
| Speed | Zoom | Tilt |
|---|---|---|
| < 15 km/h | 19 | 0° |
| < 40 km/h | 18 | 40° |
| < 70 km/h | 17 | 55° |
| < 100 km/h | 16 | 55° |
| 100+ km/h | 15 | 55° |
7. Phase 5: Finish Ride & Payment
Finish Ride Flow (map_driver_controller.dart, lines 1236-1354)
sequenceDiagram
participant D as Driver
participant MDC as MapDriverController
participant API as Ride Server
participant PayAPI as Payment Server
participant Box as GetStorage
D->>MDC: Tap "Finish Ride"
Note over MDC: Validate trip distance anti-fraud
par Parallel Execution
MDC->>API: finish_ride_updates.php
MDC->>PayAPI: process_ride_payments.php
end
API-->>MDC: Ride status updated to finished
PayAPI-->>MDC: Payment processed
MDC->>MDC: Stop pricing timer
MDC->>MDC: Stop navigation / polyline
MDC->>Box: Update status to 'finished'
MDC->>Box: Save ride price to payment_summary
MDC->>MDC: Clear polyline, markers, camera
MDC->>MDC: Show ride summary / review UI
Anti-Fraud Distance Validation (map_driver_controller.dart, lines ~1290-1330)
_validateTripDistance() {
// Actual traveled distance must be >= 1/5 of expected trip distance
// If not, auto-reject as potential fraud
// This prevents drivers from starting and immediately finishing rides
}
Payment Processing (map_driver_controller.dart, lines ~1330-1354)
- Payment is processed in parallel with ride finish
- Payment server generates secure tokens for wallet transactions
- Supports: Stripe, PayMob, MTN, Syriatel, eCash, ShamCash
8. Phase 6: Post-Ride (Rating, Review)
After finishing, the driver enters the preCheckReview state:
- Rating: Rate the passenger (
addRateToPassenger.php) - Review Screen:
ride_calculate_driver.dartshows:- Trip price breakdown
- Commission (kazan%)
- Net earnings
- Distance/time summary
- Return to Home: Status reset to
noRide, ready for next order
9. Pricing Engine
Core Pricing Timer (map_driver_controller.dart, lines 1481-1570)
void rideIsBeginPassengerTimer() {
Timer.periodic(Duration(seconds: 1), (timer) {
// 1. Calculate distance delta since last tick
// 2. Fetch current car type pricing config
// 3. Apply time-of-day multiplier
// 4. Apply distance-based thresholds
// 5. Apply airport surcharge if applicable
// 6. Calculate commission (kazan%)
// 7. Update live price display
});
}
Price Calculation Formula (map_driver_controller.dart, lines 1572-1662)
double _calculateCurrentPrice() {
// Base price depends on carType:
// Speed, Fixed, Comfort, Lady, Electric, Van, Delivery
//
// Time-of-day bands:
// nature (normal), late (evening/night), heavy (peak)
//
// Distance thresholds:
// 25km, 35km, 40km - different pricing tiers
//
// Commission: kazan% taken by platform
//
// Airport contexts: additional surcharge
//
// Formula (simplified):
// basePrice = carType.baseRate * timeMultiplier
// distancePrice = distance * carType.perKmRate
// if distance > 25km: apply longTripMultiplier
// if airport: add airportSurcharge
// finalPrice = (basePrice + distancePrice) * (1 + kazan/100)
}
10. Socket.IO Communication
Connection Setup (location_controller.dart, lines 183-228)
void initSocket() {
socket = io(
'https://location.intaleq.xyz',
<String, dynamic>{
'transports': ['websocket'], // WebSocket-only transport
'query': {
'driver_id': driverId,
'token': authToken,
},
},
);
}
Events Summary
| Event | Direction | Frequency | Purpose |
|---|---|---|---|
new_ride_request |
Server → Driver | On demand | Incoming ride request |
ride_taken |
Server → Driver | On demand | Ride accepted by another driver |
cancel_ride |
Server → Driver | On demand | Passenger cancelled the ride |
update_location |
Driver → Server | Every 5-10s | Driver location broadcast |
connect |
Bidirectional | On connect | Socket established |
disconnect |
Bidirectional | On disconnect | Socket lost |
| Heartbeat (ping/pong) | Bidirectional | Every 25s | Keep-alive |
Cancel Ride Handler (map_driver_controller.dart, lines 339-410)
void processRideCancelledByPassenger() {
// Gatekeeper: stop all timers immediately (Fix 2)
// Stop: pricingTimer, waitingTimer, navigation
// Show cancellation dialog
// Clear ride data from Box
// Reset status to noRide
// Return to HomeCaptain
}
Location Upload (location_controller.dart, lines 420-453)
void emitLocationToSocket() {
Map<String, dynamic> data = {
'driver_id': driverId,
'lat': currentLat,
'lng': currentLng,
'heading': heading,
'speed': speed,
'status': currentStatus,
'distance': distance,
};
// If ride active, inject passenger_id and ride_id
if (rideActive) {
data['passenger_id'] = passengerId;
data['ride_id'] = rideId;
}
socket.emit('update_location', data);
}
11. HTTP Backend API Endpoints
Ride Lifecycle Endpoints
| Endpoint | Method | Phase | Purpose |
|---|---|---|---|
acceptRide.php |
GET | Accept | Driver accepts ride offer |
start_ride.php |
GET | Begin | Start the ride trip |
finish_ride_updates.php |
GET | Finish | Complete ride (parallel) |
process_ride_payments.php |
GET | Finish | Process payment (parallel) |
cancelRide/add.php |
POST | Any | Log cancellation |
addCancelTripFromDriverAfterApplied.php |
POST | Applied | Driver cancels after accepting |
Ride Data Endpoints
| Endpoint | Method | Purpose |
|---|---|---|
rides/add.php |
POST | Create ride record |
rides/get.php |
GET | Retrieve ride details |
rides/update.php |
POST | Update ride status |
rides/delete.php |
DELETE | Remove ride record |
getRideStatus.php |
GET | Check ride status |
getRideOrderID.php |
GET | Get order ID for ride |
updateRideAndCheckIfApplied.php |
POST | Atomic status check + update |
getRideStatusFromStartApp.php |
GET | Recover ride status on app start |
Location Endpoints
| Endpoint | Method | Purpose |
|---|---|---|
add_batch.php |
POST | Batch location upload |
save_behavior.php |
POST | Record driving behavior |
get.php |
GET | Get car locations |
getRidesDriverByDay.php |
GET | Daily ride history |
getTotalDriverDuration.php |
GET | Total driving time |
Map SaaS Endpoint
| Endpoint | Method | Purpose |
|---|---|---|
https://map-saas.intaleqapp.com/api/maps/route |
POST | Route calculation with polyline |
https://map-saas.intaleqapp.com/api/geocoding/places |
POST | Place search/geocoding |
Route API Response Format (OSRM-compatible):
{
"routes": [{
"geometry": {
"coordinates": [[lng, lat], ...],
"points": "encoded_polyline_string"
},
"legs": [{
"steps": [
{
"maneuver": { "location": [lng, lat], "modifier": "straight" },
"instruction": "Continue straight on Main St",
"distance": 123.4,
"duration": 45.6
}
],
"distance": 5000.0,
"duration": 600.0
}],
"distance": 5000.0,
"duration": 600.0
}]
}
Payment Endpoints
| Endpoint | Method | Purpose |
|---|---|---|
payment/add.php |
POST | Record payment |
payment/get.php |
GET | Get today's payments |
getAllPaymentFromRide.php |
GET | All payments for a ride |
addPaymentTokenDriver.php |
POST | Generate payment token |
payWithPayMobCardDriver.php |
POST | PayMob card payment |
payWithWallet.php |
POST | Wallet payment |
payWithMTNConfirm.php |
POST | MTN payment confirmation |
payWithSyriatelConfirm.php |
POST | Syriatel payment confirmation |
12. Polyline Engine Deep Dive
Polyline Decoding (decode_polyline_isolate.dart)
Standard Google Encoded Polyline Format v5:
List<LatLng> decodePolylineIsolate(String encoded) {
// Standard algorithm:
// 1. Read 5-bit chunks from charCode - 63
// 2. Reconstruct signed value using ZigZag decoding
// 3. Accumulate lat/lng and divide by 1E5
// 4. Add to points list
}
Runs in separate isolate via compute(PolylineUtils.decode, ...) to avoid jank.
Route Fetching (order_request_controller.dart, lines 341-405)
Future<Map<String, dynamic>> _fetchRouteData(LatLng from, LatLng to) async {
// 1. POST to AppLink.mapSaasRoute with coordinates
// 2. Parse OSRM-style response
// 3. Decode polyline via compute(_decodePolyline, ...)
// 4. Return {distance, duration, polyline, steps}
}
Dual Polyline System (Visual)
Before traveling:
[Passenger] ============================================> [Destination]
(Full route in blue/colored)
During travel:
[Driver] ~~~~~~~~~~> [Current Position] ===============> [Destination]
(Grey traveled) (Colored upcoming)
Smart Snapping Visualization
Original route points:
P0 --- P1 --- P2 --- P3 --- P4 --- P5 --- P6 --- P7 --- P8
Driver at position X (near P2-P3 segment):
Sliding window: [P0---P1---P2---P3---P4---P5] (window=60)
Closest projection: on segment P2-P3 at point C
Result:
Traveled: P0---P1---P2---C (grey)
Upcoming: C---P3---P4---P5---P6---P7---P8 (colored)
13. Location Tracking System
Dual-Interval Architecture (location_controller.dart)
graph LR
subgraph "Normal Mode"
GPS3[GPS every 5s] --> Record3[Record to buffer every 3s]
Record3 --> Upload2[Upload batch every 2min]
Upload2 --> Socket[Socket.IO emit]
Upload2 --> HTTP[HTTP batch upload]
end
subgraph "Power Save Mode"
GPS10[GPS every 10s] --> Record10[Record to buffer every 10s]
Record10 --> Upload5[Upload batch every 5min]
Upload5 --> Socket
Upload5 --> HTTP
end
Behavior Recording
In addition to location, the system records driving behavior:
- Acceleration/deceleration events
- Speed threshold violations
- Uploaded to
save_behavior.php
Battery Optimization
- Wakelock: Maintained during active rides (
wakelock_plus) - Background Service:
flutter_background_servicekeeps location streaming alive - Overlay Window:
flutter_overlay_windowshows driver status even when app is backgrounded
14. Voice Call Signaling
WebSocket Signaling (signaling_service.dart)
sequenceDiagram
participant D as Driver App
participant WS as WebSocket wss://calls.intaleqapp.com/ws
participant P as Passenger App
D->>WS: authenticate { session_id, user_id }
WS-->>D: authenticated
P->>WS: authenticate { session_id, user_id }
WS-->>P: authenticated
P->>WS: call_request { target_user_id }
WS->>D: participant_joined { user_id }
D->>WS: offer { sdp }
WS->>P: offer { sdp }
P->>WS: answer { sdp }
WS->>D: answer { sdp }
D->>WS: ice_candidate { candidate }
WS->>P: ice_candidate { candidate }
P->>WS: ice_candidate { candidate }
WS->>D: ice_candidate { candidate }
Note over D,P: WebRTC Peer Connection established
D->>WS: call_ended
WS->>P: call_ended
15. Key Architectural Patterns & Fixes
Documented Fixes
| Fix | Issue | Solution |
|---|---|---|
| Fix 1 | Two competing GPS listeners | Merged into single stream subscription |
| Fix 2 | Timer leak on cancel | Stop ALL timers immediately at gatekeeper |
| Fix 3 | Polyline decode blocking UI | Moved to compute() isolate |
| Fix 4 | Wrong distance unit in validation | Fixed _validateTripDistance() unit conversion |
| Fix 5 | Future.delayed without await |
Added proper await |
| Fix 6 | Redundant heartbeat during stream | Skip heartbeat if location stream active |
Architecture Patterns
- Controller-per-Screen: Each screen has its own
GetxController - Box Persistence: GetStorage used for ride state recovery across app restarts
- Socket Decoupling: Location data flows through Socket.IO, but ride CRUD uses HTTP REST
- Isolate Offloading: Heavy polyline operations run in isolates via
compute() - Parallel Execution: Finish ride + payment run concurrently via
Future.wait - Dual Data Format Support: Socket data arrives as either List or Map — both handled
- Gatekeeper Pattern: Cancellation handler stops all active processes at a single entry point
16. Data Flow Diagrams
Complete Ride Lifecycle Data Flow
graph TB
subgraph "Pre-Ride"
A[Socket: new_ride_request] --> B[Parse List/Map]
B --> C[OrderRequestPage]
C --> D[Driver Accepts]
D --> E[HTTP: acceptRide.php]
E --> F[Write rideArgs to Box]
F --> G[Navigate to Map]
end
subgraph "To-Passenger"
G --> H[Route: Driver -> Passenger]
H --> I[Drew colored polyline]
I --> J[Step Nav + TTS]
J --> K[GPS updates every 5s]
K --> L[Socket: update_location]
L --> M[Smart snap to route]
end
subgraph "At Passenger"
M --> N[Arrive ~150m]
N --> O[HTTP: start_ride.php]
O --> P[Redraw route -> Destination]
end
subgraph "To-Destination"
P --> Q[Pricing Timer 1s]
Q --> R[Live price display]
R --> S[Step Nav + TTS]
S --> T[Dual polyline: grey + colored]
T --> U[Socket: update_location with status]
end
subgraph "Finish"
U --> V[HTTP: finish_ride_updates.php]
V --> W[HTTP: process_ride_payments.php]
W --> X[Stop all timers]
X --> Y[Clear polylines]
Y --> Z[Show summary / rating]
Z --> AA[Reset to noRide]
end
style A fill:#e74c3c,color:#fff
style O fill:#2ecc71,color:#fff
style V fill:#2ecc71,color:#fff
style W fill:#2ecc71,color:#fff
style AA fill:#3498db,color:#fff
Socket Event Flow During Ride
sequenceDiagram
participant Driver
participant LS as Location Server
participant PSGR as Passenger App
Note over Driver: Searching for ride
LS->>Driver: new_ride_request { data }
Driver->>LS: update_location { status: searching }
Note over Driver: Ride accepted
Driver->>LS: update_location { status: applied, ride_id }
Note over Driver: En route to passenger
Driver->>LS: update_location { lat, lng, heading, speed, status: goingToPassenger }
LS->>PSGR: driverLocationUpdate { ... }
Note over Driver: Arrived at passenger
Driver->>LS: update_location { status: arrived }
Note over Driver: Ride started
Driver->>LS: update_location { status: inProgress, ride_id }
Note over Driver: En route to destination
Driver->>LS: update_location { lat, lng, heading, speed, status: inProgress }
LS->>PSGR: driverLocationUpdate { ... }
Note over Driver: Ride finished
Driver->>LS: update_location { status: finished }
Note over Driver: Back to idle
Driver->>LS: update_location { status: online }
Key Backend Endpoints Used Per Phase
| Phase | Endpoint | Purpose |
|---|---|---|
| Accept | acceptRide.php?ride_id=X&driver_id=Y |
Accept ride |
| Begin | start_ride.php?ride_id=X&driver_id=Y&passenger_id=Z |
Start trip |
| In-Ride | update_location (Socket) |
Location streaming |
| In-Ride | updateRideAndCheckIfApplied.php |
Status sync |
| In-Ride | getKazanPercent.php |
Commission config |
| Finish | finish_ride_updates.php |
Complete ride |
| Finish | process_ride_payments.php |
Payment processing |
| Finish | addRateToPassenger.php |
Passenger rating |
| Post-Ride | getAllPaymentFromRide.php |
Payment summary |
| Any | getRideStatusFromStartApp.php |
State recovery on restart |
Appendix: Key File Reference
| File | Lines | Purpose |
|---|---|---|
lib/controller/home/captin/map_driver_controller.dart |
2644 | Core driver ride lifecycle, navigation, polyline, pricing |
lib/controller/home/captin/order_request_controller.dart |
828 | Ride request handling, accept logic, route display |
lib/controller/functions/location_controller.dart |
794 | Socket.IO, location tracking, batch upload, behavior |
lib/controller/home/navigation/navigation_controller.dart |
1383 | Step-by-step navigation, route matching, alternative routes |
lib/controller/home/navigation/route_matcher_worker.dart |
146 | Isolate-based route matching with sliding window |
lib/controller/home/navigation/decode_polyline_isolate.dart |
32 | Polyline decode in isolate |
lib/models/model/order_data.dart |
188 | Order data model (List + Map constructors) |
lib/constant/links.dart |
424 | All backend API endpoints |
lib/services/signaling_service.dart |
112 | WebRTC call signaling |
lib/services/offline_map_service.dart |
- | Offline map tile service |
pubspec.yaml |
144 | Dependencies and package config |