System Actor Mode for Systemic Flows closes #348 #361

Merged
moritz merged 16 commits from feature/348_system_actor into main 2026-01-21 08:36:41 +01:00
2 changed files with 19 additions and 8 deletions
Showing only changes of commit f0169c95b7 - Show all commits

View file

@ -73,12 +73,18 @@ defmodule Mv.Accounts.User.Validations.EmailNotUsedByOtherMember do
end end
defp check_email_uniqueness(email, exclude_member_id) do defp check_email_uniqueness(email, exclude_member_id) do
alias Mv.Helpers
alias Mv.Helpers.SystemActor
query = query =
Mv.Membership.Member Mv.Membership.Member
|> Ash.Query.filter(email == ^to_string(email)) |> Ash.Query.filter(email == ^to_string(email))
|> maybe_exclude_id(exclude_member_id) |> maybe_exclude_id(exclude_member_id)
case Ash.read(query) do system_actor = SystemActor.get_system_actor()
opts = Helpers.ash_actor_opts(system_actor)
case Ash.read(query, opts) do
{:ok, []} -> {:ok, []} ->
:ok :ok

View file

@ -30,8 +30,7 @@ defmodule Mv.Membership.Member.Validations.EmailNotUsedByOtherUser do
def validate(changeset, _opts, _context) do def validate(changeset, _opts, _context) do
email_changing? = Ash.Changeset.changing_attribute?(changeset, :email) email_changing? = Ash.Changeset.changing_attribute?(changeset, :email)
actor = Map.get(changeset.context || %{}, :actor) linked_user_id = get_linked_user_id(changeset.data)
linked_user_id = get_linked_user_id(changeset.data, actor)
is_linked? = not is_nil(linked_user_id) is_linked? = not is_nil(linked_user_id)
# Only validate if member is already linked AND email is changing # Only validate if member is already linked AND email is changing
@ -40,19 +39,22 @@ defmodule Mv.Membership.Member.Validations.EmailNotUsedByOtherUser do
if should_validate? do if should_validate? do
new_email = Ash.Changeset.get_attribute(changeset, :email) new_email = Ash.Changeset.get_attribute(changeset, :email)
check_email_uniqueness(new_email, linked_user_id, actor) check_email_uniqueness(new_email, linked_user_id)
else else
:ok :ok
end end
end end
defp check_email_uniqueness(email, exclude_user_id, actor) do defp check_email_uniqueness(email, exclude_user_id) do
alias Mv.Helpers.SystemActor
query = query =
Mv.Accounts.User Mv.Accounts.User
|> Ash.Query.filter(email == ^email) |> Ash.Query.filter(email == ^email)
|> maybe_exclude_id(exclude_user_id) |> maybe_exclude_id(exclude_user_id)
opts = Helpers.ash_actor_opts(actor) system_actor = SystemActor.get_system_actor()
opts = Helpers.ash_actor_opts(system_actor)
case Ash.read(query, opts) do case Ash.read(query, opts) do
{:ok, []} -> {:ok, []} ->
@ -69,8 +71,11 @@ defmodule Mv.Membership.Member.Validations.EmailNotUsedByOtherUser do
defp maybe_exclude_id(query, nil), do: query defp maybe_exclude_id(query, nil), do: query
defp maybe_exclude_id(query, id), do: Ash.Query.filter(query, id != ^id) defp maybe_exclude_id(query, id), do: Ash.Query.filter(query, id != ^id)
defp get_linked_user_id(member_data, actor) do defp get_linked_user_id(member_data) do
opts = Helpers.ash_actor_opts(actor) alias Mv.Helpers.SystemActor
system_actor = SystemActor.get_system_actor()
opts = Helpers.ash_actor_opts(system_actor)
case Ash.load(member_data, :user, opts) do case Ash.load(member_data, :user, opts) do
{:ok, %{user: %{id: id}}} -> id {:ok, %{user: %{id: id}}} -> id