دليل مرجعي لتقارير لوحة تحكم المدير

:bookmark: This is a reference guide for describing how the Admin Dashboard Reports function, the data they’re displaying, the corresponding Data Explorer SQL queries, and where to find the Ruby code for each report.

:person_raising_hand: Required user level: Staff

Discourse contains several built-in admin dashboard Reports that can be useful for exploring stats about a community. To access these reports, you can visit discourse.example.com/admin/dashboard/reports on your site ( or click the Reports link at the top of the dashboard). Note that only staff users will have access to these reports.

Data from all users on a site is included in these reports (including staff activity like visiting admin pages). The only condition that is put on users in the reports is that they are ‘real’ users, which is used to exclude the system user from the reports.

Plugins can also add reports to the dashboard with add_report(name, &block).

:gem: Ruby models for most reports are located at: discourse/app/models/concerns/reports/. Some reports also reference: discourse/app/models/report.rb

:bulb: The dashboard-sql topics contain all of the corresponding SQL queries that can be used to generate reports identical to the Admin Dashboard Reports. These queries can be used within the Data Explorer plugin and for Running Data Explorer queries with the Discourse API

Accepted solutions

Displays daily tally of posts marked as solutions.

Ruby code: discourse-solved/plugin.rb at main · discourse/discourse-solved · GitHub

SQL Query: Dashboard Report - Accepted Solutions

Admin Logins

List of admin login times with locations.

Ruby Code: discourse/app/models/concerns/reports/staff_logins.rb

SQL Query: Dashboard Report - Admin Logins

Anonymous

Number of new pageviews by visitors not logged in to an account.

Ruby Code: discourse/app/models/concerns/reports/consolidated_page_views.rb

SQL Query: Dashboard Report - Anonymous

Bookmarks

Number of new topics and posts bookmarked.

Ruby Code: discourse/app/models/concerns/reports/bookmarks.rb

SQL Query: Dashboard Report - Bookmarks

Consolidated API Requests

API usage statistics by date, tracking both regular API requests and user API requests.

Ruby Code: discourse/app/models/concerns/reports/consolidated_api_requests.rb at main · discourse/discourse · GitHub

SQL Query: Dashboard Report - Consolidated API Requests

Consolidated Pageviews

Pageviews for logged in users, anonymous users and crawlers.

Ruby Code: discourse/app/models/concerns/reports/consolidated_page_views.rb

SQL Query: Dashboard Report - Consolidated Pageviews

Consolidated Pageviews with Browser Detection (Experimental)

Pageviews for logged in users, anonymous users, known crawlers and other. This experimental report ensures logged-in/anon requests are coming from real browsers before counting them.

Ruby Code: discourse/app/models/concerns/reports/consolidated_page_views_browser_detection.rb

SQL Query: Dashboard Report - Consolidated Pageviews with Browser Detection

DAU/MAU

Number of members that logged in in the last day divided by number of members that logged in in the last month – returns a % which indicates community ‘stickiness’. Aim for >20%.

Ruby Code: discourse/app/models/concerns/reports/dau_by_mau.rb

SQL Query: Dashboard Report - DAU/MAU

Daily Engaged Users

Number of users that have liked or posted in the last day.

Ruby Code: discourse/app/models/concerns/reports/daily_engaged_users.rb

SQL Query: Dashboard Report - Daily Engaged Users

Emails Sent

Number of new emails sent.

Ruby Code: discourse/app/models/concerns/reports/emails.rb

SQL Query: Dashboard Report - Emails Sent

Flags

Number of new flags.

Ruby Code: discourse/app/models/concerns/reports/flags.rb

SQL Query: Dashboard Report - Flags

Flags Status

List of flags’ statuses including type of flag, poster, flagger, and time to resolution.

Ruby Code: discourse/app/models/concerns/reports/flags_status.rb

SQL Query: Dashboard Report - Flags Status

Likes

Number of new likes.

Ruby Code: discourse/app/models/concerns/reports/likes.rb

SQL Query: Dashboard Report - Likes

Logged In

Number of new pageviews from logged in users.

Ruby Code: discourse/app/controllers/admin/reports_controller.rb#L5

