Files
EventHubBack/src/handlers/admin/admin_handler_report_stats.erl
T

97 lines
3.6 KiB
Erlang
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
%%%-------------------------------------------------------------------
%%% @doc Административный обработчик статистики по жалобам.
%%% GET /v1/admin/reports/stats возвращает общее количество,
%%% распределение по типам цели, статусам и топ-10 целей по жалобам.
%%% @end
%%%-------------------------------------------------------------------
-module(admin_handler_report_stats).
-behaviour(cowboy_handler).
-export([init/2]).
-export([trails/0]).
-include("records.hrl").
%%% cowboy_handler callback
-spec init(cowboy_req:req(), any()) -> {ok, cowboy_req:req(), any()}.
init(Req, _Opts) ->
case cowboy_req:method(Req) of
<<"GET">> -> get_report_stats(Req);
_ -> handler_utils:send_error(Req, 405, <<"Method not allowed">>)
end.
%%% Swagger metadata
-spec trails() -> [map()].
trails() ->
[
#{
path => <<"/v1/admin/reports/stats">>,
method => <<"GET">>,
description => <<"Get detailed report statistics (total, by target type, by status, top 10 targets by reports)">>,
tags => [<<"Statistics">>],
responses => #{
200 => #{
description => <<"Report statistics object">>,
content => #{<<"application/json">> => #{schema => report_stats_schema()}}
},
403 => #{description => <<"Admin access required">>}
}
}
].
report_stats_schema() ->
#{
type => object,
properties => #{
<<"total_reports">> => #{type => integer, description => <<"Total number of reports">>},
<<"reports_by_target_type">> => #{
type => object,
description => <<"Number of reports grouped by target type (event, calendar, review)">>,
additionalProperties => #{type => integer}
},
<<"reports_by_status">> => #{
type => object,
description => <<"Number of reports grouped by status (pending, reviewed, dismissed)">>,
additionalProperties => #{type => integer}
},
<<"top_targets_by_reports">> => #{
type => array,
description => <<"Top 10 targets by number of reports">>,
items => #{
type => object,
properties => #{
<<"target_type">> => #{type => string},
<<"target_id">> => #{type => string},
<<"report_count">> => #{type => integer}
}
}
}
}
}.
%%% Internal functions
%% @doc GET /v1/admin/reports/stats статистика по жалобам.
-spec get_report_stats(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}.
get_report_stats(Req) ->
case handler_utils:auth_admin(Req) of
{ok, _AdminId, Req1} ->
Total = core_report:count_reports(),
ByTargetType = core_report:count_reports_by_target_type(),
ByStatus = core_report:count_reports_by_status(),
Top10 = core_report:get_top_targets_by_reports(10),
Stats = #{
<<"total_reports">> => Total,
<<"reports_by_target_type">> => maps:from_list([{atom_to_binary(Type, utf8), Count} || {Type, Count} <- ByTargetType]),
<<"reports_by_status">> => maps:from_list([{atom_to_binary(Status, utf8), Count} || {Status, Count} <- ByStatus]),
<<"top_targets_by_reports">> => lists:map(fun({TargetType, TargetId, Count}) ->
#{
<<"target_type">> => atom_to_binary(TargetType, utf8),
<<"target_id">> => TargetId,
<<"report_count">> => Count
}
end, Top10)
},
handler_utils:send_json(Req1, 200, Stats);
{error, Code, Msg, Req1} ->
handler_utils:send_error(Req1, Code, Msg)
end.