In the personal mailbox form, we now render extra fields according to the `SCHEMA_CUSTOM_ATTRIBUTES_USER` got through config endpoint. Those fields are validated through zod and the schema is generated through `zod-from-json-schema` package. Then a custom component is in charge to render the right component according to the schema property `type`.
4.1 KiB
Model Custom Attributes
Purpose
The User and MailDomain models support storing additional data via a custom_attributes JSON field.
If an identity provider is configured, these attributes are also synchronized with it.
🗒️ Note This feature allows you to extend the core models without altering the database schema.
Usage
For each model, the structure of the custom_attributes data can be defined via
environment variables.
This enables customization of your Messages instance without forking the project.
The value must be a valid JSON Schema string following the 2020-12 specification.
💡 Tip Before deploying your application, lint your JSON Schema to ensure it is correctly formatted. Several tools are available.
⚠️ Warning Altering schemas could require to you to migrate your data! Modify it with caution.
Schema Structure
Custom attributes must be an object with only primitive properties (string, number, integer or boolean).
Example of a valid JSON Schema:
job_title: a string with a minimum length of 3 characters.is_elected: a boolean that defaults tofalse.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/suitenumerique/messages/schemas/custom-fields/user",
"type": "object",
"title": "User custom fields",
"additionalProperties": false,
"properties": {
"job_title": {
"type": "string",
"title": "Job title",
"default": "",
"description": "The job name of the user",
"minLength": 3,
"x-i18n": {
"title": {
"fr": "Fonction",
"en": "Job title"
},
"description": {
"fr": "Le nom de la fonction de l'utilisateur",
"en": "The job name of the user"
}
}
},
"is_elected": {
"type": "boolean",
"title": "Is elected",
"default": false,
"description": "Whether the user is elected",
"x-i18n": {
"title": {
"fr": "Est élu",
"en": "Is elected"
},
"description": {
"fr": "Indique si l'utilisateur est élu"
}
}
}
},
"required": []
}
Internationalization
If your application is not internationalized, you can skip this section.
Providing a title and description for each property is sufficient.
In the example above, we use a
custom annotation named x-i18n.
This property allows defining localized title and description values for each property in the supported languages.
🗒️ Note The
x-i18nobject is optional. If omitted, the values intitleanddescriptionwill be used as-is.
Data Validation
The custom attributes schema is used to:
- Render input fields and validate data on the frontend.
- Validate data on the backend.
Frontend
-
Schema generation: We use zod-from-json-schema to generate a Zod schema. This library provides broad (but partial) support for the 2020-12 specification.
-
Form rendering: The custom component
RhfJsonSchemaFieldchooses the correct input to render based on the propertytype. -
Form state: Managed by React Hook Form, in line with other forms in the application.
⚠️ Warning Because
zod-from-json-schemasupport for 2020-12 is partial, certain advanced JSON Schema features may not work as expected on the frontend. Always test your schema in the UI before deploying.
Backend
We use the jsonschema package for validation. It provides full support for the 2020-12 specification, ensuring data integrity even if frontend validation is bypassed.