# PASSENGER_JOURNEY.md — Complete Passenger Lifecycle ## Stage 1: App Launch ### Screen - **Route**: `/` → SplashScreen - **File**: `siro_rider/lib/splash_screen_page.dart` - **Controller**: `SplashScreenController` (in `siro_rider/lib/controller/home/splash_screen_controlle.dart`) ### State Flow - **Type**: GetX Controller (Custom Animation) - **Events**: `controller.init()` → animations play → `controller.checkInitialStatus()` - **States**: Splash animation → Progress bar → Navigate based on auth status ### Variables | Variable | Storage | Key | |----------|---------|-----| | jwt | GetStorage | `box.read(BoxName.jwt)` | | passengerID | GetStorage | `box.read(BoxName.passengerID)` | | driverID | GetStorage | `box.read(BoxName.driverID)` | | language | GetStorage | `box.read(BoxName.lang)` | | themeMode | GetStorage | theme preference | | packageInfo | GetStorage | `BoxName.packagInfo` | ### APIs | Endpoint | Method | Input | Output | |----------|--------|-------|--------| | `$server/auth/packageInfo.php` | POST | platform, appName | version info | ### Database Tables - `packageInfo` — app version tracking ## Stage 2: Authentication Check ### State Flow: SplashScreenController 1. Check `box.read(BoxName.jwt)` existence 2. If JWT exists → check ride status (`_checkInitialRideStatus()`) → navigate to MapScreen or Login 3. If no JWT → navigate to Onboarding/Login ### Navigation Decision ``` SplashScreen → JWT exists? → Yes → MapPagePassenger → No → OnboardingPage (first time) or LoginPage ``` ### Screens | Screen | Route | File | |--------|-------|------| | Onboarding | `/onboarding` | `siro_rider/lib/onbording_page.dart` | | Login | `/login` | `siro_rider/lib/views/auth/login_page.dart` | | Register | `/register` | `siro_rider/lib/views/auth/register_page.dart` | | OTP | `/otp` | `siro_rider/lib/views/auth/otp_page.dart` | ### APIs | Endpoint | Method | Input | Output | |----------|--------|-------|--------| | `$server/auth/login.php` | POST | phone, password, fingerprint | JWT, passenger data | | `$server/auth/signup.php` | POST | phone, email, password, name, ... | user created | | `$server/auth/loginFromGooglePassenger.php` | POST | google token | JWT, passenger data | | `$server/auth/checkPhoneNumberISVerfiedPassenger.php` | POST | phone | verification status | | `$auth/otpmessage.php` | POST | phone | OTP sent | | `$auth/verifyOtpMessage.php` | POST | phone, otp | verified status | ### Models - **UserModel** → `passengers` table - **TokenModel** → `tokens` table ## Stage 3: Map Screen — Ride Request ### Screen - **File**: `siro_rider/lib/views/home/map_page_passenger.dart` - **Controllers** (all permanent in AppBindings): - `MapEngineController` — map rendering - `MapSocketController` — WebSocket management - `LocationSearchController` — place search - `NearbyDriversController` — nearby driver list - `RideLifecycleController` — ride state machine - `UiInteractionsController` — UI bottom sheets ### State Flow: RideLifecycleController - **RideState enum**: `noRide → searching → driverApplied → driverArrived → inProgress → finished → preCheckReview → cancelled` ### Search Flow 1. Passenger enters destination → `LocationSearchController.searchPlaces()` 2. Price estimate fetched via fare calculation 3. Passenger selects car type → confirms ride 4. Ride request sent → status = `waiting` → transitions to `searching` ### APIs (Ride Request) | Endpoint | Method | Input | Output | |----------|--------|-------|--------| | `$rideServerSide/ride/rides/add.php` | POST | passenger_id, start_lat, start_lng, end_lat, end_lng, carType, price, ... | ride_id | | `$rideServerSide/cancelRide/add.php` | POST | ride_id, passenger_id, note | cancellation | | `$server/ride/promo/getPromoBytody.php` | POST | passenger_id | promo code | ### Database Tables - `waitingRides` — active ride requests - `ride` — completed rides - `promos` — promo codes ### GIS Operations - **Reverse Geocoding**: Map SaaS (`/api/geocoding/reverse`) - **Search Geocoding**: Map SaaS (`/api/geocoding/search`) - **Routing**: Map SaaS (`/api/maps/route`) or OSRM (`routesy.intaleq.xyz`) - **ETA Calculation**: Local algorithm in `RideLifecycleController.updateRemainingRoute()` - **Map Rendering**: `SiroMaps` (custom Flutter map plugin) ## Stage 4: Searching for Driver ### Screen - **Widget**: `searching_captain_window.dart` - **Timer**: `timer_for_cancell_trip_from_passenger.dart` ### State Flow - `RideState.searching` - Polling loop checks `_totalSearchTimeoutSeconds` - On timeout → `_showIncreaseFeeDialog()` ### Real-time Operations | Channel | Event | Direction | |---------|-------|-----------| | WebSocket | `driver_location_update` | Server → Passenger | | WebSocket | `ride_accepted` | Server → Passenger | | Polling | `getRideStatus` | Passenger → Server (fallback) | ### Notifications - **Local**: Timer tick notifications - **Push**: When driver accepts via FCM ### Failure Scenarios | Scenario | Handling | |----------|----------| | No drivers found | Show increase fee dialog | | Network failure | Fallback to polling, show error snackbar | | Timeout | Auto-cancel, prompt retry | ## Stage 5: Driver Accepted ### Screen - **Widget**: `driver_card_from_passenger.dart`, `driver_time_arrive_passenger.dart` - **Function**: `processRideAcceptance()` ### State Flow - `RideState.driverApplied` - **Events**: `processRideAcceptance(driverData)` - **Transitions**: `applied → arrived` (when driver reaches pickup) ### Variables Stored | Variable | Description | |----------|-------------| | `dInfo` | Driver info (name, car, rating, phone) | | `currentRideId` | Active ride ID | | `rideData` | Full ride details (price, locations, timestamps) | | `datadriverCarsLocationToPassengerAfterApplied` | Driver GPS route | ### APIs | Endpoint | Method | Input | Output | |----------|--------|-------|--------| | `$rideServerSide/ride/rides/getRideStatus.php` | POST | ride_id | current status | | `$location/getDriverCarsLocationToPassengerAfterApplied.php` | POST | driver_id | GPS location | ### GIS Operations - **Route Drawing**: Yellow polyline from driver → passenger - **Driver Marker**: Real-time car icon following WebSocket updates - **Deviation Detection**: `checkAndRecalculateIfDeviated()` with 50m threshold ### Real-time Operations - **WebSocket Connect**: Join ride room - **Subscribe**: `driver_location_update` events - **Driver Tracking**: `handleDriverLocationUpdate()` → stop polling after 3 reliable updates ### Notifications - **Push**: FCM when driver accepts - **In-App**: `RideLiveNotification.showDriverOnWay()` - **iOS Live Activity**: `IosLiveActivityService.startRideActivity()` ## Stage 6: Driver Arrived ### Screen - **Widget**: `driver_time_arrive_passenger.dart`, `ride_begin_passenger.dart` - **Function**: `processDriverArrival()` ### State Flow - `RideState.driverArrived` - **Events**: `processDriverArrival("polling")` or via socket - **Timer**: 5-minute waiting timer starts - **Pre-drawing**: Blue route from pickup → destination pre-calculated ### Notifications - **In-App Dialog**: `uiInteractions.driverArrivePassengerDialoge()` - **Push**: Driver arrived notification ## Stage 7: Ride In Progress ### Screen - **Widget**: `ride_begin_passenger.dart`, `passengerRideLoctionWidget.dart` ### State Flow - `RideState.inProgress` - **Events**: `processRideBegin()` - **Timer**: `rideIsBeginPassengerTimer()` — live ride counter ### GIS Operations - **Blue Route**: Final path from driver → destination - **Live ETA**: Updated via `updateRemainingRoute()` (local calculation) - **Camera Tracking**: Follows driver, zoom adjusts by speed - **Deviation Guard**: Continuous deviation checking, re-route if >50m off path ### Real-time Operations - **WebSocket**: Continuous `driver_location_update` streaming - **Polling Fallback**: If socket disconnected, poll `getRideStatus` ### iOS Live Activity - `IosLiveActivityService` — Dynamic Island / Lock Screen widget - `RideWidget` in ios/RideWidget — SwiftUI widget ## Stage 8: Ride Finished — Payment & Rating ### Screen - **Rating**: `siro_rider/lib/views/Rate/rate_captain.dart`, `rating_driver_bottom.dart` - **Payment**: `payment_method.page.dart`, `cash_confirm_bottom_page.dart` ### State Flow - `RideState.finished` → `processRideFinished()` - Disposes ride socket, stops all timers - Navigates to RateDriverFromPassenger with driver_id, ride_id, bill ### APIs | Endpoint | Method | Input | Output | |----------|--------|-------|--------| | `$server/ride/rate/addRateToDriver.php` | POST | passenger_id, driver_id, ride_id, rating, comment | success | | `$paymentServer/ride/payment/add.php` | POST | amount, payment_method, passengerID, rideId, driverID | payment record | | `$paymentServer/ride/passengerWallet/addPaymentTokenPassenger.php` | POST | passengerId, amount, token | wallet deduction | | `$wallet/getAllPassengerTransaction.php` | POST | passenger_id | transaction history | | `$server/ride/tips/add.php` | POST | driverID, passengerID, rideID, tipAmount | tip saved | ### Payment Methods Flow 1. **Cash**: Show confirmation dialog, driver marks received 2. **Wallet**: Deduct from `passengerWallet` balance 3. **Visa (PayMob)**: `payWithPayMobCardPassenger` → `paymetVerifyPassenger` 4. **MTN**: `payWithMTNStart` → `payWithMTNConfirm` 5. **Syriatel**: `payWithSyriatelStart` → `payWithSyriatelConfirm` ### Database Tables - `payments` — ride payment records - `ratingDriver` — driver ratings - `ratingPassenger` — passenger ratings - `tips` — tips given - `passengerWallet` — wallet balance ### Notifications - **Push**: Receipt notification - **In-App**: Rating prompt ## Stage 9: Post-Ride ### Screen - **Profile**: `passenger_profile_page.dart` - **Wallet**: `passenger_wallet.dart` - **History**: `order_history.dart` - **Promos**: `promos_passenger_page.dart` ### APIs | Endpoint | Method | Input | Output | |----------|--------|-------|--------| | `$wallet/getWalletByPassenger.php` | GET | passenger_id | wallet balance | | `$profile/get.php` | POST | passenger_id | profile data | | `$rideServerSide/ride/rides/get.php` | POST | passenger_id | ride history | | `$promo/get.php` | POST | passenger_id | available promos | | `$server/ride/invitor/get_passenger_referrals.php` | POST | passenger_id | referral data | --- ## Navigation Route Map ``` SplashScreen (/) → [JWT exists?] → Yes → MapPagePassenger (/home/map_page_passenger) → No → OnboardingPage → LoginPage → OTPPage → MapPagePassenger MapPagePassenger → [Ride states trigger widgets] → [Menu] → Profile (/profile), Wallet (/wallet), Settings, Promos → [Rating] → RateCaptain page → [Contact] → ContactUsPage (/contactSupport) → [Share] → ShareAppPage (/shareApp)