Skip to content

Intent: relation.field form fields + declarative setField glue#6088

Merged
delchev merged 2 commits into
masterfrom
feat/harmonia-runtime-template
Jun 26, 2026
Merged

Intent: relation.field form fields + declarative setField glue#6088
delchev merged 2 commits into
masterfrom
feat/harmonia-runtime-template

Conversation

@delchev

@delchev delchev commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Follow-up intent-engine work on top of the merged Harmonia runtime UI (#6078). Supersedes #6087, which could not be reopened after this branch was rebased onto the squash-merged #6078 (its head commit was orphaned). Two commits, both against current master:

1. Resolve relation.field form fields via a process resolver step

A BPM user-task form's model is the process variables, which carry a to-one relation's FK id but not the related entity's own fields — so a form field like book.title / book.price rendered but stayed empty. Generalizes the decision resolver to user-task forms: scans forms for relation.field, anchors each resolver at the earliest step that needs it, and binds the form control to the <relation>_<field> process variable.

2. Declarative setField glue action + explicit next step routing

A serviceTask with args: { setField: <field>, value: <literal> } sets a string/text field of the trigger entity via a generated gen/events/<Process><Step>.java JavaDelegate (persisting with updateWithoutEvent), instead of a hand-written custom/ stub. args: { next: <step|end> } overrides a step's linear successor so a decision's two branches converge — enabling "Approve → status ACTIVE, Reject → REJECTED" as pure glue.

Covered by IntentEngineIT (18/18 green locally, including the new approve/reject diamond and the relation.field form cases).

🤖 Generated with Claude Code

delchev and others added 2 commits June 26, 2026 19:29
A BPM user-task form's model is the process variables, which carry a to-one
relation's FK id but not the related entity's own fields - so a form field like
book.title / book.price rendered but stayed empty. The decision resolver already
solved this for gateway conditions; this generalizes it to user-task forms.

- ProcessResolverSupport scans user-task forms (not just decision conditions)
  for relation.field references and anchors each resolver at the EARLIEST step
  that needs it (a path shared by a form and a later decision now resolves
  before the form, and the process-global variable still serves the decision).
- BpmnIntentGenerator inserts the resolver service task before its anchor step
  (any kind) and rewrites decisions against all process resolvers.
- FormIntentGenerator binds a relation.field control to the <relation>_<field>
  resolver variable, types it from the target entity's field, and marks it
  readonly.
- IntentParser validates a form relation.field is a one-hop to-one of forEntity
  with the field present on the target.
- IntentEngineIT covers a shared (form+decision) and a form-only relation field.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A serviceTask with no `call` used to scaffold a hand-written custom.<Step>
Java stub. This adds a declarative field-set action so an approval outcome
("Approve -> status ACTIVE, Reject -> REJECTED") is expressed as glue, no
custom code.

- setField: a serviceTask `args: { setField: <field>, value: <literal> }` sets
  a string/text field of the process trigger entity, generated as a
  gen/events/<Process><Step>.java JavaDelegate (SetFieldSupport -> the `setters`
  glue collection -> SetField.java.template + the setters case in
  generateUtils.js). It loads the entity by its PK process variable and persists
  via updateWithoutEvent (a workflow write must not re-fire onUpdate reactions).
- next: `args: { next: <step|end> }` overrides a step's linear successor so a
  decision's two branches converge on a common step instead of the first falling
  through into the second. The existing then/else fall-through is left intact
  (LoanApproval relies on it), so convergence is explicit.
- Parser validates setField is a string/text field of the trigger entity with a
  value present, and that `next` targets a declared step or `end`.
- IntentSettings scaffolds `setters` overrides; IntentEngineIT covers the
  approve/reject diamond end to end (BPMN + glue + generated JavaDelegates).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@delchev delchev merged commit a2bc7c6 into master Jun 26, 2026
12 checks passed
@delchev delchev deleted the feat/harmonia-runtime-template branch June 26, 2026 20:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant