تخطَّ إلى المحتوى

مواصفة واجهة برمجة التطبيقات

المرجع الكامل لنقاط نهاية REST. للدروس والأمثلة، انظر دليل واجهة برمجة التطبيقات.

كل ما يستطيع عضو المشروع فعله في واجهة الويب متاح هنا — فتطبيقة الصفحة الواحدة (SPA) تستهلك واجهة برمجة التطبيقات نفسها. العمليات التي تتطلّب دور المالك مُعلَّمة بـ (owner)؛ وكل ما عداها يحتاج عضوية المشروع فقط (أو، للقراءات المُعلَّمة بـ (viewer)، أي مستوى وصول).

https://eastagiletracker.com/api/v1

يقدّم https://api.eastagiletracker.com/api/v1 واجهة برمجة التطبيقات نفسها. كل الطلبات والاستجابات بصيغة JSON، باستثناء بضع نقاط نهاية لرفع الملفات تقبل multipart.

يُرسِل كل طلب مصادَق عليه مفتاح API عبر أحد:

  • X-TrackerToken: <key>
  • Authorization: Bearer <key>

تبدأ مفاتيح المستخدم بـ ea_user_. وتبدأ مفاتيح الوكلاء بـ ea_agent_. انظر دليل واجهة برمجة التطبيقات ← نوعان من المفاتيح.

