Aller au contenu principal

Package de solution

Identifiant du schéma : solution-package@1 Schéma lisible par machine : solution-package.schema.json

La représentation canonique, en texte brut, d’une solution exportée. Un package de solution est l’unité de promotion entre environnements : il est produit en exportant une solution depuis un environnement source et consommé en l’important dans un environnement cible. Le package est autodescriptif — il porte à la fois le manifeste (les composants que contient la solution) et les définitions canoniques intégrées de chaque composant Model-Driven, de sorte qu’une importation recrée de véritables tables, formulaires, vues et étapes de plug-in plutôt que des références orphelines.

La validation s’applique de manière identique quelle que soit l’origine : un package construit par l’outil d’exportation, soumis par un appel d’API ou généré par un assistant IA est validé selon ce même schéma avant que le pipeline de déploiement ne touche l’environnement cible. Un fichier écrit à la main ou généré, conforme à ce schéma, peut être importé en toute sécurité.

Structure​

Un package est un objet JSON comportant ces membres :

ChampTypeObligatoireRemarques
formatVersionintegerouiLa version du format de package. Actuellement 1.
publisherNamestringouiLe nom d’affichage de l’éditeur propriétaire.
publisherPrefixstringouiLe préfixe court en minuscules de l’éditeur (p. ex. par). Recréé à l’importation s’il est absent du locataire cible.
solutionNamestringouiLe nom de la solution.
versionstringouiVersion sémantique major.minor.patch (p. ex. 1.0.0).
descriptionstring | nullnonDescription facultative de la solution.
requiresarray | nullnonLes solutions sur lesquelles celle-ci repose : { solutionName, minVersion? }. Vérifiées dans l’environnement cible avant toute écriture ; une absente ou plus ancienne refuse l’importation.
componentsarrayouiLe manifeste : une entrée par composant (type + nom logique).
modelComponentsobjectouiLes définitions canoniques intégrées, regroupées par type.
customAppsarray | nullnonManifestes d’applications personnalisées intégrés. Facultatif, afin que les packages produits avant l’existence des applications personnalisées restent valides ; chaque élément est en outre validé selon custom-app-manifest@1 lors de la matérialisation.
webResourcesarray | nullnonRessources web intégrées (section 6.15) : des fichiers d’application stockés dans la base de données, portant chacun son content (texte UTF-8 pour les types textuels, Base64 pour les binaires). Facultatif, afin que les anciens packages restent valides ; les métadonnées de chaque élément sont validées à nouveau selon web-resource-manifest@1 et l’empreinte de son contenu vérifiée lors de la matérialisation.
customControlsarray | nullnonContrôles personnalisés intégrés (§28), portant chacun son archive de build complète encodée en Base64, afin que le code d’un contrôle voyage avec la solution au lieu d’être récupéré depuis un hôte externe. Le manifeste de chaque élément est en outre validé selon custom-control-manifest@1 lors de la matérialisation, et son archive comparée au contentHash déclaré — le moment où il est démontré que le code relu et le code exécuté sont les mêmes.

Composant du manifeste (components[])​

ChampTypeObligatoireRemarques
componentTypestringouiL’un de Entity, Form, View, App, CustomApp, CustomControl, Process, Report, WebResource, PolicyDefinition, SecurityRole, SavedQuery, Dashboard, BusinessRule, Script. (App est le plan de site d’une application pilotée par modèle ; CustomApp est une application React écrite à la main.)
logicalNamestringouiPréfixé par l’éditeur ; en minuscules, avec _, ., /, - autorisés pour les noms de ressources web en forme de chemin (p. ex. par_invoice, par_/dashboard/app.js).
componentReferenceIdstring | nullnonL’id propre du composant dans son sous-système, s’il en a un.

Définitions intégrées (modelComponents)​

Un objet contenant des tableaux d’entrées de définition de composant — entities, forms, views, pluginSteps et le tableau facultatif apps (applications pilotées par modèle). L’ordre exprime les dépendances : les tables sont matérialisées en premier, puis les formulaires/vues/étapes de plug-in, puis les applications (dont la navigation référence les tables par leur nom logique). apps est facultatif, afin qu’un package produit avant que les applications ne voyagent reste valide et importable.

seedData (facultatif) est la seule liste dont les entrées sont des lignes plutôt que des définitions : un document seed-data@1 par table — le nom logique de la table figurant à la fois dans logicalName et dans entity — contenant les lignes renvoyées à l’exportation par la vue Données initiales de la table. Une importation le matérialise en tout dernier et insère ou met à jour chaque ligne selon son id via le chemin d’écriture ordinaire des enregistrements, en n’écrivant que les colonnes que porte la ligne et sans jamais rien supprimer ; une ligne refusée par la cible est ignorée et nommée dans le détail du statut de l’importation. Voir Livrer des données initiales avec une solution.

ChampTypeObligatoireRemarques
logicalNamestringouiLe nom logique du composant.
entitystringouiLe nom logique de la table propriétaire (le propre nom de la table, pour une table).
jsonstringouiLa définition JSON canonique du composant (une définition de table, un formulaire, une vue ou une enveloppe d’étape de plug-in — chacune validée selon son propre schéma lors de la matérialisation).
isDefaultbooleannonPour les formulaires et les vues : indique s’il s’agit de celui ou celle par défaut de la table.

Un seul chemin de validation. La charge utile json de chaque composant intégré n’est pas revalidée par ce schéma de package ; chacune est validée selon son propre schéma publié (par exemple Définition de table Model-Driven, Formulaire, Vue, Étape de plug-in) au moment de sa matérialisation — la même vérification que celle qu’effectue l’enregistrement dans un concepteur.

Exemple​

{
"formatVersion": 1,
"publisherName": "Parsware",
"publisherPrefix": "par",
"solutionName": "Sales",
"version": "1.0.0",
"description": "Core sales entities.",
"components": [
{ "componentType": "Entity", "logicalName": "par_invoice" },
{ "componentType": "Form", "logicalName": "par_invoice_main" }
],
"modelComponents": {
"entities": [
{ "logicalName": "par_invoice", "entity": "par_invoice", "json": "{ ...entity definition... }" }
],
"forms": [
{ "logicalName": "par_invoice_main", "entity": "par_invoice", "json": "{ ...form definition... }", "isDefault": true }
],
"views": [],
"pluginSteps": []
}
}

Utilisation​

  • L’exportation lit le manifeste et les définitions réelles dans un environnement source, et produit un package à l’adresse GET /solutions/{id}/export?sourceEnvironmentId=….
  • L’importation valide le package selon ce schéma, résout les dépendances (chaque formulaire, vue ou étape de plug-in doit cibler une table incluse dans le package), franchit l’éventuelle étape d’approbation, puis matérialise les composants dans le schéma isolé de l’environnement cible — à l’adresse POST /solution-imports.

Gestion des versions​

Les anciennes versions du schéma sont conservées à côté des nouvelles, afin que les solutions déjà déployées continuent d’être validées après l’évolution du schéma. Une modification incompatible est publiée sous une nouvelle version (solution-package@2) plutôt qu’en modifiant celle-ci ; un package porte son propre formatVersion, afin que le pipeline puisse rejeter une version qu’il ne prend pas en charge.