Files
EventHubBack/src/logic/logic_calendar_specialist.erl
T
aleksey 3d7ae0d372
CI / test (push) Successful in 7m28s
CI / deploy-ift (push) Successful in 2m46s
CI / e2e-ift (push) Successful in 1m26s
CI / deploy-stage (push) Successful in 2m4s
CI / e2e-stage (push) Successful in 2m4s
fix(api): resolve public calendar GET by unique short_name.
2026-08-14 15:00:41 +03:00

112 lines
4.2 KiB
Erlang
Executable File

%%%-------------------------------------------------------------------
%%% @doc Логика специалистов commercial-календаря.
%%% @end
%%%-------------------------------------------------------------------
-module(logic_calendar_specialist).
-include("records.hrl").
-export([list/2, add/5, update/4, remove/3, to_json/1, ensure_owner_specialist/1]).
-spec list(ActorId :: binary(), CalendarId :: binary()) ->
{ok, [#calendar_specialist{}]} | {error, not_found | access_denied}.
list(ActorId, CalendarId) ->
case logic_calendar:get_calendar(ActorId, CalendarId) of
{ok, Cal} ->
{ok, core_calendar_specialist:list_by_calendar(Cal#calendar.id)};
Error -> Error
end.
-spec add(OwnerId :: binary(), CalendarId :: binary(), UserId :: binary(),
Name :: binary(), Specs :: [binary()]) ->
{ok, #calendar_specialist{}} |
{error, not_found | access_denied | not_commercial | user_not_found |
already_exists | term()}.
add(OwnerId, CalendarId, UserId, Name, Specs) ->
case require_owner_commercial(OwnerId, CalendarId) of
{ok, _} ->
case core_user:get_by_id(UserId) of
{ok, _} ->
core_calendar_specialist:create(CalendarId, UserId, Name, Specs);
{error, _} ->
{error, user_not_found}
end;
Error -> Error
end.
-spec update(OwnerId :: binary(), CalendarId :: binary(), UserId :: binary(),
Updates :: [{atom(), term()}]) ->
{ok, #calendar_specialist{}} | {error, not_found | access_denied | not_commercial | term()}.
update(OwnerId, CalendarId, UserId, Updates) ->
case require_owner_commercial(OwnerId, CalendarId) of
{ok, _} ->
core_calendar_specialist:update(CalendarId, UserId, Updates);
Error -> Error
end.
-spec remove(OwnerId :: binary(), CalendarId :: binary(), UserId :: binary()) ->
ok | {error, not_found | access_denied | not_commercial |
owner_specialist_protected | term()}.
remove(OwnerId, CalendarId, UserId) ->
case require_owner_commercial(OwnerId, CalendarId) of
{ok, #calendar{owner_id = CalOwnerId}} when UserId =:= CalOwnerId ->
{error, owner_specialist_protected};
{ok, _} ->
core_calendar_specialist:delete(CalendarId, UserId);
Error -> Error
end.
%% @doc Idempotent: commercial calendar always has a specialist row for owner.
%% Default status=active; name from nickname (else email). No-op if already present.
-spec ensure_owner_specialist(#calendar{}) -> ok | {error, term()}.
ensure_owner_specialist(#calendar{id = CalId, owner_id = OwnerId, type = commercial}) ->
case core_calendar_specialist:get_by_calendar_and_user(CalId, OwnerId) of
{ok, _} ->
ok;
{error, not_found} ->
case core_calendar_specialist:create(CalId, OwnerId, owner_display_name(OwnerId), []) of
{ok, _} -> ok;
{error, already_exists} -> ok;
{error, _} = Err -> Err
end
end;
ensure_owner_specialist(_) ->
ok.
-spec to_json(#calendar_specialist{}) -> map().
to_json(S) ->
#{
id => S#calendar_specialist.id,
calendar_id => S#calendar_specialist.calendar_id,
user_id => S#calendar_specialist.user_id,
name => S#calendar_specialist.name,
specialization => S#calendar_specialist.specialization,
status => S#calendar_specialist.status,
added_at => handler_utils:datetime_to_iso8601(S#calendar_specialist.added_at),
updated_at => handler_utils:datetime_to_iso8601(S#calendar_specialist.updated_at)
}.
%%%===================================================================
%%% Internal
%%%===================================================================
require_owner_commercial(OwnerId, CalendarId) ->
case core_calendar:get_by_id(CalendarId) of
{ok, #calendar{owner_id = OwnerId, type = commercial, status = active} = Cal} ->
{ok, Cal};
{ok, #calendar{owner_id = OwnerId, type = personal}} ->
{error, not_commercial};
{ok, _} ->
{error, access_denied};
Error -> Error
end.
owner_display_name(OwnerId) ->
case core_user:get_by_id(OwnerId) of
{ok, #user{nickname = Nick}} when is_binary(Nick), Nick =/= <<>> ->
Nick;
{ok, #user{email = Email}} when is_binary(Email), Email =/= <<>> ->
Email;
_ ->
<<"Owner">>
end.