نقوم بتعيين بعض المواضيع إلى مجموعات، ثم تقوم المجموعات (نظريًا) بتعيين المواضيع للأفراد للتعامل معها.
لقد أنشأنا تقريرًا لإظهار الوقت (المدة) لإعادة التعيين.
تقرير لإظهار الوقت لإعادة التعيين
-- الهدف: إيجاد الوقت من التعيين إلى المجموعة
-- إلى إغلاق الموضوع / إلغاء التعيين / إعادة التعيين إلى فريق فرعي أو فرد
-- بالنسبة للمنشورات التي لم تتم إعادة تعيينها، لا يزال الوقت مستمرًا،
-- لذلك استخدم الطابع الزمني الحالي في فرق التاريخ
--
-- ملاحظة أن هذا التقرير يتجاهل التعيينات التي لا تزال معلقة والتي تمت قبل بداية النطاق الزمني
-- [معلمات]
-- تاريخ : تاريخ_البداية = 2023-01-01
مع
-- العثور على منشورات تعيين المجموعة في النطاق الزمني
تعيين_المجموعة AS (
SELECT p.topic_id
, p.created_at as تاريخ_التعيين
, pcf.value as اسم_المجموعة
, post_number
FROM posts p
JOIN post_custom_fields pcf on pcf.post_id = p.id
WHERE p.action_code in ('assigned_group', 'reassigned_group')
AND p.created_at >= :start_date AND p.created_at < :start_date::date + INTERVAL '90 day'
ORDER BY topic_id
),
-- العثور على رقم المنشور لأدنى منشور "تغيير التعيين" بعد تعيين المجموعة
رقم_منشور_تغيير_التعيين AS (
SELECT min(p.post_number) as post_number
, p.topic_id
, ga.post_number as التعيين_الأولي -- تمرير للأمام للاستخدام في الربط اللاحق
FROM posts p
JOIN تعيين_المجموعة ga ON ga.topic_id = p.topic_id AND ga.post_number < p.post_number
WHERE p.action_code in ('reassigned_group', 'reassigned', 'unassigned', 'unassigned_group'
, 'assigned' -- ربما لن يظهر هذا، ولكن للاحتياط...
, 'closed.enabled','autoclosed.enabled') -- ربما زائدة عن الحاجة مع unassign*...
GROUP BY p.topic_id, ga.post_number
),
-- البحث عن تاريخ التغيير لرقم المنشور
تاريخ_تغيير_التعيين AS (
SELECT p.created_at as تاريخ_التغيير
, p.topic_id
, acpn.التعيين_الأولي -- تمرير للأمام للاستخدام في الربط اللاحق
FROM posts p
JOIN رقم_منشور_تغيير_التعيين acpn on p.topic_id=acpn.topic_id and p.post_number=acpn.post_number
),
-- إجراء حساب التاريخ بين التعيين وتغيير التعيين
حساب_التاريخ AS (
SELECT ga.اسم_المجموعة
-- للمنشورات التي لا تزال معينة للمجموعة، استخدم الطابع الزمني الحالي كـ "تاريخ إعادة التعيين"
, extract(epoch from (coalesce(acd.تاريخ_التغيير, NOW()) - ga.تاريخ_التعيين)/86400) as days
FROM تعيين_المجموعة ga
LEFT JOIN تاريخ_تغيير_التعيين acd on acd.topic_id = ga.topic_id
AND ga.post_number=acd.التعيين_الأولي
)
SELECT اسم_المجموعة as "الفريق"
, count(*) as "التعيينات"
, round(avg(days)::numeric,2) as "متوسط الأيام لإعادة التعيين"
, round(max(days)::numeric,2) as "الحد الأقصى"
, round(min(days)::numeric,5) as "الحد الأدنى"
FROM حساب_التاريخ
GROUP BY اسم_المجموعة
ORDER BY "متوسط الأيام لإعادة التعيين" desc
لقد نجح هذا جيدًا حتى بدأت المجموعات في إعادة تسمية نفسها (لـ… أسباب).
نظرًا لأن سجلات تعيين المواضيع تخزن أسماء المجموعات - في وقت التعيين - بدلاً من معرفات المجموعات، فلدينا الآن صفوف متعددة في التقرير لبعض المجموعات (اعتمادًا على ما إذا كان النطاق الزمني للتقرير يتضمن سجلات من قبل وبعد إعادة التسمية).
أود توحيد المتعددات وجعل هذا التقرير مستقبليًا (لذا فإن الترميز الثابت لمجموعات المرادفات لن يكون كافيًا).
هل يوجد سجل في مكان ما لأسماء المجموعات القديمة / إعادة التسمية؟ أو… شيء آخر؟
@Falco على حد علمي، تحتفظ “assignment table” بالحالة الحالية. إذا كنت أرغب في الحصول على بيانات تاريخية (وهو ما أريده)، فأنا بحاجة إلى النظر في post_custom_fields للحصول على قيمة التعيين لحالات التعيين السابقة.
SELECT p.topic_id
, p.created_at as assign_date
, pcf.value as group_name
, post_number
FROM posts p
JOIN post_custom_fields pcf on pcf.post_id = p.id
WHERE p.action_code in ('assigned_group', 'reassigned_group')
AND p.created_at >= :start_date AND p.created_at < :start_date::date + INTERVAL '90 day'
ORDER BY topic_id
أوه، فهمت الآن، تحتاج إلى تتبع جميع التغييرات التاريخية في حالة التعيين! هذه بالفعل مشكلة صعبة، وكان لدينا عميل كلفنا بإيجاد طريقة لمعالجة هذه المشكلة بشكل صحيح قبل عام، لذلك كتبت مواصفات كاملة لها:
هذه مهمة من جزأين تقريبًا.
أولاً، نحتاج إلى تخزين انتقالات حالة التعيين في جدول (تعيين جديد، تغيير في التعيين (المُعيّن أو تغيير الحالة)، حذف التعيين).
ثم نحتاج إلى استخدام تلك المعلومات لتشغيل عرض جديد وهو لوحة تحكم تحتوي على رسوم بيانية وجداول.
إعدادات جديدة
تمكين تقارير التعيين
النوع: منطقي (bool)
الافتراضي: خطأ (false)
واجهة مستخدم جديدة
ستكون هذه صفحة جديدة، إما تحت /admin/dashboard/assignments إذا كان ذلك قابلاً للتوسيع أو تحت /admin/plugins/assign.
هناك يمكن للمستخدمين عرض الرسوم البيانية وتصدير البيانات حول التعيينات، مع التصفية حسب الفترة الزمنية والمستخدم/المجموعات والحالة.
استمرارية انتقال حالة التعيينات
جدول assignments يخزن بالفعل التعيينات القديمة، ولكننا سنحتاج أيضًا إلى تتبع حالة التعيين، لذلك لست متأكدًا مما إذا كان ينبغي علينا توسيع هذا الجدول أو مجرد ابتكار جدول أبسط مخصص لحالات التعيين التاريخية. سأميل إلى اتباع المسار الأخير حتى لا نضخم الجدول الذي يتم ربطه بالفعل في مُسلسلاتنا النشطة.
تقدير الجهد
2.5 إلى 3 أسابيع للعمل الكامل مع واجهة المستخدم
أسبوع واحد للجدول الجديد فقط
للأسف، قام العميل بإلغاء تحديد أولويات هذا العمل قبل أن نتمكن من البدء فيه، ولكن هذا سيحل احتياجاتك.
تم تحديث التقرير لمن يهمه الأمر. التعديل هو إضافة الاستعلام group_aliases (واستخدامه):
-- الهدف: العثور على الوقت من التعيين إلى المجموعة
-- إلى إغلاق الموضوع / إلغاء التعيين / إعادة التعيين إلى فريق فرعي أو فردي
-- بالنسبة للمنشورات التي لم تتم إعادة تعيينها، لا يزال الوقت يمضي،
-- لذا استخدم الطابع الزمني الحالي في فرق التاريخ
--
-- ملاحظة أن هذا التقرير يتجاهل التعيينات التي لا تزال معلقة والتي تمت قبل بداية النطاق الزمني
-- [معلمات]
-- التاريخ :start_date = 2023-01-01
WITH
group_aliases AS (
SELECT group_id,
-- تحويل الأعمدة إلى صفوف
UNNEST (array[prev_value, new_value]) AS "alias"
FROM group_histories
WHERE action = 1 AND subject='name'
UNION
SELECT id as group_id
, name
FROM groups
),
-- العثور على منشورات تعيين المجموعة في النطاق الزمني
group_assignment AS (
SELECT p.topic_id
, p.created_at as assign_date
, ga.group_id as group_id
, post_number
FROM posts p
JOIN post_custom_fields pcf on pcf.post_id = p.id
JOIN group_aliases ga on pcf.value = ga.alias
WHERE p.action_code in ('assigned_group', 'reassigned_group')
AND p.created_at >= :start_date AND p.created_at < :start_date::date + INTERVAL '90 day'
ORDER BY topic_id
),
-- العثور على رقم المنشور لأدنى منشور "تغيير التعيين" بعد تعيين المجموعة
assignment_change_post_number AS (
SELECT min(p.post_number) as post_number
, p.topic_id
, ga.post_number as initial_assignment -- تمرير للأمام للاستخدام في الربط اللاحق
FROM posts p
JOIN group_assignment ga ON ga.topic_id = p.topic_id AND ga.post_number < p.post_number
WHERE p.action_code in ('reassigned_group', 'reassigned', 'unassigned', 'unassigned_group'
, 'assigned' -- ربما لن يظهر هذا هنا، ولكن من باب الأمان...
, 'closed.enabled','autoclosed.enabled') -- ربما يكون هذا مكررًا مع unassign*...
GROUP BY p.topic_id, ga.post_number
),
-- البحث عن تاريخ التغيير لرقم المنشور
assignment_change_date AS (
SELECT p.created_at as change_date
, p.topic_id
, acpn.initial_assignment -- تمرير للأمام للاستخدام في الربط اللاحق
FROM posts p
JOIN assignment_change_post_number acpn on p.topic_id=acpn.topic_id and p.post_number=acpn.post_number
),
-- إجراء حسابات التاريخ بين التعيين وتغيير التعيين
date_math AS (
SELECT ga.group_id as group_id
-- للمنشورات التي لا تزال معينة للمجموعة، استخدم الطابع الزمني الحالي كتاريخ "إعادة التعيين"
, extract(epoch from (coalesce(acd.change_date, NOW()) - ga.assign_date)/86400) as days
FROM group_assignment ga
LEFT JOIN assignment_change_date acd on acd.topic_id = ga.topic_id
AND ga.post_number=acd.initial_assignment
)
SELECT date_math.group_id
, count(*) as "Assignments"
, round(avg(days)::numeric,2) as "Avg days to reassignment"
, round(max(days)::numeric,2) as "Max"
, round(min(days)::numeric,5) as "Min"
FROM date_math
GROUP BY group_id
ORDER BY "Avg days to reassignment" desc