107 lines
3.6 KiB
Erlang
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). |