defmodule Mv.Accounts.User.Changes.SyncEmailToMember do @moduledoc """ Synchronizes user email changes to the linked member. Uses `around_transaction` for atomicity - both updates in the same transaction. """ use Ash.Resource.Change alias Mv.EmailSync.{Helpers, Loader} @impl true def change(changeset, _opts, context) do cond do Map.get(context, :syncing_email, false) -> changeset not Ash.Changeset.changing_attribute?(changeset, :email) -> changeset true -> sync_email(changeset) end end defp sync_email(changeset) do new_email = Ash.Changeset.get_attribute(changeset, :email) Ash.Changeset.around_transaction(changeset, fn cs, callback -> result = callback.(cs) with {:ok, user} <- Helpers.extract_record(result), linked_member <- Loader.get_linked_member(user) do Helpers.sync_email_to_linked_record(result, linked_member, new_email) else _ -> result end end) end end