تقرير لوحة القيادة - نشاط المشرف

هذا إصدار SQL من تقرير لوحة المعلومات لنشاط المشرف.

يوفر هذا التقرير نظرة شاملة على الأنشطة التي قام بها المشرفون خلال فترة زمنية محددة على موقع Discourse. يجمع التقرير بين جوانب متعددة لنشاط المشرف: الوقت المستغرق على المنصة، وعدد العلامات التي تمت مراجعتها، والمشاركات التي تم إنشاؤها، والرسائل الشخصية (PMs) التي تم إنشاؤها، والمواضيع التي تم إنشاؤها، ومراجعات المشاركات التي تم إجراؤها.

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

--[params]
-- date :start_date = 2023-12-01
-- date :end_date = 2024-12-01
-- boolean :include_admins = false


WITH mods AS (
    SELECT
        id AS user_id,
        username_lower AS username,
        uploaded_avatar_id
    FROM users u
    WHERE ((u.moderator = true) OR (:include_admins AND u.admin = true))
    AND u.id > 0

),

time_read AS (
    SELECT SUM(uv.time_read) AS time_read,
        uv.user_id
    FROM mods m
    JOIN user_visits uv ON m.user_id = uv.user_id
    WHERE uv.visited_at >= :start_date
        AND uv.visited_at <= :end_date
    GROUP BY uv.user_id
),
      
flag_count AS (
    WITH period_actions AS (
        SELECT agreed_by_id,
        disagreed_by_id
        FROM post_actions
        WHERE post_action_type_id IN (3,4,8,6,7)
        AND created_at >= :start_date
        AND created_at <= :end_date
    ),

agreed_flags AS (
        SELECT pa.agreed_by_id AS user_id,
        COUNT(*) AS flag_count
        FROM mods m
        JOIN period_actions pa
        ON pa.agreed_by_id = m.user_id
        GROUP BY agreed_by_id
    ),

disagreed_flags AS (
        SELECT pa.disagreed_by_id AS user_id,
        COUNT(*) AS flag_count
        FROM mods m
        JOIN period_actions pa
        ON pa.disagreed_by_id = m.user_id
        GROUP BY disagreed_by_id
    )
    SELECT
    COALESCE(af.user_id, df.user_id) AS user_id,
    COALESCE(af.flag_count, 0) + COALESCE(df.flag_count, 0) AS flag_count
    FROM agreed_flags af
    FULL OUTER JOIN disagreed_flags df
    ON df.user_id = af.user_id
      ),
      
revision_count AS (
      SELECT pr.user_id,
      COUNT(*) AS revision_count
      FROM mods m
      JOIN post_revisions pr
      ON pr.user_id = m.user_id
      JOIN posts p
      ON p.id = pr.post_id
      WHERE pr.created_at >= :start_date
      AND pr.created_at <= :end_date
      AND p.user_id <> pr.user_id
      GROUP BY pr.user_id
),
      
topic_count AS (
      SELECT t.user_id,
        COUNT(*) AS topic_count
      FROM mods m
      JOIN topics t ON t.user_id = m.user_id
      WHERE t.archetype = 'regular'
          AND t.created_at >= :start_date
          AND t.created_at <= :end_date
      GROUP BY t.user_id
),
      
post_count AS (
      SELECT p.user_id,
         COUNT(*) AS post_count
      FROM mods m
      JOIN posts p ON p.user_id = m.user_id
      JOIN topics t ON t.id = p.topic_id
      WHERE t.archetype = 'regular'
          AND p.created_at >= :start_date
          AND p.created_at <= :end_date
      GROUP BY p.user_id
),
      
pm_count AS (
      SELECT p.user_id,
        COUNT(*) AS pm_count
      FROM mods m
      JOIN posts p ON p.user_id = m.user_id
      JOIN topics t ON t.id = p.topic_id
      WHERE t.archetype = 'private_message'
          AND p.created_at >= :start_date
          AND p.created_at <= :end_date
      GROUP BY p.user_id
      )
      
SELECT
    m.user_id,
    m.username,
    fc.flag_count as flags_reviewed,
    ROUND(((tr.time_read) / 3600.00),2) as time_reading_hours,
    tc.topic_count as topics_created,
    pmc.pm_count as PMs_created,
    pc.post_count as posts_created,
    rc.revision_count as revisions
