Merge branch 'main' into feature/concept-groups
This commit is contained in:
commit
68baf71119
13 changed files with 709 additions and 187 deletions
62
docs/email-validation.md
Normal file
62
docs/email-validation.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# Email Validation Strategy
|
||||
|
||||
We use `EctoCommons.EmailValidator` with both `:html_input` and `:pow` checks, defined centrally in `Mv.Constants.email_validator_checks/0`.
|
||||
|
||||
## Checks Used
|
||||
|
||||
- `:html_input` - Pragmatic validation matching browser `<input type="email">` behavior
|
||||
- `:pow` - Stricter validation following email spec, supports internationalization (Unicode)
|
||||
|
||||
## Rationale
|
||||
|
||||
Using both checks ensures:
|
||||
- **Compatibility with common email providers** (`:html_input`) - Matches what users expect from web forms
|
||||
- **Compliance with email standards** (`:pow`) - Follows RFC 5322 and related specifications
|
||||
- **Support for international email addresses** (`:pow`) - Allows Unicode characters in email addresses
|
||||
|
||||
This dual approach provides a balance between user experience (accepting common email formats) and technical correctness (validating against email standards).
|
||||
|
||||
## Usage
|
||||
|
||||
The checks are used consistently across all email validation points:
|
||||
|
||||
- `Mv.Membership.Import.MemberCSV.validate_row/3` - CSV import validation
|
||||
- `Mv.Membership.Member` validations - Member resource validation
|
||||
- `Mv.Accounts.User` validations - User resource validation
|
||||
|
||||
All three locations use `Mv.Constants.email_validator_checks()` to ensure consistency.
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### CSV Import Validation
|
||||
|
||||
The CSV import uses a schemaless changeset for email validation:
|
||||
|
||||
```elixir
|
||||
changeset =
|
||||
{%{}, %{email: :string}}
|
||||
|> Ecto.Changeset.cast(%{email: Map.get(member_attrs, :email)}, [:email])
|
||||
|> Ecto.Changeset.update_change(:email, &String.trim/1)
|
||||
|> Ecto.Changeset.validate_required([:email])
|
||||
|> EctoCommons.EmailValidator.validate_email(:email, checks: Mv.Constants.email_validator_checks())
|
||||
```
|
||||
|
||||
This approach:
|
||||
- Trims whitespace before validation
|
||||
- Validates email is required
|
||||
- Validates email format using the centralized checks
|
||||
- Provides consistent error messages via Gettext
|
||||
|
||||
### Resource Validations
|
||||
|
||||
Both `Member` and `User` resources use similar schemaless changesets within their Ash validations, ensuring consistent validation behavior across the application.
|
||||
|
||||
## Changing the Validation Strategy
|
||||
|
||||
To change the email validation checks, update the `@email_validator_checks` constant in `Mv.Constants`. This will automatically apply to all validation points.
|
||||
|
||||
**Note:** Changing the validation strategy may affect existing data. Consider:
|
||||
- Whether existing emails will still be valid
|
||||
- Migration strategy for invalid emails
|
||||
- User communication if validation becomes stricter
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue