المصدر: specs/ar/02-api.mdتعديل هذه الصفحة

المواصفة 02 — عقود واجهة API (‏NestJS، ‏REST /api/v1)

الاصطلاحات: الصيغة JSON؛ التحقق من صحة كائنات النقل DTO عبر class-validator تحققاً صارماً — فالخصائص غير المعروفة تُرفض ولا تُحذف؛ وأحجام متون الطلبات محدودة؛ شكل الأخطاء { statusCode, code, message, messageAr }؛ التقسيم إلى صفحات ?page=1&limit=20{ items, total, page, limit }؛ المصادقة عبر كوكيز من نوع httpOnly هي nutqi_at / nutqi_rt؛ مُزخرِفات الحراسة @Roles(...)؛ وكل ذلك موصوف بتعليقات Swagger ولا يُقدَّم في الإنتاج إلا إذا فُعِّل صراحةً.

ومسارات القراءة تردّ صفوفاً مسطَّحة (‏D-26): الأسماء محلولةً في نص واحد، والتواريخ التقويمية بصيغة YYYY-MM-DD، والصور الرمزية روابط جاهزة للاستعمال، والعدّادات محسوبةً في الخادم، والعلاقات محذوفة — فلا يتسرّب تخطيط قاعدة البيانات إلى أي عميل.

وتحديد المعدّل يجري لكل عنوان شبكة، بميزانية أضيق بكثير على /auth/login ومسارات رمز التأكيد؛ وهو مكمِّل لقفل الحساب في G15 لا بديل عنه. والمتغيّران JWT_ACCESS_SECRET وCORS_ORIGIN مطلوبان في الإنتاج — فالتطبيق يرفض الإقلاع بدل الارتداد إلى قيمة افتراضية غير آمنة.

وحدة health#

  • GET /health (عام، بلا مصادقة) ← فحص حياة مع فحص قاعدة بيانات حقيقي. وهو خالٍ عمداً من أرقام الإصدارات وسلاسل الاتصال ونصوص الأخطاء؛ ويستهلكه الوسيط العكسي وفحص صحة الحاوية.

وحدة auth#

  • POST /auth/register بحمولة { role: PERSONAL_PATIENT|GUARDIAN|SPECIALIST|CENTER, firstName, lastName, email, phone, password, gender?, birthDate?, center? {nameAr, licenseNumber?, governorate?, city?, branchName?} } ← تُنشئ مستخدماً (بالحالة PENDING_VERIFICATION)، ومعه مركز وأول فرع حين يكون الدور CENTER طبقاً لـ G03؛ وتُرسل رمز تحقق للبريد والهاتف (المزوّد في بيئة التطوير هو console). تردّ 409 عند تكرار البريد أو رقم الهاتف.
  • POST /auth/verify-otp بحمولة { target, code, purpose: "verify" | "reset" } ← عند التحقق: تُعلَّم الوسيلة كمُوثَّقة، وتتحول الحالة إلى ACTIVE (للمريض وولي الأمر) أو PENDING_ACTIVATION (للأخصائي والمركز)؛ وتُضبط الكوكيز. وعند إعادة التعيين: تُعيد رمز resetToken صالحاً لمرة واحدة.
  • POST /auth/resend-otp بحمولة { target, channel? } — محكومة بمهلة 60 ثانية (مطابقة للعدّاد التنازلي في الواجهة).
  • POST /auth/login بحمولة { email, password } ← تضبط الكوكيز؛ وكلمة السر الخطأ تزيد عدّاد المحاولات؛ وعند القفل تردّ 423 مع lockedUntil طبقاً لـ G15.
  • POST /auth/forgot بحمولة { email, phone } ← رمز تحقق بغرض reset.
  • POST /auth/reset-password بحمولة { resetToken, password }.
  • POST /auth/refresh و POST /auth/logout.
  • GET /auth/me ← بيانات المستخدم + ملخص الملف الخاص بدوره + نسبة اكتمال التفعيل (وهي ما يحرّك حلقة البوابة).
  • PATCH /auth/password بحمولة { current, next } (من الإعدادات).

وحدة users#

  • PATCH /users/me (الأسماء بالعربية والإنجليزية، nationalId، تاريخ الميلاد، النوع، الصورة الشخصية، اللغة، وحقول العنوان).
  • PUT /users/me/languages بحمولة [{language, level}] (اللغات المحكية، G13-b).
  • GET/PUT /users/me/notification-channels بحمولة [{channel, target, enabled}]؛ و POST /users/me/notification-channels/:channel/verify (مسار رمز التحقق).

