تعلّم كيفية تصميم وبناء تطبيق ويب يتتبع الالتزام باتفاقية مستوى الخدمة: تعريف المقاييس، جمع الأحداث، حساب النتائج، تنبيه عند الانتهاكات، وإصدار تقارير قابلة للتدقيق.

الالتزام باتفاقية مستوى الخدمة يعني الوفاء بالوعود القابلة للقياس في اتفاقية مستوى الخدمة (SLA) — عقد بين المزود والعميل. مهمة تطبيقك هي الإجابة عن سؤال بسيط مع أدلة: هل لبّينا ما وعدنا به، لهذا العميل، خلال هذه الفترة؟
من المفيد فصل ثلاثة مصطلحات مرتبطة:
تبدأ معظم تطبيقات تتبع SLA بمجموعة صغيرة من المقاييس التي ترتبط ببيانات تشغيلية حقيقية:
مستخدمون مختلفون يريدون نفس الحقيقة، لكن معروضًا بطرق مختلفة:
هذا المنتج يتعلق بـالتتبع، الإثبات، والتقارير: جمع الإشارات، تطبيق القواعد المتفق عليها، وإنتاج نتائج صالحة للتدقيق. لا يضمن الأداء؛ بل يقيسه — بدقة وباتساق وبشكل يمكنك الدفاع عنه لاحقًا.
قبل تصميم الجداول أو كتابة الكود، كن دقيقًا جدًا بشأن معنى "الامتثال" بالنسبة لعملك. معظم مشاكل تتبع SLA ليست تقنية — بل مشاكل متعلقة بالمتطلبات.
ابدأ بجمع مصادر الحقيقة:
اكتب هذه القواعد بشكل صريح. إن لم يمكن صياغة قاعدة بوضوح، فلا يمكن حسابها بشكل موثوق.
أدرج "الأشياء" الواقعية التي قد تؤثر في رقم SLA:
وحدّد من يحتاج ماذا: الدعم يريد تحذيرًا في الوقت الحقيقي، المدراء يريدون ملخصات أسبوعية، والعملاء يريدون ملخصات بسيطة (وغالبًا صفحة حالة).
حافظ على نطاق صغير. اختَر الحد الأدنى الذي يثبت أن النظام يعمل من طرف إلى طرف، مثل:
أنشئ صفحة واحدة للاختبار لاحقًا:
النجاح يعني: شخصان يحسبان نفس الشهر يدويًا والنظام يُطابق النتيجة بالضبط.
متعقب SLA الصحيح يبدأ بنموذج بيانات يشرح لماذا الرقم هو ما هو عليه. إذا لم تستطع تتبع رقم التوافر الشهري وصولًا للأحداث والقواعد المستخدمة، ستواجه نزاعات مع العملاء وغموضًا داخليًا.
على الأقل، مثّل:
علاقة مفيدة: customer → service → SLA policy (قد تمر عبر plan). الحوادث والأحداث تشير للخدمة والعميل.
أخطاء الوقت هي السبب الأول لحسابات SLA الخاطئة. خزّن:
occurred_at كـ UTC (طابع زمني مع دلالات المنطقة)received_at (عندما رصدها نظامك)source (اسم المراقبة، التكامل، يدوي)external_id (لمنع الازدواجية عند المحاولات المتكررة)payload (JSON خام للتصحيح المستقبلي)خزّن أيضًا customer.timezone (سلسلة IANA مثل America/New_York) للعرض ومنطق ساعات العمل، لكن لا تُعدّل وقت الحدث باستخدامه.
إن كانت SLA زمن الاستجابة تتوقف خارج ساعات العمل، مثلّ التقويمات صراحةً:
working_hours لكل عميل (أو لكل منطقة/خدمة): يوم الأسبوع + وقت البداية/النهايةholiday_calendar مرتبط بالمنطقة أو العميل، بنطاقات تاريخية وتسمياتاجعل قواعد التحديث قابلة للبيانات حتى يمكن لفرق العمليات تعديل عطلة دون نشر نسخة جديدة.
خزن الأحداث الخام في جدول قابل للإلحاق فقط، وخزن النتائج المحسوبة منفصلةً (مثال: sla_period_result). يجب أن يتضمن كل صف نتيجة: حدود الفترة، إصدار المدخلات (نسخة السياسة + نسخة المحرك)، ومراجع إلى معرفات الأحداث المستخدمة. هذا يجعل إعادة الحساب آمنة ويعطيك أثر تدقيقي عندما يسأل العملاء: "أي دقائق انقطاع احتسبتم؟"
أرقام SLA جديرة بالثقة بقدر ثقة الأحداث التي تستوعبها. الهدف بسيط: التقط كل تغيير مهم (بدء انقطاع، اعتراف بالحادث، استعادة الخدمة) مع طوابع زمنية ثابتة وسياق كافٍ لحساب الامتثال لاحقًا.
تسحب معظم الفرق من مزيج من الأنظمة:
Webhooks عادةً الأفضل للدقة في الوقت الحقيقي وحمل أقل: يدفَع النظام المصدر الأحداث إلى نقطة نهاية لديك.
Polling بديل جيد عندما لا تتوافر webhooks: يتيح تطبيقك جلب التغيّرات دوريًا منذ آخر موشر. احتج لتعامل مع حدود المعدل ومنطق "since" بدقة.
CSV import مفيد لملء البيانات التاريخية والهجرات. اعتبره مسار استيعاب أساسيًا حتى تتمكن من إعادة معالجة فترات تاريخية دون حيل.
وحّد كل شيء إلى شكل "حدث" داخلي واحد، حتى لو اختلفت الحمولات الصادرة:
event_id (مطلوب): فريد ومستقر عبر المحاولات. فضّل GUID المصدر أو أنشئ هاش حتمي.source (مطلوب): مثل datadog, servicenow, manual.event_type (مطلوب): مثل incident_opened, incident_acknowledged, service_down, service_up.occurred_at (مطلوب): وقت حدوث الحدث (ليس وقت الاستلام)، مع دلالة المنطقة الزمنية.received_at (نظام): وقت استيعابه في نظامك.service_id (مطلوب): الخدمة ذات الصلة بالـSLA.incident_id (اختياري ولكنه موصى به): لربط أحداث متعددة بذات الحادث.attributes (اختياري): الأولوية، المنطقة، شريحة العميل، إلخ.خزن event_id مع قيد فريد لجعل الاستيعاب قابلًا للعدم التكرار: المحاولات المتكررة لن تُنشئ سجلات مكررة.
ارفِض أو عزل الأحداث التي:
occurred_at في المستقبل البعيدservice_id معروف (أو اجعلها تتبع مسار "غير مطابقة")event_id موجودًا بالفعلهذه الدقة في البداية توفر عليك جدالًا حول تقارير الـSLA لاحقًا—لأنك ستكون قادرًا على الإشارة إلى مدخلات نظيفة وقابلة للتتبع.
محرك الحساب هو المكان الذي تتحول فيه "الأحداث الخام" إلى نتائج SLA يمكن الدفاع عنها. المفتاح هو التعامل معه كالمحاسبة: قواعد حتمية، مدخلات واضحة، وسجل قابل للإعادة.
حوّل كل شيء إلى تيار مرتب واحد لكل حادث (أو لكل أثر خدمة):
من هذا الخط الزمني، احسب المدد بجمع الفترات، لا بطرح طابعين بصورة عشوائية.
عرّف TTFR كزمن "قابل للاحتساب" من incident_start إلى first_agent_response (أو acknowledged بحسب صياغة SLA). عرّف TTR كزمن "قابل للاحتساب" من incident_start إلى resolved.
"قابل للاحتساب" يعني إزالة الفترات التي لا تُحتسب:
تفصيل تنفيذي: خزّن دالة التقويم (ساعات العمل، العطل) ودالة القواعد التي تأخذ الخط الزمني وتُرجع الفترات المحتسبة.
قرّر مُسبقًا إن كنت ستحسب:
للانقطاعات الجزئية، زِن التأثير فقط إذا طلب العقد ذلك؛ وإلا اعتبر "تدهور" فئة انتهاك منفصلة.
يجب أن يكون كل حساب قابلاً لإعادة الإنتاج. خزّن:
عندما تتغير القواعد، يمكنك إعادة تشغيل الحسابات حسب الإصدار بدون إعادة كتابة التاريخ — وهذا مهم للمراجعات ونزاعات العملاء.
التقارير هي المكان الذي يكسب فيه تتبع SLA الثقة—أو يثير الأسئلة. يجب أن يجعل تطبيقك واضحًا ما النطاق الزمني المقاس، أي الدقائق اُحتسبت، وكيف تشكلت الأرقام النهائية.
ادعم فترات التقرير الشائعة:
خزن الفترات كبدايات/نهايات واضحة (طوابع زمنية) حتى يمكنك إعادة تشغيل الحسابات لاحقًا وشرح النتائج.
مصدر ارتباك شائع هو ما إذا كان المقام قسمة على كامل الفترة أو فقط "الوقت المؤهل".
عرّف قيمتين لكل فترة:
ثم احسب:
availability_percent = 100 * (eligible_minutes - downtime_minutes) / eligible_minutes
إذا كانت الدقائق المؤهلة صفرًا (مثال: خدمة تُراقب فقط خلال ساعات العمل والفترة لا تحتوي ساعات)، عرّف القاعدة مقدمًا: إما "N/A" أو اعتبرها 100% — لكن كن متسقًا ووثّق ذلك.
معظم العقود تحتاج إلى نسبة ونتيجة ثنائية:
وخزّن أيضًا "المسافة إلى الانتهاك" (ميزانية التوقف المتبقية) حتى تُحذر اللوحات قبل عبور العتبة.
وفي الختام، احتفظ بالمدخلات الخام (الأحداث المضمنة/المستبعدة والتعديلات) حتى يمكن لكل تقرير أن يجيب على "لماذا هذا الرقم؟" دون تهويم.
محرك الحساب قد يكون مثاليًا ومع ذلك يفشل المستخدمون إذا لم تجب الواجهة عن السؤال الأساسي فورًا: "هل نفيّ بالـSLA الآن، ولماذا؟" صمّم التطبيق لتبدأ كل شاشة بحالة واضحة، ثم تتيح الحفر إلى الأرقام والأحداث الخام التي أنتجتها.
لوحة نظرة عامة (للعمليات والمدراء). قدّم بلاطات صغيرة: امتثال الفترة الحالية، التوافر، امتثال زمن الاستجابة، و"الوقت المتبقي قبل الانتهاك" حيثما ينطبق. ضع تسميات صريحة.
تفاصيل العميل (لفِرق الحسابات والتقارير الموجهة للعملاء). صفحة العميل تجمع كل الخدمات وطبقات SLA الخاصة به، مع حالة بسيطة ناجح/تحذير/فشل وشرح قصير ("حاصلتان؛ 18 دقيقة توقف محتسبة"). أضف روابط إلى /status وتصدير التقارير.
تفاصيل الخدمة (للبحث العميق). اعرض قواعد SLA الدقيقة، نافذة الحساب، وتفصيل كيفية تشكيل رقم الامتثال. أضف رسمًا زمنيًا للتوافر وقائمة الحوادث المحتسبة.
خط زمني الحادث (للمراجعات). اعرض حدثًا واحدًا مع تسلسل الأحداث (اكتشاف، اعتراف، تخفيف، حل) والطوابع المستخدمة لمقاييس الرد والحل.
اجعل عوامل التصفية متسقة عبر الشاشات: نطاق التاريخ، العميل، الخدمة، الطبقة، والشدة. استخدم نفس الوحدات في كل الأماكن (دقائق مقابل ثوانٍ؛ نسب بنفس عدد الكسور). عند تغير نطاق التاريخ حدّث كل مقياس في الصفحة.
كل مقياس ملخّص يجب أن يحتوي مسار "لماذا؟":
استخدم تلميحات مقتضبة لشرح مصطلحات مثل "دقائق مستبعدة" أو "ساعات العمل"، وأظهر نص القاعدة الكامل على صفحة الخدمة حتى لا يخمن الناس.
فضّل اللغة العادية على الاختصارات. لعرض الحالة، اجمع اللون مع تسميات نصية ("خطر: استُخدِم 92% من ميزانية الأخطاء") لتجنب اللبس. إن وفر التطبيق سجلات تدقيق، أضف مربعًا صغيرًا "آخر تغيير" على قواعد SLA والروابط إلى /audit لتمكين التحقق.
التنبيه هو حيث يتوقف تطبيق تتبع SLA عن كونه تقريرًا سلبيًا ويصبح أداة لمساعدة الفرق على تجنب العقوبات. أفضل التنبيهات في الوقت المناسب ومحددة وقابلة للتنفيذ — تخبر من يجب أن يفعل ماذا بعد، لا تُشير فقط إلى أن "الأمر سيء".
ابدأ بثلاثة أنواع من المحفزات:
اجعل المحفزات قابلة للتخصيص لكل عميل/خدمة/SLA.
أرسل التنبيهات حيث يستجيب الناس فعليًا:
كل تنبيه يجب أن يتضمن روابط عميقة مثل /alerts، /customers/{id}، /services/{id} وصفحة الحادث أو الحدث لتمكين المجيبين من التحقق السريع من الأرقام.
نفّذ عدم تكرار بتجميع التنبيهات بالمفتاح نفسه (عميل + خدمة + SLA + فترة) وكبت التكرارات لنقطة تبريد محددة.
أضف ساعات هدوء بحسب منطقة فريق العمل حتى تنتظر التنبيهات غير الحرجة ساعات العمل، بينما يمكن لـ"الانتهاك الحاصل" تجاوز ساعات الهدوء إن كانت الشدة عالية.
أخيرًا، ادعم قواعد التصعيد (مثال: إشعار المعاون بعد 10 دقائق، تصعيد للمدير بعد 30) لمنع تكدس التنبيهات في صندوق واحد.
بيانات SLA حساسة لأنها تكشف أداء داخلي وامتيازات خاصة بالعملاء. عامل التحكم في الوصول كجزء من "قواعد الحساب": نفس الحادث قد يعطي نتائج امتثال مختلفة بحسب SLA المطبقة لذلك العميل.
احتفظ بالأدوار بسيطة ثم توسع تدريجيًا:
افتراض عملي: RBAC + نطاق المستأجر — كل سجل له مالك tenant. المستخدمون الداخليون قد يكونون مقيدين لعدة مستأجرين؛ مشاهدو العملاء لمستأجر واحد فقط.
كن صريحًا بشأن البيانات الخاصة بالعملاء:
ابدأ بـالبريد/كلمة المرور واطلب MFA للأدوار الداخلية. خطط لدعم SSO لاحقًا (SAML/OIDC) عبر فصل الهوية عن التفويض. للتكاملات، أصدر مفاتيح API مربوطة بحساب خدمة بنطاق ضيق وإمكانية تدوير.
أضف إدخالات تدقيق غير قابلة للتعديل لـ:
خزن من، ما الذي تغيّر (قبل/بعد)، متى، أين (IP/وكيل المستخدم)، ومعرّف الارتباط. اجعل سجلات التدقيق قابلة للبحث والتصدير (مثال: /settings/audit-log).
نادراً ما يكون تطبيق تتبع SLA منعزلًا. ستحتاج API يسمح لأدوات المراقبة، أنظمة التذاكر، وتدفقات العمل الداخلية بإنشاء الحوادث، دفع الأحداث، وسحب التقارير برمجيًا.
استخدم مسارًا مُنسخًا بالإصدار (مثال: /api/v1/...) حتى تتمكن من تطور الحمولات دون كسر التكاملات.
نقاط نهاية أساسية تغطي معظم الحالات:
POST /api/v1/events لاستيعاب تغيّرات الحالة. GET /api/v1/events للتدقيق والتصحيح.POST /api/v1/incidents, PATCH /api/v1/incidents/{id} (للاعتراف، الحل، التعيين), GET /api/v1/incidents.GET /api/v1/slas, POST /api/v1/slas, PUT /api/v1/slas/{id} لإدارة العقود والعتبات.GET /api/v1/reports/sla?service_id=...&from=...&to=... لملخصات الامتثال.POST /api/v1/alerts/subscriptions لإدارة الويبهوكس/البريد؛ GET /api/v1/alerts لسجل التنبيهات.اختر اصطلاحًا واحدًا واستخدمه في كل مكان: مثالًا limit مع صفحات مؤشرية (cursor)، وفلاتر قياسية مثل service_id, sla_id, status, from, to. حافظ على الفرز متوقعًا (مثال: sort=-created_at).
أعد أخطاء منظمة بحقول ثابتة:
{ "error": { "code": "VALIDATION_ERROR", "message": "service_id is required", "fields": { "service_id": "missing" } } }
استخدم حالات HTTP واضحة (400 صحة، 401/403 مصادقة/تفويض، 404 غير موجود، 409 تعارض، 429 حد المعدل). لأجل استيعاب الأحداث، فكّر في قابلية عدم التكرار (Idempotency-Key) حتى لا تُضاعف المحاولات الحوادث.
طبق حدود معقولة لكل رمز (وحدود أشد لنقاط الاستيعاب)، طهّر المدخلات، وحقّق الطوابع الزمنية/المناطق الزمنية. فضّل رموز API بمدى ضيق (قراءة تقارير مقابل كتابة حوادث)، وسجل دائمًا من استدعى أي نقطة نهاية للتتبع (تفاصيل في قسم سجلات التدقيق على /blog/audit-logs).
أرقام SLA مفيدة فقط إذا وثق بها الناس. اختبارات تطبيق تتبع SLA يجب أن تركز أقل على "هل الصفحة تحمّلت" وأكثر على "هل حسابات الزمن تتصرف بدقة طبقًا للعقد؟" عامل قواعد الحساب كمِيزة منتج مع مجموعة اختبارات خاصة بها.
ابدأ باختبار وحدات لمحرك الحساب مع مدخلات حتمية: خط زمني لأحداث (فتح الحادث، الاعتراف، التخفيف، الحل) ومجموعة قواعد SLA مُحددة بوضوح.
استخدم طوابع زمنية ثابتة و"تجميد الوقت" حتى لا تعتمد اختباراتك على الساعة الحقيقية. غطِ حالات الحافة:
أضف مجموعة صغيرة من اختبارات E2E التي تشغّل التدفق الكامل: استيعاب الأحداث → حساب الامتثال → توليد التقرير → عرض الواجهة. هذه تختبر التوافق بين ما حسبه المحرك وما عرضه اللوحة. احتفظ بالسيناريوهات قليلة لكنها عالية القيمة، وفرض التأكد من الأرقام النهائية.
ابتكر قوالب اختبار لساعات العمل، العطل، والمناطق الزمنية. تريد حالات قابلة للتكرار مثل "يحدث الحادث الجمعة 17:55 بتوقيت محلي" و"العطلة تؤثر على حساب زمن الاستجابة".
الاختبار لا يتوقف عند النشر. أضف مراقبة لأخطاء الوظائف، حجم الطوابير، مدة إعادة الحساب، ومعدلات الخطأ. إذا تأخر الاستيعاب أو فشل مهمة ليلية، فقد يكون تقرير SLA خاطئًا حتى لو كان الكود صحيحًا.
إطلاق تطبيق تتبع SLA أقل ما يكون عن بنية تحتية فاخرة وأكثر ما يكون عن عمليات متوقعة: حساباتك يجب أن تعمل في الوقت المناسب، بياناتك يجب أن تكون آمنة، والتقارير قابلة لإعادة الإنتاج.
ابدأ بخدمات مُدارة حتى تركز على الصحة الحسابية:
حافظ على بيئات قليلة: dev → staging → prod، كل منها بقاعدة بيانات وسرية خاصة.
تتبع SLA ليس طلب/استجابة فقط؛ يعتمد على أعمال مجدولة:
شغّل المهام عبر عامل + طابور، أو مجدول مُدار يستدعي واجهات داخلية. اجعل المهام قابلية الإعادة وآمنة لإعادة المحاولة وسجّل كل تشغيل للتدقيق.
حدّد الاحتفاظ حسب نوع البيانات: احتفظ بالنتائج المشتقة لفترة أطول من أحداث الخام. للصدارات، قدّم CSV أولًا (سريع وشفاف)، ثم قوالب PDF لاحقًا. كن واضحًا: التصديرات تنسيق "بأفضل جهد"، بينما تظل قاعدة البيانات مصدر الحقيقة.
إذا أردت التحقق سريعًا من نموذج البيانات، تدفق الاستيعاب، وواجهة التقارير، يمكن لمنصات توليد التطبيقات مثل Koder.ai مساعدتك في الوصول لنموذج عمل أولي بدون دورة هندسة كاملة. لأن Koder.ai يولد تطبيقات كاملة عبر المحادثة (واجهة ويب + باكند)، فهو طريقة عملية لابتكار:
بمجرد إثبات المتطلبات والحسابات (الجزء الصعب)، يمكنك التقدم، تصدير الشيفرة، والانتقال لبناء وتشغيل تقليدي—مع الحفاظ على ميزات مثل لقطات واسترداد أثناء التكرار السريع.
متتبع الـSLA يجيب عن سؤال واحد مع أدلة: هل تم الوفاء بالالتزامات التعاقدية لعميل محدد خلال فترة زمنية معينة؟
بشكل عملي، يعني ذلك استيعاب إشارات خام (مراقبة، تذاكر، تحديثات يدوية)، تطبيق قواعد العميل (ساعات العمل، الاستثناءات)، وإصدار نتيجة يمكن تدقيقها — نتيجة بنعم/لا مع تفاصيل داعمة.
استخدم:
نمذجتهم بشكل منفصل لكي تتمكن من تحسين الموثوقية (SLO) دون تغيير التقارير التعاقدية (SLA).
ينصح أن يتتبع الـMVP بقوة 1–3 مقاييس شاملة للنهاية إلى النهاية:
هذه المقاييس ترتبط بمصادر بيانات حقيقية وتفرض عليك معالجة الأجزاء الصعبة مبكرًا (الفترات، الجداول، الاستثناءات).
أخطاء المتطلبات غالبًا تأتي من قواعد غير مُعبرَة بوضوح. اجمع واكتب:
إذا لم يمكن التعبير عن قاعدة بوضوح، فلا تحاول استنتاجها في الكود — ضعها كقضية واطلب توضيحًا.
ابدأ بكيانات واضحة ومفصلة:
الهدف: القابلية للتتبع — كل رقم مُبلغ يجب أن يرتبط بمعرّفات أحداث محددة وإصدار السياسة المستخدم.
خزن الوقت بدقة واتساق:
occurred_at بتنسيق UTC مع دلالات المنطقة الزمنيةreceived_at (وقت استلامنا)واحد من أفضل الممارسات: اجعل الفترات واضحة (start/end timestamps) حتى يمكن إعادة تشغيل الحسابات لاحقًا — وحتى عبر تغييرات التوقيت الصيفي.
قم بتوحيد كل شيء إلى شكل حدث داخلي واحد مع معرف ثابت:
event_id فريد ومستقر عبر المحاولاتsource, event_type, occurred_at, احسب الأزمنة بجمع الفترات المستحقة بدلًا من طرح طابعين بشكل مباشر.
حدد "الوقت القابل للاحتساب" بإزالة الفترات التي لا تُحتسب، مثل:
خزن الفترات المشتقة مع رموز السبب حتى يمكن شرح ما اُحتسب بالضبط.
راقب قيمتين للفترة:
ثم احسب:
availability_percent = 100 * (eligible_minutes - downtime_minutes) / eligible_minutes
وحدد سلوكك إن صارت الدقائق المؤهلة صفرًا (مثلاً: ابدأ بعرض "N/A" أو اعتبرها 100%) ووثّق القاعدة وطبقها باستمرار.
اجعل الواجهة تجيب فورًا: "هل نلتزم بالـSLA الآن؟ ولماذا؟"
بالنسبة للتنبيهات: ركّز على ما يمكن فعله (اقتراب من الانتهاك، الانتهاك الحاصل، انتهاكات متكررة) مع روابط عميقة إلى /customers/{id} أو /services/{id}.
service_idincident_id اختياري وattributes إضافيةنفّذ عدم التكرار عبر قيد فريد على event_id. للأحداث التي تفتقد تطابقًا أو تأتي خارج الترتيب، عزّلها/وسمها للمراجعة بدلًا من تصحيحها تلقائيًا.