Aller au contenu

Modèles d'attributs

Maarch Digital Flow permet d'ajouter des attributs personnalisés aux entités gérées dans l'application, qu'il s'agisse des métadonnées pour les documents numériques, des données de formulaires pour les dossiers métier ou encore des informations personnelles des utilisateurs.

Bien que cela ne soit pas systématique, le plus souvent ces données doivent répondre à des contraintes en lien avec les règles du métier ou le besoin d'interopérabilité avec d'autres systèmes d'information. On peut par exemple souhaiter que les métadonnées des documents numériques de facture d'achat comportent obligatoirement l'identification du fournisseur, un numéro, une date et un montant total, ou que la structure des données d'un dossier correspondent à celle reçue depuis un formulaire de l'extranet.

Dans Maarch Digital Flow, la description de la structure des attributs des objets et les contraintes applicables sont décrites par des modèles d'attributs gérés par l'administrateur. Ces définitions sont ensuite utilisées dans les différentes sections d'administrations des entités.

Accès aux modèles

La section Modèle d'attributs de l'administration permet de créer et gérer les modèles. L'administrateur habilité l'utilise pour lister les modèles existants, les gérer et en ajouter de nouveaux.

Propriétés des modèles d'attributs

Champ Type Description
Identifiant métier texte Le nom utilisé par le système pour identifier le modèle. Il ne peut être changé quand le modèle est en cours d'utilisation
Libellé texte Le nom affiché aux utilisateurs lorsqu'ils utilisent le modèle
Description texte Description du modèle

@


Contenu du modèle

Les modèles d'attributs sont basés sur le formalisme de déclaration des schémas de données JSON Schema (cf https://json-schema.org). Ils en reprennent toute la syntaxe, les éléments de base tels que les types de données, les structures complexes de tableaux et d'objets, les contraintes sur les formats, propriétés obligatoires, etc, à laquelle ils ajoutent des éléments de description étendus pour répondre à de nouveaux besoins.

La présente documentation n'a pas pour objectif de redécrire les spécifications ou la documentation complète du standards JSON Schema. On fournit ici quelques bases mais on ne reprend dans le détail la documentation disponible sur le site du projets. Pour plus d'informations, consulter la page https://json-schema.org/understanding-json-schema.

La version de spécifications utilisée à ce jour est Draft 2020-12.

Un modèle d'attributs est un schéma JSON décrivant une structure de type object qui contient les attributs souhaités. La base de tout schéma est donc la suivante :

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type" : "object"
}

Schéma de base pour les objets

Le schéma décrit les attributs grâce au mot-clé properties. Ce bloc contient une liste qui associe les noms des propriétés à leur définition. La définition d'une propriété elle-même un schéma qui répond aux spécifications du formalisme JSON Schema. Chaque propriété doit a minima déclarer un type de données avec le mot-clé type qui peut prendre les valeurs suivantes :

  • string : chaîne de caractères (texte)
  • integer : nombre entier
  • number : nombre réel (ou décimal ou à virgule flottante)
  • boolean: indicateur booléen pouvant prendre les valeurs 'vrai' ou 'faux'
  • object : structure composite objet (ou clés-valeurs)
  • array : structure composite tableau (ou liste de valeurs non ordonnée)

Les propriétés obligatoires peuvent être déclarées par le mot-clé required sous la forme de la liste des noms des propriétés concernées.

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type" : "object",
    "properties": {
        "firstmane" : { "type": "string" },
        "lastname" : { "type": "string" },
        "age" : { "type": "integer" }
    },
    "required": [
        "lastname",
        "firstname"
    ]
}

L'application autorise aussi les définitions de propriétés complémentaires avec les mots-clés additionalProperties, patternProperties ainsi que les compositions avec les mots-clés allOf, oneOfet anyOf.

Affichage du formulaire

En plus de la définition des données, le modèle d'attributs utilise des mots-clés spécifiques liés à la présentation des attributs par l'application dans des formulaires dynamiques.

Mot-clé Type Description
position entier Permet de définir l'ordre d'affichage des propriétés dans le formulaire
collapsable indicateur Pour les propriétés de type object uniquement, permet de définir si le bloc d'affichage contenant le jeu de propriétés peut être refermé. Quelle que soit la valeur indiquée, le bloc est ouvert par défaut si les données ne sont pas valides au regard du schéma de la propriété.
view définition de champ Ce bloc fournit les paramètres d'affichage du champ dans le formulaire (voir ci-après)

