discourse/app/models/admin_dashboard_report.rb
Osama Sayegh 08fdf23a07
DEV: Scaffold backend for the new admin dashboard Reports section (#40017)
Adds the backend for the customisable Reports section on the new admin
dashboard, gated by `dashboard_improvements`.

- `admin_dashboard_reports` table + AR model for pinned reports.
- Plugin-extension contract via
  `Plugin::Instance#register_admin_dashboard_report_source` and the
  `AdminDashboard::Reports::SourceProvider` base class. Core ships a
  built-in provider; `discourse-data-explorer` registers its own.
- `AdminDashboard::Reports::Section` builds the `reports` entry in the
  dashboard's `sections` payload; `AdminDashboard::Reports::BulkFetch`
  powers the bulk endpoint. Both share a
  `Registry.dispatch_per_source` helper that batches work by source.
- `POST /admin/dashboard/reports/bulk` fetches data for multiple
  mounted reports in one round trip, batched by source.
- Defaults are seeded via core + plugin fixtures (Daily engaged users,
  Time to first response; `accepted_solutions` when Solved is in use).

Next: list-available and save-layout endpoints for the Manage Reports
modal, plus the frontend (section UI, modal, bulk loader).
2026-05-20 09:53:26 +03:00

41 lines
1.1 KiB
Ruby
Vendored

# frozen_string_literal: true
class AdminDashboardReport < ActiveRecord::Base
VISIBLE_CAP = 10
validates :source, presence: true
validates :identifier, presence: true
validates :identifier, uniqueness: { scope: :source }
validate :source_must_be_registered
before_validation :assign_default_position, on: :create
private
def assign_default_position
self.position ||= self.class.maximum(:position).to_i + 1
end
def source_must_be_registered
return if source.blank?
return if AdminDashboard::Reports::Registry.provider_for(source)
errors.add(:source, :invalid)
end
end
# == Schema Information
#
# Table name: admin_dashboard_reports
#
# id :bigint not null, primary key
# identifier :string not null
# position :integer not null
# source :string not null
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_admin_dashboard_reports_on_position (position)
# index_admin_dashboard_reports_on_source_and_identifier (source,identifier) UNIQUE
#