mirror of
https://github.com/suitenumerique/messages.git
synced 2026-08-23 16:02:26 +02:00
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`.
130 lines
4.1 KiB
Markdown
130 lines
4.1 KiB
Markdown
# 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](./env.md#model-custom-attributes-schema).
|
|
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](https://json-schema.org/draft/2020-12).
|
|
|
|
> **💡 Tip**
|
|
> Before deploying your application, lint your JSON Schema to ensure it is correctly formatted.
|
|
> [Several tools are available](https://json-schema.org/tools?query=&sortBy=name&sortOrder=ascending&groupBy=toolingTypes&licenses=&languages=&drafts=&toolingTypes=linter,validator&environments=Web+(Online)&showObsolete=false&supportsBowtie=false).
|
|
|
|
> **⚠️ 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 to `false`.
|
|
|
|
```json
|
|
{
|
|
"$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](https://json-schema.org/blog/posts/custom-annotations-will-continue#too-long-read-anyway) named `x-i18n`.
|
|
This property allows defining localized `title` and `description` values for each property in the supported languages.
|
|
|
|
> **🗒️ Note**
|
|
> The `x-i18n` object is optional. If omitted, the values in `title` and `description` will 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](https://github.com/glideapps/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 `RhfJsonSchemaField` chooses the correct input to render based on the property `type`.
|
|
|
|
- **Form state**: Managed by [React Hook Form](https://react-hook-form.com/), in line with other forms in the application.
|
|
|
|
> **⚠️ Warning**
|
|
> Because `zod-from-json-schema` support 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](https://github.com/python-jsonschema/jsonschema) package for validation.
|
|
It provides **full support** for the 2020-12 specification, ensuring data integrity even if frontend validation is bypassed.
|