11 KiB
SCHEMA.md
Conductor Project JSON Schema
This document describes the canonical JSON schema for Conductor project definitions and explains how to use it.
Location
shared/schemas/conductor-project.schema.json
The schema lives in shared/ so it is accessible to both the backend (Node.js/TypeScript) and any future frontend tooling without duplicating the file.
Purpose
Every Conductor project is represented as a single structured JSON document — the project definition. This document is the authoritative source of truth for a project. All editors (Visual Editor, JSON Editor) read from and write to this document. The backend persists it as-is to SQLite.
The JSON schema:
- Documents the exact shape of a valid project definition.
- Enables offline validation during development.
- Drives IDE autocomplete and inline error highlighting when
$schemais set in a project file. - Will be used by the backend's validation endpoint (Step 11) to reject malformed saves.
- Makes project definitions portable, diffable in Git, and importable/exportable.
Schema Version
The current schema version is 0.1.0 (semver).
Every project definition must include a schemaVersion field:
{
"schemaVersion": "0.1.0",
"project": { ... }
}
Consumers (backend, editor, preview runtime) must check the MAJOR version component. A document with a higher major version than the consumer understands should be rejected with a clear error.
Top-Level Structure
| Field | Type | Required | Description |
|---|---|---|---|
schemaVersion |
string |
✅ | Schema version in MAJOR.MINOR.PATCH format. |
project |
object |
✅ | Root project object containing all definitions. |
project Fields
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
✅ | Stable unique identifier (UUID or URL-safe slug). Must not change. |
name |
string |
✅ | Human-readable display name (1–200 characters). |
description |
string |
— | Optional free-text description. Defaults to "". |
pages |
array |
✅ | Ordered list of Page objects. May be empty. |
actions |
array |
✅ | Project-level REST action definitions. May be empty. |
bindings |
array |
✅ | Project-level binding definitions. May be empty. |
variables |
object |
✅ | Named global variable declarations. May be empty ({}). |
settings |
object |
✅ | Project display and canvas settings. May be empty ({}). |
Key Sub-Types
Page
Represents one view in the project. Required fields: id, name, components.
{
"id": "page_home",
"name": "Home",
"description": "",
"order": 0,
"components": [],
"events": []
}
Component
A UI element placed on a page canvas. Required fields: id, type, name, position, size.
Allowed type values:
Button · TextInput · TextArea · Dropdown · Checkbox · RadioGroup · Label · Table · JsonViewer · StatusPanel · Container
{
"id": "cmp_launch_btn",
"type": "Button",
"name": "launchButton",
"position": { "x": 24, "y": 284 },
"size": { "width": 160, "height": 44 },
"properties": {
"label": "Launch Workflow",
"visible": true,
"disabled": false
},
"events": [
{
"event": "onClick",
"actionId": "action_trigger_workflow"
}
],
"bindings": []
}
ComponentEvent.inputMap is retained in schema version 0.1.0 for compatibility
but is not consumed by Preview. Request values are configured in REST action
templates using {{components.<name>.value}} or {{variables.<name>}}.
Visual request-input authoring must write those executed request fields.
Action (REST Action)
A REST API call definition. Required fields: id, name, method, url, authenticationType.
Allowed method values: GET · POST · PUT · PATCH · DELETE
Allowed authenticationType values: anonymous · bearerToken · basicAuth · apiKeyHeader · apiKeyQueryParameter
{
"id": "action_trigger_workflow",
"name": "Trigger Workflow",
"description": "Calls the Concert RIA API to trigger a workflow run.",
"method": "POST",
"url": "https://api.example.com/workflows/{{workflowId}}/run",
"headers": {
"Content-Type": "application/json",
"Accept": "application/json"
},
"queryParameters": {
"environment": "{{environment}}"
},
"pathParameters": {
"workflowId": "{{workflowId}}"
},
"bodyTemplate": "{\"params\": {{params}}}",
"authenticationType": "bearerToken"
}
New response mappings belong in top-level project.bindings, not inside the action:
{
"id": "bind_trigger_status",
"source": "actions.action_trigger_workflow.response.body.data.status",
"target": "variables.lastStatus",
"trigger": "onSuccess"
}
Security note: Never store actual secret values (passwords, tokens, API keys) in the project definition. The
authenticationTypefield declares the authentication strategy only; the backend resolves credentials from server-side secrets at execution time.
REST Action Fields
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
✅ | Unique identifier within the project. |
name |
string |
✅ | Human-readable action name shown in the Actions panel. |
description |
string |
— | Optional description of what this action does. |
method |
string |
✅ | HTTP method: GET, POST, PUT, PATCH, or DELETE. |
url |
string |
✅ | Target URL. Use {{paramName}} for path parameter placeholders. |
headers |
object |
— | Static request headers. Values may use {{variableName}} syntax. |
queryParameters |
object |
— | URL query string parameters. Values may use {{variableName}} syntax. |
pathParameters |
object |
— | Path segment substitutions. Keys match {{paramName}} in the URL. |
bodyTemplate |
string |
— | Request body template. Use {{variableName}} for runtime substitutions. |
authenticationType |
string |
✅ | Authentication strategy (see allowed values above). Credentials are never stored here. |
responseMapping |
array |
— | Deprecated legacy action-local mappings. New mappings use top-level project.bindings. |
Binding
Declares data flow between a source and a target. Required fields: id, source, target.
{
"id": "bind_status_panel",
"source": "variables.lastRunStatus",
"target": "components.statusPanel.message",
"trigger": "onChange"
}
Variable
A named global variable. Required field: type.
Allowed type values: string · number · boolean · object · array
{
"lastRunStatus": {
"type": "string",
"defaultValue": "",
"description": "Status returned by the most recent workflow trigger."
}
}
ProjectSettings
Optional canvas and display configuration.
{
"theme": "system",
"defaultPageId": "page_home",
"canvasWidth": 1280,
"canvasHeight": 900
}
Example Files
| File | Description |
|---|---|
examples/project-definitions/valid-minimal.json |
Smallest valid project definition (one empty page). |
examples/project-definitions/valid-full.json |
Full example: Concert Workflow Launcher with all features. |
examples/project-definitions/valid-rest-actions.json |
Showcases all five authentication types across seven REST actions. No canvas components — validates the action model in isolation. |
examples/project-definitions/valid-visual-rest-actions.json |
Slice 2 visual-authoring fixture covering anonymous GET/POST request fields. |
examples/project-definitions/invalid-missing-required.json |
Intentionally invalid document showing schema errors. |
Validation
Using ajv-cli (recommended)
Install once globally or run via npx:
# Install globally
npm install -g ajv-cli ajv-formats
# Validate a valid document — should print: valid
ajv validate \
-s shared/schemas/conductor-project.schema.json \
-d examples/project-definitions/valid-minimal.json \
--spec=draft2020
# Validate the full example
ajv validate \
-s shared/schemas/conductor-project.schema.json \
-d examples/project-definitions/valid-full.json \
--spec=draft2020
# Validate the REST actions showcase (all five auth types)
ajv validate \
-s shared/schemas/conductor-project.schema.json \
-d examples/project-definitions/valid-rest-actions.json \
--spec=draft2020
# Validate the intentionally invalid document — should print validation errors
ajv validate \
-s shared/schemas/conductor-project.schema.json \
-d examples/project-definitions/invalid-missing-required.json \
--spec=draft2020
Using VS Code
- Open any example
.jsonfile. - The
"$schema"field at the top of the file points to the schema. - VS Code will underline validation errors inline and provide autocomplete.
In the Backend (future — Step 11)
The backend will use ajv at runtime to validate project definitions on save:
import Ajv from 'ajv';
import schema from '../../shared/schemas/conductor-project.schema.json';
const ajv = new Ajv({ strict: true });
const validate = ajv.compile(schema);
function validateProjectJson(doc: unknown): string[] {
const valid = validate(doc);
if (valid) return [];
return (validate.errors ?? []).map(e => `${e.instancePath} ${e.message}`);
}
This is documented here for reference. The validation endpoint itself is not part of Step 7.
Versioning Policy
| Change type | Version bump |
|---|---|
| Add optional field | MINOR |
| Add required field or remove existing field | MAJOR |
| Change allowed enum values | MAJOR |
| Clarify description with no structural change | PATCH |
Schema Stability
The schema is currently at 0.x (pre-stable). Breaking changes may occur between minor versions until 1.0.0 is declared.