main
rb 45 lines 2.3 KB
Raw
1 # frozen_string_literal: true
2
3 module Admin
4 # Read model for the admin dashboard. Holds every rollup the overview page
5 # needs so the controller stays a one-liner and the numbers are unit-testable
6 # without going through HTTP. All methods are memoized; build one per request.
7 class DashboardMetrics
8 # --- Growth --------------------------------------------------------------
9 def total_users = @total_users ||= User.count
10 def admins_count = @admins_count ||= User.admins.count
11 def new_users_7d = @new_users_7d ||= User.where(created_at: 7.days.ago..).count
12 def new_users_30d = @new_users_30d ||= User.where(created_at: 30.days.ago..).count
13
14 # --- Catalog -------------------------------------------------------------
15 def total_repos = @total_repos ||= Repository.count
16 def code_repos = @code_repos ||= Repository.where(kind: "code").count
17 def model_repos = @model_repos ||= Repository.where(kind: "model").count
18 def private_repos = @private_repos ||= Repository.where(is_private: true).count
19
20 # --- Recurring revenue ---------------------------------------------------
21 # group(:plan) keys back as the enum's string labels ("pro", "team").
22 def paying_by_plan
23 @paying_by_plan ||= Subscription.where(status: %i[active trialing])
24 .where.not(plan: :free)
25 .group(:plan).count
26 end
27
28 def paying(plan) = paying_by_plan[plan.to_s].to_i
29 def trialing_count = @trialing_count ||= Subscription.where(status: :trialing).count
30 def past_due_count = @past_due_count ||= Subscription.where(status: :past_due).count
31 def estimated_mrr = @estimated_mrr ||= BillingMetrics.estimated_mrr
32
33 # --- Cloud consumption ---------------------------------------------------
34 def cloud_requests_month
35 @cloud_requests_month ||=
36 CloudUsage.where(period_key: Time.current.utc.strftime("%Y-%m")).sum(:request_count)
37 end
38
39 def cloud_sessions_count = @cloud_sessions_count ||= CloudSession.count
40
41 # --- Recent activity -----------------------------------------------------
42 def recent_users = @recent_users ||= User.order(created_at: :desc).limit(8).to_a
43 def recent_repos = @recent_repos ||= Repository.includes(:user).order(created_at: :desc).limit(8).to_a
44 end
45 end