# 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)