FEATURE: participating users statistics (#28322)
Adds a new statistics (hidden from the UI, but available via the API) that tracks daily participating users. A user is considered as "participating" if they have - Reacted to a post - Replied to a topic - Created a new topic - Created a new PM - Sent a chat message - Reacted to a chat message Internal ref - t/131013
This commit is contained in:
parent
5b78bbd138
commit
d10fd36319
|
@ -46,6 +46,9 @@ class Stat
|
|||
Stat.new("users", show_in_ui: true, expose_via_api: true) { Statistics.users },
|
||||
Stat.new("active_users", show_in_ui: true, expose_via_api: true) { Statistics.active_users },
|
||||
Stat.new("likes", show_in_ui: true, expose_via_api: true) { Statistics.likes },
|
||||
Stat.new("participating_users", show_in_ui: false, expose_via_api: true) do
|
||||
Statistics.participating_users
|
||||
end,
|
||||
]
|
||||
end
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class Statistics
|
||||
def self.active_users
|
||||
{
|
||||
last_day: User.where("last_seen_at > ?", 1.days.ago).count,
|
||||
last_day: User.where("last_seen_at > ?", 1.day.ago).count,
|
||||
"7_days": User.where("last_seen_at > ?", 7.days.ago).count,
|
||||
"30_days": User.where("last_seen_at > ?", 30.days.ago).count,
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ class Statistics
|
|||
def self.likes
|
||||
{
|
||||
last_day:
|
||||
UserAction.where(action_type: UserAction::LIKE).where("created_at > ?", 1.days.ago).count,
|
||||
UserAction.where(action_type: UserAction::LIKE).where("created_at > ?", 1.day.ago).count,
|
||||
"7_days":
|
||||
UserAction.where(action_type: UserAction::LIKE).where("created_at > ?", 7.days.ago).count,
|
||||
"30_days":
|
||||
|
@ -23,7 +23,7 @@ class Statistics
|
|||
|
||||
def self.posts
|
||||
{
|
||||
last_day: Post.where("created_at > ?", 1.days.ago).count,
|
||||
last_day: Post.where("created_at > ?", 1.day.ago).count,
|
||||
"7_days": Post.where("created_at > ?", 7.days.ago).count,
|
||||
"30_days": Post.where("created_at > ?", 30.days.ago).count,
|
||||
count: Post.count,
|
||||
|
@ -32,7 +32,7 @@ class Statistics
|
|||
|
||||
def self.topics
|
||||
{
|
||||
last_day: Topic.listable_topics.where("created_at > ?", 1.days.ago).count,
|
||||
last_day: Topic.listable_topics.where("created_at > ?", 1.day.ago).count,
|
||||
"7_days": Topic.listable_topics.where("created_at > ?", 7.days.ago).count,
|
||||
"30_days": Topic.listable_topics.where("created_at > ?", 30.days.ago).count,
|
||||
count: Topic.listable_topics.count,
|
||||
|
@ -41,10 +41,38 @@ class Statistics
|
|||
|
||||
def self.users
|
||||
{
|
||||
last_day: User.real.where("created_at > ?", 1.days.ago).count,
|
||||
last_day: User.real.where("created_at > ?", 1.day.ago).count,
|
||||
"7_days": User.real.where("created_at > ?", 7.days.ago).count,
|
||||
"30_days": User.real.where("created_at > ?", 30.days.ago).count,
|
||||
count: User.real.count,
|
||||
}
|
||||
end
|
||||
|
||||
def self.participating_users
|
||||
{
|
||||
last_day: participating_users_count(1.day.ago),
|
||||
"7_days": participating_users_count(7.days.ago),
|
||||
"30_days": participating_users_count(30.days.ago),
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.participating_users_count(date)
|
||||
subqueries = [
|
||||
"SELECT DISTINCT user_id FROM user_actions WHERE created_at > :date AND action_type IN (:action_types)",
|
||||
]
|
||||
|
||||
if ActiveRecord::Base.connection.data_source_exists?("chat_messages")
|
||||
subqueries << "SELECT DISTINCT user_id FROM chat_messages WHERE created_at > :date"
|
||||
end
|
||||
|
||||
if ActiveRecord::Base.connection.data_source_exists?("chat_message_reactions")
|
||||
subqueries << "SELECT DISTINCT user_id FROM chat_message_reactions WHERE created_at > :date"
|
||||
end
|
||||
|
||||
sql = "SELECT COUNT(user_id) FROM (#{subqueries.join(" UNION ")}) u"
|
||||
|
||||
DB.query_single(sql, date: date, action_types: UserAction::USER_ACTED_TYPES).first
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Statistics do
|
||||
describe "#participating_users" do
|
||||
it "returns users who have sent a chat message" do
|
||||
Fabricate(:chat_message)
|
||||
expect(described_class.participating_users[:last_day]).to eq(1)
|
||||
end
|
||||
|
||||
it "returns users who have reacted to a chat message" do
|
||||
Fabricate(:chat_message_reaction)
|
||||
expect(described_class.participating_users[:last_day]).to eq(2) # 2 because the chat message creator is also counted
|
||||
end
|
||||
end
|
||||
end
|
|
@ -62,6 +62,8 @@ RSpec.describe DiscourseHub do
|
|||
expect(json["likes_count"]).to be_present
|
||||
expect(json["likes_7_days"]).to be_present
|
||||
expect(json["likes_30_days"]).to be_present
|
||||
expect(json["participating_users_7_days"]).to be_present
|
||||
expect(json["participating_users_30_days"]).to be_present
|
||||
expect(json["installed_version"]).to be_present
|
||||
expect(json["branch"]).to be_present
|
||||
end
|
||||
|
|
|
@ -105,6 +105,9 @@ TEXT
|
|||
:likes_7_days,
|
||||
:likes_30_days,
|
||||
:likes_count,
|
||||
:participating_users_last_day,
|
||||
:participating_users_7_days,
|
||||
:participating_users_30_days,
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Statistics do
|
||||
describe "#participating_users" do
|
||||
it "returns no participating users by default" do
|
||||
pu = described_class.participating_users
|
||||
expect(pu[:last_day]).to eq(0)
|
||||
expect(pu[:"7_days"]).to eq(0)
|
||||
expect(pu[:"30_days"]).to eq(0)
|
||||
end
|
||||
|
||||
it "returns users who have reacted to a post" do
|
||||
Fabricate(:user_action, action_type: UserAction::LIKE)
|
||||
expect(described_class.participating_users[:last_day]).to eq(1)
|
||||
end
|
||||
|
||||
it "returns users who have created a new topic" do
|
||||
Fabricate(:user_action, action_type: UserAction::NEW_TOPIC)
|
||||
expect(described_class.participating_users[:last_day]).to eq(1)
|
||||
end
|
||||
|
||||
it "returns users who have replied to a post" do
|
||||
Fabricate(:user_action, action_type: UserAction::REPLY)
|
||||
expect(described_class.participating_users[:last_day]).to eq(1)
|
||||
end
|
||||
|
||||
it "returns users who have created a new PM" do
|
||||
Fabricate(:user_action, action_type: UserAction::NEW_PRIVATE_MESSAGE)
|
||||
expect(described_class.participating_users[:last_day]).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -68,6 +68,8 @@ RSpec.describe SiteController do
|
|||
expect(json["likes_count"]).to be_present
|
||||
expect(json["likes_7_days"]).to be_present
|
||||
expect(json["likes_30_days"]).to be_present
|
||||
expect(json["participating_users_7_days"]).to be_present
|
||||
expect(json["participating_users_30_days"]).to be_present
|
||||
end
|
||||
|
||||
it "is not visible if site setting share_anonymized_statistics is disabled" do
|
||||
|
|
Loading…
Reference in New Issue