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

107 lines
3.6 KiB
Erlang

%%%-------------------------------------------------------------------
%%% @doc Административный обработчик статистики по календарям.
%%% GET /v1/admin/calendars/stats
%%% @end
%%%-------------------------------------------------------------------
-module(admin_handler_calendar_stats).
-behaviour(cowboy_handler).
-export([init/2]).
-export([trails/0]).
-include("records.hrl").
-spec init(cowboy_req:req(), any()) -> {ok, cowboy_req:req(), any()}.
init(Req, _Opts) ->
case cowboy_req:method(Req) of
<<"GET">> -> get_calendar_stats(Req);
_ -> handler_utils:send_error(Req, 405, <<"Method not allowed">>)
end.
-spec trails() -> [map()].
trails() ->
[ #{
path => <<"/v1/admin/calendars/stats">>,
method => <<"GET">>,
description => <<"Calendar statistics">>,
tags => [<<"Statistics">>],
responses => #{
200 => #{
description => <<"Calendar statistics object">>,
content => #{<<"application/json">> => #{schema => calendar_stats_schema()}}
}
}
} ].
calendar_stats_schema() ->
#{
type => object,
properties => #{
<<"total_calendars">> => #{type => integer},
<<"calendars_by_type">> => #{
type => object,
additionalProperties => #{type => integer}
},
<<"calendars_by_status">> => #{
type => object,
additionalProperties => #{type => integer}
},
<<"top_calendars_by_reviews">> => #{
type => array,
items => calendar_rank_schema()
},
<<"top_calendars_by_positive_reviews">> => #{
type => array,
items => calendar_rank_schema()
},
<<"top_calendars_by_negative_reviews">> => #{
type => array,
items => calendar_rank_schema()
},
<<"top_calendars_by_rating">> => #{
type => array,
items => calendar_rank_schema()
}
}
}.
calendar_rank_schema() ->
#{
type => object,
properties => #{
<<"id">> => #{type => string},
<<"title">> => #{type => string},
<<"rating_avg">> => #{type => number, format => float},
<<"review_count">> => #{type => integer}
}
}.
%%% Internal functions
get_calendar_stats(Req) ->
case handler_utils:auth_admin(Req) of
{ok, _AdminId, Req1} ->
Total = core_calendar:count_calendars(),
ByType = core_calendar:count_calendars_by_type(),
ByStatus = core_calendar:count_calendars_by_status(),
TopReviews = core_calendar:get_top_calendars_by_reviews(10),
TopPositive = core_calendar:get_top_calendars_by_positive_reviews(10),
TopNegative = core_calendar:get_top_calendars_by_negative_reviews(10),
TopRating = core_calendar:get_top_calendars_by_rating(10),
Stats = #{
<<"total_calendars">> => Total,
<<"calendars_by_type">> => maps:from_list([{atom_to_binary(T, utf8), C} || {T, C} <- ByType]),
<<"calendars_by_status">> => maps:from_list([{atom_to_binary(S, utf8), C} || {S, C} <- ByStatus]),
<<"top_calendars_by_reviews">> => format_calendar_list(TopReviews),
<<"top_calendars_by_positive_reviews">> => format_calendar_list(TopPositive),
<<"top_calendars_by_negative_reviews">> => format_calendar_list(TopNegative),
<<"top_calendars_by_rating">> => format_calendar_list(TopRating)
},
handler_utils:send_json(Req1, 200, Stats);
{error, Code, Msg, Req1} ->
handler_utils:send_error(Req1, Code, Msg)
end.
format_calendar_list(List) ->
lists:map(fun(#calendar{id = Id, title = Title, rating_avg = RAvg}) ->
#{<<"id">> => Id, <<"title">> => Title, <<"rating_avg">> => RAvg}
end, List).