docs: add JSON Schema for process definition documents
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -471,6 +471,7 @@ components:
|
|||||||
label:
|
label:
|
||||||
type: string
|
type: string
|
||||||
ProcessDefinitionDocument:
|
ProcessDefinitionDocument:
|
||||||
|
description: Closed document shape is docs/process-definition.schema.json. Graph rules are enforced by ProcessDefinitionParser.
|
||||||
type: object
|
type: object
|
||||||
required: [id, name, steps, transitions]
|
required: [id, name, steps, transitions]
|
||||||
properties:
|
properties:
|
||||||
|
|||||||
@@ -0,0 +1,297 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"$id": "https://jetlumen.com/ordo/schema/process-definition.json",
|
||||||
|
"title": "Ordo process definition document",
|
||||||
|
"$comment": "Document shape for ProcessDefinitionParser.fromJson. Graph connectivity, unique ids, PARALLEL membership, due.goto branch rules, and predicate depth/leaf limits are enforced only by the parser.",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["id", "name", "steps", "transitions"],
|
||||||
|
"properties": {
|
||||||
|
"id": { "$ref": "#/$defs/nonEmptyString" },
|
||||||
|
"name": { "$ref": "#/$defs/nonEmptyString" },
|
||||||
|
"version": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"$comment": "Ignored by fromJson; written by toJson after publish."
|
||||||
|
},
|
||||||
|
"startStep": { "$ref": "#/$defs/nonEmptyString" },
|
||||||
|
"steps": {
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 1,
|
||||||
|
"items": { "$ref": "#/$defs/topStep" }
|
||||||
|
},
|
||||||
|
"transitions": {
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 1,
|
||||||
|
"items": { "$ref": "#/$defs/transition" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"$defs": {
|
||||||
|
"nonEmptyString": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": ".*\\S.*"
|
||||||
|
},
|
||||||
|
"literal": {
|
||||||
|
"type": ["string", "number", "boolean"]
|
||||||
|
},
|
||||||
|
"topStep": {
|
||||||
|
"oneOf": [
|
||||||
|
{ "$ref": "#/$defs/approvalStep" },
|
||||||
|
{ "$ref": "#/$defs/actionStep" },
|
||||||
|
{ "$ref": "#/$defs/parallelStep" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"leafStep": {
|
||||||
|
"oneOf": [
|
||||||
|
{ "$ref": "#/$defs/approvalStep" },
|
||||||
|
{ "$ref": "#/$defs/actionStep" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"approvalStep": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["id", "name", "candidates"],
|
||||||
|
"properties": {
|
||||||
|
"id": { "$ref": "#/$defs/nonEmptyString" },
|
||||||
|
"name": { "$ref": "#/$defs/nonEmptyString" },
|
||||||
|
"kind": { "const": "APPROVAL" },
|
||||||
|
"candidates": {
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 1,
|
||||||
|
"uniqueItems": true,
|
||||||
|
"items": { "$ref": "#/$defs/nonEmptyString" }
|
||||||
|
},
|
||||||
|
"policy": { "type": "string", "enum": ["ANY", "ALL"] },
|
||||||
|
"due": { "$ref": "#/$defs/due" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"actionStep": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["id", "name", "kind", "action"],
|
||||||
|
"properties": {
|
||||||
|
"id": { "$ref": "#/$defs/nonEmptyString" },
|
||||||
|
"name": { "$ref": "#/$defs/nonEmptyString" },
|
||||||
|
"kind": { "const": "ACTION" },
|
||||||
|
"action": { "$ref": "#/$defs/nonEmptyString" },
|
||||||
|
"policy": { "type": "string", "enum": ["ANY", "ALL"] }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parallelStep": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["id", "name", "kind", "branches"],
|
||||||
|
"properties": {
|
||||||
|
"id": { "$ref": "#/$defs/nonEmptyString" },
|
||||||
|
"name": { "$ref": "#/$defs/nonEmptyString" },
|
||||||
|
"kind": { "const": "PARALLEL" },
|
||||||
|
"policy": { "type": "string", "enum": ["ANY", "ALL"] },
|
||||||
|
"branches": {
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 2,
|
||||||
|
"items": { "$ref": "#/$defs/branch" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"branch": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["id", "steps", "transitions"],
|
||||||
|
"properties": {
|
||||||
|
"id": { "$ref": "#/$defs/nonEmptyString" },
|
||||||
|
"steps": {
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 1,
|
||||||
|
"items": { "$ref": "#/$defs/leafStep" }
|
||||||
|
},
|
||||||
|
"transitions": {
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 1,
|
||||||
|
"items": { "$ref": "#/$defs/transition" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"due": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["after", "then", "to"],
|
||||||
|
"properties": {
|
||||||
|
"after": { "$ref": "#/$defs/isoDuration" },
|
||||||
|
"then": { "const": "reassign" },
|
||||||
|
"to": { "$ref": "#/$defs/nonEmptyString" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["after", "then"],
|
||||||
|
"properties": {
|
||||||
|
"after": { "$ref": "#/$defs/isoDuration" },
|
||||||
|
"then": { "const": "notify" },
|
||||||
|
"action": { "$ref": "#/$defs/nonEmptyString" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["after", "then", "to"],
|
||||||
|
"properties": {
|
||||||
|
"after": { "$ref": "#/$defs/isoDuration" },
|
||||||
|
"then": { "const": "goto" },
|
||||||
|
"to": { "$ref": "#/$defs/nonEmptyString" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"isoDuration": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 2,
|
||||||
|
"$comment": "java.time.Duration.parse; must be positive after parse."
|
||||||
|
},
|
||||||
|
"transition": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["from"],
|
||||||
|
"properties": {
|
||||||
|
"from": { "$ref": "#/$defs/nonEmptyString" },
|
||||||
|
"to": {
|
||||||
|
"type": ["string", "null"],
|
||||||
|
"minLength": 1
|
||||||
|
},
|
||||||
|
"when": { "$ref": "#/$defs/when" },
|
||||||
|
"priority": { "type": "integer" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"when": {
|
||||||
|
"oneOf": [
|
||||||
|
{ "$ref": "#/$defs/refWhen" },
|
||||||
|
{ "$ref": "#/$defs/predicate" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"refWhen": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["ref"],
|
||||||
|
"properties": {
|
||||||
|
"ref": { "$ref": "#/$defs/nonEmptyString" },
|
||||||
|
"args": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"predicate": {
|
||||||
|
"oneOf": [
|
||||||
|
{ "$ref": "#/$defs/compareEq" },
|
||||||
|
{ "$ref": "#/$defs/compareNe" },
|
||||||
|
{ "$ref": "#/$defs/compareGt" },
|
||||||
|
{ "$ref": "#/$defs/compareGte" },
|
||||||
|
{ "$ref": "#/$defs/compareLt" },
|
||||||
|
{ "$ref": "#/$defs/compareLte" },
|
||||||
|
{ "$ref": "#/$defs/inPredicate" },
|
||||||
|
{ "$ref": "#/$defs/andPredicate" },
|
||||||
|
{ "$ref": "#/$defs/orPredicate" },
|
||||||
|
{ "$ref": "#/$defs/notPredicate" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"comparePair": {
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 2,
|
||||||
|
"maxItems": 2,
|
||||||
|
"prefixItems": [
|
||||||
|
{ "$ref": "#/$defs/nonEmptyString" },
|
||||||
|
{ "$ref": "#/$defs/literal" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"compareEq": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["eq"],
|
||||||
|
"properties": { "eq": { "$ref": "#/$defs/comparePair" } }
|
||||||
|
},
|
||||||
|
"compareNe": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["ne"],
|
||||||
|
"properties": { "ne": { "$ref": "#/$defs/comparePair" } }
|
||||||
|
},
|
||||||
|
"compareGt": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["gt"],
|
||||||
|
"properties": { "gt": { "$ref": "#/$defs/comparePair" } }
|
||||||
|
},
|
||||||
|
"compareGte": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["gte"],
|
||||||
|
"properties": { "gte": { "$ref": "#/$defs/comparePair" } }
|
||||||
|
},
|
||||||
|
"compareLt": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["lt"],
|
||||||
|
"properties": { "lt": { "$ref": "#/$defs/comparePair" } }
|
||||||
|
},
|
||||||
|
"compareLte": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["lte"],
|
||||||
|
"properties": { "lte": { "$ref": "#/$defs/comparePair" } }
|
||||||
|
},
|
||||||
|
"inPredicate": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["in"],
|
||||||
|
"properties": {
|
||||||
|
"in": {
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 2,
|
||||||
|
"maxItems": 2,
|
||||||
|
"prefixItems": [
|
||||||
|
{ "$ref": "#/$defs/nonEmptyString" },
|
||||||
|
{
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 1,
|
||||||
|
"items": { "$ref": "#/$defs/literal" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"andPredicate": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["and"],
|
||||||
|
"properties": {
|
||||||
|
"and": {
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 1,
|
||||||
|
"items": { "$ref": "#/$defs/predicate" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"orPredicate": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["or"],
|
||||||
|
"properties": {
|
||||||
|
"or": {
|
||||||
|
"type": "array",
|
||||||
|
"minItems": 1,
|
||||||
|
"items": { "$ref": "#/$defs/predicate" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notPredicate": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["not"],
|
||||||
|
"properties": {
|
||||||
|
"not": { "$ref": "#/$defs/predicate" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -174,7 +174,7 @@ new ProcessDefinition("leave-request-routed", "Leave request",
|
|||||||
|
|
||||||
### 3.2 JSON
|
### 3.2 JSON
|
||||||
|
|
||||||
`ProcessDefinitionParser.fromJson(String|InputStream)` / `toJson(ProcessDefinition)`。Spring 默认扫 `classpath*:ordo/*.json`。`toJson` 写出 `version` 与 `startStep`(当前步骤列表首位);`fromJson` 仍忽略 JSON 里的 `version`。
|
`ProcessDefinitionParser.fromJson(String|InputStream)` / `toJson(ProcessDefinition)`。Spring 默认扫 `classpath*:ordo/*.json`。`toJson` 写出 `version` 与 `startStep`(当前步骤列表首位);`fromJson` 仍忽略 JSON 里的 `version`。文档外形:[process-definition.schema.json](process-definition.schema.json);图连通、PARALLEL 约束、谓词深度/叶子上限仍以解析器为准。
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user