Перенести все админские эндпоинты на порт 8445 и добавить отдельную авторизацию для админов. Часть 2. Final #3

This commit is contained in:
2026-04-28 12:42:10 +03:00
parent 4ed6a961ab
commit 7ea4efd7d9
38 changed files with 1252 additions and 1124 deletions
+53 -34
View File
@@ -1,89 +1,110 @@
-module(logic_ticket).
-include("records.hrl").
-export([report_error/3, get_ticket/2, list_tickets/1, list_tickets_by_status/2]).
-export([update_status/3, assign_ticket/3, resolve_ticket/3, close_ticket/2]).
-export([get_statistics/1]).
-export([report_error/3,
get_ticket/2,
list_tickets/1,
list_tickets_by_status/2,
update_status/3,
assign_ticket/3,
resolve_ticket/3,
close_ticket/2,
get_statistics/1]).
%% Зарегистрировать ошибку (создать или обновить тикет)
report_error(ErrorMessage, Stacktrace, Context) ->
case core_ticket:create_or_update(ErrorMessage, Stacktrace, Context) of
{ok, Ticket} ->
% Если это новый тикет, уведомляем администраторов (заглушка)
case Ticket#ticket.count of
1 -> notify_admins(Ticket);
_ -> ok
end,
{ok, Ticket};
Error -> Error
Existing = [T || T <- core_ticket:list_all(), T#ticket.error_message =:= ErrorMessage],
case Existing of
[Ticket] ->
% Увеличить счётчик и обновить last_seen
Updated = Ticket#ticket{
count = Ticket#ticket.count + 1,
last_seen = calendar:universal_time()
},
mnesia:dirty_write(Updated),
{ok, Updated};
[] ->
Data = #{
<<"error_message">> => ErrorMessage,
<<"stacktrace">> => Stacktrace,
<<"context">> => list_to_binary(io_lib:format("~p", [Context]))
},
case core_ticket:create_ticket(Data) of
{ok, Ticket} = Result ->
% Уведомление администраторов (заглушка)
notify_admins(Ticket),
Result;
Error -> Error
end
end.
%% Получить тикет (только для админов)
get_ticket(AdminId, TicketId) ->
case is_admin(AdminId) of
true -> core_ticket:get_by_id(TicketId);
true -> core_ticket:get_by_id(TicketId);
false -> {error, access_denied}
end.
%% Список всех тикетов (только для админов)
list_tickets(AdminId) ->
case is_admin(AdminId) of
true -> core_ticket:list_all();
true -> core_ticket:list_all();
false -> {error, access_denied}
end.
%% Список тикетов по статусу (только для админов)
list_tickets_by_status(AdminId, Status) ->
case is_admin(AdminId) of
true -> core_ticket:list_by_status(Status);
true ->
All = core_ticket:list_all(),
[T || T <- All, T#ticket.status =:= Status];
false -> {error, access_denied}
end.
%% Обновить статус тикета
update_status(AdminId, TicketId, Status) ->
case is_admin(AdminId) of
true -> core_ticket:update_status(TicketId, Status);
true -> core_ticket:update_ticket(TicketId, #{<<"status">> => Status});
false -> {error, access_denied}
end.
%% Назначить тикет администратору
assign_ticket(AdminId, TicketId, AssignToId) ->
case is_admin(AdminId) of
true -> core_ticket:assign(TicketId, AssignToId);
true -> core_ticket:update_ticket(TicketId, #{<<"assigned_to">> => AssignToId});
false -> {error, access_denied}
end.
%% Отметить тикет как решённый с примечанием
resolve_ticket(AdminId, TicketId, ResolutionNote) ->
case is_admin(AdminId) of
true ->
case core_ticket:add_resolution(TicketId, ResolutionNote) of
{ok, _Ticket} ->
core_ticket:update_status(TicketId, resolved);
Error -> Error
end;
true ->
core_ticket:update_ticket(TicketId, #{
<<"status">> => <<"closed">>,
<<"resolution_note">> => ResolutionNote
});
false -> {error, access_denied}
end.
%% Закрыть тикет
close_ticket(AdminId, TicketId) ->
case is_admin(AdminId) of
true -> core_ticket:update_status(TicketId, closed);
true -> core_ticket:update_ticket(TicketId, #{<<"status">> => <<"closed">>});
false -> {error, access_denied}
end.
%% Получить статистику по тикетам
get_statistics(AdminId) ->
case is_admin(AdminId) of
true ->
{ok, AllTickets} = core_ticket:list_all(),
Open = length([T || T <- AllTickets, T#ticket.status =:= open]),
InProgress = length([T || T <- AllTickets, T#ticket.status =:= in_progress]),
Resolved = length([T || T <- AllTickets, T#ticket.status =:= resolved]),
Closed = length([T || T <- AllTickets, T#ticket.status =:= closed]),
TotalErrors = lists:sum([T#ticket.count || T <- AllTickets]),
true ->
All = core_ticket:list_all(),
Open = length([T || T <- All, T#ticket.status =:= open]),
InProgress = length([T || T <- All, T#ticket.status =:= in_progress]),
Resolved = length([T || T <- All, T#ticket.status =:= resolved]),
Closed = length([T || T <- All, T#ticket.status =:= closed]),
TotalErrors = lists:sum([T#ticket.count || T <- All]),
#{
total_tickets => length(AllTickets),
total_tickets => length(All),
open => Open,
in_progress => InProgress,
resolved => Resolved,
@@ -102,6 +123,4 @@ is_admin(UserId) ->
end.
notify_admins(_Ticket) ->
% Заглушка для уведомлений администраторов
% В будущем здесь будет отправка email/websocket
ok.