SQL Query: Dashboard Report - Logged In

Moderator Activity

List of moderator activity including flags reviewed, reading time, topics created, posts created, personal messages created, and revisions.

SQL Query: Dashboard Report - Moderator Activity

Moderator Warning

Number of warnings sent by personal messages from moderators.

Ruby Code: discourse/app/models/concerns/reports/moderator_warning_private_messages.rb

SQL Query: Dashboard Report - Moderator Warnings

New Contributors

Number of users who made their first post during this period.

Ruby Code: discourse/app/models/concerns/reports/new_contributors.rb

SQL Query: Dashboard Report - New Contributors

Notify Moderators

Number of times moderators have been privately notified by a flag.

Ruby Code: discourse/app/models/concerns/reports/notify_moderators_private_messages.rb

SQL Query: Dashboard Report - Notify Moderators

Notify User

Number of times users have been privately notified by a flag.

Ruby Code: discourse/app/models/concerns/reports/notify_user_private_messages.rb

SQL Query: Dashboard Report - Notify User

Overall Sentiment

Number of posts classified either positive or negative with the “Sentiment” AI, over a specified period.

Ruby Code: discourse-ai/lib/sentiment/entry_point.rb at main · discourse/discourse-ai · GitHub

SQL Query: Dashboard Report - Overall Sentiment

Pageviews

Number of new pageviews from all visitors. Same as the total for Consolidated Pageviews.

Discourse uses the follow query to determine total pageviews:

SQL Query: Dashboard Report - Consolidated Pageviews

Post Edits

Number of new post edits.

Ruby Code: discourse/app/models/concerns/reports/post_edits.rb

SQL Query: Dashboard Report - Post Edits

Posts

New posts created during the selected time period

Ruby Code: discourse/app/models/concerns/reports/posts.rb

SQL Query: Dashboard Report - Posts

Post Emotion

Number of posts classified by AI with one of following emotions: Sadness, Surprise, Fear, Anger, Joy, Disgust - group by poster trust level, over a specified period.

Ruby Code: discourse-ai/lib/sentiment/entry_point.rb at main · discourse/discourse-ai · GitHub

SQL Query: Dashboard Report - Post Emotion

Reactions

List most recent reactions.

Ruby code: discourse-reactions/plugin.rb at main · discourse/discourse-reactions · GitHub

SQL Query: Dashboard Report - Reactions

Signups

New account registrations for this period.

Ruby Code: discourse/app/models/concerns/reports/signups.rb

SQL Query: Dashboard Report - Signups

Site Traffic

Ruby Code: discourse/app/models/concerns/reports/site_traffic.rb

SQL Query: Dashboard Report - Site Traffic

Suspicious Logins

Details of new logins that differ suspiciously from previous logins.

Ruby Code: discourse/app/models/concerns/reports/suspicious_logins.rb

SQL Query: Dashboard Report - Suspicious Logins

System

Number of personal messages sent automatically by the System.

Ruby Code: discourse/app/models/concerns/reports/system_private_messages.rb

SQL Query: Dashboard Report - System

Time to first response

Average time (in hours) of the first response to new topics.

Ruby Code: discourse/app/models/concerns/reports/time_to_first_response.rb + discourse/discourse/blob/main/app/models/topic.rb#L1799-L1844

SQL Query: Dashboard Report - Time to First Response

Top Ignored / Muted Users

Users who have been muted and/or ignored by many other users.

Ruby Code: discourse/app/models/concerns/reports/top_ignored_users.rb

SQL Query: Dashboard Report - Top Ignored / Muted Users

Top Referred Topics

Topics that have received the most clicks from external sources.

Ruby Code: discourse/app/models/concerns/reports/top_referred_topics.rb

SQL Query: Dashboard Report - Top Referred Topics

Top Referrers

Users listed by number of clicks on links they have shared.

Ruby Code: discourse/app/models/concerns/reports/top_referrers.rb

SQL Query: Dashboard Report - Top Referrers

Top Traffic Sources

External sources that have linked to this site the most.

Ruby Code: discourse/app/models/concerns/reports/top_traffic_sources.rb

