-module(core_user). -include("records.hrl"). -export([create/2, get_by_id/1, get_by_email/1, update/2, delete/1]). -export([email_exists/1]). -export([generate_id/0]). -export([list_users/0]). -export([block/1, unblock/1]). %% Создание пользователя create(Email, Password) -> % Проверяем, существует ли email case email_exists(Email) of true -> {error, email_exists}; false -> Id = generate_id(), {ok, PasswordHash} = logic_auth:hash_password(Password), % Определяем роль: первый пользователь становится админом Role = case mnesia:dirty_match_object(#user{_ = '_'}) of [] -> admin; _ -> user end, User = #user{ id = Id, email = Email, password_hash = PasswordHash, role = Role, status = active, created_at = calendar:universal_time(), updated_at = calendar:universal_time() }, F = fun() -> mnesia:write(User), {ok, User} end, case mnesia:transaction(F) of {atomic, Result} -> Result; {aborted, Reason} -> {error, Reason} end end. %% Получение пользователя по ID get_by_id(Id) -> case mnesia:dirty_read(user, Id) of [] -> {error, not_found}; [User] -> {ok, User} end. %% Получение пользователя по email get_by_email(Email) -> Match = #user{email = Email, _ = '_'}, case mnesia:dirty_match_object(Match) of [] -> {error, not_found}; [User] -> {ok, User} end. %% Проверка существования email email_exists(Email) -> case get_by_email(Email) of {ok, _} -> true; {error, _} -> false end. %% Обновление пользователя update(Id, Updates) -> F = fun() -> case mnesia:read(user, Id) of [] -> {error, not_found}; [User] -> UpdatedUser = apply_updates(User, Updates), mnesia:write(UpdatedUser), {ok, UpdatedUser} end end, case mnesia:transaction(F) of {atomic, Result} -> Result; {aborted, Reason} -> {error, Reason} end. %% Удаление пользователя (soft delete) delete(Id) -> update(Id, [{status, deleted}]). list_users() -> Users = mnesia:dirty_match_object(#user{_ = '_'}), ActiveUsers = [U || U <- Users, U#user.status =/= deleted], {ok, [user_to_map(U) || U <- ActiveUsers]}. user_to_map(User) -> #{ id => User#user.id, email => User#user.email, password_hash => User#user.password_hash, role => User#user.role, status => User#user.status, created_at => User#user.created_at, updated_at => User#user.updated_at }. block(Id) -> case get_by_id(Id) of {ok, User} -> Updated = User#user{status = blocked, updated_at = calendar:universal_time()}, mnesia:dirty_write(Updated), {ok, Updated}; Error -> Error end. unblock(Id) -> case get_by_id(Id) of {ok, User} -> Updated = User#user{status = active, updated_at = calendar:universal_time()}, mnesia:dirty_write(Updated), {ok, Updated}; Error -> Error end. %% Внутренние функции 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) end, User, Updates), Updated#user{updated_at = calendar:universal_time()}. set_field(email, Value, U) -> U#user{email = Value}; set_field(password_hash, Value, U) -> U#user{password_hash = Value}; set_field(role, Value, U) when Value =:= user; Value =:= admin -> U#user{role = Value}; set_field(status, Value, U) when Value =:= active; Value =:= frozen; Value =:= deleted -> U#user{status = Value}; set_field(_, _, U) -> U.