الوظائف هي مقاعد الهيكل التنظيمي في مساحة عملك: تقع كل وظيفة في وحدة تنظيمية، وتتبع وصفاً وظيفياً، ولها سعة (عدد الأشخاص الذين تستوعبهم). استخدم هذه النقاط لمزامنة الوظائف في جديرون مع نظام تخطيط الموارد (ERP) أو نظام الموارد البشرية لديك.
جميع النقاط تحت /api/v1 وتتطلب مفتاح واجهة برمجية (Authorization: Bearer jdr_live_…) ينشئه مسؤول مساحة العمل من الإعدادات ← التكاملات.
النقاط
| الطريقة والمسار | ما تفعله | الصلاحية |
|---|---|---|
GET /api/v1/positions | عرض الوظائف (ترقيم بالمؤشر، وupdatedSince، والبحث بالمعرّف الخارجي) | structure.org.view |
POST /api/v1/positions | إنشاء وظيفة | structure.org.act |
GET /api/v1/positions/{id} | عرض وظيفة واحدة | structure.org.view |
PATCH /api/v1/positions/{id} | تعديل وظيفة؛ الحقول غير المرسلة تبقى كما هي | structure.org.act |
DELETE /api/v1/positions/{id} | حذف وظيفة ليس فيها موظفون ولا سجل توظيف | structure.org.act |
POST /api/v1/positions/{id}/archive | أرشفة وظيفة | structure.org.act (ومعها recruitment.hiring.open إذا كان للوظيفة شاغر مفتوح) |
PUT /api/v1/positions/by-external/{system}/{externalId} | إنشاء أو تعديل بمعرّف نظامك | structure.org.act |
POST /api/v1/positions/bulk | إدراج أو تعديل حتى 1,000 وظيفة بالمعرّف الخارجي في الخلفية (انظر الإدراج المجمّع) | structure.org.act |
صلاحية structure.org.act تشمل structure.org.view. وتحديد الأجر أو تغييره (payScale وpayGrade وpayStepNumber) يتطلب أيضاً structure.functional.salary؛ وبدونها يُعاد 403 forbidden. وقراءة الأجر تتطلبها كذلك: بدون structure.functional.salary تكون حقول الأجر (payScaleId وpayGradeId وpayStepNumber وbaseSalary وpayPeriod) بالقيمة null في كل استجابة (القوائم والقراءة المفردة واستجابات عمليات الكتابة) وفي حمولات خطافات الويب.
كائن الوظيفة
| الحقل | النوع | ملاحظات |
|---|---|---|
id | نص | معرّف جديرون. يختلف المعرّف بين بيئات جديرون؛ اربط سجلاتك عبر externalRefs. |
title | { ar, en } | مسمّى الوظيفة الخاص. إذا كان فارغاً يعرض التطبيق اسم الوصف الوظيفي. |
jobDescriptionId | نص أو null | الوصف الوظيفي الذي تتبعه الوظيفة. يكون null فقط إذا حُذف ذلك الوصف. |
orgUnitId | نص أو null | الوحدة التنظيمية التي تقع فيها؛ null إذا كانت بلا وحدة. |
capacity | عدد صحيح | عدد المقاعد (1 أو أكثر). |
measurementMode | نص | SPECIALIZED (متخصص) أو ROUTINE (روتيني) لقياس عبء العمل، للقراءة فقط. |
hiringStatus | نص | OPEN أو CLOSED. للقراءة فقط: يتغيّر عند فتح التوظيف أو إغلاقه. |
hiringPathway | نص أو null | INTERNAL_ONLY أو INTERNAL_FIRST أو EXTERNAL أثناء فتح التوظيف. للقراءة فقط. |
hiringOpenedAt، externalAt | ISO 8601 أو null | وقت فتح التوظيف ووقت ظهور الإعلان خارجياً. للقراءة فقط. |
posting | { ar, en } | نص الإعلان العام، للقراءة فقط. |
payScaleId، payGradeId | نص أو null | سلم الرواتب والمرتبة إن وُجدا. تكون null بدون structure.functional.salary، وكذلك حقول الأجر الثلاثة التالية. |
payStepNumber | عدد صحيح أو null | الدرجة ضمن المرتبة؛ null يعرض نطاق المرتبة كاملاً. |
baseSalary | عدد صحيح أو null | الراتب الأساسي عند تلك الدرجة بوحدة payPeriod (ريال سعودي). للقراءة فقط، محسوب. |
payPeriod | نص أو null | MONTHLY (شهري) أو ANNUAL (سنوي)، من سلم الرواتب. |
archivedAt | ISO 8601 أو null | يُضبط عند أرشفة الوظيفة. |
externalRefs | مصفوفة | [{ system, externalId }] روابط بأنظمتك. |
createdAt، updatedAt | ISO 8601 | يتغيّر updatedAt أيضاً عند تعديل الوظيفة من داخل التطبيق، أو عند حذف وحدتها التنظيمية أو وصفها الوظيفي. |
الإنشاء والتعديل
يقبل POST الحقل jobDescription، واختيارياً title وorgUnit وcapacity وpayScale وpayGrade وpayStepNumber. تُرفض الحقول غير المعروفة بـ 422 validation_failed، وكذلك حقول التوظيف المخصصة للقراءة (hiringStatus وhiringPathway وexternalAt): فهي تتغيّر عند فتح شاغر أو إغلاقه.
تحدّد الحقول jobDescription وorgUnit وpayScale السجل بمعرّف جديرون أو بمعرّف نظامك، أما payGrade فيقبل معرّف جديرون:
{
"jobDescription": { "externalSystem": "oracle-hcm", "externalId": "JOB-12" },
"orgUnit": { "id": "cmv…" },
"payScale": { "id": "cmv…" },
"payGrade": { "id": "cmv…" },
"payStepNumber": 3
}
لتشير إلى وصف وظيفي بمعرّفك، اربطه أولاً عبر externalRef عند إنشائه أو تعديله (انظر الأوصاف الوظيفية). يجب أن يكون الوصف الوظيفي من الأوصاف الخاصة بمساحة عملك، وأن تتبع الوحدة التنظيمية وسلم الرواتب مساحة عملك؛ وإلا يُعاد 422 unresolved_reference. ويجب أن تتبع المرتبة السلم وأن تقع الدرجة ضمن درجات المرتبة (422 validation_failed مع details.reason بقيمة invalid_pay_grade أو invalid_pay_step). وتُرفض بالطريقة نفسها مرتبةٌ أو درجةٌ تُرسل دون سلم رواتب (لا في الطلب ولا على الوظيفة، أو مع payScale: null).
لا يمكن اختيار وصف وظيفي مؤرشف لوظيفة جديدة أو وصفاً جديداً لوظيفة قائمة: يُعاد 422 validation_failed مع details.reason بقيمة archived. أما الوظيفة المرتبطة أصلاً بوصف مؤرشف فتحتفظ به.
في PATCH، القيمة orgUnit: null تجعل الوظيفة بلا وحدة، وpayScale: null تزيل ربط الأجر كاملاً. تغيير السلم يتطلب مرتبة من السلم الجديد، وتغيير المرتبة يمسح الدرجة ما لم ترسل درجة. وخفض capacity إلى أقل من عدد الموظفين في الوظيفة يُعيد 409 conflict مع details.reason بقيمة capacity_below_filled وdetails.filled.
الإنشاء أو التعديل بالمعرّف الخارجي
يبحث الطلب PUT /api/v1/positions/by-external/oracle-hcm/POS-310 عن الوظيفة المرتبطة بـ oracle-hcm / POS-310:
- إذا وُجدت وظيفة مرتبطة: يُطبَّق الطلب مثل
PATCHويكون الرد200. - إذا لم تُوجد: تُنشأ وظيفة من الطلب (أرسل على الأقل
jobDescription) وتُربط بالمعرّف الخارجي، ويكون الرد201.
إذا حُذفت الوظيفة المرتبطة من داخل التطبيق، يُزال الربط القديم وينشئ الطلب وظيفة جديدة بربط جديد. للعثور على وظيفة بمعرّفك دون تعديلها استخدم GET /api/v1/positions?externalSystem=oracle-hcm&externalId=POS-310 (أرسل المعاملين معاً).
الأرشفة والحذف
يغلق POST /api/v1/positions/{id}/archive التوظيف على الوظيفة وشواغرها المفتوحة، ويضبط archivedAt. أرشفة وظيفة مؤرشفة لا تغيّر شيئاً وتُعيدها كما هي.
إغلاق شاغر مفتوح يتطلب recruitment.hiring.open كما في التطبيق. إذا كان للوظيفة شاغر مفتوح ولا يملك مفتاحك هذه الصلاحية، يُعاد 403 forbidden مع details.reason بقيمة hiring_permission_required وdetails.permission بقيمة recruitment.hiring.open، ولا يتغيّر شيء. أما الوظيفة التي ليس لها شاغر مفتوح فتُؤرشف بـstructure.org.act وحدها.
يُتحقق من DELETE قبل حذف أي شيء:
409 has_people(معdetails.assigned) إذا كان في الوظيفة موظفون.409 has_openings(معdetails.pipelinesوdetails.rubrics) إذا كان للوظيفة شاغر أو نموذج تقييم مقابلات في أي وقت. أرشفها بدلاً من حذفها.
عند حذف وظيفة تُحذف معها مهام عبء العمل الخاصة بها، وتُزال روابطها الخارجية، ويظهر الحذف في GET /api/v1/deleted?resource=position لمدة 180 يوماً. والموظفون السابقون الذين كانت قيمة currentPositionId لهم هذه الوظيفة تصبح لديهم currentPositionId: null، ويتغيّر updatedAt لهم، ويُرسل لكل منهم employee.updated (changedFields: ["currentPositionId"])، أو حدث واحد employee.bulk_changed إذا تجاوز عددهم 50.
قد تُحذف الوظائف أيضاً من داخل التطبيق عبر محرر البيانات. يظهر هذا الحذف في GET /api/v1/deleted?resource=position بالطريقة نفسها؛ وحفظ محرر البيانات يرسل حدثاً واحداً position.bulk_changed بدلاً من position.deleted لكل وظيفة، فاقرأ سجل المحذوفات بعده. وعند حذف وصف وظيفي من التطبيق (مثلاً بإلغاء اختيار قطاعه الفرعي) تبقى وظائفه مع jobDescriptionId: null ويتغيّر updatedAt لها.
أحداث خطافات الويب
| الحدث | متى | data.object |
|---|---|---|
position.created | إنشاء وظيفة أو نسخها (من التطبيق أو الواجهة البرمجية)، ومنها الوظيفة التي تُنشأ وتُفتح في خطوة واحدة من مسار الشواغر، والوظيفة المنسوخة عند نسخ مجموعة وظيفية مع وظائفها، والوظيفة المسودة التي تُنشأ بتطبيق توصية نقص في الأعداد من خطة القوى العاملة | الوظيفة |
position.updated | تعديل وظيفة، ومنه تغيّر حقول التوظيف عند فتح شاغر أو إغلاقه أو فتحه للخارج، وتغيّر payStepNumber وbaseSalary عندما يعيد تعديلُ مرتبة رواتبها تسعيرها؛ يسرد data.changedFields الحقول عند توفرها. وبدون structure.functional.salary تُستبعد حقول الأجر من changedFields، ولا يُرسل التعديل الذي لم يغيّر إلا الأجر | الوظيفة |
position.archived | أرشفة وظيفة | الوظيفة |
position.deleted | حذف وظيفة | { id, externalRefs } |
position.bulk_changed | استيراد وظائف من التطبيق، أو تغيّر عدد كبير منها دفعة واحدة | { resource: "position" } |
حذف وحدة تنظيمية يرسل position.updated لكل وظيفة تصبح بلا وحدة. بعد position.bulk_changed أعد قراءة القائمة مع updatedSince بقيمة occurredAt للحدث، واقرأ GET /api/v1/deleted?resource=position&since=… لمعرفة الوظائف المحذوفة.
الأخطاء
| الحالة والرمز | المعنى |
|---|---|
403 forbidden | لا يملك المفتاح الصلاحية المذكورة في الجدول أعلاه، أو أُرسلت حقول الأجر دون structure.functional.salary. |
404 not_found | لا توجد وظيفة بهذا المعرّف في مساحة عملك. |
409 has_people | في الوظيفة موظفون. |
409 has_openings | للوظيفة شاغر أو نموذج تقييم مقابلات. |
409 conflict | المعرّف الخارجي مرتبط بوظيفة أخرى، أو capacity أقل من عدد الموظفين فيها. |
422 validation_failed | الطلب غير صالح، أو أُرسل حقل للقراءة فقط؛ يوضح details السبب. |
422 unresolved_reference | تعذّر العثور على jobDescription أو orgUnit أو payScale في مساحة عملك. |
مثال
curl -X PUT https://jadiroon.com/api/v1/positions/by-external/oracle-hcm/POS-310 \
-H "Authorization: Bearer $JADIROON_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": { "ar": "أخصائي موارد بشرية", "en": "HR Specialist" },
"jobDescription": { "externalSystem": "oracle-hcm", "externalId": "JOB-12" },
"orgUnit": { "externalSystem": "oracle-hcm", "externalId": "ORG-200" },
"capacity": 2
}'
ينشئ الطلب الأول الوظيفة ويربطها ويرد بـ 201 Created، وتكراره يعدّل الوظيفة نفسها ويرد بـ 200 OK بالشكل نفسه:
{
"id": "cmvk1q2w30004kn8x7d1f0abc",
"title": { "ar": "أخصائي موارد بشرية", "en": "HR Specialist" },
"jobDescriptionId": "cmvjx0h1t0001kn3o9c2a7def",
"orgUnitId": "cmvjmf15k0008kn4q404rqwgw",
"capacity": 2,
"measurementMode": "SPECIALIZED",
"hiringStatus": "CLOSED",
"hiringPathway": null,
"hiringOpenedAt": null,
"externalAt": null,
"posting": { "ar": null, "en": null },
"payScaleId": null,
"payGradeId": null,
"payStepNumber": null,
"baseSalary": null,
"payPeriod": null,
"archivedAt": null,
"externalRefs": [{ "system": "oracle-hcm", "externalId": "POS-310" }],
"createdAt": "2026-10-22T15:02:11.204Z",
"updatedAt": "2026-10-22T15:02:11.204Z"
}