مرجع واجهة API للواجهة الأمامية
مرجع شامل لمطوري الواجهات الأمامية — المصادقة، النقاط النهائية، النماذج، التعدادات، وأنماط التكامل.
نظام الشحن — مرجع واجهة برمجة التطبيقات للواجهة الأمامية
مرجع مفصّل لمطوّري الواجهة الأمامية الذين يتكاملون مع واجهة برمجة تطبيقات المسؤول (Admin API).
النطاق: تغطّي واجهة برمجة تطبيقات المسؤول (
/api/admin/*) المصادقة، وإدارة المسؤولين/الأدوار/الصلاحيات، والسائقين، والمركبات، وفترات عدم التوفر، وتعيينات السائق–المركبة، والمستخدمين، والشحنات، ونقاط توقف الشحنات، وإثباتات التوصيل، وعمليات التوصيل الفاشلة، والمسارات ونقاط توقف المسار.
جدول المحتويات
- البدء السريع
- الاتفاقيات العامة
- المصادقة
- الملف الشخصي
- المسؤولون
- الأدوار والصلاحيات
- السائقون
- المركبات
- فترات عدم توفر السائقين
- تعيينات السائق–المركبة
- المستخدمون (العملاء)
- الشحنات
- نقاط توقف الشحنات
- إثباتات التوصيل
- عمليات التوصيل الفاشلة
- المسارات
- نقاط توقف المسار
- مرجع نماذج النطاق
- مرجع التعدادات (Enums)
- مرجع الصلاحيات
- معالجة الأخطاء
- قائمة التحقق لتكامل الواجهة الأمامية
البدء السريع
POST /api/admin/login
Content-Type: application/json
Accept-Language: en
{
"email": "mousa@example.com",
"password": "password"
}
احفظ رمز JWT المُعاد وأرسله مع كل طلب لاحق:
GET /api/admin/drivers
Authorization: Bearer {token}
Accept: application/json
Accept-Language: en
عنوان URL الأساسي: {APP_URL}/api — مثلًا http://localhost:8000/api عند تشغيل php artisan serve.
الاتفاقيات العامة
رؤوس الطلب (Request Headers)
| الرأس | مطلوب | الوصف |
|---|---|---|
Authorization |
نعم (ما عدا تسجيل الدخول) | Bearer {jwt_token} |
Accept |
موصى به | application/json |
Accept-Language |
اختياري | ar (افتراضي) أو en — يتحكم في نص message المترجم |
Content-Type |
يختلف | application/json لأجسام JSON؛ multipart/form-data عند رفع الصور |
غلاف الاستجابة (Response Envelope)
كل استجابة من واجهة برمجة التطبيقات تستخدم هذا الهيكل:
{
"status": "Success",
"message": "Data fetched successfully",
"data": {},
"statusCode": 200
}
| الحقل | النوع | الوصف |
|---|---|---|
status |
"Success" | "Error" |
مؤشر النتيجة |
message |
string | رسالة قابلة للقراءة ومترجمة |
data |
object | array | null | الحمولة (null عند الحذف/تسجيل الخروج) |
statusCode |
integer | رمز حالة HTTP مُعاد في الجسم |
عند نجاح تسجيل الدخول، يُعاد رمز JWT أيضًا في رأس الاستجابة Authorization كـ Bearer {token}.
طرق HTTP
التحديثات تستخدم POST، وليس PUT أو PATCH.
جميع نقاط نهاية التحديث تتبع النمط POST /api/admin/{resource}/{id}.
أنواع المحتوى (Content Types)
| السيناريو | Content-Type |
|---|---|
| CRUD بـ JSON (بدون ملف) | application/json |
| إنشاء/تحديث مع صورة (مسؤول، سائق، ملف شخصي) | multipart/form-data |
| تعيين/إلغاء تعيين مركبة | لا يتطلب جسمًا |
عند استخدام multipart/form-data:
- أرسل الحقول العددية كحقول نموذج.
- أرسل
working_daysكحقول متكررة أو كسلسلة JSON (مصفوفة). - أرسل
roles/permissionsكحقول متكررة أو كسلسلة JSON للمصفوفة. - أرسل
imageكحقل ملف (حد أقصى 5 ميجابايت، يجب أن يكون صورة).
القوائم والتصفية والترتيب
معظم نقاط نهاية القوائم GET تقبل معاملات سلسلة الاستعلام (query string):
| المعامل | النوع | الوصف |
|---|---|---|
search |
string | بحث نصي كامل عبر أعمدة خاصة بالنموذج |
sort_by |
string | اسم العمود (يجب أن يكون في قائمة الأعمدة القابلة للترتيب للنموذج) |
sort_direction |
"asc" | "desc" |
اتجاه الترتيب (الافتراضي يختلف حسب النموذج) |
page |
integer | رقم الصفحة (نقاط النهاية المُقسّمة إلى صفحات فقط) |
تُحوّل قيم سلسلة الاستعلام "null" و "" تلقائيًا إلى null بواسطة الوسيط (middleware).
التقسيم إلى صفحات (Pagination)
نقاط النهاية المُقسّمة (GET .../paginated) تُغلّف النتائج كالتالي:
{
"drivers": [],
"total": 50,
"count": 10,
"per_page": 10,
"current_page": 1,
"total_pages": 5,
"links": {
"first": "http://localhost:8000/api/admin/drivers/paginated?page=1",
"last": "http://localhost:8000/api/admin/drivers/paginated?page=5",
"prev": null,
"next": "http://localhost:8000/api/admin/drivers/paginated?page=2"
}
}
مفتاح المجموعة يطابق اسم المورد:
| بادئة نقطة النهاية | مفتاح المجموعة |
|---|---|
/admins/paginated |
admins |
/roles/paginated |
roles |
/drivers/paginated |
drivers |
/vehicles/paginated |
vehicles |
/users/paginated |
users |
/driver-unavailabilities/paginated |
driver_unavailabilities |
/shipments/paginated |
shipments |
/shipment-stops/paginated |
shipment_stops |
/routes/paginated |
routes |
حجم الصفحة ثابت عند 10 عناصر لكل صفحة.
المصادقة
جميع المسارات تحت /api/admin/* ما عدا POST /login تتطلب JWT صالحًا في رأس Authorization.
- الحارس (Guard):
admin - المكتبة: JWT Auth (
tymon/jwt-auth) - مدة صلاحية الرمز (Token TTL): تُعاد كـ
expires_in(بالثواني) في استجابة تسجيل الدخول. تُضبط عبر متغير البيئةJWT_TTL(بالدقائق)؛ إذا لم يُضبط، قد لا ينتهي الرمز.
POST /api/admin/login
مصادقة مسؤول واستلام JWT.
المصادقة مطلوبة: لا
جسم الطلب:
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
email |
string | نعم | بريد إلكتروني صالح |
password |
string | نعم | سلسلة غير فارغة |
fcm_token |
string | لا | رمز جهاز الإشعارات الفورية؛ يُخزّن في سجل المسؤول |
مثال على جسم الطلب:
{
"email": "mousa@example.com",
"password": "SecurePass123!",
"fcm_token": "device-fcm-token-abc123"
}
استجابة النجاح 200:
{
"status": "Success",
"message": "User successfully signed in",
"data": {
"admin": {
"id": 1,
"name": "mousa",
"email": "mousa@example.com",
"roles": ["operations_manager"],
"permission_groups": [
{
"group": "Driver",
"group_label": "Drivers",
"permissions": [
{
"id": 1,
"name": "ViewAny:Driver",
"display_name": "View Any",
"group": "Driver"
}
]
}
]
},
"token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"token_type": "bearer",
"expires_in": 3600
},
"statusCode": 200
}
استجابات الخطأ:
| الحالة | متى |
|---|---|
401 |
بريد إلكتروني/كلمة مرور غير صحيحة (credentialsError) |
422 |
فشل التحقق (بريد إلكتروني/كلمة مرور مفقودة) |
500 |
فشل إنشاء الرمز (couldNotCreateToken) |
POST /api/admin/logout
إبطال جلسة JWT الحالية.
المصادقة مطلوبة: نعم
جسم الطلب: لا يوجد
استجابة النجاح 200:
{
"status": "Success",
"message": "User successfully signed out",
"data": null,
"statusCode": 200
}
استجابات الخطأ:
| الحالة | متى |
|---|---|
403 |
لم يُقدّم رمز (Unauthenticated) |
500 |
فشل تسجيل الخروج (couldNotLogout) |
الملف الشخصي
إدارة الملف الشخصي للمسؤول المصادق حاليًا. لا تتطلب صلاحيات إدارة المسؤولين.
GET /api/admin/profile
الصلاحية المطلوبة: لا شيء (المصادقة فقط)
استجابة النجاح 200: تُعيد AdminResource (انظر المسؤولون) مع:
is_current_admin: truepermission_groupsمُضمّنةrolesمُضمّنة
POST /api/admin/profile
تحديث ملف المسؤول المصادق.
الصلاحية المطلوبة: لا شيء (المصادقة فقط)
جسم الطلب (JSON أو multipart):
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
name |
string | لا | حد أقصى 255 حرفًا |
email |
string | لا | بريد إلكتروني صالح، فريد بين المسؤولين |
password |
string | لا | قواعد كلمة مرور Laravel الافتراضية |
image |
file | لا | صورة، حد أقصى 5 ميجابايت |
مثال على جسم الطلب:
{
"name": "mousa",
"email": "mousa.updated@example.com",
"password": "NewSecurePass123!"
}
استجابة النجاح 200: AdminResource محدّث مع رسالة profileUpdatedSuccessfully.
إحصائيات لوحة التحكم
إحصائيات KPI مجمّعة للوحة تحكم العمليات. تتطلب كلا النقطتين صلاحية View:Dashboard (أو مسؤول عام).
GET /api/admin/dashboard/overview
بطاقات KPI العليا لليوم والأسبوع والشهر. لا توجد معاملات استعلام.
الصلاحية المطلوبة: View:Dashboard
استجابة النجاح 200:
{
"data": {
"shipments_created_today": 12,
"shipments_created_this_week": 48,
"shipments_created_this_month": 190,
"active_routes": 5,
"active_drivers": 18,
"pending_pickups": 9,
"out_for_delivery": 14,
"delivered_today": 22
}
}
GET /api/admin/dashboard/trends
سلسلة زمنية يومية للرسوم البيانية، تمتد 7 أو 30 يومًا.
الصلاحية المطلوبة: View:Dashboard
معاملات الاستعلام:
| المعامل | النوع | مطلوب | الوصف |
|---|---|---|---|
days |
عدد صحيح 7 أو 30 |
لا | عدد الأيام (الافتراضي: 30) |
استجابة النجاح 200:
{
"data": {
"days": 30,
"from": "2026-06-20",
"to": "2026-07-19",
"series": [
{
"date": "2026-06-20",
"shipments_created": 8,
"shipments_delivered": 6,
"failed_deliveries": 1,
"failure_rate": 0.1429
}
]
}
}
خطأ التحقق 422: يُعاد عند إرسال قيمة days غير 7 أو 30.
المسؤولون
إدارة مستخدمي المكتب الخلفي.
بادئة الصلاحية: Admin (مثل ViewAny:Admin, Create:Admin)
حسابات المسؤولين المخفية (المُضبطة عبر متغير البيئة HIDDEN_ADMIN) مستبعدة من القوائم.
نقاط النهاية
| الطريقة | المسار | الوصف | الصلاحية |
|---|---|---|---|
GET |
/api/admin/admins |
قائمة جميع المسؤولين | ViewAny:Admin |
GET |
/api/admin/admins/paginated |
قائمة مُقسّمة إلى صفحات | ViewAny:Admin |
GET |
/api/admin/admins/{id} |
جلب مسؤول واحد | View:Admin |
POST |
/api/admin/admins |
إنشاء مسؤول | Create:Admin |
POST |
/api/admin/admins/{id} |
تحديث مسؤول | Update:Admin |
DELETE |
/api/admin/admins/{id} |
حذف مسؤول | Delete:Admin |
معاملات استعلام القائمة
| المعامل | الوصف |
|---|---|
search |
يبحث في name, email |
role |
تصفية حسب اسم الدور (تطابق تام) |
sort_by |
name, email, created_at |
sort_direction |
asc أو desc (افتراضي: asc حسب name) |
جسم طلب الإنشاء
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
name |
string | نعم | حد أقصى 255 |
email |
string | نعم | بريد إلكتروني صالح، فريد |
password |
string | نعم | قواعد كلمة مرور Laravel الافتراضية |
image |
file | لا | صورة، حد أقصى 5 ميجابايت |
roles |
string[] | لا | مصفوفة من أسماء الأدوار الموجودة |
مثال على جسم الطلب:
{
"name": "mousa",
"email": "mousa@example.com",
"password": "SecurePass123!",
"roles": ["operations_manager"]
}
جسم طلب التحديث
نفس حقول الإنشاء، جميعها اختيارية (تُطبّق قواعد sometimes). احذف password للإبقاء على كلمة المرور الحالية. أرسل roles: [] لإزالة جميع الأدوار.
مثال على جسم الطلب:
{
"name": "mousa",
"email": "mousa.admin@example.com",
"roles": ["super_admin"]
}
شكل مورد المسؤول (Admin Resource Shape)
{
"id": 1,
"name": "mousa",
"email": "mousa@example.com",
"image": "http://localhost:8000/storage/1/admin_image.jpg",
"roles": ["super_admin"],
"permission_groups": [],
"is_current_admin": false,
"created_at": "2026-01-15T10:00:00.000000Z",
"updated_at": "2026-01-15T10:00:00.000000Z"
}
| الحقل | ملاحظات |
|---|---|
image |
عنوان URL كامل لصورة الملف الشخصي، أو سلسلة فارغة إن لم توجد |
roles |
مصفوفة من سلاسل أسماء الأدوار |
permission_groups |
تُضمّن فقط في GET /profile و GET /admins/{id} |
is_current_admin |
true إذا كان هذا المسؤول هو مُقدّم الطلب |
قيود الحذف
- لا يمكن حذف حسابك الخاص →
403مع رسالةcannotDeleteCurrentAdmin
الأدوار والصلاحيات
التحكم في الوصول المبني على الأدوار باستخدام Spatie Permission (الحارس: admin).
بادئات الصلاحيات: Role, Permission
نقاط النهاية
| الطريقة | المسار | الوصف | الصلاحية |
|---|---|---|---|
GET |
/api/admin/permissions |
جميع الصلاحيات مجمّعة | ViewAny:Permission |
GET |
/api/admin/roles |
قائمة جميع الأدوار | ViewAny:Role |
GET |
/api/admin/roles/paginated |
قائمة مُقسّمة إلى صفحات | ViewAny:Role |
GET |
/api/admin/roles/{id} |
جلب دور واحد | View:Role |
POST |
/api/admin/roles |
إنشاء دور | Create:Role |
POST |
/api/admin/roles/{id} |
تحديث دور | Update:Role |
POST |
/api/admin/roles/{id}/permissions |
مزامنة الصلاحيات فقط | Update:Role |
DELETE |
/api/admin/roles/{id} |
حذف دور | Delete:Role |
معاملات استعلام القائمة (الأدوار)
| المعامل | الوصف |
|---|---|
search |
يبحث في name للدور |
sort_by |
name, created_at |
sort_direction |
asc أو desc (افتراضي: asc حسب name) |
جسم طلب إنشاء الدور
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
name |
string | نعم | فريد لكل حارس، حد أقصى 255 |
permissions |
string[] | لا | مصفوفة من سلاسل أسماء الصلاحيات |
مثال على جسم الطلب:
{
"name": "warehouse_manager",
"permissions": ["ViewAny:Driver", "Create:Driver", "ViewAny:Vehicle"]
}
جسم طلب تحديث الدور
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
name |
string | لا | فريد لكل حارس، حد أقصى 255 |
permissions |
string[] | لا | يستبدل جميع الصلاحيات عند التقديم |
مثال على جسم الطلب:
{
"name": "warehouse_manager",
"permissions": ["ViewAny:Driver", "Update:Driver"]
}
جسم طلب مزامنة الصلاحيات
POST /api/admin/roles/{id}/permissions
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
permissions |
string[] | نعم | مصفوفة من سلاسل أسماء الصلاحيات |
مثال على جسم الطلب:
{
"permissions": ["ViewAny:Driver", "Create:Driver", "ViewAny:Vehicle", "Create:Vehicle"]
}
رسالة النجاح: permissionsAssignedSuccessfully
شكل مورد الدور (Role Resource Shape)
{
"id": 2,
"name": "warehouse_manager",
"guard_name": "admin",
"permission_groups": [
{
"group": "Driver",
"group_label": "Drivers",
"permissions": [
{
"id": 1,
"name": "ViewAny:Driver",
"display_name": "View Any",
"group": "Driver"
}
]
}
],
"created_at": "2026-01-15T10:00:00.000000Z",
"updated_at": "2026-01-15T10:00:00.000000Z"
}
شكل مجموعة الصلاحيات (Permission Group Shape)
يُستخدم في تسجيل الدخول والملف الشخصي والأدوار وقائمة الصلاحيات:
{
"group": "Driver",
"group_label": "Drivers",
"permissions": [
{
"id": 1,
"name": "ViewAny:Driver",
"display_name": "View Any",
"group": "Driver"
}
]
}
القيود
- دور المسؤول الأعلى (super admin) لا يمكن تعديله أو حذفه →
403(cannotModifySuperAdmin)
السائقون
إدارة سائقي التوصيل.
بادئة الصلاحية: Driver
نقاط النهاية
| الطريقة | المسار | الوصف | الصلاحية |
|---|---|---|---|
GET |
/api/admin/drivers |
قائمة جميع السائقين | ViewAny:Driver |
GET |
/api/admin/drivers/paginated |
قائمة مُقسّمة إلى صفحات | ViewAny:Driver |
GET |
/api/admin/drivers/{id} |
جلب سائق واحد | View:Driver |
POST |
/api/admin/drivers |
إنشاء سائق | Create:Driver |
POST |
/api/admin/drivers/{id} |
تحديث سائق | Update:Driver |
DELETE |
/api/admin/drivers/{id} |
حذف سائق | Delete:Driver |
GET |
/api/admin/drivers/{id}/vehicle-assignments |
تعيينات المركبات | ViewAny:DriverVehicleAssignment |
GET |
/api/admin/drivers/{id}/unavailabilities |
فترات عدم التوفر | ViewAny:DriverUnavailability |
POST |
/api/admin/drivers/{driverId}/vehicles/{vehicleId}/assign |
تعيين مركبة | Create:DriverVehicleAssignment |
POST |
/api/admin/drivers/{driverId}/vehicles/{vehicleId}/unassign |
إلغاء تعيين مركبة | Update:DriverVehicleAssignment |
معاملات استعلام القائمة
| المعامل | النوع | الوصف |
|---|---|---|
search |
string | يبحث في name, phone, email, driver_number, license_number |
is_active |
boolean | تصفية حسب حالة النشاط |
lat |
float | خط العرض للبحث القريب (يتطلب lng) |
lng |
float | خط الطول للبحث القريب (يتطلب lat) |
radius |
float | نصف قطر البحث بالكيلومتر (افتراضي: 10) |
work_start_time |
time | تصفية السائقين الذين يتداخل ورديتهم مع وقت البداية هذا |
work_end_time |
time | تصفية السائقين الذين يتداخل ورديتهم مع وقت النهاية هذا |
work_start_time_from |
time | الحد الأدنى لوقت بداية الوردية |
work_start_time_to |
time | الحد الأقصى لوقت بداية الوردية |
work_end_time_from |
time | الحد الأدنى لوقت نهاية الوردية |
work_end_time_to |
time | الحد الأقصى لوقت نهاية الوردية |
sort_by |
string | انظر الأعمدة القابلة للترتيب أدناه |
sort_direction |
string | asc أو desc |
الأعمدة القابلة للترتيب: name, phone, driver_number, work_start_time, work_end_time, created_at, distance
عند تقديم lat/lng، تتضمن النتائج حقل distance (كم) ويُرتّب افتراضيًا حسب الأقرب أولًا ما لم يُضبط sort_by صراحةً.
صيغة الوقت: HH:MM:SS أو HH:MM (تُطبّع تلقائيًا إلى HH:MM:SS).
جسم طلب الإنشاء
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
name |
string | نعم | حد أقصى 255 |
phone |
string | نعم | حد أقصى 50 |
phone_country |
string | نعم | حد أقصى 10 (مثل +963) |
email |
string | لا | بريد إلكتروني صالح، فريد |
password |
string | نعم | قواعد كلمة مرور Laravel الافتراضية |
address |
string | نعم | |
license_number |
string | لا | حد أقصى 255 |
working_days |
string[] | نعم | عنصر واحد على الأقل؛ انظر أيام العمل |
work_start_time |
time | نعم | يجب أن يختلف عن work_end_time |
work_end_time |
time | نعم | يجب أن يختلف عن work_start_time |
lat |
float | لا | -90 إلى 90 |
lng |
float | لا | -180 إلى 180 |
fcm_token |
string | لا | رمز الإشعارات الفورية |
is_active |
boolean | لا | افتراضي: true |
image |
file | لا | صورة، حد أقصى 5 ميجابايت |
vehicle_id |
integer | لا | يجب أن يكون موجودًا في vehicles؛ يُعيَّن عند الإنشاء عند التوفير |
driver_number |
string | لا | فريد؛ يُولّد تلقائيًا رقم من 6 أرقام إذا لم يُذكر |
مثال على جسم الطلب:
{
"name": "mousa",
"phone": "944123456",
"phone_country": "+963",
"email": "mousa.driver@example.com",
"password": "SecurePass123!",
"address": "Damascus, Syria",
"license_number": "SY-12345",
"working_days": ["sun", "mon", "tue", "wed", "thu"],
"work_start_time": "08:00:00",
"work_end_time": "17:00:00",
"lat": 33.5138,
"lng": 36.2765,
"is_active": true,
"vehicle_id": 7
}
تعيين المركبة عند التحديث: أرسل vehicle_id لتعيين أو تبديل المركبة؛ أرسل vehicle_id: null لإلغاء التعيين الحالي. احذف الحقل لإبقاء التعيين دون تغيير.
جسم طلب التحديث
نفس حقول الإنشاء. جميع الحقول اختيارية ما عدا حيث تُطبّق sometimes + required. كلمة المرور اختيارية (احذفها للإبقاء على الحالية).
مثال على جسم الطلب:
{
"name": "mousa",
"phone": "944654321",
"phone_country": "+963",
"work_start_time": "09:00:00",
"work_end_time": "18:00:00",
"is_active": true
}
شكل مورد السائق (Driver Resource Shape)
{
"id": 1,
"driver_number": "482910",
"name": "mousa",
"phone": "944123456",
"phone_country": "+963",
"email": "mousa.driver@example.com",
"image": "http://localhost:8000/storage/2/driver_image.jpg",
"address": "Damascus, Syria",
"license_number": "DL-12345",
"working_days": ["sun", "mon", "tue", "wed", "thu"],
"work_start_time": "08:00:00",
"work_end_time": "17:00:00",
"lat": 24.7136,
"lng": 46.6753,
"is_active": true,
"created_at": "2026-01-15T10:00:00.000000Z",
"updated_at": "2026-01-15T10:00:00.000000Z",
"distance": 3.2,
"vehicle": {
"id": 7,
"plate_number": "ABC-1234",
"owner_type": "driver",
"owner_type_label": "سائق",
"owner_id": 1,
"max_weight": 500,
"max_volume": 10,
"is_active": true,
"created_at": "2026-01-15T10:00:00.000000Z",
"updated_at": "2026-01-15T10:00:00.000000Z"
}
}
| الحقل | ملاحظات |
|---|---|
distance |
موجود فقط عند استخدام تصفية القرب (lat/lng) |
working_days |
مصفوفة JSON من رموز الأيام |
image |
عنوان URL كامل أو سلسلة فارغة |
vehicle |
VehicleResource متداخل للمركبة المُعيَّنة حاليًا للسائق (released_at = null)؛ null عندما لا توجد مركبة مُعيَّنة |
المركبات
إدارة مركبات الأسطول.
بادئة الصلاحية: Vehicle
نقاط النهاية
| الطريقة | المسار | الوصف | الصلاحية |
|---|---|---|---|
GET |
/api/admin/vehicles |
قائمة جميع المركبات | ViewAny:Vehicle |
GET |
/api/admin/vehicles/paginated |
قائمة مُقسّمة إلى صفحات | ViewAny:Vehicle |
GET |
/api/admin/vehicles/{id} |
جلب مركبة واحدة | View:Vehicle |
POST |
/api/admin/vehicles |
إنشاء مركبة | Create:Vehicle |
POST |
/api/admin/vehicles/{id} |
تحديث مركبة | Update:Vehicle |
DELETE |
/api/admin/vehicles/{id} |
حذف مركبة | Delete:Vehicle |
معاملات استعلام القائمة
| المعامل | الوصف |
|---|---|
search |
يبحث في plate_number |
owner_type |
تطابق تام: company أو driver |
is_active |
تصفية منطقية |
sort_by |
plate_number, owner_type, max_weight, max_volume, created_at |
sort_direction |
asc أو desc (افتراضي: asc حسب plate_number) |
جسم طلب الإنشاء
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
plate_number |
string | نعم | فريد، حد أقصى 255 |
owner_type |
string | نعم | company أو driver — انظر OwnerTypes |
owner_id |
integer | مشروط | مطلوب عندما يكون owner_type هو driver؛ يجب أن يكون معرّف سائق صالحًا. يجب ألا يُرسل عندما يكون owner_type هو company |
max_weight |
number | نعم | حد أدنى 0 (كجم) |
max_volume |
number | نعم | حد أدنى 0 (م³) |
مثال على جسم الطلب:
{
"plate_number": "DMS-1234",
"owner_type": "company",
"max_weight": 1500,
"max_volume": 12.5
}
مثال على جسم الطلب (مملوكة للسائق):
{
"plate_number": "DMS-5678",
"owner_type": "driver",
"owner_id": 1,
"max_weight": 2000,
"max_volume": 15
}
جسم طلب التحديث
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
plate_number |
string | لا | فريد، حد أقصى 255 |
owner_type |
string | لا | company أو driver |
owner_id |
integer | مشروط | نفس قواعد الإنشاء |
max_weight |
number | لا | حد أدنى 0 |
max_volume |
number | لا | حد أدنى 0 |
is_active |
boolean | لا |
مثال على جسم الطلب:
{
"plate_number": "DMS-9999",
"max_weight": 1800,
"max_volume": 14,
"is_active": false
}
شكل مورد المركبة (Vehicle Resource Shape)
{
"id": 1,
"plate_number": "ABC-1234",
"owner_type": "company",
"owner_type_label": "الشركة",
"owner_id": null,
"max_weight": 1500,
"max_volume": 12.5,
"is_active": true,
"created_at": "2026-01-15T10:00:00.000000Z",
"updated_at": "2026-01-15T10:00:00.000000Z"
}
| الحقل | ملاحظات |
|---|---|
owner_type_label |
تسمية عربية مترجمة (تُعيد واجهة برمجة التطبيقات التسمية العربية دائمًا بغض النظر عن Accept-Language) |
owner_id |
null للمركبات المملوكة للشركة؛ معرّف السائق للمركبات المملوكة للسائق |
فترات عدم توفر السائقين
فترات الإجازة / عدم التوفر للسائقين.
بادئة الصلاحية: DriverUnavailability
نقاط النهاية
| الطريقة | المسار | الوصف | الصلاحية |
|---|---|---|---|
GET |
/api/admin/driver-unavailabilities |
قائمة الكل | ViewAny:DriverUnavailability |
GET |
/api/admin/driver-unavailabilities/paginated |
قائمة مُقسّمة إلى صفحات | ViewAny:DriverUnavailability |
GET |
/api/admin/driver-unavailabilities/{id} |
جلب واحدة | View:DriverUnavailability |
POST |
/api/admin/driver-unavailabilities |
إنشاء | Create:DriverUnavailability |
POST |
/api/admin/driver-unavailabilities/{id} |
تحديث | Update:DriverUnavailability |
DELETE |
/api/admin/driver-unavailabilities/{id} |
حذف | Delete:DriverUnavailability |
يمكن الوصول إليها أيضًا عبر GET /api/admin/drivers/{id}/unavailabilities.
معاملات استعلام القائمة
| المعامل | الوصف |
|---|---|
driver_id |
تصفية حسب معرّف السائق (تطابق تام) |
sort_by |
start_date, end_date, created_at |
sort_direction |
افتراضي: desc حسب start_date |
جسم طلب الإنشاء
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
driver_id |
integer | نعم | يجب أن يكون موجودًا في جدول drivers |
start_date |
date | نعم | تاريخ ISO أو تاريخ ووقت |
end_date |
date | نعم | يجب أن يكون بعد start_date |
reason |
string | لا | نص حر |
مثال على جسم الطلب:
{
"driver_id": 1,
"start_date": "2026-06-01",
"end_date": "2026-06-05",
"reason": "Annual leave"
}
جسم طلب التحديث
نفس الحقول، جميعها اختيارية. إذا قُدّمت كلا التاريخين في التحديث، يجب أن يظل end_date بعد start_date.
مثال على جسم الطلب:
{
"start_date": "2026-06-01",
"end_date": "2026-06-10",
"reason": "Extended leave"
}
شكل مورد عدم توفر السائق (Driver Unavailability Resource Shape)
{
"id": 1,
"driver_id": 5,
"start_date": "2026-06-01T00:00:00.000000Z",
"end_date": "2026-06-05T00:00:00.000000Z",
"reason": "Annual leave",
"created_at": "2026-05-20T10:00:00.000000Z",
"updated_at": "2026-05-20T10:00:00.000000Z"
}
تعيينات السائق–المركبة
يربط السائقين بالمركبات للاستخدام التشغيلي. يمكن للمركبة أن يكون لها تعيين نشط واحد فقط في كل مرة (released_at === null).
بادئة الصلاحية: DriverVehicleAssignment
نقاط النهاية
| الطريقة | المسار | الوصف | الصلاحية |
|---|---|---|---|
GET |
/api/admin/drivers/{id}/vehicle-assignments |
قائمة التعيينات للسائق | ViewAny:DriverVehicleAssignment |
POST |
/api/admin/drivers/{driverId}/vehicles/{vehicleId}/assign |
تعيين مركبة للسائق | Create:DriverVehicleAssignment |
POST |
/api/admin/drivers/{driverId}/vehicles/{vehicleId}/unassign |
إنهاء التعيين | Update:DriverVehicleAssignment |
التعيين (Assign)
لا يوجد جسم طلب. ينشئ سجلًا مع:
assigned_at= الطابع الزمني الحاليreleased_at=null
خطأ: 422 إذا كانت المركبة لديها تعيين نشط بالفعل (vehicleAlreadyAssigned)
إلغاء التعيين (Unassign)
لا يوجد جسم طلب. يضبط released_at على الطابع الزمني الحالي للتعيين النشط.
خطأ: 404 إذا لم يوجد تعيين نشط (vehicleAssignmentNotFound)
شكل مورد تعيين السائق–المركبة (Driver Vehicle Assignment Resource Shape)
{
"id": 1,
"driver_id": 3,
"vehicle_id": 7,
"assigned_at": "2026-06-01T08:00:00.000000Z",
"released_at": null,
"vehicle": {
"id": 7,
"plate_number": "XYZ-5678",
"owner_type": "company",
"owner_type_label": "الشركة",
"owner_id": null,
"max_weight": 2000,
"max_volume": 15,
"is_active": true,
"created_at": "...",
"updated_at": "..."
},
"driver": {
"id": 3,
"driver_number": "482910",
"name": "mousa"
},
"created_at": "2026-06-01T08:00:00.000000Z",
"updated_at": "2026-06-01T08:00:00.000000Z"
}
| الحقل | ملاحظات |
|---|---|
vehicle |
VehicleResource متداخل عند تحميل العلاقة |
driver |
DriverResource متداخل عند تحميل العلاقة |
released_at |
null = مُعيّنة حاليًا |
المستخدمون (العملاء)
العملاء النهائيون الذين يقدّمون الشحنات. هؤلاء ليسوا حسابات مسؤولين.
بادئة الصلاحية: User
نقاط النهاية
| الطريقة | المسار | الوصف | الصلاحية |
|---|---|---|---|
GET |
/api/admin/users |
قائمة جميع المستخدمين | ViewAny:User |
GET |
/api/admin/users/paginated |
قائمة مُقسّمة إلى صفحات | ViewAny:User |
GET |
/api/admin/users/{id} |
جلب مستخدم واحد | View:User |
POST |
/api/admin/users |
إنشاء مستخدم | Create:User |
POST |
/api/admin/users/{id} |
تحديث مستخدم | Update:User |
DELETE |
/api/admin/users/{id} |
حذف مستخدم | Delete:User |
معاملات استعلام القائمة
| المعامل | الوصف |
|---|---|
search |
يبحث في name, phone, email, company_name |
sort_by |
name, phone, email, company_name, created_at |
sort_direction |
asc أو desc (افتراضي: asc حسب name) |
جسم طلب الإنشاء
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
name |
string | نعم | حد أقصى 255 |
phone |
string | نعم | حد أقصى 50؛ فريد لكل phone_country |
phone_country |
string | نعم | حد أقصى 10 |
email |
string | لا | بريد إلكتروني صالح، فريد |
company_name |
string | لا |
مثال على جسم الطلب:
{
"name": "mousa",
"phone": "944123456",
"phone_country": "+963",
"email": "mousa@example.com",
"company_name": "Mousa Trading Co."
}
جسم طلب التحديث
نفس الحقول، جميعها اختيارية. تُعاد التحقق من تفرد رقم الهاتف عند تغيير phone أو phone_country.
مثال على جسم الطلب:
{
"name": "mousa",
"phone": "944654321",
"phone_country": "+963",
"company_name": "Mousa Logistics"
}
شكل مورد المستخدم (User Resource Shape)
{
"id": 1,
"name": "mousa",
"phone": "944123456",
"phone_country": "+963",
"email": "mousa@example.com",
"company_name": "Mousa Trading Co.",
"created_at": "2026-01-15T10:00:00.000000Z",
"updated_at": "2026-01-15T10:00:00.000000Z"
}
الشحنات
إدارة دورة حياة الشحنات بالكامل — الإنشاء والتعديل والتأكيد والإلغاء والتعيين للمسارات والعمليات الجماعية.
بادئة الصلاحية: Shipment
نقاط النهاية (Endpoints)
| الطريقة | المسار | الوصف | الصلاحية |
|---|---|---|---|
GET |
/api/admin/shipments |
قائمة جميع الشحنات | ViewAny:Shipment |
GET |
/api/admin/shipments/paginated |
قائمة مع ترقيم الصفحات | ViewAny:Shipment |
GET |
/api/admin/shipments/{id} |
جلب شحنة واحدة (بالمعرّف أو رقم الشحنة) | View:Shipment |
POST |
/api/admin/shipments |
إنشاء شحنة | Create:Shipment |
POST |
/api/admin/shipments/create-with-user |
إنشاء/تحديث عميل ثم إنشاء شحنة | Create:Shipment |
POST |
/api/admin/shipments/{id} |
تعديل شحنة | Update:Shipment |
DELETE |
/api/admin/shipments/{id} |
حذف شحنة مسودة | Delete:Shipment |
POST |
/api/admin/shipments/{id}/confirm |
تأكيد مسودة → قيد الانتظار | Update:Shipment |
POST |
/api/admin/shipments/{id}/cancel |
إلغاء الشحنة | Update:Shipment |
POST |
/api/admin/shipments/{id}/status |
تغيير حالة يدوي (مسؤول) | Update:Shipment |
POST |
/api/admin/shipments/{id}/assign-route |
تعيين لمسار | Update:Shipment |
POST |
/api/admin/shipments/{id}/unassign-route |
إلغاء التعيين من المسار | Update:Shipment |
GET |
/api/admin/shipments/{id}/events |
قائمة أحداث الشحنة | View:Shipment |
POST |
/api/admin/shipments/bulk/cancel |
إلغاء جماعي | Create:Shipment |
POST |
/api/admin/shipments/bulk/confirm |
تأكيد جماعي | Create:Shipment |
POST |
/api/admin/shipments/bulk/assign-route |
تعيين جماعي لمسار | Create:Shipment |
معاملات البحث والتصفية
| المعامل | النوع | الوصف |
|---|---|---|
search |
string | البحث في shipment_number وuser_name وnotes |
status |
string | تطابق تام — انظر ShipmentStatuses |
type |
string | تطابق تام — انظر ShipmentTypes |
user_id |
integer | تصفية حسب العميل |
payment_type |
string | تطابق تام — انظر PaymentTypes |
priority |
string | تطابق تام — انظر ShipmentPriorities |
delivery_date_from |
date | بداية نطاق تاريخ التسليم |
delivery_date_to |
date | نهاية نطاق تاريخ التسليم |
sort_by |
string | shipment_number، delivery_date، status، created_at |
sort_direction |
string | asc أو desc (افتراضي: desc حسب created_at) |
جلب شحنة واحدة
GET /api/admin/shipments/{id}
{id} يقبل المعرّف الرقمي أو shipment_number (مثل SH-AB12CD34).
نموذج طلب الإنشاء
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
user_id |
integer | نعم | يجب أن يكون موجودًا في users |
delivery_date |
date | نعم | يجب أن يكون بعد اليوم |
payment_type |
string | نعم | prepaid أو cod |
cod_amount |
number | شرطي | مطلوب عند payment_type = cod |
notes |
string | لا | |
priority |
string | لا | low أو normal أو high أو urgent — انظر ShipmentPriorities؛ الافتراضي normal |
stops |
array | نعم | 2 عناصر على الأقل؛ يجب أن يحتوي على pickup واحد بالضبط وdelivery واحد بالضبط |
stops.*.type |
string | نعم | pickup أو delivery أو stop |
stops.*.country |
string | نعم | |
stops.*.city |
string | نعم | |
stops.*.lat |
number | نعم | -90 إلى 90 |
stops.*.lng |
number | نعم | -180 إلى 180 |
stops.*.sequence |
integer | نعم | الحد الأدنى 1 |
items |
array | نعم | عنصر واحد على الأقل |
items.*.name |
string | نعم | |
items.*.quantity |
integer | نعم | الحد الأدنى 1 |
items.*.weight |
number | لا | كغ |
إنشاء مع مستخدم (Upsert)
POST /api/admin/shipments/create-with-user
نفس حقول إنشاء الشحنة، مع استبدال user_id بكائن user. يطابق العميل عبر phone + phone_country ويحدّث الاسم/البريد/الشركة إن وُجد، أو ينشئ مستخدمًا جديدًا ثم ينشئ شحنة مسودة.
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
user |
object | نعم | بيانات العميل |
user.name |
string | نعم | بحد أقصى 255 |
user.phone |
string | نعم | رقم صالح لـ user.phone_country |
user.phone_country |
string | نعم | بحد أقصى 10 (مثل SA) |
user.email |
string | لا | فريد (يُتجاهل للمستخدم المطابق عند التحديث) |
user.company_name |
string | لا | |
| (حقول الشحنة) | نفس نموذج الإنشاء باستثناء user_id |
مثال:
{
"user": {
"name": "أحمد الفارسي",
"phone": "0501234567",
"phone_country": "SA",
"email": "ahmed@example.com",
"company_name": "Acme"
},
"delivery_date": "2026-07-15",
"payment_type": "cod",
"cod_amount": 150,
"total_weight": 2.5,
"total_volume": 0.0005,
"stops": [
{ "type": "pickup", "country": "SA", "city": "Riyadh", "lat": 24.7136, "lng": 46.6753 },
{ "type": "delivery", "country": "SA", "city": "Jeddah", "lat": 21.4858, "lng": 39.1925 }
],
"items": [{ "name": "صندوق إلكترونيات", "quantity": 1, "weight": 2.5 }]
}
شكل مورد الشحنة (Shipment Resource)
{
"id": 1,
"shipment_number": "AB3XZ7QR",
"user_id": 5,
"user_name": "أحمد الفارسي",
"user": { "id": 5, "name": "أحمد الفارسي" },
"delivery_date": "2026-07-15T00:00:00.000000Z",
"status": "pending",
"status_label": "في الانتظار",
"type": "domestic",
"type_label": "محلي",
"payment_type": "cod",
"payment_type_label": "عند الاستلام",
"cod_amount": 150,
"total_weight": 2.5,
"total_volume": 0.0005,
"priority": "normal",
"priority_label": "عادية",
"priority_color": "primary",
"notes": "التعامل بحذر",
"stops": [...],
"items": [...],
"events": [...],
"created_at": "2026-06-21T10:00:00.000000Z",
"updated_at": "2026-06-21T10:00:00.000000Z"
}
stops وitems وevents موجودة فقط عند جلب الشحنة عبر GET /shipments/{id}.
نقاط توقف الشحنات
قائمة نقاط توقف الشحنات مع فلاتر متعددة — مفيدة لتخطيط المسارات والعمليات اليومية. تتضمن كل نقطة ملخص الشحنة الأم.
بادئة الصلاحية: ShipmentStop
نقاط النهاية
| الطريقة | المسار | الوصف | الصلاحية |
|---|---|---|---|
GET |
/api/admin/shipment-stops |
قائمة جميع نقاط التوقف | ViewAny:ShipmentStop |
GET |
/api/admin/shipment-stops/paginated |
قائمة مع ترقيم | ViewAny:ShipmentStop |
GET |
/api/admin/shipment-stops/{id} |
جلب نقطة توقف واحدة | View:ShipmentStop |
معاملات الاستعلام للقائمة
| المعامل | النوع | الوصف |
|---|---|---|
search |
string | يبحث في contact_name, phone, city, area, street, full_address |
type |
string | نوع النقطة — pickup, delivery, أو stop |
shipment_id |
integer | تصفية حسب الشحنة |
shipment_number |
string | تطابق جزئي على shipment_number للشحنة الأم |
shipment_status |
string | تطابق تام على status للشحنة الأم — انظر ShipmentStatuses |
shipment_type |
string | تطابق تام على type للشحنة الأم — انظر ShipmentTypes |
user_id |
integer | تصفية حسب العميل في الشحنة الأم |
payment_type |
string | تطابق تام على payment_type للشحنة الأم |
priority |
string | تطابق تام على priority للشحنة الأم |
delivery_date |
date | تاريخ التسليم للشحنة الأم (يوم محدد) |
delivery_date_from |
date | بداية نطاق تاريخ التسليم |
delivery_date_to |
date | نهاية نطاق تاريخ التسليم |
country |
string | تطابق تام على country للنقطة |
city |
string | تطابق تام على city للنقطة |
unassigned |
boolean | true = غير مُعيَّنة لمسار assigned أو active |
on_route |
boolean | true = مُعيَّنة بالفعل لمسار assigned أو active |
sort_by |
string | sequence, type, city, created_at, delivery_date |
sort_direction |
string | asc أو desc (افتراضي: desc حسب created_at) |
شكل مورد نقطة التوقف
{
"id": 12,
"shipment_id": 4,
"type": "pickup",
"type_label": "تحصيل",
"contact_name": "Warehouse",
"phone": "0501234567",
"phone_country": "SA",
"country": "SA",
"city": "Riyadh",
"area": "Al Olaya",
"street": "King Fahd Rd",
"building": null,
"floor": null,
"apartment": null,
"lat": 24.7136,
"lng": 46.6753,
"full_address": "King Fahd Rd, Al Olaya, Riyadh, SA",
"sequence": 1,
"created_at": "2026-06-21T10:00:00.000000Z",
"updated_at": "2026-06-21T10:00:00.000000Z",
"shipment": {
"id": 4,
"shipment_number": "SH-AB12CD34",
"delivery_date": "2026-07-15T00:00:00.000000Z",
"status": "pending",
"type": "domestic",
"priority": "normal",
"user_id": 5,
"user_name": "Ahmed Al-Farsi",
"payment_type": "prepaid"
}
}
إثباتات التوصيل
سجلات تأكيد التوصيل للشحنات.
بادئة الصلاحية: ProofOfDelivery
نقاط النهاية
| الطريقة | المسار | الوصف | الصلاحية |
|---|---|---|---|
GET |
/api/admin/shipments/{shipmentId}/proof-of-deliveries |
قائمة إثباتات التوصيل للشحنة | ViewAny:ProofOfDelivery |
POST |
/api/admin/shipments/{shipmentId}/proof-of-deliveries |
إنشاء إثبات توصيل | Create:ProofOfDelivery |
GET |
/api/admin/proof-of-deliveries/{id} |
جلب إثبات توصيل واحد | View:ProofOfDelivery |
نموذج الطلب
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
receiver_name |
string | لا | |
receiver_phone |
string | لا | |
receiver_phone_country |
string | لا | |
delivered_at |
datetime | نعم | تاريخ صالح |
notes |
string | لا |
التأثيرات الجانبية: يُعيّن حالة الشحنة إلى delivered ويُسجّل حدث pod_uploaded.
شكل مورد إثبات التوصيل
{
"id": 1,
"shipment_id": 1,
"receiver_name": "عمر أحمد",
"receiver_phone": "0559876543",
"receiver_phone_country": null,
"delivered_at": "2026-07-15T14:30:00.000000Z",
"notes": null,
"created_by_type": "App\\Models\\Admin",
"created_by_id": 1,
"created_by_name": "Admin",
"shipment": null,
"created_at": "2026-07-15T14:31:00.000000Z",
"updated_at": "2026-07-15T14:31:00.000000Z"
}
عمليات التوصيل الفاشلة
سجلات محاولات التوصيل الفاشلة. تُنشأ تلقائيًا عند فشل RouteStop من نوع delivery، أو يدويًا عبر هذه الواجهة.
بادئة الصلاحية: FailedDelivery
نقاط النهاية
| الطريقة | المسار | الوصف | الصلاحية |
|---|---|---|---|
GET |
/api/admin/shipments/{shipmentId}/failed-deliveries |
قائمة التوصيلات الفاشلة للشحنة | ViewAny:FailedDelivery |
POST |
/api/admin/shipments/{shipmentId}/failed-deliveries |
إنشاء يدوي | Create:FailedDelivery |
GET |
/api/admin/failed-deliveries/{id} |
جلب سجل واحد | View:FailedDelivery |
نموذج الطلب
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
reason_code |
string | نعم | انظر FailedDeliveryReasons |
notes |
string | لا |
التأثيرات الجانبية: يُعيّن حالة الشحنة إلى delivery_failed ويُسجّل حدث delivery_failed.
شكل مورد التوصيل الفاشل
{
"id": 1,
"shipment_id": 1,
"reason_code": "customer_refused",
"reason_code_label": "العميل رفض الاستلام",
"notes": null,
"created_by_type": "App\\Models\\Admin",
"created_by_id": 1,
"created_by_name": "Admin",
"shipment": null,
"created_at": "2026-07-15T14:35:00.000000Z",
"updated_at": "2026-07-15T14:35:00.000000Z"
}
المسارات
مسارات السائق اليومية مع نقاط توقف مرتبة ومقاييس المسافة وإجراءات دورة الحياة (بدء، إكمال، إلغاء). يمكن إنشاء المسارات يدويًا أو توليدها عبر مهمة التخطيط.
بادئة الصلاحية: Route
نقاط النهاية
| الطريقة | المسار | الوصف | الصلاحية |
|---|---|---|---|
GET |
/api/admin/routes |
قائمة جميع المسارات | ViewAny:Route |
GET |
/api/admin/routes/paginated |
قائمة مع ترقيم | ViewAny:Route |
GET |
/api/admin/routes/{id} |
مسار واحد مع نقاط التوقف والسائق والمركبة | View:Route |
POST |
/api/admin/routes |
إنشاء مسار مع نقاط توقف | Create:Route |
POST |
/api/admin/routes/{id} |
تحديث مسار | Update:Route |
DELETE |
/api/admin/routes/{id} |
حذف مسار مسودة أو مُعيَّن | Delete:Route |
POST |
/api/admin/routes/{id}/start |
بدء المسار (assigned → active) |
Update:Route |
POST |
/api/admin/routes/{id}/complete |
إكمال المسار (active → completed) |
Update:Route |
POST |
/api/admin/routes/{id}/cancel |
إلغاء المسار | Update:Route |
GET |
/api/admin/routes/{id}/stops |
قائمة نقاط التوقف مرتبة | View:Route |
GET |
/api/admin/routes/{id}/assignments |
قائمة سجل تعيينات السائق للمسار | ViewAny:RouteAssignment |
POST |
/api/admin/routes/plan |
إرسال مهمة تخطيط المسارات | Create:Route |
GET |
/api/admin/routes/plan/result |
جلب ملخص التخطيط المخزّن | ViewAny:Route |
معاملات الاستعلام للقائمة
| المعامل | النوع | الوصف |
|---|---|---|
status |
string | تطابق تام — انظر RouteStatuses |
driver_id |
integer | تصفية حسب السائق |
vehicle_id |
integer | تصفية حسب المركبة |
route_date |
date | تصفية حسب تاريخ المسار |
sort_by |
string | route_number, route_date, status, created_at |
sort_direction |
string | asc أو desc (افتراضي: desc حسب route_date) |
نموذج طلب الإنشاء
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
driver_id |
integer | نعم | يجب أن يكون موجودًا في drivers؛ يجب أن يكون للسائق تعيين مركبة نشط |
route_date |
date | نعم | |
stops |
array | نعم | عنصر واحد على الأقل؛ قائمة مرتبة من معرفات shipment_stop — يُعيَّن الترتيب تلقائيًا |
stops.* |
integer | نعم | يجب أن يكون موجودًا في shipment_stops؛ فريد؛ غير مُعيَّن لمسار نشط؛ لنفس الشحنة يجب أن يأتي الاستلام قبل التسليم |
غير مقبول عند الإنشاء: vehicle_id, status, total_stops, optimized_distance, duration — يتم حلها أو حسابها من الخادم.
سلوك الخادم:
- يحل
vehicle_idمن أحدثDriverVehicleAssignmentنشط للسائق - يُعيّن
statusإلىassigned(السائق مُعيَّن ولم يبدأ بعد) - يحسب
total_stops,optimized_distance(كم), وduration(دقيقة) من إحداثيات نقاط التوقف - ينشئ سجلات
RouteStopمع أوقات الوصول/المغادرة المتوقعة - يُعيّن الشحنات المرتبطة (
pendingأوdelivery_failed) إلىassigned
أخطاء:
422 vehicleAssignmentNotFound— لا يوجد تعيين مركبة نشط للسائق422 shipmentStopAlreadyOnRoute— إحدى النقاط مُعيَّنة بالفعل لمسار نشط/مُعيَّن422 deliveryStopBeforePickupStop— نقطة التسليم تظهر قبل نقطة الاستلام لنفس الشحنة
مثال على نموذج الطلب:
{
"driver_id": 1,
"route_date": "2026-06-25",
"stops": [10, 11, 15]
}
نموذج طلب التحديث
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
driver_id |
integer | لا | يُعيد حل vehicle_id من تعيين السائق الجديد |
route_date |
date | لا | يُعيد حساب مقاييس نقاط التوقف عند التغيير |
status |
string | لا | انظر RouteStatuses |
stops |
array | لا | يستبدل جميع نقاط التوقف ويُعيد حساب المقاييس |
غير مقبول عند التحديث: vehicle_id, total_stops, optimized_distance, duration.
مسموح فقط عندما لا يكون المسار في حالة نهائية (completed, cancelled).
طلب تخطيط المسارات
POST /api/admin/routes/plan
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
date |
date | نعم | تاريخ التخطيط |
driver_ids |
array | لا | تصفية اختيارية؛ كل عنصر يجب أن يكون موجودًا في drivers |
يُرسل مهمة غير متزامنة. استعلم عبر GET /api/admin/routes/plan/result?date=YYYY-MM-DD للحصول على الملخص.
شكل مورد المسار (Route Resource)
{
"id": 1,
"route_number": "AB12CD34",
"route_date": "2026-06-25T00:00:00.000000Z",
"status": "assigned",
"status_label": "تم تخصيص السائق",
"total_stops": 3,
"optimized_distance": 42.5,
"duration": 95.0,
"driver": { "...": "DriverResource عند التحميل" },
"vehicle": { "...": "VehicleResource عند التحميل" },
"stops": [ { "...": "RouteStopResource عند التحميل" } ],
"created_at": "2026-06-24T20:00:00.000000Z",
"updated_at": "2026-06-24T20:00:00.000000Z"
}
driver وvehicle وstops تظهر فقط عند تحميل العلاقات عبر GET /routes/{id} أو قوائم تحمّل العلاقات.
تعيينات المسار
يتتبّع سجل تعيين السائق للمسار. يمكن تعيين سائق ثم إلغاء تعيينه عند إعادة تعيين المسار.
بادئة الصلاحية: RouteAssignment
| الطريقة | المسار | الوصف | الصلاحية |
|---|---|---|---|
GET |
/api/admin/routes/{id}/assignments |
قائمة التعيينات للمسار | ViewAny:RouteAssignment |
شكل مورد تعيين المسار
{
"id": 1,
"assigned_at": "2026-06-01T08:00:00.000000Z",
"unassigned_at": null,
"driver": {
"id": 3,
"driver_number": "482910",
"name": "mousa"
},
"created_at": "2026-06-01T08:00:00.000000Z",
"updated_at": "2026-06-01T08:00:00.000000Z"
}
| الحقل | ملاحظات |
|---|---|
driver |
DriverResource متداخل عند تحميل العلاقة |
unassigned_at |
null = مُعيَّن حاليًا لهذا المسار |
نقاط توقف المسار
نقاط توقف مرتبة على مسار السائق، مرتبطة بنقاط توقف الشحنة.
بادئة الصلاحية: Route
نقاط النهاية
| الطريقة | المسار | الوصف | الصلاحية |
|---|---|---|---|
GET |
/api/admin/route-stops/{id} |
جلب نقطة توقف واحدة | ViewAny:Route |
POST |
/api/admin/route-stops/{id} |
تحديث حالة/أوقات نقطة التوقف | Update:Route |
DELETE |
/api/admin/route-stops/{id} |
حذف نقطة توقف | Delete:Route |
تُنشأ نقاط التوقف تلقائيًا عند إنشاء أو تحديث مسار عبر POST /api/admin/routes.
نموذج طلب التحديث
| الحقل | النوع | مطلوب | التحقق |
|---|---|---|---|
status |
string | لا | انظر RouteStopStatuses |
arrived_at |
datetime | لا | |
completed_at |
datetime | لا |
شكل مورد نقطة توقف المسار (RouteStop Resource)
{
"id": 1,
"route_id": 1,
"shipment_stop_id": 10,
"sequence": 1,
"status": "pending",
"status_label": "قيد الانتظار",
"stop_type": "pickup",
"stop_type_label": "تحصيل",
"lat": 24.7136,
"lng": 46.6753,
"full_address": "Riyadh, SA",
"contact_name": "Ali Hassan",
"phone": "0501234567",
"shipment": { "...": "ShipmentResource عند التحميل" },
"distance_from_previous_km": 5.2,
"estimated_minutes_from_previous": 12.5,
"estimated_arrival_at": "2026-06-25T08:12:00.000000Z",
"estimated_departure_at": "2026-06-25T08:27:00.000000Z",
"arrived_at": null,
"completed_at": null,
"created_at": "2026-06-24T20:00:00.000000Z",
"updated_at": "2026-06-24T20:00:00.000000Z"
}
مرجع نماذج النطاق
المعرّض حاليًا عبر واجهة برمجة التطبيقات
| النموذج | الجدول | الوصف | الحقول الرئيسية |
|---|---|---|---|
| Admin | admins |
مستخدمو المكتب الخلفي | name, email, password, fcm_token |
| Role | roles |
أدوار Spatie (الحارس: admin) |
name, guard_name |
| Permission | permissions |
صلاحيات Spatie | name, guard_name |
| Driver | drivers |
سائقو التوصيل | driver_number, name, phone, working_days, work_start_time, work_end_time, lat, lng, is_active |
| Vehicle | vehicles |
مركبات الأسطول | plate_number, owner_type, owner_id, max_weight, max_volume, is_active |
| DriverVehicleAssignment | driver_vehicle_assignments |
رابط السائق ↔ المركبة | driver_id, vehicle_id, assigned_at, released_at |
| DriverUnavailability | driver_unavailabilities |
إجازة السائق | driver_id, start_date, end_date, reason |
| User | users |
العملاء / الشاحنون | name, phone, phone_country, email, company_name |
| Shipment | shipments |
طلبات التوصيل | shipment_number, user_id, status, type, payment_type, delivery_date |
| ShipmentItem | shipment_items |
محتويات الشحنة | name, quantity, weight, declared_value |
| ShipmentStop | shipment_stops |
نقاط التحصيل/التسليم | type, lat, lng, sequence |
| ShipmentEvent | shipment_events |
سجل أحداث الشحنة | event_type, data, causer_type, causer_id |
| ProofOfDelivery | proof_of_deliveries |
تأكيد التوصيل | receiver_name, delivered_at |
| FailedDelivery | failed_deliveries |
محاولات التوصيل الفاشلة | reason_code, notes |
| Route | routes |
مسارات السائق اليومية | route_number, driver_id, vehicle_id, route_date, status, total_stops, optimized_distance, duration |
| RouteStop | route_stops |
نقاط توقف مرتبة على المسار | shipment_stop_id, sequence, status, estimated_arrival_at, estimated_departure_at |
| RouteAssignment | route_assignments |
سجل تعيين السائق على المسار | route_id, driver_id, assigned_at, unassigned_at |
النطاق المخطّط (غير موجود بعد في واجهة برمجة التطبيقات)
هذه النماذج موجودة في قاعدة البيانات ولكن ليس لها نقاط نهاية HTTP مخصصة بعد.
StaticContent (static_contents)
مخزن إعدادات CMS / التطبيق بصيغة مفتاح–قيمة (غير موجود بعد في واجهة برمجة التطبيقات).
| الحقل | النوع | ملاحظات |
|---|---|---|
key |
string | المفتاح الأساسي؛ انظر StaticContentTypes |
value |
string | نص عادي أو قيمة مُرمّزة JSON |
مخطط علاقات الكيانات (نظرة عامة)
User ──< Shipment ──< ShipmentItem
──< ShipmentStop ──< RouteStop >── Route >── Driver
──< ShipmentEvent └── Vehicle
──< ProofOfDelivery
──< FailedDelivery
Driver ──< DriverVehicleAssignment >── Vehicle
──< DriverUnavailability
──< RouteAssignment >── Route
Admin ──< Role ──< Permission
مرجع التعدادات (Enums)
جميع قيم التعدادات هي سلاسل snake_case. خزّنها كثوابت سلسلة في الواجهة الأمامية.
OwnerTypes
مُستخدم في واجهة برمجة التطبيقات اليوم — ملكية المركبة.
| القيمة | التسمية العربية | القواعد |
|---|---|---|
company |
الشركة | يجب أن يكون owner_id هو null |
driver |
سائق | يجب أن يكون owner_id معرّف سائق صالحًا |
تُعيد واجهة برمجة التطبيقات كلًا من owner_type (القيمة) و owner_type_label (التسمية العربية).
TypeScript مقترح:
type OwnerType = 'company' | 'driver';
ShipmentStatuses
مخطّط — حالة دورة حياة الشحنة.
| القيمة | التسمية العربية | لون واجهة المستخدم المقترح |
|---|---|---|
draft |
مسودة | secondary |
pending |
في الانتظار | warning |
assigned |
تم التخصيص لسائق | primary |
pickup_in_progress |
قيد التحصيل | warning |
picked_up |
تم التحصيل | success |
at_hub |
في المخزن | info |
out_for_delivery |
قيد التسليم | primary |
delivered |
تم التسليم | success |
delivery_failed |
فشل التسليم | danger |
returned |
مرتجع | warning |
cancelled |
تم الإلغاء | danger |
التدفق النموذجي:
draft → pending → assigned → pickup_in_progress → picked_up → at_hub
→ out_for_delivery → delivered
↘ delivery_failed → returned
Any state → cancelled
ShipmentTypes
| القيمة | التسمية العربية |
|---|---|
domestic |
محلي |
international |
دولية |
ShipmentPriorities
مستخدم في واجهة برمجة التطبيقات اليوم — أولوية الشحنة للتخطيط والتصفية.
| القيمة | التسمية العربية | لون واجهة مقترح |
|---|---|---|
low |
منخفضة | secondary |
normal |
عادية | primary |
high |
عالية | warning |
urgent |
عاجلة | danger |
الافتراضي normal عند الإنشاء إذا لم يُرسل الحقل. تُخطَّط الشحنات ذات الأولوية الأعلى أولًا أثناء تخطيط المسارات.
ShipmentStopTypes
| القيمة | التسمية العربية | الوصف |
|---|---|---|
pickup |
تحصيل | جمع البضائع من المرسل |
delivery |
تسليم | التسليم للمستلم |
stop |
موقف | محطة وسيطة |
PaymentTypes
| القيمة | التسمية العربية | ملاحظات |
|---|---|---|
cod |
عند الاستلام | الدفع عند الاستلام؛ يتطلب cod_amount |
prepaid |
مقدما | مدفوع مسبقًا |
RouteStatuses
| القيمة | التسمية العربية |
|---|---|
draft |
مسودة |
assigned |
تم تخصيص السائق |
active |
فعال |
completed |
مكتمل |
cancelled |
ملغي |
RouteStopStatuses
| القيمة | التسمية العربية |
|---|---|
pending |
قيد الانتظار |
arrived |
تم الوصول |
completed |
مكتمل |
failed |
فشل |
skipped |
تخطي |
ShipmentEvents
أنواع أحداث الجدول الزمني المُسجّلة على الشحنات. يحتوي كل حدث على حمولة JSON في حقل data.
| القيمة | التسمية العربية | مفاتيح data |
|---|---|---|
shipment_created |
تم إنشاء الشحنة | shipment_number, type, payment_type, delivery_date |
status_changed |
تم تغيير الحالة | from_status, to_status |
route_assigned |
تم تعيين المسار | route_id, driver_id, driver_name |
route_unassigned |
تم إلغاء تعيين المسار | route_id, reason |
driver_assigned |
تم تخصيص السائق | driver_id, driver_name |
route_created |
تم إنشاء الرحلة | route_id |
pickup_started |
تم بدء التحصيل | stop_id, driver_id, driver_name |
pickup_completed |
تم إنهاء التحصيل | stop_id, arrived_at, completed_at |
out_for_delivery |
خرجت للتسليم | route_id, driver_id, driver_name |
delivery_failed |
فشل التسليم | stop_id, reason_code, notes |
delivered |
تم التسليم | stop_id, receiver_name, delivered_at |
pod_uploaded |
تم تحميل إثبات التوصيل | receiver_name, delivered_at, notes |
cancelled |
تم الإلغاء | reason, cancelled_by_type, cancelled_by_id |
returned |
تم الإرجاع | reason, returned_at |
FailedDeliveryReasons
| القيمة | التسمية العربية |
|---|---|
customer_unavailable |
العميل غير متاح |
wrong_address |
عنوان خاطئ |
customer_refused |
العميل رفض الاستلام |
unable_to_contact |
تعذر التواصل مع العميل |
damaged_package |
الطرد تالف |
other |
أخرى |
MediaTypes
أسماء مجموعات الوسائط الداخلية (تُستخدم لرفع الصور).
| القيمة | يُستخدم لـ |
|---|---|
admin_image |
صور ملف المسؤول الشخصي |
driver_image |
صور ملف السائق الشخصي |
user_image |
صور ملف المستخدم الشخصي (مستقبلًا) |
StaticContentTypes
مفاتيح إعدادات CMS / التطبيق (غير موجودة بعد في واجهة برمجة التطبيقات).
| القيمة | التسمية العربية |
|---|---|
privacy_policy |
سياسة الخصوصية |
commission |
عمولة الإدارة |
social_media |
المواقع الاجتماعية |
android_app_version |
نسخة التطبيق للاندرويد |
ios_app_version |
نسخة التطبيق لل IOS |
android_provider_app_version |
نسخة التطبيق للاندرويد للمزود |
ios_provider_app_version |
نسخة التطبيق لل IOS للمزود |
NotificationTypes
فئات الإشعارات الفورية (تعداد مدعوم بـ PHP).
| القيمة |
|---|
general |
wallet_deposit |
wallet_withdraw |
new_offer |
offer_accepted |
offer_rejected |
order_status_changed |
new_order |
أيام العمل (ليست تعداد PHP)
أيام جدول السائق. تُقبل كقيم مصفوفة في طلبات الإنشاء/التحديث.
| القيمة | اليوم |
|---|---|
sun |
الأحد |
mon |
الاثنين |
tue |
الثلاثاء |
wed |
الأربعاء |
thu |
الخميس |
fri |
الجمعة |
sat |
السبت |
TypeScript مقترح:
type WorkingDay = 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat';
مرجع الصلاحيات
تتحكم الصلاحيات فيما يمكن لكل مسؤول فعله. تحقّق منها في جانب العميل لإظهار/إخفاء عناصر الواجهة.
اتفاقية التسمية
{Action}:{Model}
| الإجراء | الوصف |
|---|---|
ViewAny |
الوصول إلى القائمة/الفهرس |
View |
عرض سجل واحد |
Create |
إنشاء سجل جديد |
Update |
تعديل سجل موجود |
Delete |
حذف سجل |
Reorder |
إعادة ترتيب السجلات (إن وُجد) |
أمثلة:
ViewAny:Driver— يمكنه عرض قائمة السائقينCreate:Vehicle— يمكنه إنشاء مركباتUpdate:Admin— يمكنه تعديل المسؤولينDelete:Role— يمكنه حذف الأدوار
الصلاحيات المخصّصة
هذه لا ترتبط بنموذج CRUD:
| الصلاحية | الوصف |
|---|---|
Export:Reports |
تصدير التقارير |
Send:Notifications |
إرسال الإشعارات الفورية |
Manage:AppSettings |
إدارة إعدادات التطبيق |
Assign:Routes |
تعيين المسارات للسائقين |
Track:Deliveries |
تتبّع التسليمات المباشرة |
كيفية التحقق من الصلاحيات في الواجهة الأمامية
بعد تسجيل الدخول، افحص data.admin.permission_groups:
function hasPermission(
permissionGroups: PermissionGroup[],
permissionName: string
): boolean {
return permissionGroups.some(group =>
group.permissions.some(p => p.name === permissionName)
);
}
// Usage
if (hasPermission(admin.permission_groups, 'Create:Driver')) {
// Show "Add Driver" button
}
دور المسؤول الأعلى (super admin) لديه جميع الصلاحيات ضمنيًا.
معالجة الأخطاء
رموز حالة HTTP
| الرمز | المعنى | متى |
|---|---|---|
200 |
نجاح | عملية عادية |
401 |
غير مصرّح | صلاحية مفقودة/غير صالحة، بيانات اعتماد خاطئة |
403 |
ممنوع | غير مصادق (لا يوجد رمز/رمز غير صالح) |
404 |
غير موجود | المسار أو المورد غير موجود |
422 |
خطأ تحقق | جسم/استعلام طلب غير صالح |
500 |
خطأ خادم | فشل غير متوقع |
رسائل الخطأ الشائعة
| مفتاح الرسالة | النص الإنجليزي | الحالة |
|---|---|---|
credentialsError |
Wrong Credentials | 401 |
Unauthenticated |
Please login first | 403 |
Unauthorized |
You do not have permissions to perform this action | 401 |
cannotDeleteCurrentAdmin |
You cannot delete your own admin account | 403 |
cannotModifySuperAdmin |
Super admin role cannot be modified | 403 |
vehicleAlreadyAssigned |
This vehicle is already assigned to a driver | 422 |
vehicleAssignmentNotFound |
No active vehicle assignment found for this driver | 404 |
couldNotCreateToken |
Could not create authentication token | 500 |
couldNotLogout |
Could not log out | 500 |
cannotUpdateShipment |
لا يمكن تعديل الشحنة في حالتها الحالية | 422 |
cannotConfirmShipment |
يمكن تأكيد الشحنات المسودة فقط | 422 |
shipmentAlreadyCancelled |
الشحنة في حالة نهائية ولا يمكن إلغاؤها | 422 |
cannotDeleteShipment |
يمكن حذف الشحنات المسودة فقط | 422 |
shipmentNotPending |
يجب أن تكون الشحنة في حالة انتظار لتعيين مسار | 422 |
shipmentNotAssigned |
يجب أن تكون الشحنة في حالة مُعيَّنة لإلغاء تعيين المسار | 422 |
invalidShipmentStatus |
حالة الشحنة المُدخلة غير صالحة | 422 |
أخطاء التحقق تُعيد أول رسالة تحقق كـ message.
شكل استجابة الخطأ
{
"status": "Error",
"message": "Wrong Credentials",
"data": null,
"statusCode": 401
}
قائمة التحقق لتكامل الواجهة الأمامية
- تخزين JWT من استجابة تسجيل الدخول (
data.token) - إرسال
Authorization: Bearer {token}مع كل طلب مصادق - ضبط
Accept-Language: enأوarللرسائل المترجمة - استخدام
POSTلجميع التحديثات (وليس PUT/PATCH) - استخدام
multipart/form-dataعند رفع حقولimage - التحكم في الواجهة بالتحقق من
permission_groupsمن استجابة تسجيل الدخول/الملف الشخصي - معالجة الغلاف القياسي
{ status, message, data, statusCode } - استخدام نقاط النهاية المُقسّمة مع معامل
pageللجداول - تمرير
search,sort_by,sort_directionللقوائم القابلة للتصفية - للمركبات: فرض قواعد
owner_idبناءً علىowner_type - للسائقين: إرسال
working_daysكمصفوفة؛ الأوقات كـHH:MMأوHH:MM:SS - للشحنات: يجب أن يحتوي مصفوف
stopsعلى نقطةpickupواحدة بالضبط ونقطةdeliveryواحدة بالضبط - للشحنات:
cod_amountمطلوب عندpayment_type = cod - معالجة أحداث
status_changedمنGET /shipments/{id}/eventsلعرض الجدول الزمني - تعيين المسار: يجب أن تكون الشحنة
pendingقبلassign-route؛ وassignedقبلunassign-route - إنشاء المسار: أرسل
driver_id+stops[]؛ لا ترسلvehicle_idأوstatusأو المقاييس — الخادم يحسبها - إنشاء المسار يتطلب أن يكون للسائق تعيين مركبة نشط
- تخطيط المسارات: أرسل عبر
POST /routes/plan، واستعلم عبرGET /routes/plan/result?date=
فهرس المسارات (مرجع سريع)
| الطريقة | المسار |
|---|---|
POST |
/api/admin/login |
POST |
/api/admin/logout |
GET |
/api/admin/profile |
POST |
/api/admin/profile |
GET |
/api/admin/dashboard/overview |
GET |
/api/admin/dashboard/trends |
GET |
/api/admin/permissions |
GET/POST/DELETE |
/api/admin/roles, /api/admin/roles/paginated, /api/admin/roles/{id}, /api/admin/roles/{id}/permissions |
GET/POST/DELETE |
/api/admin/admins, /api/admin/admins/paginated, /api/admin/admins/{id} |
GET/POST/DELETE |
/api/admin/drivers, /api/admin/drivers/paginated, /api/admin/drivers/{id} |
GET/POST |
/api/admin/drivers/{id}/vehicle-assignments, .../assign, .../unassign |
GET |
/api/admin/drivers/{id}/unavailabilities |
GET/POST/DELETE |
/api/admin/vehicles, /api/admin/vehicles/paginated, /api/admin/vehicles/{id} |
GET/POST/DELETE |
/api/admin/driver-unavailabilities, .../paginated, .../{id} |
GET/POST/DELETE |
/api/admin/users, /api/admin/users/paginated, /api/admin/users/{id} |
GET/POST/DELETE |
/api/admin/shipments, /api/admin/shipments/paginated, /api/admin/shipments/{id} |
POST |
/api/admin/shipments/{id}/confirm, /api/admin/shipments/{id}/cancel, /api/admin/shipments/{id}/status |
POST |
/api/admin/shipments/{id}/assign-route, /api/admin/shipments/{id}/unassign-route |
GET |
/api/admin/shipments/{id}/events |
POST |
/api/admin/shipments/bulk/cancel, /api/admin/shipments/bulk/confirm, /api/admin/shipments/bulk/assign-route |
GET |
/api/admin/shipment-stops, /api/admin/shipment-stops/paginated, /api/admin/shipment-stops/{id} |
GET/POST |
/api/admin/shipments/{id}/proof-of-deliveries |
GET |
/api/admin/proof-of-deliveries/{id} |
GET/POST |
/api/admin/shipments/{id}/failed-deliveries |
GET |
/api/admin/failed-deliveries/{id} |
GET/POST/DELETE |
/api/admin/routes, /api/admin/routes/paginated, /api/admin/routes/{id} |
POST |
/api/admin/routes/{id}/start, /api/admin/routes/{id}/complete, /api/admin/routes/{id}/cancel |
GET |
/api/admin/routes/{id}/stops, /api/admin/routes/{id}/assignments |
POST/GET |
/api/admin/routes/plan, /api/admin/routes/plan/result |
GET/POST/DELETE |
/api/admin/route-stops/{id} |
واجهة برمجة تطبيق السائق (Driver App API)
واجهة تطبيق السائق (/api/driver/*) مخصصة للتطبيق الجوال للسائقين. تستخدم نفس آلية JWT مع حارس driver. الرموز لا تنتهي صلاحيتها (expires_in: null).
مصادقة السائق
| الطريقة | المسار | المصادقة | الوصف |
|---|---|---|---|
POST |
/api/driver/login |
عام | تسجيل الدخول بـ phone, phone_country, password. يمكن إرسال fcm_token. يعيد JWT + ملف السائق. |
POST |
/api/driver/logout |
مطلوبة | إلغاء صلاحية الرمز الحالي. |
ملف السائق
| الطريقة | المسار | الوصف |
|---|---|---|
GET |
/api/driver/profile |
جلب ملف السائق الكامل مع المركبة المُعيَّنة. |
POST |
/api/driver/profile |
تعديل name, email, password (اختياري، الحد الأدنى 6 أحرف). |
POST |
/api/driver/fcm-token |
تحديث رمز الإشعارات. الجسم: { "fcm_token": "..." } |
POST |
/api/driver/location |
تحديث إحداثيات GPS. الجسم: { "lat": 24.71, "lng": 46.67 } |
مسارات السائق
جميع مسارات الطلبات مقيّدة تلقائيًا بالسائق المصادَق عليه. للسائق مسار واحد في اليوم.
| الطريقة | المسار | الوصف |
|---|---|---|
GET |
/api/driver/routes |
قائمة مقسّمة (15/صفحة). فلاتر: ?status=assigned&date=2026-07-02 |
GET |
/api/driver/routes/today |
مسار اليوم. يعيد 404 إذا لم يُعيَّن مسار لليوم. |
GET |
/api/driver/routes/{id} |
المسار الكامل مع نقاط التوقف. كل shipment داخل نقطة التوقف يتضمن items ليعرف السائق ما يجب استلامه أو تسليمه. |
POST |
/api/driver/routes/{id}/start |
بدء المسار: assigned → active. |
POST |
/api/driver/routes/{id}/complete |
إنهاء المسار: active → completed. |
نقاط توقف المسار
| الطريقة | المسار | الوصف |
|---|---|---|
GET |
/api/driver/routes/{routeId}/stops |
جميع نقاط التوقف مرتبة حسب sequence. |
GET |
/api/driver/routes/{routeId}/stops/{stopId} |
تفاصيل نقطة التوقف الكاملة. shipment.items يعرض ما يجب استلامه أو تسليمه. |
POST |
/api/driver/routes/{routeId}/stops/{stopId}/arrive |
تسجيل الوصول: pending → arrived. يجب أن يكون المسار active (مُبدَأ) أولاً. |
POST |
/api/driver/routes/{routeId}/stops/{stopId}/complete |
إكمال نقطة التوقف. انظر المنطق أدناه. |
POST |
/api/driver/routes/{routeId}/stops/{stopId}/fail |
تسجيل فشل التسليم. الجسم: reason_code, notes?. |
POST |
/api/driver/routes/{routeId}/stops/{stopId}/skip |
تخطي نقطة التوقف. |
منطق إكمال نقطة التوقف حسب النوع:
| نوع النقطة | ما يحدث |
|---|---|
delivery |
إنشاء ProofOfDelivery، تحديث الشحنة إلى delivered، حدث delivered. الجسم: receiver_name, receiver_phone, notes? |
pickup |
تحديث الشحنة إلى picked_up، حدث pickup_completed. لا يحتاج جسمًا. |
قيم reason_code لنقطة الفشل: customer_unavailable, wrong_address, customer_refused, unable_to_contact, damaged_package, other.
مُولّد من قاعدة شفرة shipping_system. آخر تحديث: يوليو 2026.