# AI_CONTEXT.md — Siro (Siro) Ride-Hailing Platform ## Core Architecture - **4 Flutter apps** (rider, driver, admin, service) + **PHP backend** + **MySQL** + **WebSocket** - **State Management**: GetX (permanent controllers in AppBindings) - **Maps**: Siro Maps (custom Flutter plugin) + Google Maps + Map SaaS + OSRM - **Domain**: siromove.com | **API**: api.intaleq.xyz/siro_v3 | **Ride**: rides.intaleq.xyz | **Location**: location.intaleq.xyz | **Payment**: walletintaleq.intaleq.xyz ## Passenger Flow (siro_rider) ``` Splash → Auth check → MapScreen (permanent map controllers) → Enter destination → Price calc → Ride request (waitingRides) → Searching (WebSocket polling + timer) → Driver accepts (RideState.driverApplied) → Driver arrives (RideState.driverArrived) → Ride begins (RideState.inProgress) → Ride finishes → Rating + Payment → Back to map ``` - **RideState enum**: noRide, cancelled, preCheckReview, searching, driverApplied, driverArrived, inProgress, finished - **Key Controller**: `RideLifecycleController` (4600 lines) — state machine, deviation detection, ETA calculation - **Deviation Guard**: 50m threshold, re-routes if off path - **Local ETA**: Route trimming by closest point, percentage-based time calculation ## Driver Flow (siro_driver) ``` Splash → Auth → MapScreen → Go Online (location streaming) → Ride offer via FCM + Android native overlay (TripOverlayPlugin) → Accept → Navigate to pickup → Arrived → Begin ride → Active ride → End ride → Rate passenger + Payment → Go Offline ``` - **Background**: Android foreground service for GPS + FCM background handler - **Overlay**: Custom native plugin shows trip data with accept/reject (auto-close 15s) - **Data package**: 33-index array (passengerLat/Lng, destination, fare, distance, name, phone, etc.) ## API Endpoints (59+ discovered) ### Auth | Endpoint | Caller | |----------|--------| | POST `$server/auth/login.php` | LoginController | | POST `$authCaptin/login.php` | Driver login | | POST `$server/auth/signup.php` | RegisterController | | POST `$server/loginJwtRider.php` | JWT refresh (401 handler) | ### Ride | Endpoint | Caller | |----------|--------| | POST `$rideServerSide/ride/rides/add.php` | Ride request | | POST `$rideServerSide/rides/acceptRide.php` | Driver accept | | POST `$rideServerSide/ride/rides/updateStausFromSpeed.php` | Status updates (Arrived/Begin/Finished) | | POST `$rideServerSide/ride/rides/getRideStatus.php` | Polling fallback | | POST `$server/ride/rides/getRideStatusFromStartApp.php` | App restore check | ### Location | Endpoint | Caller | |----------|--------| | POST `$location/{getSpeed,getComfort,getBalash,...}.php` | Nearby drivers by car type | | POST `$location/getDriverCarsLocationToPassengerAfterApplied.php` | Driver GPS after accept | ### Payment | Endpoint | Caller | |----------|--------| | POST `$paymentServer/ride/payment/add.php` | Ride payment | | POST `$paymentServer/ride/payMob/{wallet,card}/payWithPayMob.php` | Visa/Mastercard | | POST `$paymentServer/ride/mtn/passenger/{start,confirm}_payment.php` | MTN mobile money | | POST `$paymentServer/ride/syriatel/passenger/{start,confirm}_payment.php` | Syriatel mobile money | | POST `$paymentServer/ecash/payWithEcash.php` | E-Cash | ### Other | Endpoint | Caller | |----------|--------| | POST `$server/ride/rate/addRateToDriver.php` | Passenger rating | | POST `$server/ride/rate/addRateToPassenger.php` | Driver rating | | POST `$wallet/getWalletByPassenger.php` | Wallet balance | | POST `$walletDriver/getWalletByDriver.php` | Driver wallet | | POST `$promo/getPromoBytody.php` | Promo code check | | POST `$server/ride/invitor/get_unified_code.php` | Referral code | ## Database (60+ tables in intaleqDB1 + intaleq-ridesDB) ### Core Tables | Table | PK | Key Relationships | |-------|----|-------------------| | `passengers` | id (varchar) | → ride, waitingRides, payments, passengerWallet, tokens, ratingDriver, notifications | | `driver` | idn (auto) + id (varchar) | → ride, car_locations, payments, driverWallet, driverToken, driver_orders | | `ride` | id (auto) | passenger_id → passengers, driver_id → driver | | `waitingRides` | id (varchar) | passenger_id → passengers, SPATIAL indexes on lat/lng | | `car_locations` | driver_id (varchar) | SPATIAL idx_location_point (POINT), BTREE idx_loc_status_time | | `payments` | id (varchar) | passengerID, driverID, rideId | | `ratingDriver` | id (auto) | driver_id, passenger_id, UNIQUE ride_id | ### Key Indexes - `car_locations.location_point` — SPATIAL index for GIS queries - `waitingRides` — idx_location_status (lat,lng,status,created_at) - `palces11` — FULLTEXT on name/name_ar/name_en/address/category ## Real-time Systems - **WebSocket**: PHP Socket.IO server (socket_intaleq/{driver,passenger}_socket.php) - **Events**: `driver_location_update`, `ride_accepted`, `ride_cancelled`, `ride_finished` - **Polling fallback**: HTTP polling every N seconds when WebSocket disconnects - **3 reliable updates**: Stops polling after 3 consecutive WebSocket location updates ## Notifications - **Push**: Firebase Cloud Messaging (FCM) — `FirebaseMessagesController` - **Local**: `NotificationController` with custom channels - **iOS Live Activity**: `IosLiveActivityService` + SwiftUI RideWidget - **Background**: Android overlay (TripOverlayPlugin) for driver ride offers - **Types**: Order (ride offer), OrderSpeed, ride status updates ## GIS Logic - **Routing**: Map SaaS (`map-saas.intaleqapp.com/api/maps/route`) or OSRM (`routesy.intaleq.xyz`) - **Geocoding**: Map SaaS reverse geocoding + search - **ETA**: Local algorithm in `RideLifecycleController.updateRemainingRoute()` — finds closest route point, trims polyline, recalculates percentage - **Deviation**: `checkAndRecalculateIfDeviated()` — 50m threshold, consecutive heading check - **Driver Tracking**: `handleDriverLocationUpdate()` — camera follows driver, zoom by speed - **Marker Rotation**: Updates driver car icon rotation based on heading ## Wallet Logic - **Passenger Wallet**: `passengerWallet` table, deduct on ride, top-up via PayMob/MTN/Syriatel - **Driver Wallet**: `driverWallet` table, credit after ride, withdraw - **Payment Methods**: Cash (default), Visa (PayMob), Wallet, MTN, Syriatel, E-Cash - **Kazan**: Percentage-based commission per country (kazan table: comfortPrice, speedPrice, familyPrice, etc.) - **Tips**: `tips` table linked to ride/driver/passenger ## State Management Map ### Rider App Controllers (permanent in AppBindings) | Controller | States | Dependencies | |-----------|--------|-------------| | RideLifecycleController | RideState enum (8 states) | CRUD, MapEngine, MapSocket, UiInteractions, NearbyDrivers | | MapSocketController | connected/disconnected | WebSocket, RideLifecycle | | MapEngineController | map ready/loading | SiroMaps, markers, polylines | | LocationSearchController | idle/searching/result | Map SaaS API | | NearbyDriversController | empty/populated | Location API | | UiInteractionsController | sheet states | All ride widgets | | LoginController | logged out/authenticating/logged in | CRUD, JWT | | SplashScreenController | animating/checking/navigating | GetStorage, CRUD | ### Driver App | Controller | States | Dependencies | |-----------|--------|-------------| | HomeCaptainController | offline/online/in-ride | LocationService, WebSocket, CRUD | | NavigationController | idle/navigating/recalculating | Map, TTS | | BackgroundServiceHelper | running/stopped | Android service | ## Security - **JWT** with device fingerprint (SHA-256) in payload - **X-Device-FP** header validated against JWT fingerprint claim - **HMAC** for payment server (X-HMAC-Auth header) - **401 auto-refresh**: `LoginController.getJWT()` retries once - **Rate limiting**: login_attempts table per IP ## External Services | Service | Endpoint | Key Type | |---------|----------|----------| | Google Maps | maps.googleapis.com | API Key | | Map SaaS | map-saas.intaleqapp.com | x-api-key | | Here Maps | autosuggest.search.hereapi.com | API Key | | OSRM | routec.intaleq.xyz / routesy.intaleq.xyz | None | | PayMob | paymob.com | HMAC | | Twilio | verify.twilio.com | Account SID + Token | | Azure OCR | ocrhamza.cognitiveservices.azure.com | Subscription Key | | OpenAI | api.openai.com | Bearer Token | | Llama | Together API | Bearer Token | | SMS Kazumi | sms.kazumi.me | API Key | ## File Map (Key Files) ``` siro_rider/ lib/main.dart, app_bindings.dart, splash_screen_page.dart lib/controller/home/map/ride_lifecycle_controller.dart (4600 lines) lib/controller/home/map/ride_state.dart (8-state enum) lib/controller/home/map/map_socket_controller.dart lib/controller/home/map/map_engine_controller.dart lib/controller/functions/crud.dart (720 lines, unified HTTP client) lib/constant/links.dart (all API endpoints) lib/views/home/map_widget.dart/*.dart (20+ map UI widgets) siro_driver/ lib/main.dart (550 lines, accept/reject logic) lib/controller/functions/background_service.dart lib/controller/home/captin/home_captain_controller.dart lib/views/home/Captin/driver_map_page.dart lib/views/home/Captin/orderCaptin/order_request_page.dart backend/ schema_primary.sql (1826 lines, 60+ tables) schema_ride.sql (1787 lines) auth/*.php, ride/*.php, Admin/*.php socket_intaleq/ driver_socket.php, passenger_socket.php siro_admin/ (Flutter Web admin panel) 20+ controllers, 30+ views siro_service/ (Driver registration agent app) ``` ## Key Business Rules - **Ride timeout**: `_totalSearchTimeoutSeconds` → increase fee dialog - **Wait time**: 5-minute passenger wait after driver arrival - **Deviation**: 50m threshold before re-routing - **Socket reliability**: 3 updates → stop polling - **Cash payment**: Driver marks as received, confirmation dialog - **Wallet payment**: Deduct from passengerWallet, verify balance - **Multi-point trips**: Up to 5 waypoints (step0-step4 in ride args) - **Car types**: Speed, Comfort, Family, Delivery, Blash (free), Late, Heavy, Nature, Electric, PinkBike, Van, FemalDriver - **Regions**: Syria (routesy), Jordan (routesjo), Egypt (routec)