FROM mods m
LEFT JOIN time_read tr ON tr.user_id = m.user_id
LEFT JOIN flag_count fc ON fc.user_id = m.user_id
LEFT JOIN revision_count rc ON rc.user_id = m.user_id
LEFT JOIN topic_count tc ON tc.user_id = m.user_id
LEFT JOIN post_count pc ON pc.user_id = m.user_id
LEFT JOIN pm_count pmc ON pmc.user_id = m.user_id
ORDER BY m.username ASC

المعلمات

  • :start_date و :end_date - تحدد هذه المعلمات النطاق الزمني للتقرير. تقبل كلتا معلمتي التاريخ تنسيق التاريخ YYYY-MM-DD.
  • :include_admins - تحدد هذه المعلمة ما إذا كان سيتم تضمين المسؤولين في التقرير إلى جانب المشرفين.

شرح استعلام SQL

يتم تنظيم التقرير باستخدام تعبيرات الجدول المشتركة (CTEs) لتقسيم معالجة البيانات إلى أقسام قابلة للإدارة ومنطقية. إليك ما يحدث في كل CTE:

  1. mods: يحدد جميع المستخدمين الذين لديهم حالة مشرف أو حالة مسؤول (إذا تم تضمينهم بواسطة المعلمة :include_admins). يختار فقط أعمدة المستخدم ذات الصلة للاستعلامات الإضافية.
  2. time_read: يحسب إجمالي الوقت (بالثواني) الذي قضاه كل مشرف في قراءة المحتوى على المنصة بين تواريخ البدء والانتهاء المقدمة.
  3. flag_count: يحسب عدد العلامات التي وافق عليها المشرفون أو لم يوافقوا عليها خلال الفترة المحددة. يأخذ في الاعتبار أنواع علامات متعددة ممثلة بمعرفات إجراءات المشاركة الخاصة بها.
  4. revision_count: يحسب عدد مراجعات المشاركات التي أجراها المشرفون على مشاركات المستخدمين الآخرين ضمن الإطار الزمني المحدد.
  5. topic_count: يحسب عدد المواضيع العادية التي أنشأها المشرفون.
  6. post_count: يحسب عدد المشاركات التي أنشأها المشرفون في المواضيع العادية.
  7. pm_count: يحسب عدد الرسائل الخاصة التي بدأها المشرفون.

بعد جمع البيانات في CTEs، تقوم الاستعلامات الرئيسية بربطها بناءً على معرف المستخدم وتجميع التقرير النهائي الذي يعرض اسم المستخدم لكل مشرف، وإجمالي الوقت المستغرق في القراءة (محول إلى ساعات)، وعدد العلامات التي تمت مراجعتها، والمواضيع التي تم إنشاؤها، والرسائل الشخصية التي تم إنشاؤها، والمشاركات التي تم إنشاؤها، والمراجعات التي تم إجراؤها. يتم ترتيب النتائج أبجديًا حسب اسم المستخدم للمشرف.

نتائج مثال

user username flags_reviewed time_reading_hours topics_created pms_created posts_created revisions
1 moderator1 NULL 36.11 NULL 344 8 15
2 moderator2 46 104.52 2 271 466 363
3 moderator3 NULL 72.15 NULL 418 64 16
7 إعجابات

مرحباً @SaraDev،

هذا مفيد حقًا. هل سيكون من الممكن إضافة أعمدة “المشاركات المعتمدة” و “المشاركات المرفوضة” إلى تقرير نشاط المشرف؟

شكرًا،
T_Disco

3 إعجابات

مرحباً @T_Disco،

نعم، لإضافة نتائج المشاركات المعتمدة و المشاركات المرفوضة إلى تقرير نشاط المشرف، يمكننا استخدام جدولي reviewables و reviewable_scores. على وجه التحديد، يمكن استخدام حقل status في reviewable_scores لتحديد ما إذا كانت المشاركة معتمدة (status = 1) أو مرفوضة (status = 2).

إليك كيف سيبدو ذلك مضافًا إلى التقرير:

نشاط المشرف مع المشاركات المعتمدة والمشاركات المرفوضة

-- [params]
-- date :start_date = 2023-12-01
-- date :end_date = 2024-12-01
-- boolean :include_admins = false

WITH mods AS (
    SELECT
        id AS user_id,
        username_lower AS username,
        uploaded_avatar_id
    FROM users u
    WHERE ((u.moderator = true) OR (:include_admins AND u.admin = true))
    AND u.id > 0
),