Le bloc view contient des mots-clés pour adapter les paramètres d'affichage du champ dans le formulaire :

Mot-clé Type Description
type texte Mode de saisie de l'attribut, par exemple input-string, input-checkbox, textarea, etc.
size texte Largeur du champ de saisie small-blockoularge-block

L'application propose un mode de saisie par défaut pour les attributs en fonction de leur type de base, mais ce mode peut-être adapté grâce au mot-clé type :

Type de champ Description Type d'attribut applicables
input-text Champ de saisie de texte simple string
input-text-multiple Champ de saisie de texte multi-valeurs minItems, maxItems, copySeparatoret uniqueItems
input-textarea Zone de texte multilignes stringnbLineToShow (2, 3, 10, 15, 20)
input-number Champ numérique number, integer(minimumet maximum)
input-autocomplete Champs de saisie assistée string avec enum ou externalReference
input-checkbox Cases à cocher Type simple avec enum, boolean
input-radio Boutons radio Type simple avec enum
input-toggle Interrupteur à bascule boolean
input-date Champs de saisie avec sélecteur de date string avec format: date-timeminDate, maxDate, today
input-img Champs image string
input-array Tableau itemsuniqueItems

Ci-dessous un exemple de définition d'attributs comportant des mots-clés de présentation :

"civilite": {
          "enum": [
            "Mme",
            "M"
          ],
          "gdpr": true,
          "type": "string",
          "view": {
            "size": "small-block",
            "type": "input-select"
          },
          "title": "Civilité",
          "pattern": "^(Mme|M)$",
          "position": 3,
          "filterNode": "exact",
          "description": "Civilité"
        },
    "date_naissance": {
          "gdpr": true,
          "type": "string",
          "view": {
            "mask": {
              "mask": "d0/M0/0000",
              "showMaskTyped": true
            },
            "size": "small-block",
            "type": "input-date"
          },
          "title": "Date de naissance",
          "format": "date",
          "position": 6,
          "filterNode": "date",
          "description": "Date de naissance"
        }

Protection des données personnelles et sensibles

Le mot-clé gdpr permet d'indiquer qu'un attribut contient des données à caractère personnel ou sensible. De telles données pourront ainsi être facilement identifiées dans l'application pour des opérations ultérieures d'anonymisation ou de pseudonymisation par exemple.

Liaison à un référentiel interne ou externe

Le modèle d'attribut peut définir des contraintes sur les valeurs possibles d'un ou plusieurs attributs, en lien avec un référentiel de données externe accessible à l'application. Par exemple, il est possible de lier le matricule d'un employé au registre du service des ressources humaines fourni par le SIRH, de sorte que l'attribut devra obligatoirement contenir un matricule existant. Il est aussi possible de lier un groupe d'attributs dont les valeurs sont présentes dans une même entrée de référentiel, afin par exemple de renseigner et valider d'une seul coup le numéro, le nom et l'adresse d'un compte client présent dans un logiciel CRM.

Référentiel interne

Le bloc qui est chargé de la validation d'un référentiel interne dans un modèle d'attributs est le bloc internal ou internals comme le montre l'exemple:

