Oplossingspakket
Schema-id: solution-package@1
Machineleesbaar schema: solution-package.schema.json
De canonieke weergave in platte tekst van een geëxporteerde oplossing. Een oplossingspakket is de eenheid waarmee werk van omgeving naar omgeving wordt doorgezet: het ontstaat door een oplossing uit een bronomgeving te exporteren en wordt verwerkt door het in een doelomgeving te importeren. Het pakket beschrijft zichzelf — het bevat zowel het manifest (welke componenten de oplossing bevat) als de ingesloten canonieke definities van elke modelgestuurde component, zodat een import echte tabellen, formulieren, weergaven en plug-instappen opnieuw aanmaakt in plaats van losse verwijzingen.
De validatie is voor elke herkomst identiek: een pakket dat door de exporttool is gebouwd, met een API-aanroep is ingediend of door een AI-assistent is gegenereerd, wordt tegen hetzelfde schema gevalideerd voordat de implementatiepijplijn de doelomgeving aanraakt. Een zelfgeschreven of gegenereerd bestand dat aan dit schema voldoet, is veilig om te importeren.
Structuur
Een pakket is een JSON-object met deze leden:
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
formatVersion | geheel getal | ja | De versie van het pakketformaat. Momenteel 1. |
publisherName | tekenreeks | ja | De weergavenaam van de eigenaar-uitgever. |
publisherPrefix | tekenreeks | ja | Het korte voorvoegsel van de uitgever in kleine letters (bijv. par). Bij import opnieuw aangemaakt als het in de doeltenant ontbreekt. |
solutionName | tekenreeks | ja | De naam van de oplossing. |
version | tekenreeks | ja | Semantische versie major.minor.patch (bijv. 1.0.0). |
description | tekenreeks | null | nee | Optionele beschrijving van de oplossing. |
requires | array | null | nee | De oplossingen waarop deze is gebouwd: { solutionName, minVersion? }. Vóór elke schrijfactie in de doelomgeving gecontroleerd; een ontbrekende of oudere weigert de import. |
components | array | ja | Het manifest: één vermelding per component (type + logische naam). |
modelComponents | object | ja | De ingesloten canonieke definities, gegroepeerd per type. |
customApps | array | null | nee | Ingesloten manifesten van aangepaste apps. Optioneel, zodat pakketten die zijn gemaakt voordat aangepaste apps bestonden nog steeds valideren; elk item wordt bij het materialiseren bovendien gevalideerd tegen custom-app-manifest@1. |
webResources | array | null | nee | Ingesloten webresources (sectie 6.15): applicatiebestanden die in de database zijn opgeslagen, elk met hun content (UTF-8-tekst voor teksttypen, Base64 voor binaire). Optioneel, zodat oudere pakketten nog steeds valideren; de metadata van elk item wordt bij het materialiseren opnieuw gevalideerd tegen web-resource-manifest@1 en de inhoud wordt met een hash gecontroleerd. |
customControls | array | null | nee | Ingesloten aangepaste besturingselementen (§28), elk met het volledige build-archief in Base64, zodat de code van een besturingselement met de oplossing meereist in plaats van te worden opgehaald bij een externe host. Het manifest van elk item wordt bij het materialiseren bovendien gevalideerd tegen custom-control-manifest@1, en het archief gecontroleerd tegen de gedeclareerde contentHash — het moment waarop wordt aangetoond dat de code die is beoordeeld en de code die draait dezelfde zijn. |
Manifestcomponent (components[])
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
componentType | tekenreeks | ja | Een van Entity, Form, View, App, CustomApp, CustomControl, Process, Report, WebResource, PolicyDefinition, SecurityRole, SavedQuery, Dashboard, BusinessRule, Script. (App is het siteoverzicht van een modelgestuurde app; CustomApp is een zelfgeschreven React-app.) |
logicalName | tekenreeks | ja | Met uitgeversvoorvoegsel; kleine letters, met _, ., /, - toegestaan voor padachtige namen van webresources (bijv. par_invoice, par_/dashboard/app.js). |
componentReferenceId | tekenreeks | null | nee | De eigen id van de component in zijn subsysteem, als die er is. |
Ingesloten definities (modelComponents)
Een object met arrays van componentdefinities — entities, forms, views, pluginSteps,
en de optionele apps (modelgestuurde apps). De volgorde drukt afhankelijkheden uit: eerst
worden tabellen gematerialiseerd, dan formulieren/weergaven/plug-instappen, dan apps (waarvan
de navigatie op logische naam naar tabellen verwijst). apps is optioneel, zodat een pakket
dat is gemaakt voordat apps meereisden nog steeds valideert en importeert.
seedData (optioneel) is de enige lijst waarvan de vermeldingen rijen zijn in plaats van
definities: één seed-data@1-document per tabel — de logische naam van de tabel in zowel
logicalName als entity — met de rijen die de Seed Data-weergave van de tabel bij het
exporteren teruggaf. Een import materialiseert dit als allerlaatste en upsert elke rij op haar
id via het gewone schrijfpad voor records, waarbij alleen de kolommen worden geschreven die
de rij bevat en nooit iets wordt verwijderd; een rij die het doel weigert, wordt overgeslagen
en genoemd in de statusdetails van de import. Zie
Seedgegevens meeleveren met een oplossing.
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
logicalName | tekenreeks | ja | De logische naam van de component. |
entity | tekenreeks | ja | De logische naam van de eigenaar-tabel (voor een tabel: de eigen naam van de tabel). |
json | tekenreeks | ja | De canonieke JSON-definitie van de component (een tabeldefinitie, formulier, weergave of plug-instapwrapper — elk bij het materialiseren gevalideerd tegen het eigen schema). |
isDefault | booleaans | nee | Voor formulieren/weergaven: of dit de standaard van de tabel is. |
Eén validatiepad. De
json-inhoud van elke ingesloten component wordt niet opnieuw gevalideerd door dit pakketschema; in plaats daarvan wordt elke component bij het materialiseren gevalideerd tegen haar eigen gepubliceerde schema (bijvoorbeeld Definitie van een modelgestuurde tabel, Formulier, Weergave, Plug-instap) — dezelfde controle die een opslagactie in een ontwerper uitvoert.
Voorbeeld
{
"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": []
}
}
Hoe het wordt gebruikt
- Exporteren leest het manifest en de echte definities uit een bronomgeving en levert een
pakket op via
GET /solutions/{id}/export?sourceEnvironmentId=…. - Importeren valideert het pakket tegen dit schema, lost afhankelijkheden op (elk
formulier, elke weergave en elke plug-instap moet een tabel betreffen die in het pakket zit),
doorloopt een eventuele goedkeuringsstap en materialiseert dan de componenten in het
geïsoleerde schema van de doelomgeving — via
POST /solution-imports.
Versiebeheer
Oudere schemaversies blijven naast de nieuwe bestaan, zodat al uitgerolde oplossingen blijven
valideren nadat het schema is gewijzigd. Een brekende wijziging wordt gepubliceerd als nieuwe
versie (solution-package@2) in plaats van deze te bewerken; een pakket bevat zijn eigen
formatVersion, zodat de pijplijn een versie kan weigeren die ze niet ondersteunt.