time_read AS (
    SELECT SUM(uv.time_read) AS time_read,
        uv.user_id
    FROM mods m
    JOIN user_visits uv ON m.user_id = uv.user_id
    WHERE uv.visited_at >= :start_date
        AND uv.visited_at <= :end_date
    GROUP BY uv.user_id
),
      
flag_count AS (
    WITH period_actions AS (
        SELECT agreed_by_id,
        disagreed_by_id
        FROM post_actions
        WHERE post_action_type_id IN (3,4,8,6,7)
        AND created_at >= :start_date
        AND created_at <= :end_date
    ),

agreed_flags AS (
        SELECT pa.agreed_by_id AS user_id,
        COUNT(*) AS flag_count
        FROM mods m
        JOIN period_actions pa
        ON pa.agreed_by_id = m.user_id
        GROUP BY agreed_by_id
    ),

disagreed_flags AS (
        SELECT pa.disagreed_by_id AS user_id,
        COUNT(*) AS flag_count
        FROM mods m
        JOIN period_actions pa
        ON pa.disagreed_by_id = m.user_id
        GROUP BY disagreed_by_id
    )
    SELECT
    COALESCE(af.user_id, df.user_id) AS user_id,
    COALESCE(af.flag_count, 0) + COALESCE(df.flag_count, 0) AS flag_count
    FROM agreed_flags af
    FULL OUTER JOIN disagreed_flags df
    ON df.user_id = af.user_id
      ),
      
revision_count AS (
      SELECT pr.user_id,
      COUNT(*) AS revision_count
      FROM mods m
      JOIN post_revisions pr
      ON pr.user_id = m.user_id
      JOIN posts p
      ON p.id = pr.post_id
      WHERE pr.created_at >= :start_date
      AND pr.created_at <= :end_date
      AND p.user_id <> pr.user_id
      GROUP BY pr.user_id
),
      
topic_count AS (
      SELECT t.user_id,
        COUNT(*) AS topic_count
      FROM mods m
      JOIN topics t ON t.user_id = m.user_id
      WHERE t.archetype = 'regular'
          AND t.created_at >= :start_date
          AND t.created_at <= :end_date
      GROUP BY t.user_id
),
      
post_count AS (
      SELECT p.user_id,
         COUNT(*) AS post_count
      FROM mods m
      JOIN posts p ON p.user_id = m.user_id
      JOIN topics t ON t.id = p.topic_id
      WHERE t.archetype = 'regular'
          AND p.created_at >= :start_date
          AND p.created_at <= :end_date
      GROUP BY p.user_id
),
      
pm_count AS (
      SELECT p.user_id,
        COUNT(*) AS pm_count
      FROM mods m
      JOIN posts p ON p.user_id = m.user_id
      JOIN topics t ON t.id = p.topic_id
      WHERE t.archetype = 'private_message'
          AND p.created_at >= :start_date
          AND p.created_at <= :end_date
      GROUP BY p.user_id
),

reviewable_actions AS (
    SELECT
        rs.reviewed_by_id AS user_id,
        SUM(CASE WHEN rs.status = 1 THEN 1 ELSE 0 END) AS posts_approved,
        SUM(CASE WHEN rs.status = 2 THEN 1 ELSE 0 END) AS posts_rejected
    FROM mods m
    JOIN reviewable_scores rs ON rs.reviewed_by_id = m.user_id
    JOIN reviewables r ON r.id = rs.reviewable_id
    WHERE rs.reviewed_at >= :start_date
      AND rs.reviewed_at <= :end_date
    GROUP BY rs.reviewed_by_id
)

SELECT
    m.user_id,
    m.username,
    fc.flag_count as flags_reviewed,
    ROUND(((tr.time_read) / 3600.00),2) as time_reading_hours,
    tc.topic_count as topics_created,
    pmc.pm_count as PMs_created,
    pc.post_count as posts_created,
    rc.revision_count as revisions,
    ra.posts_approved,
    ra.posts_rejected
FROM mods m
LEFT JOIN time_read tr ON tr.user_id = m.user_id
LEFT JOIN flag_count fc ON fc.user_id = m.user_id
LEFT JOIN revision_count rc ON rc.user_id = m.user_id
LEFT JOIN topic_count tc ON tc.user_id = m.user_id
LEFT JOIN post_count pc ON pc.user_id = m.user_id
LEFT JOIN pm_count pmc ON pmc.user_id = m.user_id
LEFT JOIN reviewable_actions ra ON ra.user_id = m.user_id
ORDER BY m.username ASC