SQL Query: Dashboard Report - Top Traffic Sources

Top Uploads

List all uploads by extension, filesize and author.

Ruby Code: discourse/app/models/concerns/reports/top_uploads.rb

SQL Query: Dashboard Report - Top Uploads

Top Users by likes received

Top 10 users who have received likes.

Ruby Code: discourse/app/models/concerns/reports/top_users_by_likes_received.rb

SQL Query: Dashboard Report - Top Users by Likes Received

Top Users by likes received from a user with a lower trust level

Top 10 users in a higher trust level being liked by people in a lower trust level.

Ruby Code: discourse/app/models/concerns/reports/top_users_by_likes_received_from_inferior_trust_level.rb

SQL Query: Dashboard Report - Top Users by Likes Received from a User with a Lower Trust Level

Top Users by likes received from a variety of people

Top 10 users who have had likes from a wide range of people.

Ruby Code: discourse/app/models/concerns/reports/top_users_by_likes_received_from_a_variety_of_people.rb

SQL Query: Dashboard Report - Top Users by Likes Received From a Variety of People

Topics

New topics created during this period.

Ruby Code: discourse/app/models/concerns/reports/topics.rb

SQL Query: Dashboard Report - Topics

Topics with no response

Number of new topics created that did not receive a response.

Ruby Code: discourse/app/models/concerns/reports/topics_with_no_response.rb

SQL Query: Dashboard Report - Topics with No Response

Topic View Stats

Ruby Code: discourse/app/models/concerns/reports/topic_view_stats.rb

SQL Query: Dashboard Report - Topic View Stats

Trending Search Terms

Most popular search terms with their click-through rates.

Ruby Code: discourse/app/models/concerns/reports/trending_search.rb

SQL Query: Dashboard Report - Trending Search Terms

Trust Level growth

Number of users who increased their Trust Level during this period.

The Trust Level Growth report is pulling data from the user_histories table in the Discourse database. Specifically, this report is counting the number of times a user_histories.action is recorded for an increase in a user trust level.

Ruby Code: discourse/app/models/concerns/reports/trust_level_growth.rb

SQL Query: Dashboard Report - Trust Level Growth

Unaccepted policies

This dashboard report identifies topics with policies that have not been accepted by certain users.

Ruby code: discourse-policy/plugin.rb at main · discourse/discourse-policy · GitHub

SQL Query: Dashboard Report - Unaccepted Policies

User Flagging Ratio

List of users ordered by ratio of staff response to their flags (disagreed to agreed).

Ruby Code: discourse/app/models/concerns/reports/user_flagging_ratio.rb

SQL Query: Dashboard Report - User Flagging Ratio

User notes

List most recent user notes.

Ruby code: discourse-user-notes/plugin.rb at main · discourse/discourse-user-notes · GitHub

SQL Query: Dashboard Report - User Notes

User Profile Views

Total new views of user profiles.

Ruby Code: discourse/app/models/concerns/reports/profile_views.rb

SQL Query: Dashboard Report - User Profile Views

User Visits

The total number of logged-in user visits in the forum for the selected time period (today, yesterday, last 7 days, etc).

A User Visit is counted anytime a unique logged in user visits the site, up to once per day. For example, if a user visited a site every day within a week, Discourse would count that as 7 user visits.

Ruby Code: discourse/app/models/concerns/reports/visits.rb

SQL Query: Dashboard Report - User Visits

User Visits (mobile)

Number of unique logged-in users who visited using a mobile device.

Ruby Code: discourse/app/models/concerns/reports/mobile_visits.rb

SQL Query: Dashboard Report - User Visits

User-to-User (excluding replies)

Number of newly initiated personal messages.

Ruby Code: discourse/app/models/concerns/reports/user_to_user_private_messages.rb

SQL Query: Dashboard Report - User-to-User

User-to-User (with replies)

Number of all new personal messages and responses.

Ruby Code: discourse/app/models/concerns/reports/user_to_user_private_messages_with_replies.rb

SQL Query: Dashboard Report - User-to-User

Users per Trust Level

Number of users grouped by trust level.