{
    "identifier": "PurchaseOrder",
    "displayName": "Modèle Demande Achat",
    "internals" : [
      {
          "service": "user",
          "url": "users",
          "bindings": [
              {
                  "attribute": "commande.user_fullname",
                  "initOnField": true,
                  "serviceAttribute": "displayName",
                  "searchProperty": "displayName",
                  "searchType": "partial",
                  "limit": 15,
                  "sortField": "displayName",
                  "sort": "asc",
                  "viewFormat": "{displayName}"
              },
              {
                  "attribute": "commande.user_identifier",
                  "serviceAttribute": "identifier"
                  "searchProperty": "identifier",
                  "isValidationKey": true
              }
          ]
      }
    ],
    "content": {
        "properties": {
            "commande": {
                "type": "object",
                "title": "Commande",
                ...
            }
        }
    }
}
Nom du champ Type Obligatoire Valeur par défaut Description Exemple
attributes string Oui Nom du champ dans le modèle. "user_fullname"
initOnField boolean Non Permet de cibler le champ cible utilisé pour le référentiel (uniquement front) true
serviceAttribute string Oui Nom de l'attribut dans la réponse du service "displayName"
isValidationKey boolean Non false Si true, champ utilisé comme clé lors de la validation des données. true
searchProperty string Non null Nom de l'attribut dans le service à utiliser lors de la recherche (front) ou de la validation (back). "displayName"
sort string Non null Direction de tri pour l'attribut sortField "order[...]=desc"
sortField string Non null Nom de l'attribut dans le service à utiliser pour trier les résultats de la recherche. dans les paramètres de l'endpoint c'est order "order[displayName]=..."
limit integer Non 10 Nombre résultats de la recherche "_limit=20"
queryParams string Non null Défini un filtre prédéfini "groupType.identifier=default_group_type_identifier"
  • La validation effectue une recherche dans le service (entité) correspondant avec le filtre sur le champs qui a une searchProperty ici dans notre cas c'est le displayName
  • La recherche s'effectue sur le premier model de binding qui n'a pas de champs isValidationKey ici dans notre exemple c'est identifier
  • L'attribut user qui a la propriété isValidationKey est l'attribut que l'on va utiliser pour la validation du referentiel

Exemple

POST /entries

{
    "attributes": {
        "PurchaseOrder": {
            "commande": {
                "user_fullname": "jenny JANE",
                "user_identifier": "jenny.jane",
            }
        }
    }
}

Dans notre exemple on fait une recherche sur le user_fullname qui a l'identifier jenny.jane La validation est appelée lors du contrôle de validité de l'entité, par le service CompletenessManager si l'utilisateur qui a l'identifier jenny.jane n'est pas retrouvé alors des erreurs sont remontée au niveau du Completeness

NB: Tous les champs présents dans la configuration internals doivent etre renseignés au moment de la création d'une Entry sinon un Problem sera remonté indiquant qu'il manque des paramètres.

Référentiel externe

Les entités CsvService et DatabaseService étendent AbstractSystemEntity, et possèdent donc les champs id, owner, createdAt, createdBy, updatedAt, updatedBy, non mentionnés ici

CsvService
Nom du champ Type Obligatoire Valeur par défaut Description Exemple
identifier string oui Identifiant métier unique du service "service-fournisseur"
agent AgentInterface oui L'agent qui va lire le CSV
responseFormat array oui Mapping de la réponse du service {"nom": "fournisseur"}
filePath string oui Chemin du fichier CSV "/opt/service.csv"
separator string oui Caractère séparateur dans le fichier CSV ";"
searchableFields string[] non [] Liste des colonnes du csv utilisable lors de la recherche ["fournisseur"]
sortableFields string[] non [] Liste des colonnes de la table utilisable pour trier les résultats de la recherche ["fournisseur", "tva"]

Pour ce type de service, agent n'a pas configuration particulière requise

Si le fichier CSV est placé dans un sous-dossier du dossier source de l'application, il est possible de commencer filePath par ./.

Exemple : L'application est installé dans /var/www/mdf-api, le fichier CSV est dans /var/www/mdf-api/referential/csv/fichier.csv.

On peut mettre dans filePath le chemin ./referential/csv/fichier.csv.

DatabaseService

Le service base de données ne peut se connecter qu'à des bases de données PostgreSQL. Il est possible d'utiliser une base différente de la base de l'application MDF.

Nom du champ Type Obligatoire Valeur par défaut Description Exemple
identifier string oui Identifiant métier unique du service "service-db-agent"
agent AgentInterface oui L'agent contenant les informations de connection à la base de données
responseFormat array oui Mapping de la réponse du service {"nom": "display_name"}
tableName string oui Nom de la table SQL "agent"
searchableFields string[] non [] Liste des colonnes de la table utilisable lors de la recherche ["display_name"]
sortableFields string[] non [] Liste des colonnes de la table utilisable pour trier les résultats de la recherche ["display_name"]
Agent

Pour ce type de service, agent doit avoir dans ses attributs :

Nom du champ Type Description Exemple
dbName string Le nom de la base de données "mdf"
host string L'adresse du serveur de base de données "postgres.mdf.com" ou "10.0.0.42"
port string Le port du serveur de base de données "5432"
user string Le nom de l'utilisateur à utiliser pour se connecter à la base de données "maarch"
password string Le mot de passe l'utilisateur à utiliser pour se connecter à la base de données "maarch"

