%%%------------------------------------------------------------------- %%% @doc Follow / unfollow чужого календаря. %%% %%% POST /v1/calendars/:id/follow — подписаться %%% DELETE /v1/calendars/:id/follow — отписаться %%% @end %%%------------------------------------------------------------------- -module(handler_calendar_follow). -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) -> handle(Req, Opts). -spec trails() -> [map()]. trails() -> BaseParams = [ #{ name => <<"id">>, in => <<"path">>, description => <<"Calendar ID">>, required => true, schema => #{type => string} } ], FollowResponse = #{ type => object, properties => #{ calendar_id => #{type => string}, following => #{type => boolean} } }, [ #{ path => <<"/v1/calendars/:id/follow">>, method => <<"POST">>, description => <<"Follow a calendar (not paid subscription)">>, tags => [<<"Calendars">>], parameters => BaseParams, responses => #{ 200 => #{ description => <<"Following">>, content => #{<<"application/json">> => #{schema => FollowResponse}} }, 401 => #{description => <<"Unauthorized">>}, 403 => #{description => <<"Own calendar or access denied">>}, 404 => #{description => <<"Calendar not found">>} } }, #{ path => <<"/v1/calendars/:id/follow">>, method => <<"DELETE">>, description => <<"Unfollow a calendar">>, tags => [<<"Calendars">>], parameters => BaseParams, responses => #{ 200 => #{ description => <<"Unfollowed">>, content => #{<<"application/json">> => #{schema => FollowResponse}} }, 401 => #{description => <<"Unauthorized">>}, 403 => #{description => <<"Own calendar">>}, 404 => #{description => <<"Calendar not found">>} } } ]. -spec handle(cowboy_req:req(), any()) -> {ok, cowboy_req:req(), any()}. handle(Req, _Opts) -> case cowboy_req:method(Req) of <<"POST">> -> follow(Req); <<"DELETE">> -> unfollow(Req); _ -> handler_utils:send_error(Req, 405, <<"Method not allowed">>) end. -spec follow(cowboy_req:req()) -> {ok, cowboy_req:req(), any()}. follow(Req) -> case handler_utils:auth_user(Req) of {ok, UserId, Req1} -> CalendarId = cowboy_req:binding(id, Req1), case logic_calendar_follow:follow(UserId, CalendarId) of {ok, _} -> handler_utils:send_json(Req1, 200, #{ calendar_id => CalendarId, following => true }); {error, not_found} -> handler_utils:send_error(Req1, 404, <<"Calendar not found">>); {error, own_calendar} -> handler_utils:send_error(Req1, 403, <<"Cannot follow own calendar">>); {error, access_denied} -> handler_utils:send_error(Req1, 403, <<"Access denied">>); {error, _} -> handler_utils:send_error(Req1, 500, <<"Internal server error">>) end; {error, Code, Message, Req1} -> handler_utils:send_error(Req1, Code, Message) end. -spec unfollow(cowboy_req:req()) -> {ok, cowboy_req:req(), any()}. unfollow(Req) -> case handler_utils:auth_user(Req) of {ok, UserId, Req1} -> CalendarId = cowboy_req:binding(id, Req1), case logic_calendar_follow:unfollow(UserId, CalendarId) of ok -> handler_utils:send_json(Req1, 200, #{ calendar_id => CalendarId, following => false }); {error, own_calendar} -> handler_utils:send_error(Req1, 403, <<"Cannot unfollow own calendar">>); {error, _} -> handler_utils:send_error(Req1, 500, <<"Internal server error">>) end; {error, Code, Message, Req1} -> handler_utils:send_error(Req1, Code, Message) end.