Paquete de solución
Id del esquema: solution-package@1
Esquema legible por máquina: solution-package.schema.json
La representación canónica, en texto plano, de una solución exportada. Un paquete de solución es la unidad de promoción entre entornos: se genera al exportar una solución de un entorno de origen y se consume al importarla en un entorno de destino. El paquete es autodescriptivo: incluye tanto el manifiesto (qué componentes contiene la solución) como las definiciones canónicas incrustadas de cada componente basado en modelo, de modo que una importación vuelve a crear entidades, formularios, vistas y pasos de complemento reales, y no referencias sueltas.
La validación se aplica de forma idéntica sea cual sea el origen: un paquete generado por la herramienta de exportación, enviado mediante una llamada a la API o generado por un asistente de IA se valida con este mismo esquema antes de que la canalización de implementación toque el entorno de destino. Un archivo escrito a mano o generado que cumpla este esquema puede importarse con seguridad.
Forma
Un paquete es un objeto JSON con estos miembros:
| Campo | Tipo | Obligatorio | Notas |
|---|---|---|---|
formatVersion | integer | sí | La versión del formato del paquete. Actualmente 1. |
publisherName | string | sí | El nombre para mostrar del editor propietario. |
publisherPrefix | string | sí | El prefijo corto en minúsculas del editor (p. ej., par). Se vuelve a crear al importar si no existe en el inquilino de destino. |
solutionName | string | sí | El nombre de la solución. |
version | string | sí | Versión semántica major.minor.patch (p. ej., 1.0.0). |
description | string | null | no | Descripción opcional de la solución. |
requires | array | null | no | Las soluciones sobre las que se construye esta: { solutionName, minVersion? }. Se comprueban en el entorno de destino antes de escribir nada; una ausente o más antigua rechaza la importación. |
components | array | sí | El manifiesto: una entrada por componente (tipo + nombre lógico). |
modelComponents | object | sí | Las definiciones canónicas incrustadas, agrupadas por tipo. |
customApps | array | null | no | Manifiestos de aplicaciones personalizadas incrustados. Opcional para que los paquetes generados antes de que existieran las aplicaciones personalizadas sigan validándose; además, cada elemento se valida con custom-app-manifest@1 al materializarse. |
webResources | array | null | no | Recursos web incrustados (sección 6.15): archivos de aplicación almacenados en la base de datos, cada uno con su content (texto UTF-8 para los tipos de texto, Base64 para los binarios). Opcional para que los paquetes antiguos sigan validándose; al materializarse, los metadatos de cada elemento se vuelven a validar con web-resource-manifest@1 y se comprueba el hash de su contenido. |
customControls | array | null | no | Controles personalizados incrustados (§28), cada uno con su archivo comprimido de compilación completo codificado en Base64, de modo que el código de un control viaja con la solución en lugar de obtenerse de un host externo. Además, al materializarse, el manifiesto de cada elemento se valida con custom-control-manifest@1 y su archivo comprimido se comprueba frente al contentHash declarado: el momento en que se demuestra que el código que se revisó y el código que se ejecuta son el mismo. |
Componente del manifiesto (components[])
| Campo | Tipo | Obligatorio | Notas |
|---|---|---|---|
componentType | string | sí | Uno de Entity, Form, View, App, CustomApp, CustomControl, Process, Report, WebResource, PolicyDefinition, SecurityRole, SavedQuery, Dashboard, BusinessRule, Script. (App es el mapa del sitio de una aplicación basada en modelo; CustomApp es una aplicación React escrita a mano). |
logicalName | string | sí | Con el prefijo del editor; en minúsculas, admitiendo _, ., / y - para los nombres de recursos web con forma de ruta (p. ej., par_invoice, par_/dashboard/app.js). |
componentReferenceId | string | null | no | El id propio del componente en su subsistema, si lo tiene. |
Definiciones incrustadas (modelComponents)
Un objeto con matrices de entradas de definición de componentes: entities, forms, views,
pluginSteps y el opcional apps (aplicaciones basadas en modelo). El orden refleja la intención
de las dependencias: primero se materializan las entidades, después los formularios, las vistas y
los pasos de complemento, y por último las aplicaciones (cuya navegación hace referencia a las
entidades por nombre lógico). apps es opcional para que un paquete generado antes de que las
aplicaciones viajaran siga validándose e importándose.
seedData (opcional) es la única lista cuyas entradas son filas y no definiciones: un
documento seed-data@1 por tabla —con el nombre lógico de la tabla tanto en logicalName como en
entity— que contiene las filas que devolvió la vista de datos iniciales de la tabla al exportar.
Una importación lo materializa en último lugar e inserta o actualiza cada fila por su id a través
de la ruta habitual de escritura de registros, escribiendo solo las columnas que contiene la fila y
sin eliminar nunca nada; una fila que el destino rechaza se omite y se indica en el detalle del
estado de la importación. Consulte
Incluir datos iniciales en una solución.
| Campo | Tipo | Obligatorio | Notas |
|---|---|---|---|
logicalName | string | sí | El nombre lógico del componente. |
entity | string | sí | El nombre lógico de la entidad propietaria (el propio nombre de la entidad, en el caso de una entidad). |
json | string | sí | La definición JSON canónica del componente (una definición de entidad, un formulario, una vista o un contenedor de paso de complemento, cada uno validado con su propio esquema al materializarse). |
isDefault | boolean | no | Para formularios y vistas: indica si es el predeterminado de la entidad. |
Una única vía de validación. La carga
jsonde cada componente incrustado no se vuelve a validar con este esquema de paquete; en su lugar, cada una se valida con su propio esquema publicado (por ejemplo, Definición de entidad basada en modelo, Formulario, Vista, Paso de complemento) al materializarse: la misma comprobación que realiza el guardado desde un diseñador.
Ejemplo
{
"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": []
}
}
Cómo se usa
- La exportación lee el manifiesto y las definiciones reales de un entorno de origen y genera
un paquete en
GET /solutions/{id}/export?sourceEnvironmentId=…. - La importación valida el paquete con este esquema, resuelve las dependencias (cada
formulario, vista o paso de complemento debe apuntar a una entidad incluida en el paquete), supera
cualquier puerta de aprobación y después materializa los componentes en el esquema aislado del
entorno de destino, en
POST /solution-imports.
Control de versiones
Las versiones anteriores del esquema se conservan junto a las nuevas para que las soluciones ya
implementadas sigan validándose después de que el esquema evolucione. Un cambio incompatible se
publica como una versión nueva (solution-package@2) en lugar de editar esta; un paquete incluye su
propio formatVersion para que la canalización pueda rechazar una versión que no admite.