حيث ستبدو نتائج هذا التقرير كالتالي:

user username flags_reviewed time_reading_hours topics_created pms_created posts_created revisions posts_approved posts_rejected
1 moderator1 NULL 36.11 NULL 344 8 15 10 5
2 moderator2 46 104.52 2 271 466 363 7 3
3 moderator3 NULL 72.15 NULL 418 64 16 NULL NULL
إعجاب واحد (1)

هذا رائع، شكرًا لك @SaraDev!

هل ستتم إضافة هذه الأعمدة إلى تقرير نشاط المشرف في علامة التبويب /admin/dashboard/moderation في وقت ما؟

شكرًا مرة أخرى :slight_smile:
T_Disco

إعجاب واحد (1)

@SaraDev
هل الاستعلام ممكن لعدد عمليات دمج المواضيع التي تم إجراؤها في فترة زمنية معينة

إعجابَين (2)

ليس لدينا حاليًا أي خطط لإضافة هذه الأعمدة إلى نسخة لوحة المعلومات من التقرير، ولكن يمكنني طرح هذا الأمر على فريقنا لمعرفة ما إذا كان بإمكاننا إجراء بعض التحسينات في المستقبل. :slightly_smiling_face:

نعم، لإنشاء استعلام يُظهر متى تم نقل المشاركات إلى مواضيع أخرى، يمكنك تصفية جدول posts بحثًا عن الإدخالات التي يشير فيها action_code إلى نقل مع إدخال split_topic.

على سبيل المثال:

إجراءات نقل المشاركات الفردية

SELECT
    id AS post_id,
    user_id,
    topic_id,
    post_number,
    created_at::date,
    updated_at::date,
    action_code
FROM
    posts
WHERE
    action_code = 'split_topic'
ORDER BY
    created_at DESC

سيُظهر نتائج مثل:

post user topic post_number created_at updated_at action_code
تم دمج مشاركة في موضوع موجود:: [عنوان الموضوع المدمج] USERNAME Original_Topic_Title 3 2024-10-30 2024-10-30 split_topic
تم دمج مشاركتين في موضوع موجود:: [عنوان الموضوع المدمج] USERNAME Original_Topic_Title 5 2024-10-30 2024-10-30 split_topic
تم تقسيم مشاركة إلى موضوع جديد: [عنوان الموضوع المقسم] USERNAME Original_Topic_Title 2 2024-10-30 2024-10-30 split_topic

إذا كنت ترغب في إظهار العدد الإجمالي لنقل المشاركات لكل مستخدم في موقع ما، وإضافة زوج من المعلمات لتصفية إجراءات النقل حسب التاريخ، يمكنك أيضًا استخدام استعلام مثل التالي:

عدد إجراءات نقل المشاركات لكل مستخدم

-- [params]
-- date :start_date
-- date :end_date

SELECT
    user_id,
    COUNT(*) AS move_count
FROM
    posts
WHERE
    action_code = 'split_topic'
    AND created_at BETWEEN :start_date AND :end_date
GROUP BY
    user_id
ORDER BY
    move_count DESC

حيث ستبدو النتائج النموذجية مثل:

user move_count
Username_1 5
Username_2 2

لاحظ أنه مع كلا الاستعلامين، يتم احتساب نقل أي عدد من المشاركات من موضوع إلى موضوع آخر كإجراء واحد فقط، بغض النظر عن عدد المشاركات التي تم نقلها. كما يتم احتساب نقل محتوى موضوع كامل إلى موضوع آخر كإجراء واحد فقط.

يمكن رؤية عدد المشاركات التي تم نقلها خلال كل إجراء في استعلام إجراءات نقل المشاركات الفردية تحت عمود post مع النص X posts were merged into an existing topic...، ومع ذلك، فإن هذه المعلومات غير موجودة في الاستعلام الثاني.

في استعلام إجراءات نقل المشاركات الفردية، قد ترى أيضًا مشاركات بالنص: A post was split to a new topic ...، والتي تشير إلى أنه تم تقسيم المشاركة إلى موضوع جديد بدلاً من نقلها إلى موضوع موجود، حيث تعتبر Discourse كلا الإجراءين split_topic، نظرًا لأنه يتم نقل المشاركات من موضوع إلى موضوع آخر.

إعجابَين (2)

تم تقسيم 5 مشاركات إلى موضوع جديد: مقاييس صفحة المستخدم