Exemple :

{
  "attributes": {
    "dbName": "mdf",
    "host": "localhost",
    "port": "5432",
    "user": "maarch",
    "password": "maarch"
  }
}

Il est également possible d'utiliser un seul champ url, qui contient tous ces paramètres dans le même champ. Exemple :

{
  "attributes": {
    "url": "postgresql://maarch:maarch@127.0.0.1:5432/mdf"
  }
}

postgresql:// est obligatoire et ne peut pas être changé

Ces champs sont dans les attributs d'un agent, mais ne sont pas dans un modèle d'attributs, et le mot de passe n'est pas chiffré. Ce format sera revu lors d'une refonte de la gestion des agents délégués

Fonctionnement de responseFormat

L'objet responseFormat contient un ensemble de clé-valeur où la clé est le nom du champ utilisé par le système MDF (retourné dans la recherche, utilisé pour la validation), et la valeur est le nom du champ dans le service externe.

Exemple

Avec un service CSV qui contient comme valeurs :

provider;city_name;country
A Soft Software;PARIS;FR
Adirrp;NANTERRE;FR
Agile Infomedia;SCRANTON;USA

On peut utiliser le mapping suivant :

{
  "responseFormat": {
    "fournisseur": "provider",
    "ville": "city_name"
  }
}

Lors d'une recherche sur ce service, l'API MDF retournera un tableau d'objets de la forme :

[
  {
    "fournisseur": "A Soft Software",
    "ville": "PARIS"
  },
  {
    "fournisseur": "Adirrp",
    "ville": "NANTERRE"
  }
]

Il n'est pas nécessaire de mapper tous les champs du service, ici le champ country n'est pas mappé

Modèle d'attributs - config external

Cette configuration permet de relier des attributs d'un modèle à des champs d'un service externe.

Nom du champ Type Obligatoire Description Exemple
service string Oui identifier du service à utiliser "service-fournisseur"
bindings ExternalConfig[] Oui Liste des bindings des champs
Modèle d'attributs - ExternalBinding
Nom du champ Type Obligatoire Valeur par défaut Description Exemple
attributes string Oui Nom de l'attribut dans le modèle. "nomFournisseur", "fournisseur.nom"
serviceAttribute string Oui Nom du champ dans la réponse du service, selon le mapping de responseFormat du service "fournisseur"
isValidationKey boolean Non false Si true, champ utilisé comme clé lors de la validation des données. true
conflictStrategy ConflictStrategy Non "keep" Stratégie à appliquer si la valeur dans l'attribut ne correspond pas à la valeur du service lors de la validation "replace"
searchProperty string Non null Nom du champ dans le service à utiliser lors de la recherche. Doit être dans la liste searchableFields du service "provider"
sort string Non null Nom du champ dans le service à utiliser pour trier les résultats de la recherche. Doit être dans la liste sortableFields du service "provider"
limit integer Non 10 Nombre résultats de la recherche 50

L'objet external doit avoir un ExternalBinding avec isValidationKey à true. S'il n'y en a pas, la validation ne fonctionnera pas. S'il y en a plus d'un, le premier trouvé dans la liste sera utilisé. Les autres seront ignorés.

ConflictStrategy
Valeur Description
keep Si les valeurs sont différentes, garde la valeur de l'attribut. Un Problem sera remonté
replace Si les valeurs sont différentes, remplace la valeur de l'attribut par la valeur du service. Les attributs seront considérés valides
replaceIfEmpty Si les valeurs sont différentes, et que l'attribut est vide, remplace la valeur de l'attribut par la valeur du service. Les attributs seront considérés valides.
Si l'attribut n'est pas vide, garde la valeur de l'attribut.Un Problem sera remonté
Exemple
{
  "external": {
    "service": "fournisseur-service",
    "bindings": [
      {
        "attribute": "fournisseur",
        "serviceAttribute": "fournisseur",
        "isValidationKey": true,
        "searchProperty": "fournisseur",
        "viewFormat": "{matricule} - {nom} {prenom}",
        "sort": "fournisseur",
        "limit": 50
      },
      {
        "attribute": "intraco",
        "serviceAttribute": "intracoTVA",
        "conflictStrategy": "replace"
      }
    ]
  }
}