Mnesia migrations with global lock on startup. Refs EventHub/EventHubBack#24
This commit is contained in:
+232
-231
@@ -1,232 +1,233 @@
|
||||
-module(eventhub_app).
|
||||
-behaviour(application).
|
||||
-export([start/2, stop/1]).
|
||||
|
||||
start(_StartType, _StartArgs) ->
|
||||
case infra_sup:start_link() of
|
||||
{ok, Pid} ->
|
||||
% Определяем список узлов кластера, если режим CLUSTER_MODE=true
|
||||
Nodes = case os:getenv("CLUSTER_MODE", "false") of
|
||||
"true" ->
|
||||
DnsName = os:getenv("DNS_NAME", "eventhub-node"),
|
||||
try inet:getaddrs(DnsName, inet) of
|
||||
{ok, IPs} when is_list(IPs), IPs /= [] ->
|
||||
% Получаем имена всех узлов Erlang, зарегистрированных в EPMD
|
||||
AllNodes = lists:flatmap(fun(IP) ->
|
||||
case erl_epmd:names(IP) of
|
||||
{ok, Names} ->
|
||||
[list_to_atom(Name ++ "@" ++ Name) || {Name, _Port} <- Names,
|
||||
lists:prefix("eventhub-node", Name)];
|
||||
_ -> []
|
||||
end
|
||||
end, IPs),
|
||||
% Исключаем свой узел, чтобы не подключаться к самому себе
|
||||
AllNodes -- [node()];
|
||||
_ -> []
|
||||
catch
|
||||
_:_ ->
|
||||
io:format("DNS lookup failed, starting as first node~n"),
|
||||
[]
|
||||
end;
|
||||
_ -> []
|
||||
end,
|
||||
case Nodes of
|
||||
[] ->
|
||||
io:format("~nCluster: no nodes found or first node~n");
|
||||
_ ->
|
||||
io:format("~nCluster: discovered nodes ~p, joining cluster~n", [Nodes]),
|
||||
application:set_env(eventhub, extra_db_nodes, Nodes)
|
||||
end,
|
||||
application:ensure_all_started(mnesia),
|
||||
ok = infra_mnesia:init_tables(),
|
||||
ok = infra_mnesia:wait_for_tables(),
|
||||
calendar_html_renderer:init_cache(),
|
||||
application:ensure_all_started(cowboy),
|
||||
start_http(), % Пользовательский API (8080)
|
||||
start_admin_http(), % Административный API (8445)
|
||||
start_swagger_http(), % Swagger UI и спецификация (8447)
|
||||
application:ensure_all_started(prometheus),
|
||||
application:ensure_all_started(prometheus_cowboy),
|
||||
init_default_admins(),
|
||||
{ok, Pid};
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
stop(_State) -> ok.
|
||||
|
||||
%% ===================================================================
|
||||
%% Пользовательский HTTP (порт 8080) — только публичные эндпоинты
|
||||
%% ===================================================================
|
||||
start_http() ->
|
||||
Port = get_env_int(http_port, 8080),
|
||||
Dispatch = cowboy_router:compile([
|
||||
{'_', [
|
||||
{"/metrics/[:registry]", prometheus_cowboy2_handler, []},
|
||||
{"/health", handler_health, []},
|
||||
{"/v1/register", handler_register, []},
|
||||
{"/v1/verify", handler_verify, []},
|
||||
{"/v1/login", handler_login, []},
|
||||
{"/v1/refresh", handler_refresh, []},
|
||||
{"/v1/user/me", handler_user_me, []},
|
||||
{"/v1/user/bookings", handler_user_bookings, []},
|
||||
{"/v1/user/reviews", handler_user_reviews, []},
|
||||
{"/v1/search", handler_search, []},
|
||||
{"/v1/calendars", handler_calendars, []},
|
||||
{"/v1/calendars/:id", handler_calendar_by_id, []},
|
||||
{"/v1/calendars/:calendar_id/view", handler_calendar_view, []},
|
||||
{"/v1/calendars/:calendar_id/events", handler_events, []},
|
||||
{"/v1/events/:id", handler_event_by_id, []},
|
||||
{"/v1/events/:id/occurrences", handler_event_occurrences, []},
|
||||
{"/v1/events/:id/occurrences/:start_time", handler_event_occurrences, []},
|
||||
{"/v1/events/:id/bookings", handler_bookings, []},
|
||||
{"/v1/bookings/:id", handler_booking_by_id, []},
|
||||
{"/v1/reviews", handler_reviews, []},
|
||||
{"/v1/reviews/:id", handler_review_by_id, []},
|
||||
{"/v1/reports", handler_reports, []},
|
||||
{"/v1/tickets", handler_tickets, []},
|
||||
{"/v1/tickets/:id", handler_ticket_by_id, []},
|
||||
{"/v1/subscription", handler_subscription, []}
|
||||
]} %% 23
|
||||
]),
|
||||
Middlewares = [cowboy_router, cowboy_handler],
|
||||
Env = #{dispatch => Dispatch},
|
||||
cowboy:start_clear(http, [{port, Port}],
|
||||
#{env => Env, middlewares => Middlewares,
|
||||
metrics_callback => fun prometheus_cowboy2_instrumenter:observe/1,
|
||||
stream_handlers => [cowboy_metrics_h, cowboy_stream_h]
|
||||
}),
|
||||
io:format("HTTP server started on port ~p~n", [Port]).
|
||||
|
||||
%% ===================================================================
|
||||
%% Административный HTTP (порт 8445) — все админские эндпоинты
|
||||
%% ===================================================================
|
||||
start_admin_http() ->
|
||||
PortAdmin = get_env_int(admin_http_port, 8445),
|
||||
Dispatch = cowboy_router:compile([
|
||||
{'_', [
|
||||
% ================== БАЗОВЫЕ ==================
|
||||
{"/admin/health", admin_handler_health, []},
|
||||
{"/v1/admin/stats", admin_handler_stats, []},
|
||||
{"/v1/admin/nodes/metrics", admin_handler_node_metrics, []},
|
||||
{"/v1/admin/login", admin_handler_login, []},
|
||||
{"/v1/admin/refresh", admin_handler_refresh, []},
|
||||
% ================== ПОЛЬЗОВАТЕЛИ ==================
|
||||
{"/v1/admin/users", admin_handler_users, []},
|
||||
{"/v1/admin/users/stats", admin_handler_user_stats, []},
|
||||
{"/v1/admin/users/:id", admin_handler_user_by_id, []},
|
||||
{"/v1/admin/users/:id/verification-token", admin_handler_user_verification_token, []},
|
||||
% ================== КАЛЕНДАРИ ==================
|
||||
{"/v1/admin/calendars", admin_handler_calendars, []},
|
||||
{"/v1/admin/calendars/stats", admin_handler_calendar_stats, []},
|
||||
{"/v1/admin/calendars/:id", admin_handler_calendar_by_id, []},
|
||||
% ================== СОБЫТИЯ ==================
|
||||
{"/v1/admin/events", admin_handler_events, []},
|
||||
{"/v1/admin/events/stats", admin_handler_event_stats, []},
|
||||
{"/v1/admin/events/:id", admin_handler_event_by_id, []},
|
||||
% ================== ОТЧЁТЫ ==================
|
||||
{"/v1/admin/reports", admin_handler_reports, []},
|
||||
{"/v1/admin/reports/stats", admin_handler_report_stats, []},
|
||||
{"/v1/admin/reports/:id", admin_handler_report_by_id, []},
|
||||
% ================== ОТЗЫВЫ ==================
|
||||
{"/v1/admin/reviews", admin_handler_reviews, []},
|
||||
{"/v1/admin/reviews/stats", admin_handler_reviews_stats, []},
|
||||
{"/v1/admin/reviews/:id", admin_handler_reviews_by_id, []},
|
||||
% ================== БАН-СЛОВА ==================
|
||||
{"/v1/admin/banned-words/batch", admin_handler_banned_words, []},
|
||||
{"/v1/admin/banned-words", admin_handler_banned_words, []},
|
||||
{"/v1/admin/banned-words/:word", admin_handler_banned_words, []},
|
||||
% ================== ТИКЕТЫ ==================
|
||||
{"/v1/admin/tickets/stats", admin_handler_ticket_stats, []},
|
||||
{"/v1/admin/tickets/:id", admin_handler_ticket_by_id, []},
|
||||
{"/v1/admin/tickets", admin_handler_tickets, []},
|
||||
% ================== ПОДПИСКИ ==================
|
||||
{"/v1/admin/subscriptions", admin_handler_subscriptions, []},
|
||||
{"/v1/admin/subscriptions/stats", admin_handler_subscription_stats, []},
|
||||
{"/v1/admin/subscriptions/:id", admin_handler_subscriptions_by_id, []},
|
||||
% ================== Управление ролями (только для superadmin) ==================
|
||||
{"/v1/admin/me", admin_handler_me, []},
|
||||
{"/v1/admin/admins", admin_handler_admins, []},
|
||||
{"/v1/admin/admins/:id", admin_handler_admins_by_id, []},
|
||||
{"/v1/admin/audit", admin_handler_audit, []},
|
||||
% ================== МОДЕРАЦИЯ (общий маршрут) ==================
|
||||
{"/v1/admin/:target_type/:id", admin_handler_moderation, []}
|
||||
]}
|
||||
]),
|
||||
|
||||
Middlewares = [cowboy_router, cowboy_handler],
|
||||
Env = #{dispatch => Dispatch},
|
||||
cowboy:start_clear(admin_http, [{port, PortAdmin}],
|
||||
#{env => Env, middlewares => Middlewares,
|
||||
metrics_callback => fun prometheus_cowboy2_instrumenter:observe/1,
|
||||
stream_handlers => [cowboy_metrics_h, cowboy_stream_h]
|
||||
}),
|
||||
io:format("Admin HTTP server started on port ~p~n", [PortAdmin]),
|
||||
|
||||
% WebSocket для пользователей
|
||||
WsDispatch = cowboy_router:compile([{'_', [{"/ws", ws_handler, []}]}]),
|
||||
PortWs = get_env_int(ws_port, 8081),
|
||||
cowboy:start_clear(ws, [{port, PortWs}], #{env => #{dispatch => WsDispatch}}),
|
||||
|
||||
% WebSocket для админов
|
||||
AdminWsDispatch = cowboy_router:compile([{'_', [
|
||||
{"/admin/ws/metrics", admin_ws_handler, []},
|
||||
{"/admin/ws", admin_ws_handler, []}
|
||||
]}]),
|
||||
PortAdminWs = get_env_int(admin_ws_port, 8446),
|
||||
cowboy:start_clear(admin_ws, [{port, PortAdminWs}], #{env => #{dispatch => AdminWsDispatch}}),
|
||||
|
||||
io:format("WebSocket started on ports ~p (user) and ~p (admin)~n", [PortWs, PortAdminWs]).
|
||||
|
||||
%% ===================================================================
|
||||
%% Swagger HTTP (порт 8447) — документация API
|
||||
%% ===================================================================
|
||||
start_swagger_http() ->
|
||||
PortSwagger = get_env_int(swagger_http_port, 8447),
|
||||
Dispatch = cowboy_router:compile([
|
||||
{'_', [
|
||||
{"/", swagger_docs_handler, []},
|
||||
{"/[...]", swagger_docs_handler, []}
|
||||
]}
|
||||
]),
|
||||
Middlewares = [cowboy_router, cowboy_handler],
|
||||
Env = #{dispatch => Dispatch},
|
||||
cowboy:start_clear(swagger_http, [{port, PortSwagger}], #{env => Env, middlewares => Middlewares}),
|
||||
io:format("Swagger HTTP server started on port ~p~n", [PortSwagger]).
|
||||
|
||||
%% ---------- Инициализация администраторов ----------
|
||||
init_default_admins() ->
|
||||
case core_admin:list_all() of
|
||||
[] ->
|
||||
% Суперадмин
|
||||
SuperEmail = list_to_binary(os:getenv("ADMIN_SUPER_EMAIL", "superadmin@eventhub.local")),
|
||||
SuperPass = list_to_binary(os:getenv("ADMIN_SUPER_PASSWORD", "123456")),
|
||||
{ok, _} = core_admin:create(SuperEmail, SuperPass, superadmin),
|
||||
io:format("Default superadmin created: ~s~n", [SuperEmail]),
|
||||
|
||||
% Админ
|
||||
AdminEmail = list_to_binary(os:getenv("ADMIN_EMAIL", "admin@eventhub.local")),
|
||||
AdminPass = list_to_binary(os:getenv("ADMIN_PASSWORD", "123456")),
|
||||
{ok, _} = core_admin:create(AdminEmail, AdminPass, admin),
|
||||
io:format("Default admin created: ~s~n", [AdminEmail]),
|
||||
|
||||
% Модератор
|
||||
ModerEmail = list_to_binary(os:getenv("ADMIN_MODER_EMAIL", "moderator@eventhub.local")),
|
||||
ModerPass = list_to_binary(os:getenv("ADMIN_MODER_PASSWORD", "123456")),
|
||||
{ok, _} = core_admin:create(ModerEmail, ModerPass, moderator),
|
||||
io:format("Default moderator created: ~s~n", [ModerEmail]),
|
||||
|
||||
% Поддержка
|
||||
SupportEmail = list_to_binary(os:getenv("ADMIN_SUPPORT_EMAIL", "support@eventhub.local")),
|
||||
SupportPass = list_to_binary(os:getenv("ADMIN_SUPPORT_PASSWORD", "123456")),
|
||||
{ok, _} = core_admin:create(SupportEmail, SupportPass, support),
|
||||
io:format("Default support created: ~s~n", [SupportEmail]);
|
||||
_ ->
|
||||
io:format("Admins already exist. Skipping creation.~n")
|
||||
end.
|
||||
|
||||
get_env_int(Key, Default) ->
|
||||
case application:get_env(eventhub, Key, Default) of
|
||||
Val when is_list(Val) -> list_to_integer(Val);
|
||||
Val when is_integer(Val) -> Val
|
||||
-module(eventhub_app).
|
||||
-behaviour(application).
|
||||
-export([start/2, stop/1]).
|
||||
|
||||
start(_StartType, _StartArgs) ->
|
||||
case infra_sup:start_link() of
|
||||
{ok, Pid} ->
|
||||
% Определяем список узлов кластера, если режим CLUSTER_MODE=true
|
||||
Nodes = case os:getenv("CLUSTER_MODE", "false") of
|
||||
"true" ->
|
||||
DnsName = os:getenv("DNS_NAME", "eventhub-node"),
|
||||
try inet:getaddrs(DnsName, inet) of
|
||||
{ok, IPs} when is_list(IPs), IPs /= [] ->
|
||||
% Получаем имена всех узлов Erlang, зарегистрированных в EPMD
|
||||
AllNodes = lists:flatmap(fun(IP) ->
|
||||
case erl_epmd:names(IP) of
|
||||
{ok, Names} ->
|
||||
[list_to_atom(Name ++ "@" ++ Name) || {Name, _Port} <- Names,
|
||||
lists:prefix("eventhub-node", Name)];
|
||||
_ -> []
|
||||
end
|
||||
end, IPs),
|
||||
% Исключаем свой узел, чтобы не подключаться к самому себе
|
||||
AllNodes -- [node()];
|
||||
_ -> []
|
||||
catch
|
||||
_:_ ->
|
||||
io:format("DNS lookup failed, starting as first node~n"),
|
||||
[]
|
||||
end;
|
||||
_ -> []
|
||||
end,
|
||||
case Nodes of
|
||||
[] ->
|
||||
io:format("~nCluster: no nodes found or first node~n");
|
||||
_ ->
|
||||
io:format("~nCluster: discovered nodes ~p, joining cluster~n", [Nodes]),
|
||||
application:set_env(eventhub, extra_db_nodes, Nodes)
|
||||
end,
|
||||
application:ensure_all_started(mnesia),
|
||||
ok = infra_mnesia:init_tables(),
|
||||
ok = infra_mnesia:wait_for_tables(),
|
||||
ok = migration_engine:ensure_applied(),
|
||||
calendar_html_renderer:init_cache(),
|
||||
application:ensure_all_started(cowboy),
|
||||
start_http(), % Пользовательский API (8080)
|
||||
start_admin_http(), % Административный API (8445)
|
||||
start_swagger_http(), % Swagger UI и спецификация (8447)
|
||||
application:ensure_all_started(prometheus),
|
||||
application:ensure_all_started(prometheus_cowboy),
|
||||
init_default_admins(),
|
||||
{ok, Pid};
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
stop(_State) -> ok.
|
||||
|
||||
%% ===================================================================
|
||||
%% Пользовательский HTTP (порт 8080) — только публичные эндпоинты
|
||||
%% ===================================================================
|
||||
start_http() ->
|
||||
Port = get_env_int(http_port, 8080),
|
||||
Dispatch = cowboy_router:compile([
|
||||
{'_', [
|
||||
{"/metrics/[:registry]", prometheus_cowboy2_handler, []},
|
||||
{"/health", handler_health, []},
|
||||
{"/v1/register", handler_register, []},
|
||||
{"/v1/verify", handler_verify, []},
|
||||
{"/v1/login", handler_login, []},
|
||||
{"/v1/refresh", handler_refresh, []},
|
||||
{"/v1/user/me", handler_user_me, []},
|
||||
{"/v1/user/bookings", handler_user_bookings, []},
|
||||
{"/v1/user/reviews", handler_user_reviews, []},
|
||||
{"/v1/search", handler_search, []},
|
||||
{"/v1/calendars", handler_calendars, []},
|
||||
{"/v1/calendars/:id", handler_calendar_by_id, []},
|
||||
{"/v1/calendars/:calendar_id/view", handler_calendar_view, []},
|
||||
{"/v1/calendars/:calendar_id/events", handler_events, []},
|
||||
{"/v1/events/:id", handler_event_by_id, []},
|
||||
{"/v1/events/:id/occurrences", handler_event_occurrences, []},
|
||||
{"/v1/events/:id/occurrences/:start_time", handler_event_occurrences, []},
|
||||
{"/v1/events/:id/bookings", handler_bookings, []},
|
||||
{"/v1/bookings/:id", handler_booking_by_id, []},
|
||||
{"/v1/reviews", handler_reviews, []},
|
||||
{"/v1/reviews/:id", handler_review_by_id, []},
|
||||
{"/v1/reports", handler_reports, []},
|
||||
{"/v1/tickets", handler_tickets, []},
|
||||
{"/v1/tickets/:id", handler_ticket_by_id, []},
|
||||
{"/v1/subscription", handler_subscription, []}
|
||||
]} %% 23
|
||||
]),
|
||||
Middlewares = [cowboy_router, cowboy_handler],
|
||||
Env = #{dispatch => Dispatch},
|
||||
cowboy:start_clear(http, [{port, Port}],
|
||||
#{env => Env, middlewares => Middlewares,
|
||||
metrics_callback => fun prometheus_cowboy2_instrumenter:observe/1,
|
||||
stream_handlers => [cowboy_metrics_h, cowboy_stream_h]
|
||||
}),
|
||||
io:format("HTTP server started on port ~p~n", [Port]).
|
||||
|
||||
%% ===================================================================
|
||||
%% Административный HTTP (порт 8445) — все админские эндпоинты
|
||||
%% ===================================================================
|
||||
start_admin_http() ->
|
||||
PortAdmin = get_env_int(admin_http_port, 8445),
|
||||
Dispatch = cowboy_router:compile([
|
||||
{'_', [
|
||||
% ================== БАЗОВЫЕ ==================
|
||||
{"/admin/health", admin_handler_health, []},
|
||||
{"/v1/admin/stats", admin_handler_stats, []},
|
||||
{"/v1/admin/nodes/metrics", admin_handler_node_metrics, []},
|
||||
{"/v1/admin/login", admin_handler_login, []},
|
||||
{"/v1/admin/refresh", admin_handler_refresh, []},
|
||||
% ================== ПОЛЬЗОВАТЕЛИ ==================
|
||||
{"/v1/admin/users", admin_handler_users, []},
|
||||
{"/v1/admin/users/stats", admin_handler_user_stats, []},
|
||||
{"/v1/admin/users/:id", admin_handler_user_by_id, []},
|
||||
{"/v1/admin/users/:id/verification-token", admin_handler_user_verification_token, []},
|
||||
% ================== КАЛЕНДАРИ ==================
|
||||
{"/v1/admin/calendars", admin_handler_calendars, []},
|
||||
{"/v1/admin/calendars/stats", admin_handler_calendar_stats, []},
|
||||
{"/v1/admin/calendars/:id", admin_handler_calendar_by_id, []},
|
||||
% ================== СОБЫТИЯ ==================
|
||||
{"/v1/admin/events", admin_handler_events, []},
|
||||
{"/v1/admin/events/stats", admin_handler_event_stats, []},
|
||||
{"/v1/admin/events/:id", admin_handler_event_by_id, []},
|
||||
% ================== ОТЧЁТЫ ==================
|
||||
{"/v1/admin/reports", admin_handler_reports, []},
|
||||
{"/v1/admin/reports/stats", admin_handler_report_stats, []},
|
||||
{"/v1/admin/reports/:id", admin_handler_report_by_id, []},
|
||||
% ================== ОТЗЫВЫ ==================
|
||||
{"/v1/admin/reviews", admin_handler_reviews, []},
|
||||
{"/v1/admin/reviews/stats", admin_handler_reviews_stats, []},
|
||||
{"/v1/admin/reviews/:id", admin_handler_reviews_by_id, []},
|
||||
% ================== БАН-СЛОВА ==================
|
||||
{"/v1/admin/banned-words/batch", admin_handler_banned_words, []},
|
||||
{"/v1/admin/banned-words", admin_handler_banned_words, []},
|
||||
{"/v1/admin/banned-words/:word", admin_handler_banned_words, []},
|
||||
% ================== ТИКЕТЫ ==================
|
||||
{"/v1/admin/tickets/stats", admin_handler_ticket_stats, []},
|
||||
{"/v1/admin/tickets/:id", admin_handler_ticket_by_id, []},
|
||||
{"/v1/admin/tickets", admin_handler_tickets, []},
|
||||
% ================== ПОДПИСКИ ==================
|
||||
{"/v1/admin/subscriptions", admin_handler_subscriptions, []},
|
||||
{"/v1/admin/subscriptions/stats", admin_handler_subscription_stats, []},
|
||||
{"/v1/admin/subscriptions/:id", admin_handler_subscriptions_by_id, []},
|
||||
% ================== Управление ролями (только для superadmin) ==================
|
||||
{"/v1/admin/me", admin_handler_me, []},
|
||||
{"/v1/admin/admins", admin_handler_admins, []},
|
||||
{"/v1/admin/admins/:id", admin_handler_admins_by_id, []},
|
||||
{"/v1/admin/audit", admin_handler_audit, []},
|
||||
% ================== МОДЕРАЦИЯ (общий маршрут) ==================
|
||||
{"/v1/admin/:target_type/:id", admin_handler_moderation, []}
|
||||
]}
|
||||
]),
|
||||
|
||||
Middlewares = [cowboy_router, cowboy_handler],
|
||||
Env = #{dispatch => Dispatch},
|
||||
cowboy:start_clear(admin_http, [{port, PortAdmin}],
|
||||
#{env => Env, middlewares => Middlewares,
|
||||
metrics_callback => fun prometheus_cowboy2_instrumenter:observe/1,
|
||||
stream_handlers => [cowboy_metrics_h, cowboy_stream_h]
|
||||
}),
|
||||
io:format("Admin HTTP server started on port ~p~n", [PortAdmin]),
|
||||
|
||||
% WebSocket для пользователей
|
||||
WsDispatch = cowboy_router:compile([{'_', [{"/ws", ws_handler, []}]}]),
|
||||
PortWs = get_env_int(ws_port, 8081),
|
||||
cowboy:start_clear(ws, [{port, PortWs}], #{env => #{dispatch => WsDispatch}}),
|
||||
|
||||
% WebSocket для админов
|
||||
AdminWsDispatch = cowboy_router:compile([{'_', [
|
||||
{"/admin/ws/metrics", admin_ws_handler, []},
|
||||
{"/admin/ws", admin_ws_handler, []}
|
||||
]}]),
|
||||
PortAdminWs = get_env_int(admin_ws_port, 8446),
|
||||
cowboy:start_clear(admin_ws, [{port, PortAdminWs}], #{env => #{dispatch => AdminWsDispatch}}),
|
||||
|
||||
io:format("WebSocket started on ports ~p (user) and ~p (admin)~n", [PortWs, PortAdminWs]).
|
||||
|
||||
%% ===================================================================
|
||||
%% Swagger HTTP (порт 8447) — документация API
|
||||
%% ===================================================================
|
||||
start_swagger_http() ->
|
||||
PortSwagger = get_env_int(swagger_http_port, 8447),
|
||||
Dispatch = cowboy_router:compile([
|
||||
{'_', [
|
||||
{"/", swagger_docs_handler, []},
|
||||
{"/[...]", swagger_docs_handler, []}
|
||||
]}
|
||||
]),
|
||||
Middlewares = [cowboy_router, cowboy_handler],
|
||||
Env = #{dispatch => Dispatch},
|
||||
cowboy:start_clear(swagger_http, [{port, PortSwagger}], #{env => Env, middlewares => Middlewares}),
|
||||
io:format("Swagger HTTP server started on port ~p~n", [PortSwagger]).
|
||||
|
||||
%% ---------- Инициализация администраторов ----------
|
||||
init_default_admins() ->
|
||||
case core_admin:list_all() of
|
||||
[] ->
|
||||
% Суперадмин
|
||||
SuperEmail = list_to_binary(os:getenv("ADMIN_SUPER_EMAIL", "superadmin@eventhub.local")),
|
||||
SuperPass = list_to_binary(os:getenv("ADMIN_SUPER_PASSWORD", "123456")),
|
||||
{ok, _} = core_admin:create(SuperEmail, SuperPass, superadmin),
|
||||
io:format("Default superadmin created: ~s~n", [SuperEmail]),
|
||||
|
||||
% Админ
|
||||
AdminEmail = list_to_binary(os:getenv("ADMIN_EMAIL", "admin@eventhub.local")),
|
||||
AdminPass = list_to_binary(os:getenv("ADMIN_PASSWORD", "123456")),
|
||||
{ok, _} = core_admin:create(AdminEmail, AdminPass, admin),
|
||||
io:format("Default admin created: ~s~n", [AdminEmail]),
|
||||
|
||||
% Модератор
|
||||
ModerEmail = list_to_binary(os:getenv("ADMIN_MODER_EMAIL", "moderator@eventhub.local")),
|
||||
ModerPass = list_to_binary(os:getenv("ADMIN_MODER_PASSWORD", "123456")),
|
||||
{ok, _} = core_admin:create(ModerEmail, ModerPass, moderator),
|
||||
io:format("Default moderator created: ~s~n", [ModerEmail]),
|
||||
|
||||
% Поддержка
|
||||
SupportEmail = list_to_binary(os:getenv("ADMIN_SUPPORT_EMAIL", "support@eventhub.local")),
|
||||
SupportPass = list_to_binary(os:getenv("ADMIN_SUPPORT_PASSWORD", "123456")),
|
||||
{ok, _} = core_admin:create(SupportEmail, SupportPass, support),
|
||||
io:format("Default support created: ~s~n", [SupportEmail]);
|
||||
_ ->
|
||||
io:format("Admins already exist. Skipping creation.~n")
|
||||
end.
|
||||
|
||||
get_env_int(Key, Default) ->
|
||||
case application:get_env(eventhub, Key, Default) of
|
||||
Val when is_list(Val) -> list_to_integer(Val);
|
||||
Val when is_integer(Val) -> Val
|
||||
end.
|
||||
Reference in New Issue
Block a user