Рефакторинг обработчиков. Часть 1 #21
This commit is contained in:
+39
-4
@@ -1,14 +1,15 @@
|
||||
-module(core_admin).
|
||||
-include("records.hrl").
|
||||
-export([create/3, get_by_email/1, get_by_id/1, list_all/0,
|
||||
update_role/2, block/1, unblock/1, generate_id/0, update_last_login/1]).
|
||||
update_role/2, block/1, unblock/1, update_last_login/1]).
|
||||
-export([update/2]).
|
||||
|
||||
create(Email, Password, Role) ->
|
||||
case get_by_email(Email) of
|
||||
{ok, _} ->
|
||||
{error, email_exists};
|
||||
{error, not_found} ->
|
||||
Id = generate_id(),
|
||||
Id = infra_utils:generate_id(16),
|
||||
{ok, Hash} = argon2:hash(Password),
|
||||
Now = calendar:universal_time(),
|
||||
Admin = #admin{
|
||||
@@ -24,6 +25,22 @@ create(Email, Password, Role) ->
|
||||
{ok, Admin}
|
||||
end.
|
||||
|
||||
%% Обновление администратора (любые поля)
|
||||
update(AdminId, Updates) ->
|
||||
F = fun() ->
|
||||
case mnesia:read(admin, AdminId) of
|
||||
[] -> {error, not_found};
|
||||
[Admin] ->
|
||||
UpdatedAdmin = apply_updates(Admin, Updates),
|
||||
mnesia:write(UpdatedAdmin),
|
||||
{ok, UpdatedAdmin}
|
||||
end
|
||||
end,
|
||||
case mnesia:transaction(F) of
|
||||
{atomic, Result} -> Result;
|
||||
{aborted, Reason} -> {error, Reason}
|
||||
end.
|
||||
|
||||
get_by_email(Email) ->
|
||||
Match = #admin{email = Email, _ = '_'},
|
||||
case mnesia:dirty_match_object(Match) of
|
||||
@@ -73,5 +90,23 @@ update_status(Id, Status) ->
|
||||
Error -> Error
|
||||
end.
|
||||
|
||||
generate_id() ->
|
||||
base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}).
|
||||
%%%===================================================================
|
||||
%%% ВНУТРЕННИЕ ФУНКЦИИ
|
||||
%%%===================================================================
|
||||
|
||||
apply_updates(Admin, []) -> Admin;
|
||||
apply_updates(Admin, [{Field, Value} | Rest]) ->
|
||||
NewAdmin = case Field of
|
||||
email -> Admin#admin{email = Value};
|
||||
password_hash -> Admin#admin{password_hash = Value};
|
||||
role -> Admin#admin{role = Value};
|
||||
status -> Admin#admin{status = Value};
|
||||
nickname -> Admin#admin{nickname = Value};
|
||||
avatar_url -> Admin#admin{avatar_url = Value};
|
||||
timezone -> Admin#admin{timezone = Value};
|
||||
language -> Admin#admin{language = Value};
|
||||
phone -> Admin#admin{phone = Value};
|
||||
preferences -> Admin#admin{preferences = Value};
|
||||
_ -> Admin
|
||||
end,
|
||||
apply_updates(NewAdmin#admin{updated_at = calendar:universal_time()}, Rest).
|
||||
@@ -6,7 +6,7 @@
|
||||
log(AdminId, Email, Role, Action, EntityType, EntityId, Ip) ->
|
||||
log(AdminId, Email, Role, Action, EntityType, EntityId, Ip, undefined).
|
||||
log(AdminId, Email, Role, Action, EntityType, EntityId, Ip, Reason) ->
|
||||
Id = base64:encode(crypto:strong_rand_bytes(9)),
|
||||
Id = infra_utils:generate_id(9),
|
||||
Entry = #admin_audit{
|
||||
id = Id,
|
||||
admin_id = AdminId,
|
||||
|
||||
@@ -10,7 +10,7 @@ list_banned_words() ->
|
||||
mnesia:dirty_match_object(#banned_word{_ = '_'}).
|
||||
|
||||
add_banned_word(Word, AddedBy) ->
|
||||
Id = generate_id(),
|
||||
Id = infra_utils:generate_id(9),
|
||||
Now = calendar:universal_time(),
|
||||
BW = #banned_word{id = Id, word = Word, added_by = AddedBy, added_at = Now},
|
||||
case mnesia:transaction(fun() ->
|
||||
@@ -48,7 +48,4 @@ update_banned_word(OldWord, NewWord) ->
|
||||
end) of
|
||||
{atomic, {ok, UpdatedRec}} -> {ok, UpdatedRec};
|
||||
{aborted, not_found} -> {error, not_found}
|
||||
end.
|
||||
|
||||
generate_id() ->
|
||||
base64:encode(crypto:strong_rand_bytes(9)).
|
||||
end.
|
||||
@@ -3,12 +3,11 @@
|
||||
|
||||
-export([create/2, get_by_id/1, get_by_event_and_user/2, list_by_event/1, list_by_user/1]).
|
||||
-export([update_status/2, delete/1]).
|
||||
-export([generate_id/0]).
|
||||
-export([count_bookings/0]).
|
||||
|
||||
%% Создание бронирования
|
||||
create(EventId, UserId) ->
|
||||
Id = generate_id(),
|
||||
Id = infra_utils:generate_id(16),
|
||||
Booking = #booking{
|
||||
id = Id,
|
||||
event_id = EventId,
|
||||
@@ -98,8 +97,4 @@ delete(Id) ->
|
||||
{aborted, Reason} -> {error, Reason}
|
||||
end.
|
||||
|
||||
count_bookings() -> mnesia:table_info(booking, size).
|
||||
|
||||
%% Внутренние функции
|
||||
generate_id() ->
|
||||
base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}).
|
||||
count_bookings() -> mnesia:table_info(booking, size).
|
||||
@@ -1,13 +1,12 @@
|
||||
-module(core_calendar).
|
||||
-include("records.hrl").
|
||||
-export([create/4, create/5, get_by_id/1, list_by_owner/1, update/2, delete/1]).
|
||||
-export([generate_id/0]).
|
||||
-export([count_calendars/0]).
|
||||
-export([freeze/2, unfreeze/2]). % ← новые функции
|
||||
|
||||
%% Создание календаря
|
||||
create(OwnerId, Title, Description, Confirmation) ->
|
||||
Id = generate_id(),
|
||||
Id = infra_utils:generate_id(16),
|
||||
Calendar = #calendar{
|
||||
id = Id,
|
||||
owner_id = OwnerId,
|
||||
@@ -30,7 +29,7 @@ create(OwnerId, Title, Description, Confirmation) ->
|
||||
|
||||
%% Создание календаря с типом и политикой
|
||||
create(OwnerId, Title, Description, Confirmation, Type) ->
|
||||
Id = generate_id(),
|
||||
Id = infra_utils:generate_id(16),
|
||||
Calendar = #calendar{
|
||||
id = Id,
|
||||
owner_id = OwnerId,
|
||||
@@ -94,10 +93,6 @@ freeze(Id, Reason) ->
|
||||
unfreeze(Id, Reason) ->
|
||||
update(Id, [{status, active}, {reason, Reason}]).
|
||||
|
||||
%% Внутренние функции
|
||||
generate_id() ->
|
||||
base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}).
|
||||
|
||||
apply_updates(Calendar, Updates) ->
|
||||
Updated = lists:foldl(fun({Field, Value}, C) ->
|
||||
set_field(Field, Value, C)
|
||||
|
||||
@@ -3,14 +3,13 @@
|
||||
|
||||
-export([create/4, create_recurring/5, get_by_id/1, list_by_calendar/1,
|
||||
update/2, delete/1, materialize_occurrence/3]).
|
||||
-export([generate_id/0]).
|
||||
-export([count_events/0, count_events_by_date/2]).
|
||||
-export([freeze/2, unfreeze/2]).
|
||||
-export([list_all/0]).
|
||||
|
||||
%% Создание одиночного события
|
||||
create(CalendarId, Title, StartTime, Duration) ->
|
||||
Id = generate_id(),
|
||||
Id = infra_utils:generate_id(16),
|
||||
Event = #event{
|
||||
id = Id,
|
||||
calendar_id = CalendarId,
|
||||
@@ -46,7 +45,7 @@ create(CalendarId, Title, StartTime, Duration) ->
|
||||
|
||||
%% Создание повторяющегося события (мастер-запись)
|
||||
create_recurring(CalendarId, Title, StartTime, Duration, RRule) ->
|
||||
Id = generate_id(),
|
||||
Id = infra_utils:generate_id(16),
|
||||
Event = #event{
|
||||
id = Id,
|
||||
calendar_id = CalendarId,
|
||||
@@ -94,7 +93,7 @@ materialize_occurrence(MasterId, OccurrenceStart, SpecialistId) ->
|
||||
case Existing of
|
||||
[] ->
|
||||
% Создаём новый экземпляр
|
||||
InstanceId = generate_id(),
|
||||
InstanceId = infra_utils:generate_id(16),
|
||||
Instance = #event{
|
||||
id = InstanceId,
|
||||
calendar_id = Master#event.calendar_id,
|
||||
@@ -193,10 +192,6 @@ count_events_by_date(From, To) ->
|
||||
|
||||
date_part({{Y,M,D}, _}) -> {Y,M,D}.
|
||||
|
||||
%% Внутренние функции
|
||||
generate_id() ->
|
||||
base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}).
|
||||
|
||||
apply_updates(Event, Updates) ->
|
||||
Updated = lists:foldl(fun({Field, Value}, E) ->
|
||||
set_field(Field, Value, E)
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
-export([generate_id/0]).
|
||||
-export([count_reports_by_status/1, count_reports_by_admin/2]).
|
||||
-export([count_reports_resolved_by_admin/2, avg_resolution_time/1]).
|
||||
-export([delete/1, update/2]). % <-- добавлено
|
||||
|
||||
%% Создание жалобы
|
||||
create(ReporterId, TargetType, TargetId, Reason) ->
|
||||
Id = generate_id(),
|
||||
Id = infra_utils:generate_id(16),
|
||||
Report = #report{
|
||||
id = Id,
|
||||
reporter_id = ReporterId,
|
||||
@@ -109,6 +110,41 @@ avg_resolution_time(Status) ->
|
||||
TotalSeconds / length(Resolved) / 3600.0
|
||||
end.
|
||||
|
||||
%% Внутренние функции
|
||||
%% Мягкое удаление жалобы (просто физически удаляем запись)
|
||||
-spec delete(binary()) -> {ok, deleted} | {error, not_found}.
|
||||
delete(Id) ->
|
||||
case get_by_id(Id) of
|
||||
{ok, _} ->
|
||||
mnesia:dirty_delete(report, Id),
|
||||
{ok, deleted};
|
||||
Error -> Error
|
||||
end.
|
||||
|
||||
%% Обновление произвольных полей жалобы (для административных целей)
|
||||
-spec update(binary(), proplists:proplist()) -> {ok, #report{}} | {error, not_found}.
|
||||
update(Id, Updates) ->
|
||||
case get_by_id(Id) of
|
||||
{ok, Report} ->
|
||||
UpdatedReport = apply_updates(Report, Updates),
|
||||
mnesia:dirty_write(UpdatedReport),
|
||||
{ok, UpdatedReport};
|
||||
Error -> Error
|
||||
end.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Внутренние функции
|
||||
%%%===================================================================
|
||||
|
||||
generate_id() ->
|
||||
base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}).
|
||||
base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}).
|
||||
|
||||
apply_updates(Report, []) -> Report;
|
||||
apply_updates(Report, [{Field, Value} | Rest]) ->
|
||||
NewReport = case Field of
|
||||
status -> Report#report{status = Value};
|
||||
resolved_at -> Report#report{resolved_at = Value};
|
||||
resolved_by -> Report#report{resolved_by = Value};
|
||||
reason -> Report#report{reason = Value};
|
||||
_ -> Report
|
||||
end,
|
||||
apply_updates(NewReport, Rest).
|
||||
@@ -4,12 +4,11 @@
|
||||
-export([create/5, get_by_id/1, list_by_target/2, list_by_user/1,
|
||||
update/2, delete/1, hide/2, unhide/2]).
|
||||
-export([get_average_rating/2, has_user_reviewed/3]).
|
||||
-export([generate_id/0]).
|
||||
-export([count_reviews/0, list_all/0]).
|
||||
|
||||
%% Создание отзыва
|
||||
create(UserId, TargetType, TargetId, Rating, Comment) ->
|
||||
Id = generate_id(),
|
||||
Id = infra_utils:generate_id(16),
|
||||
Review = #review{
|
||||
id = Id,
|
||||
user_id = UserId,
|
||||
@@ -117,10 +116,6 @@ count_reviews() -> mnesia:table_info(review, size).
|
||||
|
||||
list_all() -> mnesia:dirty_match_object(#review{_ = '_'}).
|
||||
|
||||
%% Внутренние функции
|
||||
generate_id() ->
|
||||
base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}).
|
||||
|
||||
apply_updates(Review, Updates) ->
|
||||
Updated = lists:foldl(fun({Field, Value}, R) ->
|
||||
set_field(Field, Value, R)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
-export([create/3, get_by_id/1, get_active_by_user/1, list_by_user/1, list_all/0]).
|
||||
-export([update_status/2, check_expired/0]).
|
||||
-export([generate_id/0]).
|
||||
% --------------- новые обёртки для админки ------------------
|
||||
-export([list_subscriptions/0,
|
||||
create_subscription/1,
|
||||
@@ -16,7 +15,7 @@
|
||||
|
||||
%% Создание подписки
|
||||
create(UserId, Plan, TrialUsed) ->
|
||||
Id = generate_id(),
|
||||
Id = infra_utils:generate_id(16),
|
||||
Now = calendar:universal_time(),
|
||||
|
||||
{StartDate, EndDate} = case TrialUsed of
|
||||
@@ -129,10 +128,6 @@ downgrade_user_calendars(UserId) ->
|
||||
core_calendar:update(Cal#calendar.id, [{type, personal}])
|
||||
end, Calendars).
|
||||
|
||||
%% Внутренние функции
|
||||
generate_id() ->
|
||||
base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}).
|
||||
|
||||
plan_to_months(monthly) -> 1;
|
||||
plan_to_months(quarterly) -> 3;
|
||||
plan_to_months(biannual) -> 6;
|
||||
|
||||
@@ -48,7 +48,7 @@ stats() ->
|
||||
|
||||
%% ── новые функции ──────────────────────────────────────
|
||||
create_ticket(Data) ->
|
||||
Id = base64:encode(crypto:strong_rand_bytes(9), #{mode => urlsafe, padding => false}),
|
||||
Id = infra_utils:generate_id(9),
|
||||
Now = calendar:universal_time(),
|
||||
Ticket = #ticket{
|
||||
id = Id,
|
||||
@@ -103,4 +103,4 @@ apply_updates(Ticket, Updates) ->
|
||||
<<"context">> -> Acc#ticket{context = Value};
|
||||
_ -> Acc
|
||||
end
|
||||
end, Ticket, maps:to_list(Updates)).
|
||||
end, Ticket, maps:to_list(Updates)).
|
||||
@@ -3,10 +3,9 @@
|
||||
|
||||
-export([create/2, get_by_id/1, get_by_email/1, update/2, update_status/3, delete/1, update_last_login/1]).
|
||||
-export([email_exists/1]).
|
||||
-export([generate_id/0]).
|
||||
-export([list_users/0]).
|
||||
-export([block/2, unblock/2]).
|
||||
-export([count_users/0, count_users_by_date/2]).
|
||||
-export([count_users/0, count_users_by_date/2, list_all/0]).
|
||||
-export([create_bot/2, delete_bot/1]).
|
||||
|
||||
%% Создание пользователя
|
||||
@@ -16,7 +15,7 @@ create(Email, Password) ->
|
||||
true ->
|
||||
{error, email_exists};
|
||||
false ->
|
||||
Id = generate_id(),
|
||||
Id = infra_utils:generate_id(16),
|
||||
{ok, PasswordHash} = logic_auth:hash_password(Password),
|
||||
|
||||
User = #user{
|
||||
@@ -150,6 +149,10 @@ unblock(Id, Reason) ->
|
||||
count_users() ->
|
||||
mnesia:table_info(user, size).
|
||||
|
||||
%% Административный список (все пользователи, без фильтрации)
|
||||
list_all() ->
|
||||
mnesia:dirty_match_object(#user{_ = '_'}).
|
||||
|
||||
count_users_by_date(From, To) ->
|
||||
All = mnesia:dirty_match_object(#user{_ = '_'}),
|
||||
Filtered = lists:filter(fun(U) ->
|
||||
@@ -166,10 +169,6 @@ count_users_by_date(From, To) ->
|
||||
|
||||
date_part({{Y,M,D}, _}) -> {Y,M,D}.
|
||||
|
||||
%% Внутренние функции
|
||||
generate_id() ->
|
||||
base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}).
|
||||
|
||||
apply_updates(User, Updates) ->
|
||||
Updated = lists:foldl(fun({Field, Value}, U) ->
|
||||
set_field(Field, Value, U)
|
||||
@@ -196,7 +195,7 @@ create_bot(Email, Password) ->
|
||||
case mnesia:dirty_index_read(user, Email, email) of
|
||||
[] ->
|
||||
{ok, PasswordHash} = logic_auth:hash_password(Password),
|
||||
Id = generate_id(),
|
||||
Id = infra_utils:generate_id(16),
|
||||
User = #user{
|
||||
id = Id,
|
||||
email = Email,
|
||||
|
||||
Reference in New Issue
Block a user