feat: pass ProcessRuntime to host SPIs

Keep initiator and instance identity off ProcessContext variables so AssigneeResolver, RoutingCondition, and ActionHandler can read them from a dedicated runtime view.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
0264408
2026-09-20 10:40:16 +08:00
co-authored by Cursor
parent e4478656c1
commit e4e2c6ed9b
7 changed files with 70 additions and 34 deletions
@@ -1,16 +1,16 @@
package com.jetlumen.ordo.api;
/**
* Executes a named action step against the running instance's context. Hosts supply a
* Executes a named action step against the running instance. Hosts supply a
* singleton implementation (same pattern as {@link RoutingCondition}); the database only stores
* the {@code actionKey} string.
*/
@FunctionalInterface
public interface ActionHandler {
void execute(String actionKey, ProcessContext context);
void execute(String actionKey, ProcessRuntime runtime);
static ActionHandler noop() {
return (key, context) -> {
return (key, runtime) -> {
};
}
}
@@ -8,9 +8,9 @@ package com.jetlumen.ordo.api;
*/
@FunctionalInterface
public interface AssigneeResolver {
String resolve(String candidate, ApprovalStep step, ProcessContext context);
String resolve(String candidate, ApprovalStep step, ProcessRuntime runtime);
static AssigneeResolver direct() {
return (candidate, step, context) -> candidate;
return (candidate, step, runtime) -> candidate;
}
}
@@ -0,0 +1,27 @@
package com.jetlumen.ordo.api;
import java.util.Objects;
/**
* Read-only engine metadata plus business {@link ProcessContext} for host SPIs.
* Initiator and instance identity stay here; they are not copied into context variables.
*/
public record ProcessRuntime(String instanceId, String definitionId, int definitionVersion, String initiator,
String stepId, ProcessContext context) {
public ProcessRuntime {
Texts.requireText(instanceId, "instance id");
Texts.requireText(definitionId, "definition id");
if (definitionVersion < 1) {
throw new IllegalArgumentException("definition version must be at least 1");
}
Texts.requireText(initiator, "initiator");
Texts.requireText(stepId, "step id");
Objects.requireNonNull(context, "context must not be null");
}
public static ProcessRuntime of(ProcessInstance instance, String stepId) {
Objects.requireNonNull(instance, "instance must not be null");
return new ProcessRuntime(instance.id(), instance.definitionId(), instance.definitionVersion(),
instance.initiator(), stepId, instance.context());
}
}
@@ -3,15 +3,15 @@ package com.jetlumen.ordo.api;
import java.util.Map;
/**
* Evaluates a named routing condition ({@code when.ref}) against the running instance's context.
* Evaluates a named routing condition ({@code when.ref}) against the running instance.
* Hosts supply a singleton implementation (same pattern as {@link AssigneeResolver}); the
* definition stores the {@code ref} key and optional {@code args}.
*/
@FunctionalInterface
public interface RoutingCondition {
boolean matches(String conditionKey, Map<String, Object> args, ProcessContext context);
boolean matches(String conditionKey, Map<String, Object> args, ProcessRuntime runtime);
static RoutingCondition always() {
return (key, args, context) -> true;
return (key, args, runtime) -> true;
}
}