All checks were successful
continuous-integration/drone/push Build is passing
Complete refactoring of resources, database tables, code references, tests, and documentation for improved naming consistency.
70 lines
1.7 KiB
Elixir
70 lines
1.7 KiB
Elixir
defmodule Mv.Membership.Email do
|
|
@moduledoc """
|
|
Custom Ash type for validated email addresses.
|
|
|
|
## Overview
|
|
This type extends `:string` with email-specific validation constraints.
|
|
It ensures that email values stored in CustomFieldValue resources are valid email
|
|
addresses according to a standard regex pattern.
|
|
|
|
## Validation Rules
|
|
- Minimum length: 5 characters
|
|
- Maximum length: 254 characters (RFC 5321 maximum)
|
|
- Pattern: Standard email format (username@domain.tld)
|
|
- Automatic trimming of leading/trailing whitespace
|
|
|
|
## Usage
|
|
This type is used in the CustomFieldValue union type for custom fields with
|
|
`value_type: :email` in CustomField definitions.
|
|
|
|
## Example
|
|
# In a custom field definition
|
|
CustomField.create!(%{
|
|
name: "work_email",
|
|
value_type: :email
|
|
})
|
|
|
|
# Valid values
|
|
"user@example.com"
|
|
"first.last@company.co.uk"
|
|
|
|
# Invalid values
|
|
"not-an-email" # Missing @ and domain
|
|
"a@b" # Too short
|
|
"""
|
|
@match_pattern ~S/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/
|
|
@match_regex Regex.compile!(@match_pattern)
|
|
@min_length 5
|
|
@max_length 254
|
|
|
|
use Ash.Type.NewType,
|
|
subtype_of: :string,
|
|
constraints: [
|
|
match: @match_pattern,
|
|
trim?: true,
|
|
min_length: @min_length,
|
|
max_length: @max_length
|
|
]
|
|
|
|
@impl true
|
|
def cast_input(value, _) when is_binary(value) do
|
|
value = String.trim(value)
|
|
|
|
cond do
|
|
String.length(value) < @min_length ->
|
|
:error
|
|
|
|
String.length(value) > @max_length ->
|
|
:error
|
|
|
|
!Regex.match?(@match_regex, value) ->
|
|
:error
|
|
|
|
true ->
|
|
{:ok, value}
|
|
end
|
|
end
|
|
|
|
@impl true
|
|
def cast_input(_, _), do: :error
|
|
end
|