conductor/shared/schemas/conductor-project.schema.json

543 lines
20 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://conductor.local/schemas/conductor-project.schema.json",
"title": "Conductor Project Definition",
"description": "Canonical JSON document representing a complete Conductor UI project. This is the authoritative source of truth for a project — persisted to the backend, portable between installations, and suitable for version control.",
"type": "object",
"required": ["schemaVersion", "project"],
"additionalProperties": false,
"properties": {
"$schema": {
"type": "string",
"description": "URI reference to the JSON schema that validates this document. Used by editors for autocomplete and inline validation."
},
"schemaVersion": {
"type": "string",
"description": "Version of the Conductor project schema used by this document. Follows semver (MAJOR.MINOR.PATCH). Consumers must reject documents whose MAJOR version they do not understand.",
"pattern": "^\\d+\\.\\d+\\.\\d+$",
"examples": ["0.1.0"]
},
"project": {
"type": "object",
"description": "The root project object containing all application definitions.",
"required": ["id", "name", "pages", "actions", "bindings", "variables", "settings"],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Stable, unique identifier for this project. Should be a UUID or URL-safe slug. Must not change after initial creation.",
"minLength": 1,
"examples": ["proj_01h9z3x7k2m4n6p8q0r5s7t9u1"]
},
"name": {
"type": "string",
"description": "Human-readable display name for the project.",
"minLength": 1,
"maxLength": 200,
"examples": ["Concert Workflow Launcher"]
},
"description": {
"type": "string",
"description": "Optional free-text description of the project's purpose.",
"default": "",
"examples": ["Launches IBM Concert Workflows via the RIA REST API."]
},
"pages": {
"type": "array",
"description": "Ordered list of pages in this project. A project must have at least one page to be renderable.",
"items": { "$ref": "#/$defs/Page" },
"default": []
},
"actions": {
"type": "array",
"description": "Project-level REST API action definitions. Actions are referenced by bindings and triggered by component events.",
"items": { "$ref": "#/$defs/Action" },
"default": []
},
"bindings": {
"type": "array",
"description": "Project-level binding definitions that connect component events to actions or other components.",
"items": { "$ref": "#/$defs/Binding" },
"default": []
},
"variables": {
"type": "object",
"description": "Named global variables available throughout the project. Keys are variable names; values are the initial (design-time) values.",
"additionalProperties": {
"$ref": "#/$defs/Variable"
},
"default": {}
},
"settings": {
"$ref": "#/$defs/ProjectSettings"
}
}
}
},
"$defs": {
"Page": {
"type": "object",
"description": "A single page within the project. Each page has its own canvas and component tree.",
"required": ["id", "name", "components"],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for the page within this project.",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable page name shown in navigation.",
"minLength": 1
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
"maxLength": 80,
"description": "Stable URL segment for this page. Older documents may omit it; runtimes derive a deterministic slug from name/id."
},
"showInNavigation": {
"type": "boolean",
"description": "Whether this page appears in automatic application navigation. This is not an authorization control.",
"default": true
},
"description": {
"type": "string",
"description": "Optional description of this page's purpose.",
"default": ""
},
"order": {
"type": "integer",
"description": "Display order of this page in the navigation list. Lower numbers appear first.",
"minimum": 0,
"default": 0
},
"components": {
"type": "array",
"description": "Ordered list of UI components placed on this page's canvas.",
"items": { "$ref": "#/$defs/Component" },
"default": []
},
"events": {
"type": "array",
"description": "Page-level lifecycle events (e.g., onLoad).",
"items": { "$ref": "#/$defs/Event" },
"default": []
}
}
},
"Component": {
"type": "object",
"description": "A UI component placed on a page canvas.",
"required": ["id", "type", "name", "position", "size"],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for this component within the project.",
"minLength": 1
},
"type": {
"type": "string",
"description": "Component type. Determines which renderer and property schema applies.",
"enum": [
"Button",
"TextInput",
"TextArea",
"Dropdown",
"Checkbox",
"RadioGroup",
"Label",
"Table",
"JsonViewer",
"StatusPanel",
"Container"
]
},
"name": {
"type": "string",
"description": "Developer-facing name used in bindings and variable references. Must be unique within the page.",
"minLength": 1
},
"position": {
"$ref": "#/$defs/Position"
},
"size": {
"$ref": "#/$defs/Size"
},
"properties": {
"$ref": "#/$defs/ComponentProperties"
},
"events": {
"type": "array",
"description": "Component-level event handlers (e.g., onClick, onChange).",
"items": { "$ref": "#/$defs/Event" },
"default": []
},
"bindings": {
"type": "array",
"description": "Component-level bindings. May reference project-level bindings or declare inline bindings.",
"items": { "$ref": "#/$defs/ComponentBindingRef" },
"default": []
}
}
},
"Position": {
"type": "object",
"description": "Top-left position of the component on the canvas grid, in pixels.",
"required": ["x", "y"],
"additionalProperties": false,
"properties": {
"x": { "type": "number", "description": "Horizontal offset from canvas left edge." },
"y": { "type": "number", "description": "Vertical offset from canvas top edge." }
}
},
"Size": {
"type": "object",
"description": "Width and height of the component, in pixels.",
"required": ["width", "height"],
"additionalProperties": false,
"properties": {
"width": { "type": "number", "minimum": 1 },
"height": { "type": "number", "minimum": 1 }
}
},
"ComponentProperties": {
"type": "object",
"description": "Key/value map of component configuration properties. Common properties are listed below; additional component-specific properties are permitted.",
"properties": {
"label": { "type": "string", "description": "Visible label text displayed alongside or on the component." },
"placeholder": { "type": "string", "description": "Placeholder text shown inside input components when empty." },
"defaultValue": { "description": "Design-time default value. Type varies by component." },
"visible": { "type": "boolean", "description": "Whether the component is visible at runtime.", "default": true },
"disabled": { "type": "boolean", "description": "Whether the component is disabled at runtime.", "default": false },
"required": { "type": "boolean", "description": "Whether the component requires a value before form submission.", "default": false },
"style": {
"type": "object",
"description": "Basic per-component appearance overrides.",
"additionalProperties": false,
"properties": {
"fontSize": { "type": "number", "minimum": 8, "maximum": 72 },
"textColor": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" },
"backgroundColor": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" }
}
},
"options": {
"type": "array",
"description": "Static option list for Dropdown and RadioGroup components.",
"items": {
"type": "object",
"required": ["label", "value"],
"additionalProperties": false,
"properties": {
"label": { "type": "string" },
"value": { "type": "string" }
}
}
},
"columns": {
"type": "array",
"description": "Column definitions for Table components.",
"items": {
"type": "object",
"required": ["key", "header"],
"additionalProperties": false,
"properties": {
"key": { "type": "string", "description": "Row object field key to display in this column." },
"header": { "type": "string", "description": "Column header text displayed in the table." },
"width": { "type": "integer", "minimum": 1, "description": "Optional fixed column width in pixels." }
}
}
},
"rows": {
"type": "array",
"description": "Static row data for Table components. Each row is a JSON object.",
"items": {
"type": "object",
"description": "A single data row. Keys map to column keys.",
"additionalProperties": true
}
}
},
"additionalProperties": true
},
"Action": {
"type": "object",
"description": "A REST API action definition. Describes how to call an external HTTP endpoint. Credentials are never stored here — only the authentication type is declared; the backend resolves secrets at execution time.",
"required": ["id", "name", "method", "url", "authenticationType"],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for this action within the project.",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable action name shown in the actions panel.",
"minLength": 1
},
"description": {
"type": "string",
"description": "Optional description of what this action does.",
"default": ""
},
"method": {
"type": "string",
"description": "HTTP method for this action.",
"enum": ["GET", "POST", "PUT", "PATCH", "DELETE"]
},
"url": {
"type": "string",
"description": "Target URL template. Path parameter placeholders use {{paramName}} syntax (e.g. https://api.example.com/items/{{itemId}}).",
"minLength": 1,
"examples": ["https://api.example.com/workflows/{{workflowId}}/run"]
},
"headers": {
"type": "object",
"description": "Static HTTP headers sent with every request. Values may use {{variableName}} template syntax.",
"additionalProperties": { "type": "string" },
"default": {}
},
"queryParameters": {
"type": "object",
"description": "Static URL query parameters. Values may use {{variableName}} template syntax.",
"additionalProperties": { "type": "string" },
"default": {}
},
"pathParameters": {
"type": "object",
"description": "Named path segment substitutions. Keys match {{paramName}} placeholders in the URL. Values may use {{variableName}} template syntax.",
"additionalProperties": { "type": "string" },
"default": {}
},
"bodyTemplate": {
"type": "string",
"description": "Request body template string. Typically JSON with {{variableName}} placeholders resolved at runtime. Ignored for GET and DELETE.",
"default": ""
},
"authenticationType": {
"type": "string",
"description": "Authentication strategy for this action. Determines how the backend injects credentials at execution time. Credentials themselves are never stored in the project definition.",
"enum": [
"anonymous",
"bearerToken",
"basicAuth",
"apiKeyHeader",
"apiKeyQueryParameter"
]
},
"secretReferenceId": {
"type": "string",
"minLength": 1,
"description": "Opaque reference to a server-side encrypted credential. Required at execution time for credential-backed authentication and omitted for anonymous actions."
},
"responseMapping": {
"type": "array",
"deprecated": true,
"description": "DEPRECATED. Use top-level project.bindings for response data movement. This field is retained for backward compatibility. It is not executed by the Preview runtime or backend proxy. See docs/response-mapping-model.md.",
"items": { "$ref": "#/$defs/ResponseMappingRule" },
"default": []
}
}
},
"ResponseMappingRule": {
"type": "object",
"description": "Maps a field from an API response to a target component property or project variable.",
"required": ["source", "target"],
"additionalProperties": false,
"properties": {
"source": {
"type": "string",
"description": "JSONPath-style expression pointing to the field within the API response (e.g., 'data.items' or 'result.status').",
"minLength": 1
},
"target": {
"type": "string",
"description": "Dot-separated target path. Use 'components.<componentName>.<property>' for component targets or 'variables.<variableName>' for global variables.",
"minLength": 1,
"examples": ["components.resultsTable.data", "variables.lastStatus"]
}
}
},
"Binding": {
"type": "object",
"description": "Declares how data flows between a source (component or action output) and a target.",
"required": ["id", "source", "target"],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for this binding.",
"minLength": 1
},
"source": {
"type": "string",
"description": "Source expression. Typically 'components.<name>.<property>' or 'actions.<actionId>.response'.",
"minLength": 1
},
"target": {
"type": "string",
"description": "Target expression. Typically 'components.<name>.<property>' or 'variables.<name>'.",
"minLength": 1
},
"trigger": {
"type": "string",
"description": "Event name that activates this binding (e.g., 'onClick', 'onChange', 'onLoad').",
"default": "onChange"
},
"transform": {
"type": "string",
"description": "Optional inline JavaScript expression applied to the source value before writing to the target. The source value is available as `value`.",
"examples": ["value.toUpperCase()", "value.data.items"]
}
}
},
"ComponentBindingRef": {
"type": "object",
"description": "Reference from a component to a project-level binding, or an inline binding declared on the component.",
"required": ["bindingId"],
"additionalProperties": false,
"properties": {
"bindingId": {
"type": "string",
"description": "ID of the project-level binding this component participates in.",
"minLength": 1
}
}
},
"Variable": {
"type": "object",
"description": "A named global or page-owned runtime variable declaration.",
"required": ["type"],
"allOf": [
{
"if": { "properties": { "scope": { "const": "page" } }, "required": ["scope"] },
"then": { "required": ["pageId"] }
},
{
"if": { "properties": { "scope": { "const": "global" } }, "required": ["scope"] },
"then": { "not": { "required": ["pageId"] } }
}
],
"additionalProperties": false,
"properties": {
"type": {
"type": "string",
"enum": ["string", "number", "boolean", "object", "array"],
"description": "The runtime type of this variable."
},
"scope": {
"type": "string",
"enum": ["global", "page"],
"description": "Runtime scope. Omitted means global for backward compatibility.",
"default": "global"
},
"pageId": {
"type": "string",
"minLength": 1,
"description": "Owning page ID. Required when scope is page and forbidden for global variables."
},
"defaultValue": {
"description": "Design-time default. Must be compatible with the declared type."
},
"description": {
"type": "string",
"description": "Optional documentation for this variable.",
"default": ""
}
}
},
"ProjectSettings": {
"type": "object",
"description": "Project-level configuration and display settings.",
"additionalProperties": false,
"properties": {
"theme": {
"type": "string",
"enum": ["light", "dark", "system"],
"description": "UI colour theme preference.",
"default": "system"
},
"defaultPageId": {
"type": "string",
"description": "ID of the page shown first when the project loads. Defaults to the first page in the pages array if omitted."
},
"canvasWidth": {
"type": "integer",
"minimum": 320,
"description": "Design-time canvas width in pixels.",
"default": 1280
},
"canvasHeight": {
"type": "integer",
"minimum": 240,
"description": "Design-time canvas height in pixels.",
"default": 900
}
},
"default": {}
},
"Event": {
"type": "object",
"description": "An event handler that fires when a lifecycle or user-interaction event occurs.",
"required": ["event"],
"anyOf": [
{ "required": ["actionId"] },
{ "required": ["navigateToPageId"] }
],
"additionalProperties": false,
"properties": {
"event": {
"type": "string",
"description": "Name of the triggering event (e.g., 'onClick', 'onChange', 'onLoad').",
"minLength": 1
},
"actionId": {
"type": "string",
"description": "ID of the project-level action to execute when this event fires.",
"minLength": 1
},
"navigateToPageId": {
"type": "string",
"description": "Typed client-side page-navigation target used instead of a REST action.",
"minLength": 1
},
"inputMap": {
"type": "object",
"description": "Reserved legacy field retained for compatibility. Preview request inputs use templates in REST action request fields; inputMap is not executed.",
"additionalProperties": { "type": "string" },
"default": {}
}
}
}
}
}