Member/Setting/validations: domain, actor, and seeds
- setting.ex: domain/authorize for default_membership_fee_type_id check - validate_same_interval: require membership_fee_type (no None) - set_membership_fee_start_date: domain/actor for fee type lookup - Validations: domain/authorize for cross-resource checks - helpers.ex, email_sync change, seeds.exs actor/authorize fixes - Update related tests
This commit is contained in:
parent
5889683854
commit
5ed41555e9
13 changed files with 118 additions and 55 deletions
|
|
@ -81,7 +81,7 @@ defmodule Mv.Accounts.User.Validations.EmailNotUsedByOtherMember do
|
|||
query =
|
||||
Mv.Membership.Member
|
||||
|> Ash.Query.filter(email == ^to_string(email))
|
||||
|> maybe_exclude_id(exclude_member_id)
|
||||
|> Mv.Helpers.query_exclude_id(exclude_member_id)
|
||||
|
||||
system_actor = SystemActor.get_system_actor()
|
||||
opts = Helpers.ash_actor_opts(system_actor)
|
||||
|
|
@ -101,7 +101,4 @@ defmodule Mv.Accounts.User.Validations.EmailNotUsedByOtherMember do
|
|||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_exclude_id(query, nil), do: query
|
||||
defp maybe_exclude_id(query, id), do: Ash.Query.filter(query, id != ^id)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@ defmodule Mv.EmailSync.Changes.SyncUserEmailToMember do
|
|||
Modified changeset with email synchronization applied, or original changeset
|
||||
if recursion detected.
|
||||
"""
|
||||
# Ash 3.12+ calls this to decide whether to run the change in certain contexts.
|
||||
@impl true
|
||||
def has_change?, do: true
|
||||
|
||||
@impl true
|
||||
def change(changeset, _opts, context) do
|
||||
# Only recursion protection needed - trigger logic is in `where` clauses
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ defmodule Mv.Helpers do
|
|||
Provides utilities that are not specific to a single domain or layer.
|
||||
"""
|
||||
|
||||
require Ash.Query
|
||||
|
||||
@doc """
|
||||
Converts an actor to Ash options list for authorization.
|
||||
Returns empty list if actor is nil.
|
||||
|
|
@ -24,4 +26,22 @@ defmodule Mv.Helpers do
|
|||
@spec ash_actor_opts(Mv.Accounts.User.t() | nil) :: keyword()
|
||||
def ash_actor_opts(nil), do: []
|
||||
def ash_actor_opts(actor) when not is_nil(actor), do: [actor: actor]
|
||||
|
||||
@doc """
|
||||
Returns the query unchanged if `exclude_id` is nil; otherwise adds a filter `id != ^exclude_id`.
|
||||
|
||||
Used in uniqueness validations that must exclude the current record (e.g. name uniqueness
|
||||
on update, duplicate association checks). Call with the record's primary key to exclude it
|
||||
from the result set.
|
||||
|
||||
## Examples
|
||||
|
||||
query
|
||||
|> Ash.Query.filter(name == ^name)
|
||||
|> Mv.Helpers.query_exclude_id(current_id)
|
||||
|
||||
"""
|
||||
@spec query_exclude_id(Ash.Query.t(), String.t() | nil) :: Ash.Query.t()
|
||||
def query_exclude_id(query, nil), do: query
|
||||
def query_exclude_id(query, id), do: Ash.Query.filter(query, id != ^id)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ defmodule Mv.Membership.Member.Validations.EmailNotUsedByOtherUser do
|
|||
query =
|
||||
Mv.Accounts.User
|
||||
|> Ash.Query.filter(email == ^email)
|
||||
|> maybe_exclude_id(exclude_user_id)
|
||||
|> Mv.Helpers.query_exclude_id(exclude_user_id)
|
||||
|
||||
system_actor = SystemActor.get_system_actor()
|
||||
opts = Helpers.ash_actor_opts(system_actor)
|
||||
|
|
@ -76,7 +76,4 @@ defmodule Mv.Membership.Member.Validations.EmailNotUsedByOtherUser do
|
|||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_exclude_id(query, nil), do: query
|
||||
defp maybe_exclude_id(query, id), do: Ash.Query.filter(query, id != ^id)
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue