feat: calendar follow API (POST/DELETE follow, GET following). Refs EventHub/EventHubFront#9
This commit is contained in:
Executable
+84
@@ -0,0 +1,84 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @doc Бизнес-логика follow чужого календаря.
|
||||
%%% Follow не даёт право на отзыв (см. logic_review:can_review/3).
|
||||
%%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(logic_calendar_follow).
|
||||
-include("records.hrl").
|
||||
|
||||
-export([follow/2, unfollow/2, is_following/2, list_following_calendars/1]).
|
||||
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @doc Follow доступного чужого календаря.
|
||||
%%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
-spec follow(UserId :: binary(), CalendarId :: binary()) ->
|
||||
{ok, #calendar_follow{}} | {error, term()}.
|
||||
follow(UserId, CalendarId) ->
|
||||
case core_calendar:get_by_id(CalendarId) of
|
||||
{error, not_found} ->
|
||||
{error, not_found};
|
||||
{ok, #calendar{owner_id = UserId}} ->
|
||||
{error, own_calendar};
|
||||
{ok, Calendar} ->
|
||||
case logic_calendar:can_access(UserId, Calendar) of
|
||||
false ->
|
||||
{error, access_denied};
|
||||
true ->
|
||||
case Calendar#calendar.status of
|
||||
active ->
|
||||
core_calendar_follow:follow(CalendarId, UserId);
|
||||
_ ->
|
||||
{error, not_found}
|
||||
end
|
||||
end
|
||||
end.
|
||||
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @doc Unfollow. Идемпотентно.
|
||||
%%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
-spec unfollow(UserId :: binary(), CalendarId :: binary()) -> ok | {error, term()}.
|
||||
unfollow(UserId, CalendarId) ->
|
||||
case core_calendar:get_by_id(CalendarId) of
|
||||
{error, not_found} ->
|
||||
%% всё равно снимаем локальный follow, если был
|
||||
core_calendar_follow:unfollow(CalendarId, UserId);
|
||||
{ok, #calendar{owner_id = UserId}} ->
|
||||
{error, own_calendar};
|
||||
{ok, _} ->
|
||||
core_calendar_follow:unfollow(CalendarId, UserId)
|
||||
end.
|
||||
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @doc Флаг following для текущего пользователя.
|
||||
%%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
-spec is_following(UserId :: binary(), CalendarId :: binary()) -> boolean().
|
||||
is_following(UserId, CalendarId) ->
|
||||
core_calendar_follow:is_following(UserId, CalendarId).
|
||||
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @doc Список календарей, на которые подписан пользователь (active, доступные).
|
||||
%%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
-spec list_following_calendars(UserId :: binary()) -> {ok, [#calendar{}]}.
|
||||
list_following_calendars(UserId) ->
|
||||
Follows = core_calendar_follow:list_by_user(UserId),
|
||||
Calendars = lists:filtermap(
|
||||
fun(#calendar_follow{calendar_id = CalId}) ->
|
||||
case core_calendar:get_by_id(CalId) of
|
||||
{ok, #calendar{status = active} = Cal} ->
|
||||
case logic_calendar:can_access(UserId, Cal) of
|
||||
true -> {true, Cal};
|
||||
false -> false
|
||||
end;
|
||||
_ ->
|
||||
false
|
||||
end
|
||||
end,
|
||||
Follows),
|
||||
Sorted = lists:sort(
|
||||
fun(#calendar{title = A}, #calendar{title = B}) -> A =< B end,
|
||||
Calendars),
|
||||
{ok, Sorted}.
|
||||
Reference in New Issue
Block a user