refactor: adds schemales changeset and validation constant

This commit is contained in:
carla 2026-01-19 11:43:51 +01:00
parent 14a8417fdf
commit 7da037d81d
6 changed files with 158 additions and 34 deletions

62
docs/email-validation.md Normal file
View 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