Validation
Phone normalization and the field rules applied to every write path.
One rule set, every path
The same validator runs on the API, the dashboard forms, CSV and XLSX import, and the Google Sheets sync. Anything valid in one path is valid in all of them, and client-side checks cannot be bypassed by calling the API directly.
Phone numbers
Numbers must be Moroccan and are canonicalized to +212XXXXXXXXX before storage, so the same customer is never dialed twice under two spellings. The subscriber part is 9 digits starting with 5 (landline), 6, or 7 (mobile). Spaces, dashes, dots, and parentheses are stripped, and the 0, 212, +212, and 00212 prefixes are all accepted. Anything else fails validation rather than being stored as-is.
Normalization examples
| Input | Stored |
|---|---|
| 0600112233 | +212600112233 |
| +212 600-11-22-33 | +212600112233 |
| 00212600112233 | +212600112233 |
| 600112233 | +212600112233 |
| 0400112233 | rejected |
| +33612345678 | rejected |
Field rules
| Field | Required | Max length |
|---|---|---|
| clientName | yes | 120 |
| phone | yes | valid Moroccan number |
| storeName | yes | 120 |
| productsName | yes | 500 |
| address | no | 250 |
Validation error shape
{
"error": "Invalid order fields",
"code": "VALIDATION_ERROR",
"fields": {
"phone": "orders.form.errors.phoneInvalid",
"clientName": "orders.form.errors.required"
}
}fields values are i18n keys, not display strings. Branch on the key; render your own copy.
Field error keys
| Key | Meaning |
|---|---|
| orders.form.errors.required | Missing or whitespace only. |
| orders.form.errors.tooLong | Over the max length for that field. |
| orders.form.errors.phoneInvalid | Not a valid Moroccan number. |