64 lines
2.1 KiB
Elixir
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
|