وحدة patients (بوابة ولي الأمر)#

  • GET /patients (الخاصة بي) / POST /patients (إضافة طفل، G09) / GET|PATCH /patients/:id.
  • POST /patients/:id/documents (رفع متعدد الأجزاء، النوع DOC|VIDEO) / GET /patients/:id/documents / DELETE …/:docId.
  • التشخيص: GET /forms/diagnosis-template ← القالب النظامي؛ و POST /patients/:id/diagnosis-response (تُنشئ الاستجابة أو تحدّثها عبر واجهة الإجابات الموصوفة أدناه).

وحدة specialists#

  • GET /specialists — الدليل العام (G12): المرشِّحات q و governorate و specialty و sessionType و priceMin/Max و rating؛ ولا يظهر إلا من كان بالحالة ACTIVE.
  • GET /specialists/:id/profile ← حمولة النظرة العامة (الإحصاءات: الخط الزمني للحجوزات، وتوزيع الأنواع، وأعلى البرامج — وكلها محسوبة)، والبيانات (الشهادات والتدريبات والفيديوهات)، والعيادات، وملخص التقييمات.
  • GET /specialists/:id/schedule?weekStart= ← شبكة الجلسات مع الأسعار؛ و GET /specialists/:id/slots?date=&clinicId?= ← المواعيد المتاحة بفترات نصف ساعة (ساعات العمل − الحجوزات − أيام الراحة) طبقاً لـ D-09.
  • مقصورة على الحساب نفسه: GET/PUT /specialists/me/profile، و POST/PATCH/DELETE /specialists/me/work-info، و …/certificates، و …/videos، و …/clinics، و PUT /specialists/me/schedule (كتل أيام الأسبوع)، و POST /specialists/me/days-off.
  • PUT /specialists/me/booking-settings بحمولة { availableForWork, acceptsOnline, acceptsOffline, acceptsConsultation }.
  • GET/POST/DELETE /specialists/me/blocklist.
  • GET /specialists/me/stats?period=all|year|month|week|day{ dailyAvgCases, totalCases, earningsCents, pending: bool }.

وحدة bookings#

  • POST /bookings بحمولة { patientId, specialistId, clinicId?|type ONLINE, sessionType, date, startTime } ← تُنشئ الحجز بالحالة PENDING؛ وتتحقق من أن الميعاد شاغر، وأن الأخصائي مفعَّل ومتاح، وأن الحاجز غير محظور؛ ويُحتسب السعر في الخادم. وتردّ 409 إذا كان الميعاد محجوزاً.
  • GET /bookings قائمة محدودة بنطاق الدور مع مرشِّحات (status و type و q و dateRange) بالإضافة إلى ?export=csv.
  • PATCH /bookings/:id/status بحمولة { status, meetingUrl?, newDate?/newTime? for POSTPONED } — الانتقالات المسموح بها محكومة بآلة الحالات (المواصفة docs-content/02 §5)؛ ويجوز لولي الأمر إلغاء حجزه هو وهو بالحالة PENDING/WAITING.
  • GET /bookings/upcoming ← الحجز التالي لعرضه في الشريط طبقاً لـ E10.

وحدة sessions#

  • POST /sessions (من حجز أو من حالة خاصة) / PATCH /sessions/:id بحمولة { progressPercent, evaluation, notes }.
  • GET /patients/:id/sessions، و GET /special-cases/:id/sessions.

وحدة special-cases (للأخصائي)#

  • عمليات إنشاء وقراءة وتعديل وحذف على /special-cases؛ والمرفقات على /special-cases/:id/attachments (المرحلة BEFORE|AFTER)؛ والملاحظات لها العمليات نفسها (حذف ناعم مع نافذة تراجع، G18).

وحدة forms (محرك الخطط والمقاييس)#

  • القوالب: GET/POST /forms/templates (الخاصة بي)، و GET/PATCH/DELETE /forms/templates/:id (مع حمولة متداخلة للصفحات والأسئلة، ومُدارة بالإصدارات).
  • الإسناد: POST /forms/assignments بحمولة { templateId, patientId|specialCaseId, dueDate? } ← إشعار إلى ولي الأمر.
  • GET /forms/assignments?role=guardian|specialist&status= ← بيانات البطاقات (لم يتم / تم).
  • الإجابة: GET /forms/assignments/:id/response (أو إنشاؤها)، و PUT /forms/responses/:id/answers/:questionId بحمولة { value }حفظ تلقائي بالإدراج أو التحديث طبقاً لـ E01، و POST /forms/responses/:id/submit ← يتحقق من الحقول المطلوبة ← يصبح الإسناد ANSWERED.
  • النتائج: GET /forms/assignments/:id/result (عرض للقراءة فقط للسؤال والإجابة).

