# Email Validation Strategy 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]`). ## Why both checks - `:html_input` — pragmatic validation matching browser `` behavior; accepts the common formats users expect from web forms. - `:pow` — stricter, spec-following validation (RFC 5322 and related); supports international (Unicode) email addresses. Using both balances user experience (accepting common formats) against technical correctness (validating against email standards) and international support. ## Usage 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 (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. Member and User use similar schemaless changesets inside their Ash validations. ## Changing the validation strategy 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.