Ruby Code: discourse/app/models/concerns/reports/users_by_trust_level.rb

SQL Query: Dashboard Report - Users Per Trust Level

Users per Type

Number of users grouped by admin, moderator, suspended, and silenced.

Ruby Code: discourse/app/models/concerns/reports/users_by_type.rb

SQL Query: Dashboard Report - Users Per Type

Web Crawler Pageviews

Total pageviews from web crawlers over time.

Ruby Code: discourse/app/models/report.rb

SQL Query: Dashboard Report - Web Crawler Pageviews

Web Crawler User Agents

List of web crawler user agents, sorted by pageviews.

Ruby Code: discourse/app/models/concerns/reports/web_crawlers.rb

SQL Query: Dashboard Report - Web Crawler User Agents

Last edited by @SaraDev 2025-10-15T20:49:23Z

Last checked by @SaraDev 2025-01-28T21:42:37Z

Check documentPerform check on document:
17 إعجابًا

لا أرى رابطًا لهذا في /admin. هل أفشل في القراءة؟ يبدو أن هذا يجب أن يكون أكثر قابلية للاكتشاف. أعتقد أنني كنت أعرف أن هذه التقارير كانت هنا ولكنني بحثت ولم أتمكن من العثور عليها.

على الرغم من أن الأمر استغرق مني بضع دقائق فقط للعثور عليه، إلا أنه قد يكون من الجيد إضافة شيء مثل

3 إعجابات

نعم، قد يكون من الجيد ذكرها في رسالة خاصة للموظفين عند إنشاء موقع لأول مرة. :thinking:

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

:crying_cat_face:

آسف. بالتأكيد اعتقدت أنني رأيتها في مكان ما من قبل.

لا يمكنك جعل الناس يقرؤون الأشياء. . . . باستثناء أنه يمكنني قراءة الكود المصدري لمعرفة كيفية القيام بذلك في إضافة؟

ولكن ربما قم بتحديث ما سبق إلى

أعتقد أن هذا قد يكون ما أربكني حقًا. (ولكن لا، ليس لدي عذر.)

لقد جعلت الموضوع ويكي، تفضل! :+1:

إعجابَين (2)

هذا لا يتطابق مع واجهة المستخدم (تستخدم الواجهة 20%)، أيهما يجب أن يكون؟

إعجابَين (2)

تم اكتشاف ذلك جيدًا. تم تحديثه مؤخرًا إلى 20٪. سأقوم بإجراء التغيير في المنشور الأصلي. :slight_smile: :+1:

إعجابَين (2)

مرحباً @SaraDev هل يمكن الحصول على مخرجات هذا التقرير باستخدام استعلام SQL؟ هل يمكنك مشاركته؟
شكراً

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

نعم، يمكنك استخدام تقرير SQL التالي لأهم مصادر الزيارات:

-- [params]
-- date :start_date = 01/05/2023
-- date :end_date = 03/06/2023

WITH count_links AS (

SELECT COUNT(*) AS clicks,
       ind.name AS domain
FROM incoming_links il
  INNER JOIN posts p ON p.deleted_at ISNULL AND p.id = il.post_id
  INNER JOIN topics t ON t.deleted_at ISNULL AND t.id = p.topic_id
  INNER JOIN incoming_referers ir ON ir.id = il.incoming_referer_id
  INNER JOIN incoming_domains ind ON ind.id = ir.incoming_domain_id
WHERE t.archetype = 'regular'
  AND il.created_at::date BETWEEN :start_date AND :end_date
GROUP BY ind.name
ORDER BY clicks DESC
),

count_topics AS (

SELECT COUNT(DISTINCT p.topic_id) AS topics,
       ind.name AS domain
FROM incoming_links il
INNER JOIN posts p ON p.deleted_at ISNULL AND p.id = il.post_id
INNER JOIN topics t ON t.deleted_at ISNULL AND t.id = p.topic_id
INNER JOIN incoming_referers ir ON ir.id = il.incoming_referer_id
INNER JOIN incoming_domains ind ON ind.id = ir.incoming_domain_id
WHERE t.archetype = 'regular'
  AND il.created_at > (CURRENT_TIMESTAMP - INTERVAL '30 DAYS')
GROUP BY ind.name
)

