Рефакторинг обработчиков. Часть 3 #21

This commit is contained in:
2026-05-13 23:02:59 +03:00
parent 61bb44ab4a
commit 40806df62a
91 changed files with 6138 additions and 7150 deletions
+35 -49
View File
@@ -1,6 +1,5 @@
%%%-------------------------------------------------------------------
%%% @doc Обработчик конкретного календаря (клиентский API).
%%%
%%% GET – получить информацию о календаре.
%%% PUT – обновить календарь (владельцем).
%%% DELETE – удалить календарь (владельцем).
@@ -16,11 +15,7 @@
%%% cowboy_handler callback
-spec init(cowboy_req:req(), any()) -> {ok, cowboy_req:req(), any()}.
init(Req, Opts) ->
handle(Req, Opts).
-spec handle(cowboy_req:req(), any()) -> {ok, cowboy_req:req(), any()}.
handle(Req, _Opts) ->
init(Req, _Opts) ->
case cowboy_req:method(Req) of
<<"GET">> -> get_calendar(Req);
<<"PUT">> -> update_calendar(Req);
@@ -31,15 +26,13 @@ handle(Req, _Opts) ->
%%% Swagger metadata
-spec trails() -> [map()].
trails() ->
BaseParams = [
#{
name => <<"id">>,
in => <<"path">>,
description => <<"Calendar ID">>,
required => true,
schema => #{type => string}
}
],
BaseParams = [#{
name => <<"id">>,
in => <<"path">>,
description => <<"Calendar ID">>,
required => true,
schema => #{type => string}
}],
[
#{ % GET
path => <<"/v1/calendars/:id">>,
@@ -51,9 +44,7 @@ trails() ->
200 => #{
description => <<"Calendar details">>,
content => #{<<"application/json">> => #{schema => calendar_schema()}}
},
403 => #{description => <<"Access denied">>},
404 => #{description => <<"Calendar not found">>}
}
}
},
#{ % PUT
@@ -67,10 +58,7 @@ trails() ->
content => #{<<"application/json">> => #{schema => calendar_update_schema()}}
},
responses => #{
200 => #{description => <<"Calendar updated">>},
400 => #{description => <<"Invalid request">>},
403 => #{description => <<"Access denied">>},
404 => #{description => <<"Calendar not found">>}
200 => #{description => <<"Calendar updated">>}
}
},
#{ % DELETE
@@ -80,9 +68,7 @@ trails() ->
tags => [<<"Calendars">>],
parameters => BaseParams,
responses => #{
200 => #{description => <<"Calendar deleted">>},
403 => #{description => <<"Access denied">>},
404 => #{description => <<"Calendar not found">>}
200 => #{description => <<"Calendar deleted">>}
}
}
].
@@ -90,24 +76,18 @@ trails() ->
-spec calendar_schema() -> map().
calendar_schema() ->
#{
type => object,
type => object,
properties => #{
id => #{type => string},
owner_id => #{type => string},
title => #{type => string},
description => #{type => string},
short_name => #{type => string, nullable => true},
category => #{type => string, nullable => true},
color => #{type => string, nullable => true},
image_url => #{type => string, nullable => true},
settings => #{type => object, nullable => true},
tags => #{type => array, items => #{type => string}},
type => #{type => string, enum => [<<"personal">>, <<"commercial">>]},
confirmation => #{type => string, description => <<"auto, manual, or {timeout, N}">>},
confirmation => #{type => string, enum => [<<"auto">>, <<"manual">>]},
tags => #{type => array, items => #{type => string}},
rating_avg => #{type => number, format => float},
rating_count => #{type => integer},
status => #{type => string, enum => [<<"active">>, <<"frozen">>, <<"deleted">>]},
reason => #{type => string, nullable => true},
status => #{type => string},
created_at => #{type => string, format => <<"date-time">>},
updated_at => #{type => string, format => <<"date-time">>}
}
@@ -116,22 +96,18 @@ calendar_schema() ->
-spec calendar_update_schema() -> map().
calendar_update_schema() ->
#{
type => object,
type => object,
properties => #{
title => #{type => string},
description => #{type => string},
type => #{type => string, enum => [<<"personal">>, <<"commercial">>]},
confirmation => #{type => string, description => <<"auto, manual, or {timeout, N}">>},
type => #{type => string},
confirmation => #{type => string},
tags => #{type => array, items => #{type => string}}
}
}.
%%%===================================================================
%%% HTTP-методы
%%%===================================================================
%%% Internal functions
%% @doc GET /v1/calendars/:id — получение календаря.
-spec get_calendar(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}.
get_calendar(Req) ->
case handler_utils:auth_user(Req) of
{ok, UserId, Req1} ->
@@ -150,8 +126,6 @@ get_calendar(Req) ->
handler_utils:send_error(Req1, Code, Message)
end.
%% @doc PUT /v1/calendars/:id — обновление календаря.
-spec update_calendar(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}.
update_calendar(Req) ->
case handler_utils:auth_user(Req) of
{ok, UserId, Req1} ->
@@ -159,7 +133,8 @@ update_calendar(Req) ->
{ok, Body, Req2} = cowboy_req:read_body(Req1),
try jsx:decode(Body, [return_maps]) of
UpdatesMap when is_map(UpdatesMap) ->
Updates = maps:to_list(UpdatesMap),
Updates0 = maps:to_list(UpdatesMap),
Updates = convert_calendar_fields(Updates0),
case logic_calendar:update_calendar(UserId, CalendarId, Updates) of
{ok, Calendar} ->
handler_utils:send_json(Req2, 200, handler_utils:calendar_to_json(Calendar));
@@ -179,8 +154,6 @@ update_calendar(Req) ->
handler_utils:send_error(Req1, Code, Message)
end.
%% @doc DELETE /v1/calendars/:id — удаление календаря.
-spec delete_calendar(cowboy_req:req()) -> {ok, binary(), cowboy_req:req()}.
delete_calendar(Req) ->
case handler_utils:auth_user(Req) of
{ok, UserId, Req1} ->
@@ -197,4 +170,17 @@ delete_calendar(Req) ->
end;
{error, Code, Message, Req1} ->
handler_utils:send_error(Req1, Code, Message)
end.
end.
%% @private Преобразует бинарные ключи и значения в атомы для обновлений календаря.
-spec convert_calendar_fields([{binary(), term()}]) -> [{atom(), term()}].
convert_calendar_fields(Updates) ->
lists:map(fun convert_field/1, Updates).
-spec convert_field({binary(), term()}) -> {atom(), term()}.
convert_field({<<"title">>, Val}) -> {title, Val};
convert_field({<<"description">>, Val}) -> {description, Val};
convert_field({<<"type">>, Val}) -> {type, Val};
convert_field({<<"confirmation">>, Val}) -> {confirmation, Val};
convert_field({<<"tags">>, Val}) -> {tags, Val};
convert_field(Other) -> Other.