who_need_help/lib/who_need_help/admin.ex

64 lines
2.1 KiB
Elixir

defmodule WhoNeedHelp.Admin do
@moduledoc "Read-only operational summaries for the staff workspace."
import Ecto.Query
alias WhoNeedHelp.Accounts
alias WhoNeedHelp.Accounts.{Scope, StaffRoleAssignment, User}
alias WhoNeedHelp.Catalog.CategoryProposal
alias WhoNeedHelp.ContentRemoval.Notice
alias WhoNeedHelp.Repo
alias WhoNeedHelp.Support.SupportRequest
alias WhoNeedHelp.Trust.{AbuseSignal, Report}
def dashboard(%Scope{user: user}) do
if Accounts.authorized?(user, :dashboard_view) do
%{}
|> maybe_put(user, :support_view, :support_open, fn ->
count(SupportRequest, [status: [:open, :reviewing, :waiting_for_requester]], true)
end)
|> maybe_put(user, :legal_view, :legal_open, fn ->
count(Notice, status: [:open, :urgent_review, :reviewing, :needs_information])
end)
|> maybe_put(user, :moderation_view, :reports_open, fn ->
count(Report, status: [:open, :reviewing])
end)
|> maybe_put(user, :moderation_view, :signals_open, fn ->
count(AbuseSignal, status: [:open])
end)
|> maybe_put(user, :categories_manage, :category_proposals_open, fn ->
count(CategoryProposal, status: [:open])
end)
|> maybe_put(user, :users_view, :users_total, fn -> Repo.aggregate(User, :count) end)
|> maybe_put(user, :staff_manage, :staff_total, fn ->
Repo.one(
from assignment in StaffRoleAssignment,
select: count(assignment.user_id, :distinct)
)
end)
else
%{}
end
end
defp maybe_put(summary, user, permission, key, value_fun) do
if Accounts.authorized?(user, permission),
do: Map.put(summary, key, value_fun.()),
else: summary
end
defp count(schema, filters, verified_only \\ false) do
query =
Enum.reduce(filters, schema, fn
{:status, statuses}, query -> where(query, [record], record.status in ^statuses)
end)
query =
if verified_only,
do: where(query, [record], not is_nil(record.contact_verified_at)),
else: query
Repo.aggregate(query, :count)
end
end