SS توثيق API
واجهة الإدارة

مرجع واجهة API للواجهة الأمامية

مرجع شامل لمطوري الواجهات الأمامية — المصادقة، النقاط النهائية، النماذج، التعدادات، وأنماط التكامل.

REST + JWT استجابات JSON صلاحيات حسب الدور

نظام الشحن — مرجع واجهة برمجة التطبيقات للواجهة الأمامية

مرجع مفصّل لمطوّري الواجهة الأمامية الذين يتكاملون مع واجهة برمجة تطبيقات المسؤول (Admin API).

النطاق: واجهة برمجة تطبيقات المسؤول فقط هي المعرّضة عبر HTTP حاليًا (/api/admin/*). نماذج نطاق الشحنات والمسارات والتسليم موجودة في قاعدة البيانات وموثّقة أدناه للسياق، لكن نقاط النهاية (endpoints) الخاصة بها غير مُنفّذة بعد.


جدول المحتويات

  1. البدء السريع
  2. الاتفاقيات العامة
  3. المصادقة
  4. الملف الشخصي
  5. المسؤولون
  6. الأدوار والصلاحيات
  7. السائقون
  8. المركبات
  9. فترات عدم توفر السائقين
  10. تعيينات السائق–المركبة
  11. المستخدمون (العملاء)
  12. مرجع نماذج النطاق
  13. مرجع التعدادات (Enums)
  14. مرجع الصلاحيات
  15. معالجة الأخطاء
  16. قائمة التحقق لتكامل الواجهة الأمامية

البدء السريع

HTTP
POST /api/admin/login
Content-Type: application/json
Accept-Language: en

{
  "email": "mousa@example.com",
  "password": "password"
}

احفظ رمز JWT المُعاد وأرسله مع كل طلب لاحق:

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

كل استجابة من واجهة برمجة التطبيقات تستخدم هذا الهيكل:

JSON
{
  "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) تُغلّف النتائج كالتالي:

JSON
{
  "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

حجم الصفحة ثابت عند 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 لا رمز جهاز الإشعارات الفورية؛ يُخزّن في سجل المسؤول

مثال على جسم الطلب:

JSON
{
  "email": "mousa@example.com",
  "password": "SecurePass123!",
  "fcm_token": "device-fcm-token-abc123"
}

استجابة النجاح 200:

JSON
{
  "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:

JSON
{
  "status": "Success",
  "message": "User successfully signed out",
  "data": null,
  "statusCode": 200
}

استجابات الخطأ:

الحالة متى
403 لم يُقدّم رمز (Unauthenticated)
500 فشل تسجيل الخروج (couldNotLogout)

الملف الشخصي

إدارة الملف الشخصي للمسؤول المصادق حاليًا. لا تتطلب صلاحيات إدارة المسؤولين.


GET /api/admin/profile

الصلاحية المطلوبة: لا شيء (المصادقة فقط)

استجابة النجاح 200: تُعيد AdminResource (انظر المسؤولون) مع:

  • is_current_admin: true
  • permission_groups مُضمّنة
  • roles مُضمّنة

POST /api/admin/profile

تحديث ملف المسؤول المصادق.

الصلاحية المطلوبة: لا شيء (المصادقة فقط)

جسم الطلب (JSON أو multipart):

الحقل النوع مطلوب التحقق
name string لا حد أقصى 255 حرفًا
email string لا بريد إلكتروني صالح، فريد بين المسؤولين
password string لا قواعد كلمة مرور Laravel الافتراضية
image file لا صورة، حد أقصى 5 ميجابايت

مثال على جسم الطلب:

JSON
{
  "name": "mousa",
  "email": "mousa.updated@example.com",
  "password": "NewSecurePass123!"
}

استجابة النجاح 200: AdminResource محدّث مع رسالة profileUpdatedSuccessfully.


المسؤولون

إدارة مستخدمي المكتب الخلفي.

بادئة الصلاحية: 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[] لا مصفوفة من أسماء الأدوار الموجودة

مثال على جسم الطلب:

JSON
{
  "name": "mousa",
  "email": "mousa@example.com",
  "password": "SecurePass123!",
  "roles": ["operations_manager"]
}

جسم طلب التحديث

نفس حقول الإنشاء، جميعها اختيارية (تُطبّق قواعد sometimes). احذف password للإبقاء على كلمة المرور الحالية. أرسل roles: [] لإزالة جميع الأدوار.

مثال على جسم الطلب:

JSON
{
  "name": "mousa",
  "email": "mousa.admin@example.com",
  "roles": ["super_admin"]
}

شكل مورد المسؤول (Admin Resource Shape)

JSON
{
  "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[] لا مصفوفة من سلاسل أسماء الصلاحيات

مثال على جسم الطلب:

JSON
{
  "name": "warehouse_manager",
  "permissions": ["ViewAny:Driver", "Create:Driver", "ViewAny:Vehicle"]
}

جسم طلب تحديث الدور

الحقل النوع مطلوب التحقق
name string لا فريد لكل حارس، حد أقصى 255
permissions string[] لا يستبدل جميع الصلاحيات عند التقديم

مثال على جسم الطلب:

JSON
{
  "name": "warehouse_manager",
  "permissions": ["ViewAny:Driver", "Update:Driver"]
}

جسم طلب مزامنة الصلاحيات

POST /api/admin/roles/{id}/permissions

الحقل النوع مطلوب التحقق
permissions string[] نعم مصفوفة من سلاسل أسماء الصلاحيات

مثال على جسم الطلب:

JSON
{
  "permissions": ["ViewAny:Driver", "Create:Driver", "ViewAny:Vehicle", "Create:Vehicle"]
}

رسالة النجاح: permissionsAssignedSuccessfully

شكل مورد الدور (Role Resource Shape)

JSON
{
  "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)

يُستخدم في تسجيل الدخول والملف الشخصي والأدوار وقائمة الصلاحيات:

JSON
{
  "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 ميجابايت
driver_number string لا فريد؛ يُولّد تلقائيًا رقم من 6 أرقام إذا لم يُذكر

مثال على جسم الطلب:

JSON
{
  "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
}

جسم طلب التحديث

نفس حقول الإنشاء. جميع الحقول اختيارية ما عدا حيث تُطبّق sometimes + required. كلمة المرور اختيارية (احذفها للإبقاء على الحالية).

مثال على جسم الطلب:

JSON
{
  "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)

JSON
{
  "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
}
الحقل ملاحظات
distance موجود فقط عند استخدام تصفية القرب (lat/lng)
working_days مصفوفة JSON من رموز الأيام
image عنوان URL كامل أو سلسلة فارغة

المركبات

إدارة مركبات الأسطول.

بادئة الصلاحية: 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 (م³)

مثال على جسم الطلب:

JSON
{
  "plate_number": "DMS-1234",
  "owner_type": "company",
  "max_weight": 1500,
  "max_volume": 12.5
}

مثال على جسم الطلب (مملوكة للسائق):

JSON
{
  "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 لا

مثال على جسم الطلب:

JSON
{
  "plate_number": "DMS-9999",
  "max_weight": 1800,
  "max_volume": 14,
  "is_active": false
}

شكل مورد المركبة (Vehicle Resource Shape)

JSON
{
  "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 لا نص حر

مثال على جسم الطلب:

JSON
{
  "driver_id": 1,
  "start_date": "2026-06-01",
  "end_date": "2026-06-05",
  "reason": "Annual leave"
}

جسم طلب التحديث

نفس الحقول، جميعها اختيارية. إذا قُدّمت كلا التاريخين في التحديث، يجب أن يظل end_date بعد start_date.

مثال على جسم الطلب:

JSON
{
  "start_date": "2026-06-01",
  "end_date": "2026-06-10",
  "reason": "Extended leave"
}

شكل مورد عدم توفر السائق (Driver Unavailability Resource Shape)

JSON
{
  "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)

JSON
{
  "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 لا

مثال على جسم الطلب:

JSON
{
  "name": "mousa",
  "phone": "944123456",
  "phone_country": "+963",
  "email": "mousa@example.com",
  "company_name": "Mousa Trading Co."
}

جسم طلب التحديث

نفس الحقول، جميعها اختيارية. تُعاد التحقق من تفرد رقم الهاتف عند تغيير phone أو phone_country.

مثال على جسم الطلب:

JSON
{
  "name": "mousa",
  "phone": "944654321",
  "phone_country": "+963",
  "company_name": "Mousa Logistics"
}

شكل مورد المستخدم (User Resource Shape)

JSON
{
  "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"
}

مرجع نماذج النطاق

المعرّض حاليًا عبر واجهة برمجة التطبيقات

النموذج الجدول الوصف الحقول الرئيسية
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

النطاق المخطّط (غير موجود بعد في واجهة برمجة التطبيقات)

هذه النماذج موجودة في قاعدة البيانات وستشغّل ميزات الشحنات/المسارات. لا توجد نقاط نهاية HTTP لها بعد.

Shipment (shipments)

طلب التوصيل الأساسي الذي يقدّمه العميل.

الحقل النوع التعداد / ملاحظات
shipment_number string معرّف فريد
user_id integer FK → users
user_name string اسم العميل مُكرّر (denormalized)
delivery_date datetime تاريخ التسليم المستهدف
status string ShipmentStatuses
type string ShipmentTypes
payment_type string PaymentTypes
cod_amount float مطلوب عند الدفع COD
total_weight float كجم
total_volume float م³
notes string اختياري

العلاقات:

  • user → User
  • shipment_items → ShipmentItem[]
  • shipment_stops → ShipmentStop[]
  • shipment_events → ShipmentEvent[]
  • proof_of_deliveries → ProofOfDelivery[]
  • failed_deliveries → FailedDelivery[]

ShipmentItem (shipment_items)

العناصر الفردية ضمن شحنة.

الحقل النوع ملاحظات
shipment_id integer FK → shipments
name string اسم العنصر
weight float كجم
length, width, height float الأبعاد
quantity integer
description string اختياري
declared_value float اختياري

ShipmentStop (shipment_stops)

محطات التحصيل أو التسليم أو المحطات الوسيطة على مسار الشحنة.

الحقل النوع التعداد / ملاحظات
shipment_id integer FK → shipments
type string ShipmentStopTypes
contact_name string
phone, phone_country string
country, city, area string مكوّنات العنوان
street, building, floor, apartment string
lat, lng float الإحداثيات
full_address string عنوان مُنسّق
sequence integer الترتيب ضمن الشحنة

ShipmentEvent (shipment_events)

إدخالات سجل التدقيق / الجدول الزمني للشحنة.

الحقل النوع التعداد / ملاحظات
shipment_id integer FK → shipments
event_type string ShipmentEvents
data string حمولة JSON (اختياري)
causer_type, causer_id string, int المُسبّب متعدد الأشكال
causer_name string اسم المُسبّب مُكرّر
notes string اختياري

Route (routes)

مسار يومي مُحسّن مُخصّص لسائق ومركبة.

الحقل النوع التعداد / ملاحظات
driver_id integer FK → drivers
vehicle_id integer FK → vehicles
route_date datetime تاريخ المسار
status string RouteStatuses
total_stops integer
optimized_distance float كم
duration float دقائق

العلاقات:

  • driver → Driver
  • vehicle → Vehicle
  • route_stops → RouteStop[]
  • route_assignments → RouteAssignment[]

RouteStop (route_stops)

محطة مرتّبة على مسار السائق، مرتبطة بمحطة شحنة.

الحقل النوع التعداد / ملاحظات
route_id integer FK → routes
shipment_stop_id integer FK → shipment_stops
status string RouteStopStatuses
distance_from_previous_km float
estimated_minutes_from_previous float
arrived_at, completed_at datetime
sequence integer الترتيب على المسار

RouteAssignment (route_assignments)

يتتبّع سجل تعيين السائق للمسار.

الحقل النوع ملاحظات
route_id integer FK → routes
driver_id integer FK → drivers
assigned_at datetime
unassigned_at datetime null أثناء النشاط

ProofOfDelivery (proof_of_deliveries)

سجل تأكيد التسليم.

الحقل النوع ملاحظات
shipment_id integer FK → shipments
receiver_name string
receiver_phone, receiver_phone_country string
delivered_at datetime
notes string
created_by_type, created_by_id string, int المُنشئ متعدد الأشكال
created_by_name string

FailedDelivery (failed_deliveries)

سجل محاولة تسليم فاشلة.

الحقل النوع ملاحظات
shipment_id integer FK → shipments
reason_code string رمز سبب الفشل
notes string
created_by_type, created_by_id string, int المُنشئ متعدد الأشكال
created_by_name string

StaticContent (static_contents)

مخزن إعدادات CMS / التطبيق بصيغة مفتاح–قيمة (غير موجود بعد في واجهة برمجة التطبيقات).

الحقل النوع ملاحظات
key string المفتاح الأساسي؛ انظر StaticContentTypes
value string نص عادي أو قيمة مُرمّزة JSON

مخطط علاقات الكيانات (نظرة عامة)

TEXT
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 مقترح:

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

التدفق النموذجي:

TEXT
draft → pending → assigned → pickup_in_progress → picked_up → at_hub
  → out_for_delivery → delivered
                                    ↘ delivery_failed → returned
Any state → cancelled

ShipmentTypes

القيمة التسمية العربية
domestic محلي
international دولية

ShipmentStopTypes

القيمة التسمية العربية الوصف
pickup تحصيل جمع البضائع من المرسل
delivery تسليم التسليم للمستلم
stop موقف محطة وسيطة

PaymentTypes

القيمة التسمية العربية ملاحظات
cod عند الاستلام الدفع عند الاستلام؛ يتطلب cod_amount
prepaid مقدما مدفوع مسبقًا

RouteStatuses

القيمة التسمية العربية
draft مسودة
assigned تم تخصيص السائق
active فعال
completed مكتمل
cancelled ملغي

RouteStopStatuses

القيمة التسمية العربية
pending قيد الانتظار
arrived تم الوصول
completed مكتمل
failed فشل
skipped تخطي

ShipmentEvents

أنواع أحداث الجدول الزمني المُسجّلة على الشحنات.

القيمة التسمية العربية
shipment_created تم إنشاء الشحنة
driver_assigned تم تخصيص السائق
route_created تم إنشاء الرحلة
pickup_started تم بدء التحصيل
pickup_completed تم إنهاء التحصيل
delivery_failed فشل التسليم
pod_uploaded تم تحميل إثبات التوصيل

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 مقترح:

TYPESCRIPT
type WorkingDay = 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat';

مرجع الصلاحيات

تتحكم الصلاحيات فيما يمكن لكل مسؤول فعله. تحقّق منها في جانب العميل لإظهار/إخفاء عناصر الواجهة.

اتفاقية التسمية

TEXT
{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:

TYPESCRIPT
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

أخطاء التحقق تُعيد أول رسالة تحقق كـ message.

شكل استجابة الخطأ

JSON
{
  "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
  • ميزات الشحنات/المسارات: استخدم التعدادات من هذا المستند لكن انتظر مسارات واجهة برمجة التطبيقات في الخلفية

فهرس المسارات (مرجع سريع)

الطريقة المسار
POST /api/admin/login
POST /api/admin/logout
GET /api/admin/profile
POST /api/admin/profile
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}

مُولّد من قاعدة شفرة shipping_system. آخر تحديث: يونيو 2026.