Update: 2026-06-19 01:47:48
This commit is contained in:
352
knowledge/syria_driver_registration_report.md
Normal file
352
knowledge/syria_driver_registration_report.md
Normal file
@@ -0,0 +1,352 @@
|
||||
|
||||
# تقرير نظام تسجيل السائق — سوريا 🇸🇾
|
||||
|
||||
> **ملف المحاكاة التفاعلية:** [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 |
|
||||
|
||||
Reference in New Issue
Block a user