
# تقرير نظام تسجيل السائق — سوريا 🇸🇾

> **ملف المحاكاة التفاعلية:** [siro_driver_registration_simulation.html](file:///Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/siro_driver_registration_simulation.html)

---

## 🗺️ خريطة النظام الكاملة

```mermaid
flowchart TD
    A[📱 السائق يفتح التطبيق] --> B[RegisterCaptainController<br/>إدخال رقم الهاتف]
    B --> C{التحقق من الدولة}
    C -->|🇸🇾 سوريا| D[Phone Formatting<br/>09xx → 963xx]
    D --> E[POST /auth/otp/request.php<br/>country: Syria]
    E --> F{OTP Router}
    F -->|Primary| G[Intaleq WhatsApp]
    F -->|Failover 1| H[Nabeh JWT]
    F -->|Failover 2| I[SMS]
    G --> J[DB: phone_verification<br/>AES-GCM encrypted × 5min]
    J --> K[OtpVerificationController<br/>countdown 120s]
    K --> L[POST /auth/otp/verify.php]
    L --> M{✅ صحيح؟}
    M -->|نعم| N[RegistrationController<br/>3-Step Wizard]
    M -->|لا| K
    N --> O[Step 1: Driver Info<br/>الاسم + HID + DOB + License]
    O --> P[Step 2: Car Info<br/>Plate + Make + Model + VIN]
    P --> Q[Step 3: Doc Upload × 8]
    Q --> R[uploadToSyria × 8<br/>MultipartRequest + JWT]
    R --> S[uploadSyrianDocs.php<br/>private_uploads Signed URL 48h]
    S --> T[submitRegistration<br/>POST /register_driver_and_car.php]
    T --> U[🤖 Gemini Flash<br/>Vision AI Analysis]
    U --> V{AI Face Match}
    V -->|✅ high| W[DB Transaction<br/>driver + CarRegistration]
    V -->|❌ mismatch| X[jsonError - رفض]
    W --> Y[FCM → topic:service<br/>Admin Notification]
    Y --> Z[status: yet ⏳]
    Z --> AA[Admin Review]
    AA --> AB[status: active ✅]
    AB --> AC[JWT + driverToken<br/>السائق جاهز للعمل]
```

---

## 📱 مراحل التسجيل (8 خطوات)

### 1️⃣ إدخال رقم الهاتف — `RegisterCaptainController`

**منطق تنسيق الرقم السوري:**

```php
// من: register_driver_and_car.php
if (strpos($phone, '00963') === 0) {
    $phone = substr($phone, 2);          // 00963 → 963
} elseif (strpos($phone, '09') === 0) {
    $phone = '963' . substr($phone, 1);  // 09xx → 9639xx
} elseif (strpos($phone, '9') === 0 && strlen($phone) == 9) {
    $phone = '963' . $phone;             // 9xxxxxxxx → 9639xxxxxxxx
}
// التأكد من وجود 9 بعد 963
if (strpos($phone, '963') === 0 && strpos($phone, '9639') !== 0) {
    $phone = '9639' . substr($phone, 3);
}
```

---

### 2️⃣ نظام OTP — `OtpVerificationController`

| الدولة | المزود الأساسي | Failover 1 | Failover 2 |
|--------|---------------|-----------|-----------|
| 🇸🇾 سوريا | Intaleq WhatsApp | Nabeh JWT | SMS |
| 🇪🇬 مصر | Kazumi SMS | Intaleq WhatsApp | Nabeh JWT |
| 🇯🇴 الأردن | Intaleq SMS | Nabeh JWT | — |

**مخطط DB:**

```sql
-- جدول التحقق للسائق
INSERT INTO phone_verification (
  phone_number,     -- مشفر AES-GCM
  driverId,
  email,            -- مشفر AES-GCM
  token_code,       -- مشفر AES-GCM (3 أرقام)
  expiration_time,  -- NOW() + 5 دقائق
  is_verified       -- 0 → 1 عند النجاح
)
```

> [!NOTE]
> Rate Limiting: 3 محاولات كل 5 دقائق لكل IP عبر Redis

---

### 3️⃣ معلومات السائق — `RegistrationController` Page 0

**الحقول المطلوبة:**
- `first_name`, `last_name`, `national_number`, `birthdate`, `expiry_date`
- التحقق عبر `driverInfoFormKey.validate()`

**ملاحظة تاريخ الميلاد:**
```php
// من register_driver_and_car.php
$data['birthdate'] = trim($data['birthdate']) . '-01-01';
// "1990" → "1990-01-01"
```

---

### 4️⃣ معلومات المركبة — `RegistrationController` Page 1

**الحقول الجديدة (vehicle_category_id + fuel_type_id):**

| ID | نوع المركبة | ID | نوع الوقود |
|---|------------|---|-----------|
| 1 | سيارة (Car) | 1 | بنزين (Petrol) |
| 2 | دراجة نارية | 2 | ديزل (Diesel) |
| 3 | فان / باص | 3 | كهربائي |
| — | — | 4 | هايبرد |

```dart
// Flutter → submitRegistration()
_addField(fields, 'vehicle_category_id', selectedVehicleCategoryId.toString());
_addField(fields, 'fuel_type_id', selectedFuelTypeId.toString());
_addField(fields, 'fuel', fuelObj['name'].toString()); // للتوافق
```

---

### 5️⃣ رفع الوثائق — `uploadToSyria()` × 8

**الوثائق المطلوبة لسوريا:**

| المستند | الحقل | إلزامي سوريا؟ |
|---------|-------|--------------|
| هوية — وجه | `id_front` | ✅ |
| هوية — خلف | `id_back` | ✅ |
| رخصة القيادة — وجه | `driver_license` | ✅ |
| رخصة القيادة — خلف | `driver_license_back` | **🇸🇾 إلزامي فقط!** |
| صورة شخصية | `profile_picture` | ✅ |
| لا حكم عليه | `criminal_record` | ✅ |
| ترخيص سيارة — وجه | `car_license_front` | ✅ |
| ترخيص سيارة — خلف | `car_license_back` | ✅ |

**آلية الرفع:**

```dart
// Flutter: uploadToSyria()
final req = http.MultipartRequest('POST', syrianUploadUri);
req.headers.addAll({
  'Authorization': 'Bearer JWT',
  'X-HMAC-Auth': hmacHeader,
});
req.fields['driver_id'] = driverId;
req.fields['doc_type'] = docType; // e.g., 'driver_license_back'
// timeout: 120 ثانية — 3 محاولات تلقائية
```

**Backend — الرد (Signed URL):**

```json
{
  "status": "success",
  "file_url": "https://api-syria.siromove.com/siro/secure_image.php?driver_id=DRV...&doc_type=id_front&ext=jpg&expires=1720000000&signature=sha256...",
  "mime_type": "image/jpeg",
  "size_bytes": 98340,
  "expires_at": "2024-06-21T..."
}
```

> [!IMPORTANT]
> الملفات تُحفظ في `private_uploads/` (خارج الويب العام) ولا يمكن الوصول إليها إلا عبر رابط موقّع صالح لمدة **48 ساعة**.

---

### 6️⃣ الذكاء الاصطناعي Gemini Flash — Vision AI

**البرومبت الكامل يطلب:**

```json
{
  "status": "success|failure",
  "reason": "إذا فشل",
  "face_match_confidence": "high|low",
  "driver": {
    "full_name": "",        // الاسم الكامل بالعربي
    "national_number": "",  // أرقام لاتينية فقط
    "dob": "YYYY-MM-DD",
    "governorate": "",
    "license_expiry_date": "YYYY-MM-DD",
    "license_category": "B|D1|..."
  },
  "car": {
    "car_plate": "",        // e.g., "155186 درعا"
    "vin": "",              // أحرف وأرقام لاتينية
    "color": "",
    "color_hex": "#FFFFFF",
    "make": "", "model": "", "year": ""
  }
}
```

**قواعد الذكاء الاصطناعي الحرجة:**
1. **FACE MATCHING**: مقارنة الصورة الشخصية ↔ الهوية ↔ رخصة القيادة
2. **OCR ذكي**: المسح من كلا وجهي كل وثيقة
3. تحويل الأرقام العربية (٠١٢) إلى لاتينية (012)
4. تطبيع ألوان السيارات `أبيض → White → #FFFFFF`
5. الفشل الكلي فقط عند: وجه غير متطابق / وثائق مزورة

> [!WARNING]
> **SSRF Protection**: URLs يُسمح بها فقط من `allowedHosts` — يُمنع تحميل أي صورة من مصادر خارجية.

---

### 7️⃣ إدراج قاعدة البيانات — Transaction Atomique

**الحقول المشفرة في جدول `driver`:**

```php
$toEncryptDriver = [
    "phone", "email", "first_name", "last_name",
    "name_arabic", "gender", "national_number",
    "address", "site", "fullNameMaritial", "birthdate"
];
// كلها تُشفَّر بـ AES-GCM قبل الإدراج
```

**كلمة المرور (HMAC + bcrypt):**

```php
$baseString = implode('|', [$data['id'], $data['phone'], $data['national_number']]);
$rawSecret  = hash_hmac('sha256', $baseString, $pepper, true);
$pwdHashed  = password_hash($rawSecret, PASSWORD_DEFAULT);
```

---

### 8️⃣ جداول قاعدة البيانات (`schema_primary.sql`)

**`CarRegistration` — الجدول الرئيسي للمركبات:**

```sql
CREATE TABLE `CarRegistration` (
  `id`                 int AUTO_INCREMENT PRIMARY KEY,
  `driverID`           varchar(100) NOT NULL,          -- FK → driver.id
  `vin`                varchar(100) NOT NULL,           -- مشفر
  `car_plate`          varchar(150),                   -- مشفر
  `make`               varchar(255) NOT NULL,
  `model`              varchar(255) NOT NULL,
  `year`               int NOT NULL,
  `expiration_date`    varchar(30) NOT NULL,
  `color`              varchar(255) NOT NULL,
  `owner`              varchar(255) NOT NULL,           -- مشفر
  `color_hex`          varchar(20) NOT NULL,
  `fuel`               varchar(100) NOT NULL,
  `vehicle_category_id` tinyint DEFAULT 1,             -- 1=Car,2=Moto,3=Van
  `fuel_type_id`       tinyint DEFAULT 1,              -- 1=Petrol,2=Diesel...
  `status`             varchar(20) DEFAULT 'yet',      -- yet|active|suspended
  `isDefault`          tinyint DEFAULT 0,
  KEY `idx_driverID` (`driverID`)
)
```

**`driver` — الجدول الرئيسي للسائقين:**

```sql
CREATE TABLE `driver` (
  `id`              varchar(100) NOT NULL,            -- DRV{timestamp}{random}
  `phone`           varchar(255) NOT NULL,            -- مشفر AES-GCM
  `email`           varchar(255) NOT NULL,
  `password`        varchar(255) NOT NULL,            -- bcrypt(HMAC)
  `first_name`      varchar(255) NOT NULL,            -- مشفر
  `last_name`       varchar(255) NOT NULL,            -- مشفر
  `national_number` varchar(255),                     -- مشفر (UNIQUE)
  `name_arabic`     varchar(255),                     -- مشفر — من AI
  `birthdate`       varchar(255),                     -- مشفر
  `status`          varchar(20) DEFAULT 'notDeleted', -- yet|active|notDeleted
  `expiry_date`     date,                             -- انتهاء رخصة القيادة
  UNIQUE KEY `national_number` (`national_number`)
)
```

**`driver_documents`:**

```sql
CREATE TABLE `driver_documents` (
  `id`          int AUTO_INCREMENT PRIMARY KEY,
  `driverID`    varchar(64) NOT NULL,
  `doc_type`    varchar(64) NOT NULL,  -- id_front, driver_license_back, ...
  `image_name`  varchar(255) NOT NULL,
  `link`        varchar(512) NOT NULL, -- Signed URL
  `upload_date` datetime NOT NULL,
  KEY `driverID` (`driverID`)
)
```

---

## 🔒 طبقات الأمان

| الطبقة | التقنية | التفاصيل |
|--------|---------|---------|
| Authentication | JWT Bearer | يُعاد التوليد عند كل دخول |
| Transport | HMAC-SHA256 | X-HMAC-Auth header |
| Encryption at Rest | AES-GCM | جميع البيانات الحساسة |
| Password | HMAC + bcrypt | pepper من env |
| Rate Limiting | Redis | 3 OTP / 5 دقائق لكل IP |
| File Access | Signed URLs | HMAC-SHA256 صالح 48 ساعة |
| SSRF Protection | Allowlist hosts | منع URL injection في AI |
| SQL Injection | PDO Prepared Statements | كل الاستعلامات |
| File Upload | MIME detection + finfo | ليس Content-Type فقط |

---

## ✅ النتيجة: هل النظام يعمل صح؟

| العملية | السلوك | التقييم |
|---------|--------|---------|
| تنسيق الهاتف السوري | `09xx` → `9639xx` تلقائياً | ✅ |
| OTP سوريا | Intaleq WhatsApp → Nabeh Failover | ✅ |
| خلف رخصة القيادة | إلزامي فقط لـ `countryCode == Syria` | ✅ |
| رفع الوثائق | Retry × 3 + Timeout 120s | ✅ |
| AI Face Match | Gemini Flash Vision — تحقق ذكي | ✅ |
| AI يعيد كتابة البيانات | اسم، DOB، لوحة، VIN من الوثائق | ✅ |
| Transaction | Atomic: driver + CarRegistration + documents | ✅ |
| تشفير الحقول | phone, name, national_number → AES-GCM | ✅ |
| `vehicle_category_id` و `fuel_type_id` | يُرسلان من Flutter ويُخزنان في CarRegistration | ✅ |
| إشعار خدمة العملاء | FCM → topic:service بعد التسجيل | ✅ |
| Signed URL | صالح 48 ساعة + HMAC signed | ✅ |

> [!CAUTION]
> **ملاحظة:** حقل `vin` في `submitRegistration()` يُرسل كـ `'yet'` افتراضياً ولا يُرسل من حقل `carVinController`:
> ```dart
> _addField(fields, 'vin', 'yet'); // ← يجب ربطه بـ carVinController.text
> ```
> AI سيُصحح هذا من خلال استخراج VIN من صورة ترخيص السيارة، لكن إذا لم يعمل AI فسيُخزن 'yet'.

---

## 📁 الملفات المرجعية

| الملف | الدور |
|-------|-------|
| [registration_controller.dart](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/auth/syria/registration_controller.dart) | Controller رئيسي — رفع الوثائق + تقديم التسجيل |
| [register_captin_controller.dart](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/auth/captin/register_captin_controller.dart) | تسجيل مبدئي + OTP |
| [opt_token_controller.dart](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/auth/captin/opt_token_controller.dart) | إدارة OTP (120 ثانية countdown) |
| [register_driver_and_car.php](file:///Users/hamzaaleghwairyeen/development/App/Siro/backend/auth/syria/driver/register_driver_and_car.php) | Backend — Gemini AI + DB Transaction |
| [uploadSyrianDocs.php](file:///Users/hamzaaleghwairyeen/development/App/Siro/backend/auth/syria/uploadSyrianDocs.php) | Backend — رفع الوثائق + Signed URL |
| [request.php](file:///Users/hamzaaleghwairyeen/development/App/Siro/backend/auth/otp/request.php) | Backend — إرسال OTP حسب الدولة |
| [verify.php](file:///Users/hamzaaleghwairyeen/development/App/Siro/backend/auth/otp/verify.php) | Backend — التحقق من OTP |
| [schema_primary.sql](file:///Users/hamzaaleghwairyeen/development/App/Siro/backend/schema_primary.sql) | DB Schema — driver + CarRegistration + driver_documents |