وحدة reviews#

  • POST /reviews بحمولة { specialistId, bookingId?, stars, text, kind } (يشترط أن يكون لصاحب التقييم حجز بالحالة DONE مع الأخصائي حين يكون النوع SESSION).
  • GET /specialists/:id/reviews?kind=&period=؛ و PATCH /reviews/:id/like، و PATCH /reviews/:id/reply (للأخصائي)، و POST /reviews/:id/report طبقاً لـ G17.

وحدة payments#

  • GET /payments/mine (سجل مدفوعات ولي الأمر، G01) ← الصفوف مع الإجماليات.
  • POST /bookings/:id/payment بحمولة { method, status } (تسجّله السكرتارية أو الأخصائي؛ ويُنشئ معاملة محفظة من نوع EARNING عند الحالة PAID).
  • GET /wallet (للأخصائي) ← { balanceCents, withdrawnCents }؛ و GET /wallet/transactions.
  • POST /wallet/withdrawals بحمولة { amountCents, method, target } طبقاً لـ G19؛ و GET /wallet/withdrawals.

وحدة centers#

  • GET/PATCH /centers/me (للمالك والمدير)؛ والفروع لها العمليات الكاملة على /centers/me/branches.
  • الموظفون: GET/POST /centers/me/staff (إنشاء مستخدم موظف مع الدور والفرع والراتب)، و PATCH/DELETE /centers/me/staff/:id.
  • مرضى المركز: GET /centers/me/patients (مع تمرير طلبات الملفات الشخصية).

وحدة hr (للمركز)#

  • POST /hr/attendance/clock-in|clock-out (للموظف نفسه، بدور CENTER_SPECIALIST/SECRETARY) — و branchId اختياري طبقاً لـ G20.
  • GET /hr/attendance?staffId?&range (المالك والمدير يريان الجميع؛ والموظف يرى سجلّه هو).
  • عمليات شبه كاملة على /hr/absences، و /hr/overtime، و /hr/penalties (مع deductionCents)، وهي للمالك والمدير فقط.
  • الطلبات: POST /hr/requests (للموظف)، و GET /hr/requests (محدودة بالنطاق)، و PATCH /hr/requests/:id/decision بحمولة { status: APPROVED|REJECTED } (للمالك والمدير) ← إشعار.

وحدة jobs#

  • للمركز: GET/POST /jobs/postings، و PATCH /jobs/postings/:id (مسودة ← منشورة ← مغلقة)، والطلبات: GET /jobs/postings/:id/applications، و PATCH /jobs/applications/:id/decision ← عند الحالة ACCEPTED تُعرض حمولة إنشاء سجل CenterStaff.
  • للأخصائي: GET /jobs/market (المنشورة، مع مرشِّحات، G08)، و POST /jobs/postings/:id/apply، و GET /jobs/applications/mine.

وحدة notifications#

  • GET /notifications?unread=، و PATCH /notifications/:id/read، و PATCH /notifications/read-all.
  • GET /notifications/stream — بتقنية SSE طبقاً لـ E13.
  • خدمة إطلاق الأحداث تستعملها بقية الوحدات؛ وهي تُرسل دائماً عبر القناة IN_APP إضافةً إلى القنوات المفعَّلة والمُوثَّقة (البريد عبر console أو SMTP تطويري؛ وواتساب وتليجرام واجهتان صوريتان تسجّلان الحمولات فقط، D-17).

وحدة files#

  • POST /files رفع متعدد الأجزاء (يتطلب المصادقة) ← StoredFile؛ و GET /files/:id (الصلاحية بحسب الملكية أو الارتباط)؛ مع حدود للحجم والنوع (الصور 5 ميجابايت، والمستندات 10 ميجابايت، والفيديو 100 ميجابايت).

وحدة admin (عبر واجهة API فقط في الإصدار الأول)#

  • GET /admin/activations (الأخصائيون والمراكز المعلَّقون)، و PATCH /admin/activations/:userId بحمولة { approve|reject }.
  • GET /admin/withdrawals، و PATCH /admin/withdrawals/:id بحمولة { TRANSFERRED|REJECTED }.
  • GET /admin/reported-reviews.

الأحداث ← الإشعارات (الحد الأدنى)#

booking.created (← الأخصائي/السكرتارية)، و booking.status_changed (← ولي الأمر)، و assignment.created (← ولي الأمر)، و assignment.answered (← الأخصائي)، و application.decided (← الأخصائي)، و hr.request.decided (← الموظف)، و withdrawal.processed (← الأخصائي)، و activation.decided (← المستخدم).