feat: add custom email type for validation
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Moritz 2025-05-28 22:04:54 +02:00
parent 3e2140fda7
commit 859f5f4497
Signed by: moritz
GPG key ID: 1020A035E5DD0824
4 changed files with 43 additions and 18 deletions

34
lib/membership/email.ex Normal file
View file

@ -0,0 +1,34 @@
defmodule Mv.Membership.Email do
@constraints [
match: ~r/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/,
trim?: true,
min_length: 5,
max_length: 254
]
use Ash.Type.NewType,
subtype_of: :string,
constraints: @constraints
@impl true
def cast_input(value, _) when is_binary(value) do
value = if @constraints[:trim?], do: String.trim(value), else: value
cond do
@constraints[:min_length] && String.length(value) < @constraints[:min_length] ->
:error
@constraints[:max_length] && String.length(value) > @constraints[:max_length] ->
:error
@constraints[:match] && !Regex.match?(@constraints[:match], value) ->
:error
true ->
{:ok, value}
end
end
@impl true
def cast_input(_, _), do: :error
end

View file

@ -23,7 +23,8 @@ defmodule Mv.Membership.Property do
boolean: [type: :boolean],
date: [type: :date],
integer: [type: :integer],
string: [type: :string]
string: [type: :string],
email: [type: Mv.Membership.Email]
]
]
end

View file

@ -19,7 +19,7 @@ defmodule Mv.Membership.PropertyType do
attribute :name, :string, allow_nil?: false, public?: true
attribute :value_type, :atom,
constraints: [one_of: [:string, :integer, :boolean, :date]],
constraints: [one_of: [:string, :integer, :boolean, :date, :email]],
allow_nil?: false,
description: "Definies the datatype `Property.value` is interpreted as"

View file

@ -2,13 +2,6 @@
#
# mix run priv/repo/seeds.exs
#
# Inside the script, you can read and write to any of your
# repositories directly:
#
# Mv.Repo.insert!(%Mv.SomeSchema{})
#
# We recommend using the bang functions (`insert!`, `update!`
# and so on) as they will fail if something goes wrong.
alias Mv.Membership
@ -43,18 +36,15 @@ for attrs <- [
},
%{
name: "Email",
value_type: :string,
value_type: :email,
description: "Email-Adresse des Mitglieds",
immutable: true,
required: true
}
] do
# upsert?: true sorgt dafür, dass bei bestehendem Namen kein Fehler,
# sondern ein Update (hier effektiv No-Op) ausgeführt wird
{:ok, _} =
Membership.create_property_type(
attrs,
upsert?: true,
upsert_identity: :unique_name
)
Membership.create_property_type!(
attrs,
upsert?: true,
upsert_identity: :unique_name
)
end