أمثلة ومراجع

مثال: تطبيق تشغيل مراكز الرعاية النهارية (External)

هذا القسم مثال عملي متكامل يوضّح كيف تبني تطبيقاً External يستهدف مستأجرين من نوع مركز الرعاية النهارية (daycare_center) — النوع الجديد الذي أضافته منصة أوكتا لكيانات التشغيل التعليمي.

لماذا External وليس Embedded؟

مراكز الرعاية النهارية تحتاج عمليات تشغيلية ذات طبيعة خاصة: تسجيل الحضور والمغادرة، إرسال تقارير يومية للأهالي، إدارة قائمة الأشخاص المُصرَّح لهم بالاستلام. هذه بيانات ذات دورة حياة قصيرة (يوميّة) وتحتاج إشعارات فورية، وكثيراً ما يرتبط فيها الشريك بمنصة هاتفية أو قاعدة بيانات مستقلة. لذلك يكون External الخيار المناسب:

السبب التفصيل
بيانات تشغيلية خاصة سجلّات الحضور والتقارير اليومية تعيش في متجر الشريك، ليس في okta-web.
Stack مستقل الشريك قد يستخدم نظام تحقّق هوية بيومتري أو قارئ RFID — لا يُشحن داخل okta-web.
إشعارات فورية للأهالي بوّابات الرسائل الخاصة بالشريك (واتساب، Push، SMS) مُعدَّة مسبقاً على بنيته.
حرية الـ Stack أي لغة/إطار، دون قيود قواعد عزل Embedded.

بيانات الحضور والتقارير اليومية والاستلام لا تُخزَّن في okta-web ولا تُعرَّف كـ scopes للشركاء — هذه بيانات تشغيلية يمتلكها تطبيق الشريك بالكامل. الـ scopes تُستخدم فقط لقراءة بيانات okta-web الضرورية للربط (قائمة الطلاب وأولياء الأمور).

نوع المستأجر daycare_center

أضافت المنصة نوع المستأجر daycare_center (مركز رعاية نهارية) إلى الكتالوج المُشترك canonicalTenantTypes، الذي يُرسَل من okta-web إلى okta-partners عبر الجسر. هذا يعني:

  • النوع يظهر تلقائياً في بوّابة الشركاء دون أي إجراء من جانبك.
  • يمكنك الإعلان عن استهداف daycare_center كنوع مستأجر أساسي لتطبيقك من نموذج الإنشاء.
  • مستأجرو نوع daycare_center يُمكِّنهم تثبيت تطبيقك وتفويض الصلاحيات المطلوبة، تماماً كأي نوع آخر.

لا تحتاج لأي كود إضافي لاستقبال هذا النوع — بمجرد نشر تطبيقك في المتجر، المنصة تعرضه للمستأجرين المؤهَّلين.

النطاقات المطلوبة

تطبيق الرعاية النهارية يحتاج قراءة بيانات الطلاب من okta-web ليربطها بسجلّاته التشغيلية. النطاقات تُختار من picker الصلاحيات في بوّابة الشركاء — الكتالوج مرآةٌ من okta-web ويُزامَن تلقائياً في جدول partner_available_scopes. لا تُدخِل scopes بصيغ ثابتة في كودك؛ ما يظهر في الـ picker هو مصدر الحقيقة.

النطاق السبب
education.students.read قراءة قائمة الأطفال المسجَّلين لدى كل مستأجر وبياناتهم الأساسية لمطابقتها مع سجلّات الحضور.
education.students.write اختياري — لو أراد التطبيق تحديث حقل مخصَّص على ملف الطالب (مثل رقم بطاقة RFID). اطلبه فقط إن احتجته فعلاً؛ اقرأ مبدأ الأقل صلاحيةً.

قاعدة الأقل صلاحية: اطلب education.students.read فقط في المرحلة الأولى. لو قرّرت لاحقاً الكتابة، أضف education.students.write في إصدار جديد مع تبرير واضح في الـ manifest.

لا يوجد scope خاص بالحضور أو التقارير اليومية لأن هذه البيانات تعيش في متجر تطبيقك، ليس في okta-web.

الـ Manifest

{
  "moduleId": "daycare-ops",
  "displayName": "Daycare Operations",
  "version": "1.0.0",
  "category": "operations",
  "integrationType": "external",
  "description": "Attendance check-in/out, daily guardian reports, and authorized pickup management for daycare centers.",
  "scopes": [
    {
      "key": "education.students.read",
      "required": true,
      "reason": "لمطابقة أطفال المستأجر مع سجلّات الحضور والاستلام"
    }
  ],
  "external": {
    "webhookUrl":    "https://daycare.example/okta/webhook",
    "webhookEvents": [
      "education.students.created",
      "education.students.updated",
      "partner.installation.token_rotated"
    ],
    "redirectUrls":  ["https://daycare.example/oauth/callback"]
  }
}

redirectUrls مفيد إن أردت تدفّق OAuth-style لمزامنة أولية بعد تثبيت المستأجر: توجّهه لـ /oauth/callback، تحصل على installation token، تُجري مزامنة أوّلية للطلاب.

المزامنة عبر Webhooks

بعد التثبيت تستلم الأحداث المشتركة فيها تلقائياً. يجب التحقّق من التوقيع لكل webhook (انظر قسم الـ Webhooks):

// مثال: معالجة حدث تغيير بيانات طالب
$event = $request->json('event'); // "education.students.updated"
$data  = $request->json('data.student');

match ($event) {
    'education.students.created' => $this->syncNewStudent($data),
    'education.students.updated' => $this->updateStudentRecord($data),
    'partner.installation.token_rotated' => $this->storeNewToken(
        $request->json('data.new_token')
    ),
    default => null,
};

return response()->json(['ok' => true]);

ردّك يجب أن يكون 2xx خلال 10 ثوانٍ. لو احتجت معالجة أطول، ردّ بـ 202 فوراً وعالج عبر queue.

الأحداث الموصى بها لتطبيق مراكز الرعاية:

الحدث متى يصلك
education.students.created طفل جديد يُضاف للمستأجر
education.students.updated تغيير في بيانات الطالب (اسم، جهة اتصال، ...)
partner.installation.token_rotated المستأجر دوَّر الـ token — احفظ الجديد فوراً

أسماء الأحداث بصيغة <feature>.<resource>.<action> المعيارية؛ لا تخترع أسماء جديدة.

المزامنة الأولية بعد التثبيت

عند أول تثبيت، اجلب قائمة الطلاب كاملةً بـ pagination لبناء قاعدة بياناتك المحلية:

# الصفحة الأولى
GET /api/apps/education/students?page=1&per_page=100
Authorization: Bearer <installation_token>

# كرّر حتى last_page

بعد المزامنة الأولية تعتمد على الـ Webhooks للتغييرات التدريجية — هذا يُقلّل استدعاءات الـ API ويُبقيك محدَّثاً لحظياً.

إشعارات الأهالي

تطبيق الرعاية النهارية يُرسِل إشعارات خاصة به (وصول الطفل، مغادرته، تقرير اليوم) عبر قنواته المستقلة (واتساب/SMS/Push). هذه ليست جزءاً من نظام إشعارات أوكتا، بل بنية الشريك الخاصة.

إن أردت توحيد الإشعارات مع منصة أوكتا مستقبلاً (ليختار المستأجر القنوات من لوحته)، يمكنك إضافة كتالوج إشعارات لتطبيقك — راجع قسم كتالوج الإشعارات.

خلاصة الخطوات

  1. أنشئ تطبيقاً External من البوّابة، اختر daycare_center كنوع مستأجر مستهدف.
  2. اطلب education.students.read من picker النطاقات (و write إن احتجت).
  3. اشترك في education.students.created، education.students.updated، partner.installation.token_rotated.
  4. أضف redirect_urls لو أردت تدفّق OAuth-style للمزامنة الأولية.
  5. عند التثبيت: اجلب الطلاب كاملاً، ثم اعتمد على Webhooks للتغييرات.
  6. أرسل للمراجعة — فريق أوكتا يتحقق من الـ manifest و webhook URL ثم ينشره في المتجر.

عرض الدليل كاملاً في صفحة واحدة · ↧ Markdown خام