Files
intaleq_driver/plans/driver_ride_lifecycle_report.md

32 KiB

Intaleq Driver App — Complete Ride Lifecycle Analysis Report

Table of Contents

  1. System Architecture Overview
  2. Ride State Machine
  3. Phase 1: Ride Request Ingress (Socket → Order Request)
  4. Phase 2: Accept Order & Navigation to Pickup
  5. Phase 3: Arrival & Begin Ride
  6. Phase 4: In-Ride Navigation & Polyline System
  7. Phase 5: Finish Ride & Payment
  8. Phase 6: Post-Ride (Rating, Review)
  9. Pricing Engine
  10. Socket.IO Communication
  11. HTTP Backend API Endpoints
  12. Polyline Engine Deep Dive
  13. Location Tracking System
  14. Voice Call Signaling
  15. Key Architectural Patterns & Fixes
  16. 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) at https://location.intaleq.xyz
  • Map: Custom intaleq_maps package (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&timestamp=...
    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:

  1. Upcoming Route (polyline in MapDriverController): Colored polyline from the driver's current snapped position to the destination
  2. Traveled Route (polyline2 in MapDriverController): 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
< 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:

  1. Rating: Rate the passenger (addRateToPassenger.php)
  2. Review Screen: ride_calculate_driver.dart shows:
    • Trip price breakdown
    • Commission (kazan%)
    • Net earnings
    • Distance/time summary
  3. 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_service keeps location streaming alive
  • Overlay Window: flutter_overlay_window shows 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

  1. Controller-per-Screen: Each screen has its own GetxController
  2. Box Persistence: GetStorage used for ride state recovery across app restarts
  3. Socket Decoupling: Location data flows through Socket.IO, but ride CRUD uses HTTP REST
  4. Isolate Offloading: Heavy polyline operations run in isolates via compute()
  5. Parallel Execution: Finish ride + payment run concurrently via Future.wait
  6. Dual Data Format Support: Socket data arrives as either List or Map — both handled
  7. 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