Add comprehensive module documentation to Member, Property, PropertyType, and Email. Improves code discoverability and enables ExDoc generation.
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 Property 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 Property union type for properties with
|
|
`value_type: :email` in PropertyType definitions.
|
|
|
|
## Example
|
|
# In a property type definition
|
|
PropertyType.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
|