diff --git a/CHANGELOG.md b/CHANGELOG.md index 7253f64..784e4e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ project follows [Semantic Versioning](https://semver.org/). ### Changed +- `build-epilot-journey` now documents `logicsV4` (display, required, + prefill, show-options, jump and skip rules) and `validationRules` as + journey sections that `create_journey` and `update_journey` accept, with + the reference checks the epilot MCP runs before a write and the + Validation Rules API operations that own the rules. A copied journey keeps + its logic only when every section is sent. - Merged `epilot-interface-designer` into `build-epilot-app`. Interface design was only ever needed while building an App component, so the Volt UI MCP guidance, the working method, and the `interface-principles.md` and diff --git a/plugins/epilot-core/skills/build-epilot-journey/SKILL.md b/plugins/epilot-core/skills/build-epilot-journey/SKILL.md index ded5bff..1241500 100644 --- a/plugins/epilot-core/skills/build-epilot-journey/SKILL.md +++ b/plugins/epilot-core/skills/build-epilot-journey/SKILL.md @@ -59,8 +59,13 @@ copy right is what makes the journey good. Both are this skill's job. 4. **Create inactive, then iterate.** `create_journey` starts journeys with `isActive: false` by default. Review, refine with `update_journey`, and only then set `settings.isActive: true`. Update replaces whole sections - (steps, logics, rules, settings fields); read with - `get_journey`, modify, write back. + (steps, logicsV4, validationRules, logics, rules, contextSchema, settings + fields); read with `get_journey`, modify, write back. Conditional + display, required state, prefilling, and step jumps are `logicsV4` + entries; validation is a `validationRules` binding to a rule from the + Validation Rules API. Both are part of the journey, not a follow-up in + the builder. Copying a journey means sending all of its sections to + `create_journey`, or the copy loses its logic. 5. **Map the submission.** Check `get_journey_mapping`: every block whose data the organization needs must map onto an entity attribute, and the executing automation must exist (create_journey sets both up; block @@ -72,10 +77,11 @@ copy right is what makes the journey good. Both are this skill's job. automation `runs`, per-action execution status, produced entities), rather than trusting the builder's green state. 6. **Verify.** Re-read the definition, walk the wiring (every button's - `targetStepId` resolves, every block scope has a schema property — - `create_journey` and `update_journey` check exactly this before any API - call and reject with the problem list, so there is no separate validation - tool), and run the + `targetStepId` resolves, every block scope has a schema property, every + block, step, and context parameter a logic or validation binding + references exists — `create_journey` and `update_journey` check exactly + this before any API call and reject with the problem list, so there is + no separate validation tool), and run the design checklist. For a live check, open the journey in the epilot 360 Journey Builder — configuration created via API appears there immediately. diff --git a/plugins/epilot-core/skills/build-epilot-journey/references/journey-anatomy.md b/plugins/epilot-core/skills/build-epilot-journey/references/journey-anatomy.md index 4a2dee8..da72a49 100644 --- a/plugins/epilot-core/skills/build-epilot-journey/references/journey-anatomy.md +++ b/plugins/epilot-core/skills/build-epilot-journey/references/journey-anatomy.md @@ -9,6 +9,8 @@ accept (the server injects `organizationId` and manages the signed { "name": "Wallbox bestellen", "steps": [ { "stepId": "…", "name": "…", "schema": {}, "uischema": {} } ], + "logicsV4": {}, + "validationRules": {}, "logics": [], "rules": [], "contextSchema": [], @@ -68,15 +70,45 @@ omitted), `accessMode` (`PUBLIC` | `PRIVATE`), `isActive`, `isPublished`, `safeModeAutomation`. The signed `publicToken` is server-managed: reads never include it and updates preserve it automatically. -## Logics, rules, context - -- `logics` (v3) — `{ conditions: string[], actions: string[] }` expressions - referencing block names; `logicsV4` — structured conditions over block or - context facts with `action` and `triggeredOn`. +## Logics, validation, rules, context + +- `logicsV4` — the logic the Journey Builder writes, keyed by logic id. Each + entry has `id`, `action`, `triggeredOn` (`on-value-changed` | + `on-click-next`), `conditions` (OR-groups of AND-clauses, each `{ fact: + { referenceType, referenceId, path? }, operator, value }`), and + action-specific `settings`. Actions: `display-condition`, + `display-field-condition`, `required-condition`, + `required-field-condition`, `readonly-condition`, `show-options`, + `filter-condition`, `content-condition`, `prefill`, `data-injection`, + `jump-to-step`, `skip-step`. Facts read a `block` (by the uischema + element `id`), a `context-parameter` (by its `id`), a `datasource`, + `global`, or `environment` value; settings name the target with + `targetBlock` / `targetField`, `sourceBlock`, `targetStep`, or + `skipSteps`. Prefilling is `prefill` (a fixed or context-derived value) or + `data-injection` (copy one block's value into another). +- `validationRules` — bindings of validation rules to blocks, keyed by block + id: a rule id or ordered list of rule ids for the whole block, or + `{ field: ruleId | ruleIds }` per field. The rules themselves live in the + Validation Rules API: list them with `call_read_api_operation + getValidationRules`, create one with `call_api_operation + createValidationRule`, then bind its id here. +- `logics` (v3, legacy) — `{ conditions: string[], actions: string[] }` + expressions referencing block names. Prefer `logicsV4` for anything new. - `rules` — data injection between scopes: `{ type: "inject", sourceType: "journey|step|block", source, target }`. -- `contextSchema` — declared launch parameters: `{ paramKey, type, - isRequired }`; type is an entity slug or `text`. - -Copy working logic and rule shapes from an existing journey via +- `contextSchema` — declared launch parameters: `{ id, paramKey, type, + isRequired, shouldLoadEntity }`; type is an entity slug or `text`; + `shouldLoadEntity` makes the runtime load the entity whose id is passed. + +Every section is replaced as a whole by `update_journey`: to change one +logic, read `logicsV4` with `get_journey`, modify it, and send the full +object back. `create_journey` and `update_journey` check that every block, +step, and context parameter a logic or binding references exists in the +steps being written, that every validation rule id exists in the +organization, and reject sections they do not know instead of dropping +them. An update whose steps remove a block that stored logics still target +is rejected; send the pruned `logicsV4` in the same call. Datasource facts +are not checked. + +Copy working logic and binding shapes from an existing journey via `get_journey` before authoring new ones.