SELECT cl.domain,
       cl.clicks AS "Clicks",
       ct.topics AS "Topics"
FROM count_links cl
JOIN count_topics ct ON cl.domain = ct.domain
LIMIT 10

مع هذا الاستعلام، لاحظ أن معلمات التاريخ تقبل التواريخ بالتنسيق يوم/شهر/سنة.

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

مرحباً @SaraDev، شكراً لمشاركتك الاستعلام.
سؤال أعم حول هذا التقرير، وجدول incoming_links في الواقع - إنه يمثل الزيارات لصفحات المنشورات فقط وليس الزيارات لجميع صفحات المنتدى، صحيح؟

السياق: أنا أتطلع إلى تحليل اتجاهات الزيارات الإجمالية للمنتدى وكنت آمل في الحصول على الزيارات الإجمالية حسب المصادر من تقرير مصادر الزيارات الأعلى.
ولكن بينما الزيارات الإجمالية حوالي 272 ألف في الشهر الماضي (للمستخدمين والمجهولين)، فإن إجمالي النقرات في تقرير مصادر الزيارات لنفس الإطار الزمني هو 59 ألف فقط.
أيضاً، أرى أنك تستخدم inner join مع جدولي topics و posts مما يعني أنه إذا لم يكن هناك post_id مرتبط بالنقرة، فلن تحتسبها.

هل يمكنك تأكيد استنتاجي وربما شرح المنطق وراء جدول incoming_links؟

مرحباً @SaraDev لقد قمت بتشغيل هذا الاستعلام والنتيجة لا تتطابق تمامًا مع تقرير المشاركات في علامة التبويب العامة.
على سبيل المثال في 30 نوفمبر:
الاستعلام = 112 مشاركة
التقرير = 120 مشاركة
هل يمكنك التحقق من الفجوة؟
شكرا

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

فقط للعلم @Yotam_Hagay - على الرغم من أن سارة هي صاحبة الموضوع الأصلي، إلا أن الدليل هو مسؤولية الجميع :slight_smile: :discourse: لا داعي لذكر @ على كل مشاركة. :slight_smile:

إعجابَين (2)

شكرا @JammyDodger للتوضيح.
هل هناك أي شخص آخر يمكنني الإشارة إليه أو اللجوء إليه للحصول على إجابة؟

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

نتائج هذا الاستعلام مختلفة قليلاً عن تقرير وقت الاستجابة الأولية:
في 8 نوفمبر على سبيل المثال:
الاستعلام: 93 ساعة
التقرير: 116 ساعة
هل يمكن لأحد أن ينصحني؟

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

أعتقد أن بعض هذه قد تستغرق بعض الوقت للبحث فيها. أنا ألقي نظرة عليها بنفسي لمعرفة ما يجري (على الرغم من أن الفجوة بين مهاراتي في SQL ومهاراتي في Ruby كبيرة جدًا :slight_smile:).

لكن استمر في تقديم النتائج حيث سيكون من الرائع ترسيخ كل هذه المعلومات. :+1:

إعجابَين (2)

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

أعتقد أن استعلام SQL سيبدو كالتالي:

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

SELECT
    p.created_at::date AS "اليوم",
    COUNT(p.id) AS "العدد"
FROM posts p
INNER JOIN topics t ON t.id = p.topic_id AND t.deleted_at ISNULL
WHERE p.created_at::date BETWEEN :start_date AND :end_date
    AND p.deleted_at ISNULL
    AND t.archetype = 'regular'
    AND p.post_type = 1
GROUP BY p.created_at::date
ORDER BY 1

هل يمكنك تشغيل ذلك على موقعك ومعرفة ما إذا كان يتطابق؟

إعجابَين (2)

شكرًا جيمي، سأتحقق!
أعمل حاليًا على تحليل الوقت المستغرق لأول استجابة، لذا سأكون ممتنًا لو أمكنك إلقاء نظرة على هذا أيضًا.

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