نقاط النهاية غير المصادَق عليها: /openapi.json، و/docs، ونقاط نهاية /auth/*، وعمليات البحث في البيانات المرجعية (/story_types، و/story_states، و/effort_scales، …). أما /meta فهي مصادَق عليها — أي مفتاح صالح يعمل، لكنها غير محصورة بالمشروع (يصل إليها أيضًا مفتاح وكيل مرتبط بمشروع).

ثلاثة مستويات تتحكّم في نقاط النهاية المحصورة بالمشروع:

المستوىمن يجتازالعمليات النموذجية
viewerviewer، member، ownerالقراءات (سرد/جلب القصص، والبحث، والتحليلات)
membermember، ownerكل كتابات عناصر العمل (القصص، والمهام، والتعليقات، …)
ownerowner فقطإعدادات المشروع، وإدارة العضوية، ومفاتيح الوكلاء، والحذف، والاستيراد، وسجل التدقيق

يتلقّى غير العضو 404 unfound_resource (لا 403) على مسارات المشروع، فلا تكون معرّفات المشاريع قابلة للتعداد.

نقاط النهاية ذاتية الوصف

Section titled “نقاط النهاية ذاتية الوصف”
الطريقةالمسارالوصف
GET/openapi.jsonمواصفة OpenAPI 3 الحيّة. غير مصادَق عليها.
GET/docsواجهة Swagger UI. غير مصادَق عليها.
GET/metaهوية المستدعي (auth.kind/key_id/agent_id/project_id) + رسم انتقالات حالات نوع القصة. مصادَق عليها (أي مفتاح صالح؛ غير محصورة بالمشروع). استدعِها أولًا.

تتصرّف هذه على المستدعي وتحتاج مفتاحًا صالحًا فقط (بلا دور مشروع).

الطريقةالمسارالوصف
POST/auth/registerتسجيل حساب جديد
POST/auth/loginتسجيل الدخول، يُعيد رمز جلسة
POST/auth/logoutتسجيل الخروج
POST/auth/forgot-passwordطلب بريد إعادة تعيين كلمة المرور
POST/auth/reset-passwordاستخدام رمز إعادة تعيين لضبط كلمة مرور جديدة
GET/auth/verify-emailتوثيق عنوان بريد إلكتروني
POST/auth/accept-invite/lookupتحويل رمز دعوة ← بريد إلكتروني (غير مصادَق عليها)
POST/auth/accept-inviteقبول دعوة مشروع (بعد المصادقة)
GET/meالملف الشخصي للمستخدم الحالي
PUT/meتحديث الملف الشخصي
DELETE/meحذف الحساب
PUT/me/passwordتغيير كلمة المرور
PUT/me/settingsتحديث الإعدادات (السمة، وتفضيلات الإشعارات)
POST/me/avatarرفع صورة رمزية (multipart)
POST/me/api-token/regenerateتدوير رمز API الخاص بك — يُبطِل الجلسات/المفاتيح القائمة
GET/me/api_keys · POST /me/api_keys · DELETE /me/api_keys/{id}إدارة مفاتيح API للمستخدم (ea_user_)
GET/me/activityنشاطك عبر كل المشاريع
GET/me/data-exportتصدير ذاتي لبياناتك بموجب اللائحة العامة لحماية البيانات (GDPR)
GET/me/consent · POST /me/consentقراءة / تسجيل الموافقة ({ consent_type, granted })
GET/legal/pending · POST /legal/acceptمستندات الموافقة بالنقر المعلّقة / تسجيل القبول
POST/contact · POST /feedback · POST /feedback/with-screenshotاتصال + تغذية راجعة داخل التطبيق

البيانات المرجعية (غير مصادَق عليها)

Section titled “البيانات المرجعية (غير مصادَق عليها)”

عمليات بحث بذرية تُستخدَم عند إنشاء/تقدير القصص. معرّفات مستقرة.

الطريقةالمسارالوصف
GET/story_typesfeature، bug، chore، release (+ allow_points)
GET/story_statesunstarted … accepted، rejected
GET/effort_scalesمقاييس التقدير المتاحة
GET/effort_scales/{scale_id}/valuesقيم النقاط في مقياس
الطريقةالمسارالوصف
GET/projectsسرد مشاريعك
POST/projectsإنشاء مشروع
GET/projects/{id}جلب تفاصيل المشروع (viewer)
PUT/projects/{id}تحديث إعدادات المشروع (owner)
DELETE/projects/{id}حذف مشروع (owner)
GET/projects/{id}/audit-logتدفق نشاط المشروع (owner)
GET/projects/{id}/eventsتدفق أحداث مقسَّم صفحاتٍ بمؤشّر (viewer) — انظر الأحداث

الأعضاء ومفاتيح الوكلاء

Section titled “الأعضاء ومفاتيح الوكلاء”
الطريقةالمسارالوصف
GET/projects/{id}/membershipsسرد الأعضاء (viewer)
POST/projects/{id}/membershipsدعوة عضو عبر البريد الإلكتروني (owner)
PUT/projects/{id}/memberships/{mid}تحديث الدور (owner)
DELETE/projects/{id}/memberships/{mid}إزالة عضو (owner)
GET / POST/projects/{id}/agent_keysسرد / إصدار مفاتيح الوكلاء (owner)
DELETE/projects/{id}/agent_keys/{kid}إلغاء مفتاح وكيل (owner)

كل كتابات القصص تحتاج دور member.

الطريقةالمسارالوصف
GET/projects/{id}/storiesسرد القصص (مقسَّم صفحات، قابل للتصفية) (viewer)
POST/projects/{id}/storiesإنشاء قصة
GET/projects/{id}/stories/{sid}جلب قصة واحدة (viewer)
PUT/projects/{id}/stories/{sid}تحديث قصة
DELETE/projects/{id}/stories/{sid}حذف قصة
POST/projects/{id}/stories/{sid}/transitionsتغيير الحالة مع التحقّق
POST/projects/{id}/stories/bulk_transitionنقل قصص كثيرة (1–100) دفعةً واحدة
POST/projects/{id}/stories/bulk-deleteحذف قصص كثيرة
POST/projects/{id}/stories/bulk-duplicateتكرار قصص كثيرة
POST/projects/{id}/stories/{sid}/duplicateتكرار قصة واحدة

الإنشاء (POST …/stories): { "name" (required), "story_type": "feature|bug|chore|release", "description"?, "estimate"?, "current_state"?, "icebox"?, "labels"? }. يقبل labels صيغة ["auth"] أو [{ "name": "auth" }]؛ وتُنشأ التسميات غير المعروفة. القيم الافتراضية: story_type=feature، وcurrent_state=unstarted.

التحديث (PUT …/stories/{sid}): الحقول نفسها، كلها اختيارية، إضافةً إلى "position" (float) و"force_state_change" (bool).

الانتقال (POST …/transitions): { "to": "<state>", "reason"? }. الحقل هو to. يُعيد { story_id, state }. الحركة غير القانونية ← 422 invalid_transition مع details: { from, to, allowed }.

الانتقال الجماعي (POST …/bulk_transition): { "story_ids": [int,…] (1–100), "to": "<state>", "reason"? }. تُحكَم كل قصة على نحوٍ مستقل؛ يُعيد { results: [ { id, status: "ok" } | { id, status: "failed", error } ] }.

كلها member. السرد/الجلب على معظمها (viewer).

الطريقةالمسارالجسم / ملاحظات
GET / POST/projects/{id}/stories/{sid}/tasks · PUT/DELETE …/tasks/{tid}{ description (or task_desc), complete?, task_order? }
GET / POST/projects/{id}/stories/{sid}/comments · PUT/DELETE …/comments/{cid}{ text (or comment_text) } أو { comment_emoji }
GET / POST/projects/{id}/stories/{sid}/blockers · PUT/DELETE …/blockers/{bid}{ blocker_desc, resolved? }
GET / POST/projects/{id}/stories/{sid}/links · DELETE …/links/{lid}{ url, link_type?, title? }
GET / POST/projects/{id}/stories/{sid}/reviews · PUT/DELETE …/reviews/{rid}{ reviewer_id? / reviewer_agent_id?, status, comment? }
GET / POST/projects/{id}/stories/{sid}/owners · DELETE …/owners/{mid} · DELETE …/owners/agents/{aid}{ member_id? / agent_id? } — احذف كليهما لإضافة المستدعي
GET / POST/projects/{id}/stories/{sid}/followers · DELETE …/followers/{mid} · DELETE …/followers/agents/{aid}{ member_id? / agent_id? }
GET / POST/projects/{id}/stories/{sid}/labels · DELETE …/labels/{lid}{ name }
GET / POST/projects/{id}/stories/{sid}/attachments (+ /json) · DELETE …/attachments/{aid}رفع multipart (≤ 2 غيغابايت لكل ملف)؛ السرد (viewer)

member للكتابات، و(viewer) للقراءات.

الطريقةالمسارالوصف
GET / POST/projects/{id}/labelsسرد / إنشاء تسمية
PUT / DELETE/projects/{id}/labels/{lid}تحديث / حذف تسمية
POST/projects/{id}/labels/{lid}/archiveأرشفة (إخفاء ناعم) تسمية
الطريقةالمسارالوصف
GET/projects/{id}/iterationsسرد التكرارات (member)
POST/projects/{id}/iterationsإنشاء تكرار يدوي (owner)
DELETE/projects/{id}/iterations/{itid}حذف تكرار (owner)

البحث، والتحليلات، والمقاييس، والتفضيلات

Section titled “البحث، والتحليلات، والمقاييس، والتفضيلات”
الطريقةالمسارالوصف
GET/projects/{id}/search?query=…بحث بصيغة التصفية (viewer) — انظر الدليل
GET/projects/{id}/analytics/{overview,iteration,releases,activity,cycle-time,projections}تحليلات (viewer). يأخذ تعمّق التكرار ?iteration_id=
GET/projects/{id}/metrics/{velocity,burndown,story-types}مقاييس (viewer)
GET / PUT/projects/{id}/preferencesتفضيلات لوحتك لهذا المشروع (member)
الطريقةالمسارالوصف
GET/projects/{id}/eventsتدفق أحداث مقسَّم صفحاتٍ بمؤشّر (viewer)

معاملات الاستعلام: since=<event_id>، وtypes=story.created,story.transitioned,comment.created,…، وlimit=، وcursor=. تتضمّن الاستجابة next_cursor. مرّر آخر event_id رأيته كـ since لاستئناف.

الطريقةالمسارالوصف
POST/projects/{id}/import (+ /json)رفع multipart. source=pivotal، وjira، وasana، وgitlab، وshortcut، وtrello، وlinear، وplane، وplane_json.
wss://eastagiletracker.com/ws/control?token=<key>

للتحكّم التفاعلي عن بُعد بالواجهة ({ "action": "get_state", "id": "req-1" }). ليست قناة بيانات — كل القراءات/الكتابات تمرّ عبر REST. أحادية النسخة فقط؛ لا تُبثّ عبر النسخ المتعددة.

تقبل نقاط نهاية الكتابة (POST، وPUT، وDELETE) ترويسة Idempotency-Key. المفتاح نفسه + الجسم نفسه يعيد تشغيل الاستجابة المخزّنة مؤقتًا (نافذة 24 ساعة)؛ والمفتاح نفسه + جسم مختلف يُعيد 409 idempotency_conflict. لا تُطبَّق على GET/HEAD/OPTIONS، أو /auth/*، أو مسارات /attachments. لا تُخزَّن استجابات 5xx أبدًا — تصل إعادة المحاولة إلى المعالِج.

تقبل نقاط نهاية السرد cursor=<opaque> وlimit=<n≤200>. وعند ضبطهما، تكون الاستجابة { "items": [...], "next_cursor": "<str|null>" }؛ مرّر next_cursor لتصفّح الصفحات. وتُعيد بعض القوائم أيضًا ترويسة X-Tracker-Pagination-Total.

تقبل نقاط نهاية السرد fields= (مفصولة بفواصل) لإعادة حقول محددة فقط. يُضمَّن story_id دائمًا؛ ويُعيد اسم حقل غير معروف 400 validation_failed مع الأسماء المخالِفة في details.fields.

GET /projects/123/stories?fields=story_id,name,current_state,owners

لكل خطأ بصيغة JSON code وerror؛ ويضيف بعضها details:

{ "code": "invalid_transition",
"error": "Cannot move story from `unstarted` to `accepted`",
"details": { "from": "unstarted", "to": "accepted", "allowed": ["started"] } }
الحالةcodeمتى
400invalid_parameterإدخال سيّئ؛ الرسالة في error، بلا details (معظم التحقّق: فراغ/طول/بايت صفري/بريد إلكتروني)
400validation_failedخطأ إدخال مهيكَل؛ details.fields هو مصفوفة بأسماء الحقول المخالِفة
401unauthenticatedرمز مفقود/غير صالح
403unauthorized_operationمصادَق عليه لكن الدور غير كافٍ
404unfound_resourceغير موجود — يُعاد أيضًا لغير الأعضاء
409conflictتعارض في المورد (مثل التكرار)
409idempotency_conflictأُعيد استخدام Idempotency-Key بجسم مختلف
422invalid_transitionحركة حالة غير قانونية؛ يحمل details الحقول { from, to, allowed }
500internal_errorعطل في الخادم — رسالة عامة؛ آمن لإعادة المحاولة

details.fields هو مصفوفة JSON بأسماء الحقول (مثل ["to"])، أحيانًا مع مفاتيح إضافية مثل max. لا توجد خريطة حقل←رسالة.

{ "code": "validation_failed", "error": "unknown field(s): foo", "details": { "fields": ["foo"] } }

لكل مفتاح (لكل IP لنقاط النهاية غير المصادَق عليها)، دلو رموز GCRA:

  • المصادقة/auth/*: 0.5 طلب/ث، بدفعة 20.
  • العامة/contact، و/feedback: 0.2 طلب/ث، بدفعة 10.
  • الحساسة — إعادة تعيين كلمة المرور: نحو 0.002 طلب/ث، بدفعة 5.

تجاوز الحدّ يُعيد 429 Too Many Requests مع ترويسة Retry-After وجسم نصّي صِرف (لا غلاف خطأ JSON).