docs(ui): condense and translate email, UI and PDF docs to English

This commit is contained in:
Moritz 2026-06-15 21:53:36 +02:00
parent 0b36a43edc
commit 3797bc8fae
5 changed files with 113 additions and 731 deletions

View file

@ -1,62 +1,38 @@
# Email Validation Strategy
We use `EctoCommons.EmailValidator` with both `:html_input` and `:pow` checks, defined centrally in `Mv.Constants.email_validator_checks/0`.
We use `EctoCommons.EmailValidator` with **both** `:html_input` and `:pow`
checks, defined centrally in `Mv.Constants.email_validator_checks/0`
(`@email_validator_checks [:html_input, :pow]`).
## Checks Used
## Why both checks
- `:html_input` - Pragmatic validation matching browser `<input type="email">` behavior
- `:pow` - Stricter validation following email spec, supports internationalization (Unicode)
- `:html_input` — pragmatic validation matching browser `<input type="email">`
behavior; accepts the common formats users expect from web forms.
- `:pow` — stricter, spec-following validation (RFC 5322 and related);
supports international (Unicode) email addresses.
## 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).
Using both balances user experience (accepting common formats) against
technical correctness (validating against email standards) and international
support.
## Usage
The checks are used consistently across all email validation points:
The checks are applied consistently at every validation point, all reading the
single central constant so they stay in sync:
- `Mv.Membership.Import.MemberCSV.validate_row/3` - CSV import validation
- `Mv.Membership.Member` validations - Member resource validation
- `Mv.Accounts.User` validations - User resource validation
- `Mv.Membership.Import.MemberCSV.validate_row/3` — CSV import (schemaless
changeset: trims whitespace, requires email, then validates format via the
shared checks).
- `Mv.Membership.Member` validations — Member resource.
- `Mv.Accounts.User` validations — User resource.
All three locations use `Mv.Constants.email_validator_checks()` to ensure consistency.
Member and User use similar schemaless changesets inside their Ash validations.
## Implementation Details
## Changing the validation strategy
### 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
Update `@email_validator_checks` in `Mv.Constants`; the change applies
everywhere automatically.
**Migration caveat:** tightening validation may invalidate existing data.
Consider whether stored emails are still valid, a migration strategy for those
that are not, and user communication.