بالنظر إلى إصدار SQL، أعتقد أنه يفتقد AND p.user_id <> t.user_id لاستبعاد الردود من المنشئ الأصلي للموضوع. إذا أضفت ذلك، فإنه يعطيني الوقت الدقيق بين المنشئ الأصلي للموضوع والاستجابة الأولى من شخص آخر:

--[params]
-- date :date_start
-- date :date_end

WITH first_reply AS (
    SELECT
        p.topic_id,
        MIN(post_number) post_number,
        t.created_at
    FROM posts p
    INNER JOIN topics t ON (p.topic_id = t.id)
    WHERE p.deleted_at IS NULL
        AND p.user_id <> t.user_id
        AND p.post_number != 1
        AND p.post_type = 1
        AND p.user_id > 0
        AND t.user_id > 0
        AND t.deleted_at IS NULL
        AND t.archetype = 'regular'
        AND t.created_at::date BETWEEN :date_start AND :date_end
    GROUP BY p.topic_id, t.created_at
    ORDER BY 2 DESC
)

SELECT
    p.topic_id,
    fr.created_at::date dt_topic_created,
    (p.created_at - fr.created_at) response_time
FROM posts p
INNER JOIN first_reply fr
    ON fr.topic_id = p.topic_id
    AND fr.post_number = p.post_number
    AND p.created_at > fr.created_at
ORDER BY response_time

أعتقد أيضًا أن تقرير المخزون بالكسور العشرية بدلاً من الساعات والدقائق كما في SQL. سأحاول مرة أخرى لجعله مطابقًا. :+1:


تحديث صغير لتضمين AVG ليكون أكثر تشابهًا مع ناتج تقرير المخزون:

--[params]
-- date :date_start
-- date :date_end

WITH first_reply AS (
    SELECT
        p.topic_id,
        MIN(post_number) post_number,
        t.created_at
    FROM posts p
    INNER JOIN topics t ON p.topic_id = t.id
    WHERE p.deleted_at IS NULL
        AND p.user_id <> t.user_id
        AND p.post_type = 1
        AND p.user_id > 0
        AND t.user_id > 0
        AND t.deleted_at IS NULL
        AND t.archetype = 'regular'
        AND t.created_at::date BETWEEN :date_start AND :date_end
    GROUP BY p.topic_id, t.created_at
)

SELECT
    fr.created_at::date dt_topic_created,
    AVG(p.created_at - fr.created_at) response_time
FROM posts p
INNER JOIN first_reply fr
    ON fr.topic_id = p.topic_id
    AND fr.post_number = p.post_number
    AND p.created_at > fr.created_at
GROUP BY fr.created_at::date
ORDER BY response_time

يبدو أن هذا يتوافق مع تقرير المخزون طالما أنك تأخذ في الاعتبار أن أحدهما بالكسور العشرية والآخر بالساعات والدقائق. أنا متأكد من وجود طريقة لتحويل response_time في SQL إلى كسور عشرية، لكن الساعات والدقائق تبدو طريقة أكثر بديهية للقيام بذلك. (أعتقد أن هناك أيضًا بعض المعايير الإضافية التي قد لا تكون ضرورية، ولكنها قد تكون أيضًا إجراءً وقائيًا ضد الظروف غير العادية، لذلك تركت تلك الأجزاء كما هي في النهاية حتى أتمكن من التأكيد بشكل قاطع :slight_smile:)

هل يمكنك تشغيل هذا ومعرفة كيف يتطابق؟

4 إعجابات

نعم، أصبح المجموع الآن مطابقًا للأرقام المعروضة في تقرير المخزون، شكرًا لك!
تعليق واحد فقط -
وجدت أن دالة AVG أدناه تُرجع نتائج مفقودة في حالة تجاوز الوقت 24 ساعة (أعتقد أن قسم عدد الأيام مفقود).

AVG(p.created_at - fr.created_at)::time response_time

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

نعم، كان تحويل النوع إلى time اختيارًا سيئًا. :slight_smile: إذا قمت بإزالة ::time، فسيعود إلى الإصدار الأكثر دقة (وإن كان أكثر صعوبة على العين).

سأقوم بتحرير ما ورد أعلاه أيضًا. :+1:

إعجابَين (2)