diff --git a/AGENTS.md b/AGENTS.md index a71987e..51600f1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -67,7 +67,8 @@ before writing code. The hard rules: root package, so `io.miragon.blueprint.config` would fail. Cross-cutting `@Configuration` (CORS, OpenAPI, error handling) goes in `adapter.inbound.rest` — the `Configuration` suffix is whitelisted there. -- **`adapter/process` is generated.** Never hand-edit `*ProcessApi.java`; edit the `.bpmn` and re-run +- **`adapter/process` is generated.** Never hand-edit `*ProcessApi.java` or the shared + `ServiceTasks`/`Messages`/`ProcessVariables`/`Errors`/`Escalations` files; edit the `.bpmn` and re-run `./mvnw -pl service/app generate-sources`. - **Service tasks are external topics.** A custom model rule (`ServiceTaskExternalTopicRule`) requires every service task to be an external task with a topic — no embedded delegates. The trade-offs @@ -81,6 +82,8 @@ before writing code. The hard rules: - `bpmn-to-code` generates typed process constants from the models at build time; a custom model test requires every service task to be an external task with a topic. +- Since bpmn-to-code 6 the API is node-centric: `ProcessApi.FlowNodes.` carries the + element (`ELEMENT_ID`, `INSTANCE`), its `Variables` and its successors (`Next`). - `bpmnlint` tooling lives at the **repo root** (`package.json`, `.bpmnlintrc`): `npm ci && npm run lint:bpmn`. It also runs on staged `.bpmn` via `.githooks/pre-commit` (install: `npm run hooks:install`). diff --git a/README.md b/README.md index fd042f4..57dbeae 100644 --- a/README.md +++ b/README.md @@ -72,8 +72,11 @@ docs/{README.md, adr/, assets/} ADR index + records + the process diagram - **Stack:** Java 21 · Spring Boot 4 · Operaton 2.1 (embedded) · process-engine-api (bpm-crafters) · PostgreSQL · Maven multi-module (`./mvnw`), versions centralized in the root `pom.xml`. - **Generated process API:** the [`bpmn-to-code`](https://github.com/emaarco/bpmn-to-code) Maven - plugin turns each `.bpmn` into a typed `*ProcessApi` class, so element ids, messages, timers and - variables are compile-checked constants used by both delegates and tests. + plugin turns each `.bpmn` into a typed `*ProcessApi` class plus shared `ServiceTasks`, `Messages`, + `ProcessVariables`, `Errors` and `Escalations` files. Since 6.x the API is node-centric: + `ProcessApi.FlowNodes.` carries the element id (`ELEMENT_ID`), its `Variables` and its + successors (`Next`), so element ids, messages, timers and variables are compile-checked constants used + by both workers and tests. - **Forms:** Camunda Forms (`.form`) are deployed with the process and render in the Operaton Tasklist/Cockpit for the user tasks. - **BPMN linting:** [`bpmnlint`](https://github.com/bpmn-io/bpmnlint) (`bpmnlint:recommended` plus diff --git a/pom.xml b/pom.xml index e1dd21a..28badb4 100644 --- a/pom.xml +++ b/pom.xml @@ -37,7 +37,7 @@ 3.1.1 - 5.2.0 + 6.6.1 1.5.1 1.30.0 diff --git a/service/app/pom.xml b/service/app/pom.xml index e23c60c..98c8a06 100644 --- a/service/app/pom.xml +++ b/service/app/pom.xml @@ -226,6 +226,11 @@ false io.miragon.blueprint.adapter.process.*ProcessApi* + io.miragon.blueprint.adapter.process.ServiceTasks* + io.miragon.blueprint.adapter.process.Messages* + io.miragon.blueprint.adapter.process.ProcessVariables* + io.miragon.blueprint.adapter.process.Errors* + io.miragon.blueprint.adapter.process.Escalations* io.miragon.blueprint.adapter.process.HistoryCleanupConfiguration* io.miragon.blueprint.adapter.process.EngineApiConfiguration* io.miragon.blueprint.OperatonBikeLeasingApplication* diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/ActivateLeasingWorker.java b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/ActivateLeasingWorker.java index f95d6f3..82c1d04 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/ActivateLeasingWorker.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/ActivateLeasingWorker.java @@ -2,7 +2,7 @@ import dev.bpmcrafters.processengine.worker.ProcessEngineWorker; import dev.bpmcrafters.processengine.worker.Variable; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.ServiceTasks; +import io.miragon.blueprint.adapter.process.ServiceTasks; import io.miragon.blueprint.application.port.inbound.ActivateLeasingUseCase; import io.miragon.blueprint.domain.leasing.ApplicationId; import org.springframework.stereotype.Component; diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/BookCostsWorker.java b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/BookCostsWorker.java index 58405d6..0eb1cdc 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/BookCostsWorker.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/BookCostsWorker.java @@ -2,7 +2,7 @@ import dev.bpmcrafters.processengine.worker.ProcessEngineWorker; import dev.bpmcrafters.processengine.worker.Variable; -import io.miragon.blueprint.adapter.process.CancelBikeOrderProcessApi.ServiceTasks; +import io.miragon.blueprint.adapter.process.ServiceTasks; import io.miragon.blueprint.application.port.inbound.BookCancellationCostsUseCase; import io.miragon.blueprint.domain.bike.OrderId; import org.springframework.stereotype.Component; diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/CancelContractWorker.java b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/CancelContractWorker.java index 29b86a2..9baf852 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/CancelContractWorker.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/CancelContractWorker.java @@ -2,7 +2,7 @@ import dev.bpmcrafters.processengine.worker.ProcessEngineWorker; import dev.bpmcrafters.processengine.worker.Variable; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.ServiceTasks; +import io.miragon.blueprint.adapter.process.ServiceTasks; import io.miragon.blueprint.application.port.inbound.CancelContractUseCase; import io.miragon.blueprint.domain.leasing.ApplicationId; import org.springframework.stereotype.Component; diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/CancelPolicyWorker.java b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/CancelPolicyWorker.java index 9dd9a85..1dde640 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/CancelPolicyWorker.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/CancelPolicyWorker.java @@ -2,7 +2,7 @@ import dev.bpmcrafters.processengine.worker.ProcessEngineWorker; import dev.bpmcrafters.processengine.worker.Variable; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.ServiceTasks; +import io.miragon.blueprint.adapter.process.ServiceTasks; import io.miragon.blueprint.application.port.inbound.CancelInsurancePolicyUseCase; import io.miragon.blueprint.domain.leasing.ApplicationId; import org.springframework.stereotype.Component; diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/IssueInsurancePolicyWorker.java b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/IssueInsurancePolicyWorker.java index b9c1d4c..7bce4eb 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/IssueInsurancePolicyWorker.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/IssueInsurancePolicyWorker.java @@ -2,7 +2,7 @@ import dev.bpmcrafters.processengine.worker.ProcessEngineWorker; import dev.bpmcrafters.processengine.worker.Variable; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.ServiceTasks; +import io.miragon.blueprint.adapter.process.ServiceTasks; import io.miragon.blueprint.application.port.inbound.IssueInsurancePolicyUseCase; import io.miragon.blueprint.domain.leasing.ApplicationId; import org.springframework.stereotype.Component; diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/OrderBikeWorker.java b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/OrderBikeWorker.java index 412771e..cf1af65 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/OrderBikeWorker.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/OrderBikeWorker.java @@ -3,9 +3,9 @@ import dev.bpmcrafters.processengine.worker.BpmnErrorOccurred; import dev.bpmcrafters.processengine.worker.ProcessEngineWorker; import dev.bpmcrafters.processengine.worker.Variable; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.Errors; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.ServiceTasks; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.Variables; +import io.miragon.blueprint.adapter.process.Errors; +import io.miragon.blueprint.adapter.process.ServiceTasks; +import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.FlowNodes; import io.miragon.blueprint.application.port.inbound.OrderBikeUseCase; import io.miragon.blueprint.domain.bike.BikeId; import io.miragon.blueprint.domain.bike.BikeUnavailableException; @@ -34,7 +34,7 @@ public Map orderBike(@Variable String applicationId, @Variable S throws BpmnErrorOccurred { try { OrderId orderId = useCase.orderBike(ApplicationId.of(applicationId), new BikeId(bikeId)); - return Map.of(Variables.ServiceTaskOrderBike.ORDER_ID.getValue(), orderId.value()); + return Map.of(FlowNodes.ServiceTaskOrderBike.Variables.ORDER_ID.getValue(), orderId.value()); } catch (BikeUnavailableException e) { throw new BpmnErrorOccurred(e.getMessage(), Errors.BIKE_UNAVAILABLE.getCode(), Map.of()); } diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/RequestCancellationWorker.java b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/RequestCancellationWorker.java index 6180437..cd97ad0 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/RequestCancellationWorker.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/RequestCancellationWorker.java @@ -2,8 +2,8 @@ import dev.bpmcrafters.processengine.worker.ProcessEngineWorker; import dev.bpmcrafters.processengine.worker.Variable; -import io.miragon.blueprint.adapter.process.CancelBikeOrderProcessApi.ServiceTasks; -import io.miragon.blueprint.adapter.process.CancelBikeOrderProcessApi.Variables; +import io.miragon.blueprint.adapter.process.ServiceTasks; +import io.miragon.blueprint.adapter.process.CancelBikeOrderProcessApi.FlowNodes; import io.miragon.blueprint.application.port.inbound.RequestOrderCancellationUseCase; import io.miragon.blueprint.domain.bike.OrderId; import java.util.Map; @@ -25,6 +25,6 @@ public RequestCancellationWorker(RequestOrderCancellationUseCase useCase) { @ProcessEngineWorker(topic = ServiceTasks.REQUEST_CANCELLATION) public Map requestCancellation(@Variable String orderId) { boolean cancellationPossible = useCase.requestCancellation(new OrderId(orderId)); - return Map.of(Variables.ServiceTaskRequestCancellation.CANCELLATION_POSSIBLE.getValue(), cancellationPossible); + return Map.of(FlowNodes.ServiceTaskRequestCancellation.Variables.CANCELLATION_POSSIBLE.getValue(), cancellationPossible); } } diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendCancellationConfirmationWorker.java b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendCancellationConfirmationWorker.java index f7ded3d..00a77fa 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendCancellationConfirmationWorker.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendCancellationConfirmationWorker.java @@ -2,7 +2,7 @@ import dev.bpmcrafters.processengine.worker.ProcessEngineWorker; import dev.bpmcrafters.processengine.worker.Variable; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.ServiceTasks; +import io.miragon.blueprint.adapter.process.ServiceTasks; import io.miragon.blueprint.application.port.inbound.SendCancellationConfirmationUseCase; import io.miragon.blueprint.domain.leasing.ApplicationId; import org.springframework.stereotype.Component; diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendContractWorker.java b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendContractWorker.java index 12a679e..11b859a 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendContractWorker.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendContractWorker.java @@ -2,7 +2,7 @@ import dev.bpmcrafters.processengine.worker.ProcessEngineWorker; import dev.bpmcrafters.processengine.worker.Variable; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.ServiceTasks; +import io.miragon.blueprint.adapter.process.ServiceTasks; import io.miragon.blueprint.application.port.inbound.SendContractUseCase; import io.miragon.blueprint.domain.leasing.ApplicationId; import org.springframework.stereotype.Component; diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendRejectionWorker.java b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendRejectionWorker.java index 451f32d..2ebe5a0 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendRejectionWorker.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendRejectionWorker.java @@ -2,7 +2,7 @@ import dev.bpmcrafters.processengine.worker.ProcessEngineWorker; import dev.bpmcrafters.processengine.worker.Variable; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.ServiceTasks; +import io.miragon.blueprint.adapter.process.ServiceTasks; import io.miragon.blueprint.application.port.inbound.RejectApplicationUseCase; import io.miragon.blueprint.domain.leasing.ApplicationId; import org.springframework.stereotype.Component; diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendReminderMailWorker.java b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendReminderMailWorker.java index 06d46cb..138841e 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendReminderMailWorker.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/inbound/operaton/SendReminderMailWorker.java @@ -2,7 +2,7 @@ import dev.bpmcrafters.processengine.worker.ProcessEngineWorker; import dev.bpmcrafters.processengine.worker.Variable; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.ServiceTasks; +import io.miragon.blueprint.adapter.process.ServiceTasks; import io.miragon.blueprint.application.port.inbound.SendSignatureReminderUseCase; import io.miragon.blueprint.domain.leasing.ApplicationId; import org.springframework.stereotype.Component; diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/outbound/operaton/LeasingProcessAdapter.java b/service/app/src/main/java/io/miragon/blueprint/adapter/outbound/operaton/LeasingProcessAdapter.java index 191904b..a1c2e6d 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/outbound/operaton/LeasingProcessAdapter.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/outbound/operaton/LeasingProcessAdapter.java @@ -10,9 +10,8 @@ import dev.bpmcrafters.processengineapi.task.TaskInformation; import dev.bpmcrafters.processengineapi.task.UserTaskCompletionApi; import dev.bpmcrafters.processengineapi.task.support.UserTaskSupport; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.Elements; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.Messages; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.Variables; +import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.FlowNodes; +import io.miragon.blueprint.adapter.process.Messages; import io.miragon.blueprint.application.port.outbound.LeasingProcess; import io.miragon.blueprint.domain.bike.BikeId; import io.miragon.blueprint.domain.leasing.ApplicationId; @@ -60,11 +59,11 @@ public LeasingProcessAdapter( public void submitRequest(LeasingApplication application) { var key = application.id().value().toString(); var payload = new HashMap(); - payload.put(Variables.StartEventLeasingRequestReceived.APPLICATION_ID.getValue(), key); - payload.put(Variables.StartEventLeasingRequestReceived.BIKE_ID.getValue(), application.bikeId().value()); - payload.put(Variables.StartEventLeasingRequestReceived.MONTHLY_NET_INCOME.getValue(), + payload.put(FlowNodes.StartEventLeasingRequestReceived.Variables.APPLICATION_ID.getValue(), key); + payload.put(FlowNodes.StartEventLeasingRequestReceived.Variables.BIKE_ID.getValue(), application.bikeId().value()); + payload.put(FlowNodes.StartEventLeasingRequestReceived.Variables.MONTHLY_NET_INCOME.getValue(), application.monthlyNetIncome()); - payload.put(Variables.StartEventLeasingRequestReceived.AGE.getValue(), application.age()); + payload.put(FlowNodes.StartEventLeasingRequestReceived.Variables.AGE.getValue(), application.age()); // Preserve the engine business key and seed the global correlation variable. payload.put(CommonRestrictions.BUSINESS_KEY, key); payload.put(CommonRestrictions.CORRELATION_KEY, key); @@ -125,9 +124,9 @@ private void correlate(String messageName, ApplicationId id) { public void completeAlternativeClarification(ApplicationId id, boolean alternativeFound, @Nullable BikeId bikeId) { var taskId = awaitClarifyAlternativeTaskId(id); var variables = new HashMap(); - variables.put(Variables.UserTaskClarifyAlternative.ALTERNATIVE_FOUND.getValue(), alternativeFound); + variables.put(FlowNodes.UserTaskClarifyAlternative.Variables.ALTERNATIVE_FOUND.getValue(), alternativeFound); if (bikeId != null) { - variables.put(Variables.UserTaskClarifyAlternative.BIKE_ID.getValue(), bikeId.value()); + variables.put(FlowNodes.UserTaskClarifyAlternative.Variables.BIKE_ID.getValue(), bikeId.value()); } userTaskCompletionApi.completeTask(new CompleteTaskCmd(taskId, variables)).join(); } @@ -138,10 +137,10 @@ public void completeAlternativeClarification(ApplicationId id, boolean alternati */ private String awaitClarifyAlternativeTaskId(ApplicationId id) { var applicationId = id.value().toString(); - var applicationIdKey = Variables.StartEventLeasingRequestReceived.APPLICATION_ID.getValue(); + var applicationIdKey = FlowNodes.StartEventLeasingRequestReceived.Variables.APPLICATION_ID.getValue(); for (int attempt = 0; attempt < TASK_LOOKUP_ATTEMPTS; attempt++) { var task = userTaskSupport.getAllTasks().stream() - .filter(it -> Elements.USER_TASK_CLARIFY_ALTERNATIVE.getValue() + .filter(it -> FlowNodes.UserTaskClarifyAlternative.ELEMENT_ID .equals(it.getMeta().get(CommonRestrictions.ACTIVITY_ID))) .filter(it -> belongsToApplication(it, applicationIdKey, applicationId)) .findFirst() @@ -152,7 +151,7 @@ private String awaitClarifyAlternativeTaskId(ApplicationId id) { sleep(TASK_LOOKUP_INTERVAL_MS); } throw new IllegalStateException( - "No open '" + Elements.USER_TASK_CLARIFY_ALTERNATIVE.getValue() + "' task for application " + "No open '" + FlowNodes.UserTaskClarifyAlternative.ELEMENT_ID + "' task for application " + applicationId); } diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/outbound/operaton/TaskInboxAdapter.java b/service/app/src/main/java/io/miragon/blueprint/adapter/outbound/operaton/TaskInboxAdapter.java index b42456e..454e3c1 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/outbound/operaton/TaskInboxAdapter.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/outbound/operaton/TaskInboxAdapter.java @@ -1,6 +1,6 @@ package io.miragon.blueprint.adapter.outbound.operaton; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.Elements; +import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.FlowNodes; import io.miragon.blueprint.application.port.outbound.TaskInboxPort; import io.miragon.blueprint.domain.leasing.ApplicationId; import java.time.ZoneId; @@ -38,7 +38,7 @@ public TaskInboxAdapter(TaskService taskService, RuntimeService runtimeService) @Override public List findOpenClarifications() { - var tasks = findOpenTasks(Elements.USER_TASK_CLARIFY_ALTERNATIVE.getValue()); + var tasks = findOpenTasks(FlowNodes.UserTaskClarifyAlternative.ELEMENT_ID); var businessKeys = businessKeysById(tasks.stream().map(Task::getProcessInstanceId).toList()); var clarifications = new ArrayList(); for (var task : tasks) { diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/process/BikeLeasingProcessProcessApi.java b/service/app/src/main/java/io/miragon/blueprint/adapter/process/BikeLeasingProcessProcessApi.java index 65f247f..6a5f28b 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/process/BikeLeasingProcessProcessApi.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/process/BikeLeasingProcessProcessApi.java @@ -1,18 +1,36 @@ // Generated by bpmn-to-code package io.miragon.blueprint.adapter.process; +import io.miragon.bpmn.runtime.AbstractFlowNode; +import io.miragon.bpmn.runtime.AssociatedCompensationHandler; +import io.miragon.bpmn.runtime.AttachedBoundaryEvent; +import io.miragon.bpmn.runtime.BoundaryEvent; +import io.miragon.bpmn.runtime.BpmnElementType; import io.miragon.bpmn.runtime.BpmnEngine; -import io.miragon.bpmn.runtime.BpmnError; -import io.miragon.bpmn.runtime.BpmnEscalation; -import io.miragon.bpmn.runtime.BpmnFlow; -import io.miragon.bpmn.runtime.BpmnRelations; +import io.miragon.bpmn.runtime.BpmnErrorDefinition; +import io.miragon.bpmn.runtime.BpmnEscalationDefinition; +import io.miragon.bpmn.runtime.BpmnEventType; import io.miragon.bpmn.runtime.BpmnTimer; +import io.miragon.bpmn.runtime.CallActivity; +import io.miragon.bpmn.runtime.CompensationThrowEvent; import io.miragon.bpmn.runtime.ElementId; +import io.miragon.bpmn.runtime.ErrorEvent; +import io.miragon.bpmn.runtime.EscalationEvent; +import io.miragon.bpmn.runtime.Event; +import io.miragon.bpmn.runtime.FlowNode; +import io.miragon.bpmn.runtime.FlowScope; +import io.miragon.bpmn.runtime.HasJobType; +import io.miragon.bpmn.runtime.HasMessage; +import io.miragon.bpmn.runtime.HasSuccessors; +import io.miragon.bpmn.runtime.HasVariables; import io.miragon.bpmn.runtime.InputOutputMapping; import io.miragon.bpmn.runtime.MessageName; import io.miragon.bpmn.runtime.ProcessId; +import io.miragon.bpmn.runtime.SequenceFlows; +import io.miragon.bpmn.runtime.TimerEvent; +import io.miragon.bpmn.runtime.TimerType; +import io.miragon.bpmn.runtime.VariableDefinitions; import io.miragon.bpmn.runtime.VariableName; -import java.lang.String; import java.util.List; public final class BikeLeasingProcessProcessApi { @@ -20,382 +38,1479 @@ public final class BikeLeasingProcessProcessApi { public static final BpmnEngine PROCESS_ENGINE = BpmnEngine.CAMUNDA_7; + private BikeLeasingProcessProcessApi() { + } + /** - * BPMN element ids as declared in the source model. - * Typically used in process-level tests or when searching for tasks. - * Worker runtime code rarely needs these. + * Typed navigation over the process flow: one nested class per BPMN element. */ - public static final class Elements { - public static final ElementId BUSINESS_RULE_TASK_CHECK_CREDIT_RATING = new ElementId("businessRuleTask_checkCreditRating"); + public static final class FlowNodes { + private FlowNodes() { + } - public static final ElementId CALL_ACTIVITY_CANCEL_BIKE_ORDER = new ElementId("callActivity_cancelBikeOrder"); + public static BusinessRuleTaskCheckCreditRating businessRuleTaskCheckCreditRating() { + return BusinessRuleTaskCheckCreditRating.INSTANCE; + } - public static final ElementId END_EVENT_APPLICATION_CANCELLED = new ElementId("endEvent_applicationCancelled"); + public static CallActivityCancelBikeOrder callActivityCancelBikeOrder() { + return CallActivityCancelBikeOrder.INSTANCE; + } - public static final ElementId END_EVENT_APPLICATION_REJECTED = new ElementId("endEvent_applicationRejected"); + public static EndEventApplicationCancelled endEventApplicationCancelled() { + return EndEventApplicationCancelled.INSTANCE; + } - public static final ElementId END_EVENT_CONTRACT_CANCELLED = new ElementId("endEvent_contractCancelled"); + public static EndEventApplicationRejected endEventApplicationRejected() { + return EndEventApplicationRejected.INSTANCE; + } - public static final ElementId END_EVENT_CONTRACT_VALID = new ElementId("endEvent_contractValid"); + public static EndEventContractCancelled endEventContractCancelled() { + return EndEventContractCancelled.INSTANCE; + } - public static final ElementId END_EVENT_LEASING_ACTIVE = new ElementId("endEvent_leasingActive"); + public static EndEventContractValid endEventContractValid() { + return EndEventContractValid.INSTANCE; + } - public static final ElementId END_EVENT_NOT_SIGNED = new ElementId("endEvent_notSigned"); + public static EndEventLeasingActive endEventLeasingActive() { + return EndEventLeasingActive.INSTANCE; + } - public static final ElementId END_EVENT_PROSPECT_REMINDED = new ElementId("endEvent_prospectReminded"); + public static EndEventNotSigned endEventNotSigned() { + return EndEventNotSigned.INSTANCE; + } - public static final ElementId EVENT_BIKE_UNAVAILABLE = new ElementId("event_bikeUnavailable"); + public static EndEventProspectReminded endEventProspectReminded() { + return EndEventProspectReminded.INSTANCE; + } - public static final ElementId EVENT_COMPENSATE_CONTRACT = new ElementId("event_compensateContract"); + public static EventBikeUnavailable eventBikeUnavailable() { + return EventBikeUnavailable.INSTANCE; + } - public static final ElementId EVENT_COMPENSATE_INSURANCE = new ElementId("event_compensateInsurance"); + public static EventCompensateContract eventCompensateContract() { + return EventCompensateContract.INSTANCE; + } - public static final ElementId EVENT_COMPENSATE_ORDER = new ElementId("event_compensateOrder"); + public static EventCompensateInsurance eventCompensateInsurance() { + return EventCompensateInsurance.INSTANCE; + } - public static final ElementId EVENT_CONTRACT_NOT_SIGNED = new ElementId("event_contractNotSigned"); + public static EventCompensateOrder eventCompensateOrder() { + return EventCompensateOrder.INSTANCE; + } - public static final ElementId EVENT_CONTRACT_SIGNED = new ElementId("event_contractSigned"); + public static EventContractNotSigned eventContractNotSigned() { + return EventContractNotSigned.INSTANCE; + } - public static final ElementId EVENT_HANDOVER_REPORTED = new ElementId("event_handoverReported"); + public static EventContractSigned eventContractSigned() { + return EventContractSigned.INSTANCE; + } - public static final ElementId EVENT_REVERSE_APPLICATION = new ElementId("event_reverseApplication"); + public static EventHandoverReported eventHandoverReported() { + return EventHandoverReported.INSTANCE; + } - public static final ElementId EVENT_SIGNATURE_DEADLINE = new ElementId("event_signatureDeadline"); + public static EventReverseApplication eventReverseApplication() { + return EventReverseApplication.INSTANCE; + } - public static final ElementId EVENT_SIGNATURE_REMINDER = new ElementId("event_signatureReminder"); + public static EventSignatureDeadline eventSignatureDeadline() { + return EventSignatureDeadline.INSTANCE; + } - public static final ElementId EVENT_TRIGGER_REVERSAL = new ElementId("event_triggerReversal"); + public static EventSignatureReminder eventSignatureReminder() { + return EventSignatureReminder.INSTANCE; + } - public static final ElementId EVENT_WITHDRAWAL_PERIOD_ELAPSED = new ElementId("event_withdrawalPeriodElapsed"); + public static EventTriggerReversal eventTriggerReversal() { + return EventTriggerReversal.INSTANCE; + } - public static final ElementId GATEWAY_ALTERNATIVE_FOUND = new ElementId("gateway_alternativeFound"); + public static EventWithdrawalPeriodElapsed eventWithdrawalPeriodElapsed() { + return EventWithdrawalPeriodElapsed.INSTANCE; + } - public static final ElementId GATEWAY_AWAIT_SIGNATURE = new ElementId("gateway_awaitSignature"); + public static GatewayAlternativeFound gatewayAlternativeFound() { + return GatewayAlternativeFound.INSTANCE; + } - public static final ElementId GATEWAY_BIKE_SOURCE_JOIN = new ElementId("gateway_bikeSourceJoin"); + public static GatewayAwaitSignature gatewayAwaitSignature() { + return GatewayAwaitSignature.INSTANCE; + } - public static final ElementId GATEWAY_FORK = new ElementId("gateway_fork"); + public static GatewayBikeSourceJoin gatewayBikeSourceJoin() { + return GatewayBikeSourceJoin.INSTANCE; + } - public static final ElementId GATEWAY_IS_SOLVENT = new ElementId("gateway_isSolvent"); + public static GatewayFork gatewayFork() { + return GatewayFork.INSTANCE; + } - public static final ElementId GATEWAY_JOIN = new ElementId("gateway_join"); + public static GatewayIsSolvent gatewayIsSolvent() { + return GatewayIsSolvent.INSTANCE; + } - public static final ElementId GATEWAY_REJECTION_JOIN = new ElementId("gateway_rejectionJoin"); + public static GatewayJoin gatewayJoin() { + return GatewayJoin.INSTANCE; + } - public static final ElementId SERVICE_TASK_ACTIVATE_LEASING = new ElementId("serviceTask_activateLeasing"); + public static GatewayRejectionJoin gatewayRejectionJoin() { + return GatewayRejectionJoin.INSTANCE; + } - public static final ElementId SERVICE_TASK_CANCEL_CONTRACT = new ElementId("serviceTask_cancelContract"); + public static ServiceTaskActivateLeasing serviceTaskActivateLeasing() { + return ServiceTaskActivateLeasing.INSTANCE; + } - public static final ElementId SERVICE_TASK_CANCEL_POLICY = new ElementId("serviceTask_cancelPolicy"); + public static ServiceTaskCancelContract serviceTaskCancelContract() { + return ServiceTaskCancelContract.INSTANCE; + } - public static final ElementId SERVICE_TASK_CONFIRM_CONTRACT_CANCELLATION = new ElementId("serviceTask_confirmContractCancellation"); + public static ServiceTaskCancelPolicy serviceTaskCancelPolicy() { + return ServiceTaskCancelPolicy.INSTANCE; + } - public static final ElementId SERVICE_TASK_ISSUE_INSURANCE_POLICY = new ElementId("serviceTask_issueInsurancePolicy"); + public static ServiceTaskConfirmContractCancellation serviceTaskConfirmContractCancellation() { + return ServiceTaskConfirmContractCancellation.INSTANCE; + } - public static final ElementId SERVICE_TASK_ORDER_BIKE = new ElementId("serviceTask_orderBike"); + public static ServiceTaskIssueInsurancePolicy serviceTaskIssueInsurancePolicy() { + return ServiceTaskIssueInsurancePolicy.INSTANCE; + } - public static final ElementId SERVICE_TASK_SEND_CANCELLATION_CONFIRMATION = new ElementId("serviceTask_sendCancellationConfirmation"); + public static ServiceTaskOrderBike serviceTaskOrderBike() { + return ServiceTaskOrderBike.INSTANCE; + } - public static final ElementId SERVICE_TASK_SEND_CONTRACT = new ElementId("serviceTask_sendContract"); + public static ServiceTaskSendCancellationConfirmation serviceTaskSendCancellationConfirmation() { + return ServiceTaskSendCancellationConfirmation.INSTANCE; + } - public static final ElementId SERVICE_TASK_SEND_REJECTION = new ElementId("serviceTask_sendRejection"); + public static ServiceTaskSendContract serviceTaskSendContract() { + return ServiceTaskSendContract.INSTANCE; + } - public static final ElementId SERVICE_TASK_SEND_REMINDER_MAIL = new ElementId("serviceTask_sendReminderMail"); + public static ServiceTaskSendRejection serviceTaskSendRejection() { + return ServiceTaskSendRejection.INSTANCE; + } - public static final ElementId START_EVENT_APPLICATION_WITHDRAWN = new ElementId("startEvent_applicationWithdrawn"); + public static ServiceTaskSendReminderMail serviceTaskSendReminderMail() { + return ServiceTaskSendReminderMail.INSTANCE; + } - public static final ElementId START_EVENT_CUSTOMER_ELIGIBLE = new ElementId("startEvent_customerEligible"); + public static StartEventApplicationWithdrawn startEventApplicationWithdrawn() { + return StartEventApplicationWithdrawn.INSTANCE; + } - public static final ElementId START_EVENT_LEASING_REQUEST_RECEIVED = new ElementId("startEvent_leasingRequestReceived"); + public static StartEventCustomerEligible startEventCustomerEligible() { + return StartEventCustomerEligible.INSTANCE; + } - public static final ElementId SUB_PROCESS_APPLICATION_WITHDRAWN = new ElementId("subProcess_applicationWithdrawn"); + public static StartEventLeasingRequestReceived startEventLeasingRequestReceived() { + return StartEventLeasingRequestReceived.INSTANCE; + } - public static final ElementId SUB_PROCESS_CONCLUDE_CONTRACT = new ElementId("subProcess_concludeContract"); + public static SubProcessApplicationWithdrawn subProcessApplicationWithdrawn() { + return SubProcessApplicationWithdrawn.INSTANCE; + } - public static final ElementId USER_TASK_CLARIFY_ALTERNATIVE = new ElementId("userTask_clarifyAlternative"); - } + public static SubProcessConcludeContract subProcessConcludeContract() { + return SubProcessConcludeContract.INSTANCE; + } - /** - * Call activities grouped by element. Each nested class exposes the called {@code PROCESS_ID} plus the variable mappings passed into ({@code Inputs}) and returned from ({@code Outputs}) the called process. - */ - public static final class CallActivities { - public static final class CallActivityCancelBikeOrder { - public static final ProcessId PROCESS_ID = new ProcessId("cancelBikeOrder"); + public static UserTaskClarifyAlternative userTaskClarifyAlternative() { + return UserTaskClarifyAlternative.INSTANCE; + } + + public static List all() { + return List.of( + BusinessRuleTaskCheckCreditRating.INSTANCE, + CallActivityCancelBikeOrder.INSTANCE, + EndEventApplicationCancelled.INSTANCE, + EndEventApplicationRejected.INSTANCE, + EndEventContractCancelled.INSTANCE, + EndEventContractValid.INSTANCE, + EndEventLeasingActive.INSTANCE, + EndEventNotSigned.INSTANCE, + EndEventProspectReminded.INSTANCE, + EventBikeUnavailable.INSTANCE, + EventCompensateContract.INSTANCE, + EventCompensateInsurance.INSTANCE, + EventCompensateOrder.INSTANCE, + EventContractNotSigned.INSTANCE, + EventContractSigned.INSTANCE, + EventHandoverReported.INSTANCE, + EventReverseApplication.INSTANCE, + EventSignatureDeadline.INSTANCE, + EventSignatureReminder.INSTANCE, + EventTriggerReversal.INSTANCE, + EventWithdrawalPeriodElapsed.INSTANCE, + GatewayAlternativeFound.INSTANCE, + GatewayAwaitSignature.INSTANCE, + GatewayBikeSourceJoin.INSTANCE, + GatewayFork.INSTANCE, + GatewayIsSolvent.INSTANCE, + GatewayJoin.INSTANCE, + GatewayRejectionJoin.INSTANCE, + ServiceTaskActivateLeasing.INSTANCE, + ServiceTaskCancelContract.INSTANCE, + ServiceTaskCancelPolicy.INSTANCE, + ServiceTaskConfirmContractCancellation.INSTANCE, + ServiceTaskIssueInsurancePolicy.INSTANCE, + ServiceTaskOrderBike.INSTANCE, + ServiceTaskSendCancellationConfirmation.INSTANCE, + ServiceTaskSendContract.INSTANCE, + ServiceTaskSendRejection.INSTANCE, + ServiceTaskSendReminderMail.INSTANCE, + StartEventApplicationWithdrawn.INSTANCE, + StartEventCustomerEligible.INSTANCE, + StartEventLeasingRequestReceived.INSTANCE, + SubProcessApplicationWithdrawn.INSTANCE, + SubProcessConcludeContract.INSTANCE, + UserTaskClarifyAlternative.INSTANCE); + } + + public static final class BusinessRuleTaskCheckCreditRating extends AbstractFlowNode implements HasSuccessors { + public static final String ELEMENT_ID = "businessRuleTask_checkCreditRating"; + + public static final BusinessRuleTaskCheckCreditRating INSTANCE = new BusinessRuleTaskCheckCreditRating(); + + private BusinessRuleTaskCheckCreditRating() { + super(new ElementId(ELEMENT_ID), BpmnElementType.BUSINESS_RULE_TASK, "Check credit rating"); + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows gatewayIsSolvent() { + return SequenceFlows.single(new ElementId("flow_creditCheckToSolvency"), GatewayIsSolvent.INSTANCE); + } + } + } + + public static final class CallActivityCancelBikeOrder extends AbstractFlowNode implements CallActivity, HasVariables { + public static final String ELEMENT_ID = "callActivity_cancelBikeOrder"; + + public static final CallActivityCancelBikeOrder INSTANCE = new CallActivityCancelBikeOrder(); + + private static final Variables VARIABLES = new Variables(); + + private CallActivityCancelBikeOrder() { + super(new ElementId(ELEMENT_ID), BpmnElementType.CALL_ACTIVITY, "Cancel bike order"); + } + + @Override + public ProcessId getCalledProcess() { + return new ProcessId("cancelBikeOrder"); + } + + @Override + public Variables getVariables() { + return VARIABLES; + } + + public static final class Variables extends VariableDefinitions { + public static final VariableName.Input BIKE_ID = new VariableName.Input(ProcessVariables.BIKE_ID); + + public static final VariableName.Input ORDER_ID = new VariableName.Input(ProcessVariables.ORDER_ID); + + private Variables() { + } + + @Override + public List getAll() { + return List.of(BIKE_ID, ORDER_ID); + } + } public static final class Inputs { public static final InputOutputMapping BIKE_ID = new InputOutputMapping("bikeId", "bikeId", null); public static final InputOutputMapping ORDER_ID = new InputOutputMapping("orderId", "orderId", null); + + private Inputs() { + } } } - } - /** - * BPMN message names used to correlate messages to running process instances. - */ - public static final class Messages { - public static final MessageName MIRAVELO_APPLICATION_WITHDRAWN = new MessageName("miravelo.applicationWithdrawn"); + public static final class EndEventApplicationCancelled extends AbstractFlowNode implements Event { + public static final String ELEMENT_ID = "endEvent_applicationCancelled"; - public static final MessageName MIRAVELO_CONTRACT_SIGNED = new MessageName("miravelo.contractSigned"); + public static final EndEventApplicationCancelled INSTANCE = new EndEventApplicationCancelled(); - public static final MessageName MIRAVELO_HANDOVER_REPORTED = new MessageName("miravelo.handoverReported"); + private EndEventApplicationCancelled() { + super(new ElementId(ELEMENT_ID), BpmnElementType.END_EVENT, "Leasing cancelled"); + } - public static final MessageName MIRAVELO_LEASING_REQUEST_RECEIVED = new MessageName("miravelo.leasingRequestReceived"); - } + @Override + public BpmnEventType getEventType() { + return BpmnEventType.NONE; + } + } - /** - * Job worker task types used in {@code @JobWorker(type = ServiceTasks.X)} annotations. - * Kept as {@code public static final String} because annotation arguments must be compile-time constants. - */ - public static final class ServiceTasks { - public static final String ACTIVATE_LEASING = "activateLeasing"; + public static final class EndEventApplicationRejected extends AbstractFlowNode implements Event { + public static final String ELEMENT_ID = "endEvent_applicationRejected"; - public static final String CANCEL_CONTRACT = "cancelContract"; + public static final EndEventApplicationRejected INSTANCE = new EndEventApplicationRejected(); - public static final String CANCEL_POLICY = "cancelPolicy"; + private EndEventApplicationRejected() { + super(new ElementId(ELEMENT_ID), BpmnElementType.END_EVENT, "Application rejected"); + } - public static final String ISSUE_INSURANCE_POLICY = "issueInsurancePolicy"; + @Override + public BpmnEventType getEventType() { + return BpmnEventType.NONE; + } + } - public static final String ORDER_BIKE = "orderBike"; + public static final class EndEventContractCancelled extends AbstractFlowNode implements Event { + public static final String ELEMENT_ID = "endEvent_contractCancelled"; - public static final String SEND_CANCELLATION_CONFIRMATION = "sendCancellationConfirmation"; + public static final EndEventContractCancelled INSTANCE = new EndEventContractCancelled(); - public static final String SEND_CONTRACT = "sendContract"; + private EndEventContractCancelled() { + super(new ElementId(ELEMENT_ID), BpmnElementType.END_EVENT, "Contract cancelled"); + } - public static final String SEND_REJECTION = "sendRejection"; + @Override + public BpmnEventType getEventType() { + return BpmnEventType.TERMINATE; + } + } - public static final String SEND_REMINDER_MAIL = "sendReminderMail"; - } + public static final class EndEventContractValid extends AbstractFlowNode implements Event { + public static final String ELEMENT_ID = "endEvent_contractValid"; - public static final class Timers { - public static final BpmnTimer EVENT_SIGNATURE_DEADLINE = new BpmnTimer("Duration", "P14D"); + public static final EndEventContractValid INSTANCE = new EndEventContractValid(); - public static final BpmnTimer EVENT_SIGNATURE_REMINDER = new BpmnTimer("Duration", "P7D"); + private EndEventContractValid() { + super(new ElementId(ELEMENT_ID), BpmnElementType.END_EVENT, "Contract valid"); + } - public static final BpmnTimer EVENT_WITHDRAWAL_PERIOD_ELAPSED = new BpmnTimer("Duration", "P14D"); - } + @Override + public BpmnEventType getEventType() { + return BpmnEventType.NONE; + } + } - public static final class Errors { - public static final BpmnError BIKE_UNAVAILABLE = new BpmnError("Bike_Unavailable", "bikeUnavailable"); - } + public static final class EndEventLeasingActive extends AbstractFlowNode implements Event { + public static final String ELEMENT_ID = "endEvent_leasingActive"; - public static final class Escalations { - public static final BpmnEscalation CONTRACT_NOT_SIGNED = new BpmnEscalation("Contract_Not_Signed", "contractNotSigned"); - } + public static final EndEventLeasingActive INSTANCE = new EndEventLeasingActive(); - public static final class Compensations { - public static final ElementId EVENT_COMPENSATE_CONTRACT = new ElementId("event_compensateContract"); + private EndEventLeasingActive() { + super(new ElementId(ELEMENT_ID), BpmnElementType.END_EVENT, "Leasing active"); + } - public static final ElementId EVENT_COMPENSATE_INSURANCE = new ElementId("event_compensateInsurance"); + @Override + public BpmnEventType getEventType() { + return BpmnEventType.NONE; + } + } - public static final ElementId EVENT_COMPENSATE_ORDER = new ElementId("event_compensateOrder"); + public static final class EndEventNotSigned extends AbstractFlowNode implements Event, EscalationEvent { + public static final String ELEMENT_ID = "endEvent_notSigned"; - public static final ElementId EVENT_REVERSE_APPLICATION = new ElementId("event_reverseApplication"); + public static final EndEventNotSigned INSTANCE = new EndEventNotSigned(); - public static final ElementId EVENT_TRIGGER_REVERSAL = new ElementId("event_triggerReversal"); - } + private EndEventNotSigned() { + super(new ElementId(ELEMENT_ID), BpmnElementType.END_EVENT, "Not signed"); + } - /** - * Process variables grouped by the BPMN element that declares them. - * Direction is encoded in each variable's wrapper type: {@code VariableName.Input}, {@code VariableName.Output}, or {@code VariableName.InOut} when the variable is both read and written by the same element. - * Consumer APIs that take a specific subtype (for example, a method accepting {@code VariableName.Output}) get compile-time direction enforcement. - */ - public static final class Variables { - public static final class CallActivityCancelBikeOrder { - public static final VariableName.Input BIKE_ID = new VariableName.Input("bikeId"); + @Override + public BpmnEventType getEventType() { + return BpmnEventType.ESCALATION; + } + + @Override + public BpmnEscalationDefinition getEscalation() { + return Escalations.CONTRACT_NOT_SIGNED; + } + } + + public static final class EndEventProspectReminded extends AbstractFlowNode implements Event { + public static final String ELEMENT_ID = "endEvent_prospectReminded"; + + public static final EndEventProspectReminded INSTANCE = new EndEventProspectReminded(); + + private EndEventProspectReminded() { + super(new ElementId(ELEMENT_ID), BpmnElementType.END_EVENT, "Prospect reminded"); + } + + @Override + public BpmnEventType getEventType() { + return BpmnEventType.NONE; + } + } + + public static final class EventBikeUnavailable extends AbstractFlowNode implements HasSuccessors, BoundaryEvent, ErrorEvent { + public static final String ELEMENT_ID = "event_bikeUnavailable"; + + public static final EventBikeUnavailable INSTANCE = new EventBikeUnavailable(); - public static final VariableName.Input ORDER_ID = new VariableName.Input("orderId"); + private EventBikeUnavailable() { + super(new ElementId(ELEMENT_ID), BpmnElementType.BOUNDARY_EVENT, "Bike unavailable"); + } + + @Override + public BpmnEventType getEventType() { + return BpmnEventType.ERROR; + } + + @Override + public BpmnErrorDefinition getError() { + return Errors.BIKE_UNAVAILABLE; + } + + @Override + public ServiceTaskOrderBike getAttachedTo() { + return ServiceTaskOrderBike.INSTANCE; + } + + @Override + public boolean isInterrupting() { + return true; + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows userTaskClarifyAlternative() { + return SequenceFlows.single(new ElementId("flow_bikeUnavailable"), UserTaskClarifyAlternative.INSTANCE); + } + } } - public static final class ServiceTaskOrderBike { - public static final VariableName.Input BIKE_ID = new VariableName.Input("bikeId"); + public static final class EventCompensateContract extends AbstractFlowNode implements HasSuccessors, BoundaryEvent { + public static final String ELEMENT_ID = "event_compensateContract"; + + public static final EventCompensateContract INSTANCE = new EventCompensateContract(); + + private EventCompensateContract() { + super(new ElementId(ELEMENT_ID), BpmnElementType.BOUNDARY_EVENT, "Compensate contract"); + } + + @Override + public BpmnEventType getEventType() { + return BpmnEventType.COMPENSATION; + } + + @Override + public SubProcessConcludeContract getAttachedTo() { + return SubProcessConcludeContract.INSTANCE; + } + + @Override + public boolean isInterrupting() { + return true; + } - public static final VariableName.Output ORDER_ID = new VariableName.Output("orderId"); + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public AssociatedCompensationHandler serviceTaskCancelContract() { + return new AssociatedCompensationHandler<>(ServiceTaskCancelContract.INSTANCE); + } + } } - public static final class StartEventLeasingRequestReceived { - public static final VariableName.Input AGE = new VariableName.Input("age"); + public static final class EventCompensateInsurance extends AbstractFlowNode implements HasSuccessors, BoundaryEvent { + public static final String ELEMENT_ID = "event_compensateInsurance"; - public static final VariableName.Input APPLICATION_ID = new VariableName.Input("applicationId"); + public static final EventCompensateInsurance INSTANCE = new EventCompensateInsurance(); + + private EventCompensateInsurance() { + super(new ElementId(ELEMENT_ID), BpmnElementType.BOUNDARY_EVENT, "Compensate policy"); + } - public static final VariableName.Input BIKE_ID = new VariableName.Input("bikeId"); + @Override + public BpmnEventType getEventType() { + return BpmnEventType.COMPENSATION; + } + + @Override + public ServiceTaskIssueInsurancePolicy getAttachedTo() { + return ServiceTaskIssueInsurancePolicy.INSTANCE; + } - public static final VariableName.Input MONTHLY_NET_INCOME = new VariableName.Input("monthlyNetIncome"); + @Override + public boolean isInterrupting() { + return true; + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public AssociatedCompensationHandler serviceTaskCancelPolicy() { + return new AssociatedCompensationHandler<>(ServiceTaskCancelPolicy.INSTANCE); + } + } } - public static final class UserTaskClarifyAlternative { - public static final VariableName.Output ALTERNATIVE_FOUND = new VariableName.Output("alternativeFound"); + public static final class EventCompensateOrder extends AbstractFlowNode implements HasSuccessors, BoundaryEvent { + public static final String ELEMENT_ID = "event_compensateOrder"; + + public static final EventCompensateOrder INSTANCE = new EventCompensateOrder(); + + private EventCompensateOrder() { + super(new ElementId(ELEMENT_ID), BpmnElementType.BOUNDARY_EVENT, "Compensate order"); + } - public static final VariableName.Output BIKE_ID = new VariableName.Output("bikeId"); + @Override + public BpmnEventType getEventType() { + return BpmnEventType.COMPENSATION; + } + + @Override + public ServiceTaskOrderBike getAttachedTo() { + return ServiceTaskOrderBike.INSTANCE; + } + + @Override + public boolean isInterrupting() { + return true; + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public AssociatedCompensationHandler callActivityCancelBikeOrder() { + return new AssociatedCompensationHandler<>(CallActivityCancelBikeOrder.INSTANCE); + } + } } - } - /** - * Sequence flows between BPMN elements. - * Mainly useful for process-model tooling, tests, and AI-agent consumers reasoning about the process shape. - * Worker code typically does not need these. - */ - public static final class Flows { - public static final BpmnFlow FLOW_ACTIVATE_TO_LEASING_ACTIVE = new BpmnFlow("flow_activateToLeasingActive", null, "serviceTask_activateLeasing", "endEvent_leasingActive", null, false); + public static final class EventContractNotSigned extends AbstractFlowNode implements HasSuccessors, BoundaryEvent, EscalationEvent { + public static final String ELEMENT_ID = "event_contractNotSigned"; + + public static final EventContractNotSigned INSTANCE = new EventContractNotSigned(); + + private EventContractNotSigned() { + super(new ElementId(ELEMENT_ID), BpmnElementType.BOUNDARY_EVENT, "Contract not signed"); + } + + @Override + public BpmnEventType getEventType() { + return BpmnEventType.ESCALATION; + } + + @Override + public BpmnEscalationDefinition getEscalation() { + return Escalations.CONTRACT_NOT_SIGNED; + } + + @Override + public SubProcessConcludeContract getAttachedTo() { + return SubProcessConcludeContract.INSTANCE; + } - public static final BpmnFlow FLOW_ALTERNATIVE_FOUND = new BpmnFlow("flow_alternativeFound", "Yes", "gateway_alternativeFound", "gateway_bikeSourceJoin", null, true); + @Override + public boolean isInterrupting() { + return true; + } - public static final BpmnFlow FLOW_AWAIT_TO_DEADLINE = new BpmnFlow("flow_awaitToDeadline", null, "gateway_awaitSignature", "event_signatureDeadline", null, false); + @Override + public Next getNext() { + return new Next(); + } - public static final BpmnFlow FLOW_AWAIT_TO_SIGNED = new BpmnFlow("flow_awaitToSigned", null, "gateway_awaitSignature", "event_contractSigned", null, false); + public static final class Next { + public SequenceFlows gatewayRejectionJoin() { + return SequenceFlows.single(new ElementId("flow_notSignedToRejection"), GatewayRejectionJoin.INSTANCE); + } + } + } - public static final BpmnFlow FLOW_BIKE_SOURCE_TO_ORDER = new BpmnFlow("flow_bikeSourceToOrder", null, "gateway_bikeSourceJoin", "serviceTask_orderBike", null, false); + public static final class EventContractSigned extends AbstractFlowNode implements HasSuccessors, Event, HasMessage { + public static final String ELEMENT_ID = "event_contractSigned"; - public static final BpmnFlow FLOW_BIKE_UNAVAILABLE = new BpmnFlow("flow_bikeUnavailable", null, "event_bikeUnavailable", "userTask_clarifyAlternative", null, false); + public static final EventContractSigned INSTANCE = new EventContractSigned(); - public static final BpmnFlow FLOW_CLARIFY_TO_ALTERNATIVE_GATEWAY = new BpmnFlow("flow_clarifyToAlternativeGateway", null, "userTask_clarifyAlternative", "gateway_alternativeFound", null, false); + private EventContractSigned() { + super(new ElementId(ELEMENT_ID), BpmnElementType.INTERMEDIATE_CATCH_EVENT, "Contract signed"); + } - public static final BpmnFlow FLOW_CONFIRMATION_TO_CANCELLED = new BpmnFlow("flow_confirmationToCancelled", null, "serviceTask_sendCancellationConfirmation", "endEvent_applicationCancelled", null, false); + @Override + public BpmnEventType getEventType() { + return BpmnEventType.MESSAGE; + } - public static final BpmnFlow FLOW_CONFIRMATION_TO_CONTRACT_CANCELLED = new BpmnFlow("flow_confirmationToContractCancelled", null, "serviceTask_confirmContractCancellation", "endEvent_contractCancelled", null, false); + @Override + public MessageName getMessage() { + return Messages.MIRAVELO_CONTRACT_SIGNED; + } - public static final BpmnFlow FLOW_CONTRACT_CONCLUDED_TO_FORK = new BpmnFlow("flow_contractConcludedToFork", null, "subProcess_concludeContract", "gateway_fork", null, false); + @Override + public Next getNext() { + return new Next(); + } - public static final BpmnFlow FLOW_CONTRACT_SENT_TO_AWAIT = new BpmnFlow("flow_contractSentToAwait", null, "serviceTask_sendContract", "gateway_awaitSignature", null, false); + public static final class Next { + public SequenceFlows endEventContractValid() { + return SequenceFlows.single(new ElementId("flow_signedToContractValid"), EndEventContractValid.INSTANCE); + } + } + } - public static final BpmnFlow FLOW_CREDIT_CHECK_TO_SOLVENCY = new BpmnFlow("flow_creditCheckToSolvency", null, "businessRuleTask_checkCreditRating", "gateway_isSolvent", null, false); + public static final class EventHandoverReported extends AbstractFlowNode implements HasSuccessors, Event, HasMessage { + public static final String ELEMENT_ID = "event_handoverReported"; - public static final BpmnFlow FLOW_DEADLINE_TO_NOT_SIGNED = new BpmnFlow("flow_deadlineToNotSigned", null, "event_signatureDeadline", "endEvent_notSigned", null, false); + public static final EventHandoverReported INSTANCE = new EventHandoverReported(); - public static final BpmnFlow FLOW_ELIGIBLE_TO_SEND_CONTRACT = new BpmnFlow("flow_eligibleToSendContract", null, "startEvent_customerEligible", "serviceTask_sendContract", null, false); + private EventHandoverReported() { + super(new ElementId(ELEMENT_ID), BpmnElementType.INTERMEDIATE_CATCH_EVENT, "Handover reported"); + } - public static final BpmnFlow FLOW_FORK_TO_BIKE_SOURCE = new BpmnFlow("flow_forkToBikeSource", null, "gateway_fork", "gateway_bikeSourceJoin", null, false); + @Override + public BpmnEventType getEventType() { + return BpmnEventType.MESSAGE; + } - public static final BpmnFlow FLOW_FORK_TO_INSURANCE = new BpmnFlow("flow_forkToInsurance", null, "gateway_fork", "serviceTask_issueInsurancePolicy", null, false); + @Override + public MessageName getMessage() { + return Messages.MIRAVELO_HANDOVER_REPORTED; + } - public static final BpmnFlow FLOW_HANDOVER_TO_WITHDRAWAL_PERIOD = new BpmnFlow("flow_handoverToWithdrawalPeriod", null, "event_handoverReported", "event_withdrawalPeriodElapsed", null, false); + @Override + public Next getNext() { + return new Next(); + } - public static final BpmnFlow FLOW_INSURANCE_TO_JOIN = new BpmnFlow("flow_insuranceToJoin", null, "serviceTask_issueInsurancePolicy", "gateway_join", null, false); + public static final class Next { + public SequenceFlows eventWithdrawalPeriodElapsed() { + return SequenceFlows.single(new ElementId("flow_handoverToWithdrawalPeriod"), EventWithdrawalPeriodElapsed.INSTANCE); + } + } + } - public static final BpmnFlow FLOW_JOIN_TO_HANDOVER = new BpmnFlow("flow_joinToHandover", null, "gateway_join", "event_handoverReported", null, false); + public static final class EventReverseApplication extends AbstractFlowNode implements HasSuccessors, Event, CompensationThrowEvent { + public static final String ELEMENT_ID = "event_reverseApplication"; - public static final BpmnFlow FLOW_MAIL_TO_PROSPECT_REMINDED = new BpmnFlow("flow_mailToProspectReminded", null, "serviceTask_sendReminderMail", "endEvent_prospectReminded", null, false); + public static final EventReverseApplication INSTANCE = new EventReverseApplication(); - public static final BpmnFlow FLOW_NO_ALTERNATIVE_FOUND = new BpmnFlow("flow_noAlternativeFound", "No", "gateway_alternativeFound", "event_triggerReversal", "${!alternativeFound}", false); + private EventReverseApplication() { + super(new ElementId(ELEMENT_ID), BpmnElementType.INTERMEDIATE_THROW_EVENT, "Reverse application"); + } - public static final BpmnFlow FLOW_NOT_SIGNED_TO_REJECTION = new BpmnFlow("flow_notSignedToRejection", null, "event_contractNotSigned", "gateway_rejectionJoin", null, false); + @Override + public BpmnEventType getEventType() { + return BpmnEventType.COMPENSATION; + } - public static final BpmnFlow FLOW_NOT_SOLVENT = new BpmnFlow("flow_notSolvent", "No", "gateway_isSolvent", "gateway_rejectionJoin", "${!solvent}", false); + @Override + public Next getNext() { + return new Next(); + } - public static final BpmnFlow FLOW_ORDERED_TO_JOIN = new BpmnFlow("flow_orderedToJoin", null, "serviceTask_orderBike", "gateway_join", null, false); + public static final class Next { + public SequenceFlows serviceTaskSendCancellationConfirmation() { + return SequenceFlows.single(new ElementId("flow_reversalToConfirmation"), ServiceTaskSendCancellationConfirmation.INSTANCE); + } + } + } - public static final BpmnFlow FLOW_REJECTION_JOINED = new BpmnFlow("flow_rejectionJoined", null, "gateway_rejectionJoin", "serviceTask_sendRejection", null, false); + public static final class EventSignatureDeadline extends AbstractFlowNode implements HasSuccessors, Event, TimerEvent { + public static final String ELEMENT_ID = "event_signatureDeadline"; - public static final BpmnFlow FLOW_REJECTION_SENT = new BpmnFlow("flow_rejectionSent", null, "serviceTask_sendRejection", "endEvent_applicationRejected", null, false); + public static final EventSignatureDeadline INSTANCE = new EventSignatureDeadline(); - public static final BpmnFlow FLOW_REMINDER_TO_MAIL = new BpmnFlow("flow_reminderToMail", null, "event_signatureReminder", "serviceTask_sendReminderMail", null, false); + private EventSignatureDeadline() { + super(new ElementId(ELEMENT_ID), BpmnElementType.INTERMEDIATE_CATCH_EVENT, "14 days"); + } - public static final BpmnFlow FLOW_REQUEST_TO_CREDIT_CHECK = new BpmnFlow("flow_requestToCreditCheck", null, "startEvent_leasingRequestReceived", "businessRuleTask_checkCreditRating", null, false); + @Override + public BpmnEventType getEventType() { + return BpmnEventType.TIMER; + } - public static final BpmnFlow FLOW_REVERSAL_TO_CONFIRMATION = new BpmnFlow("flow_reversalToConfirmation", null, "event_reverseApplication", "serviceTask_sendCancellationConfirmation", null, false); + @Override + public BpmnTimer getTimer() { + return new BpmnTimer(TimerType.DURATION, "P14D"); + } - public static final BpmnFlow FLOW_SIGNED_TO_CONTRACT_VALID = new BpmnFlow("flow_signedToContractValid", null, "event_contractSigned", "endEvent_contractValid", null, false); + @Override + public Next getNext() { + return new Next(); + } - public static final BpmnFlow FLOW_SOLVENT = new BpmnFlow("flow_solvent", null, "gateway_isSolvent", "subProcess_concludeContract", null, true); + public static final class Next { + public SequenceFlows endEventNotSigned() { + return SequenceFlows.single(new ElementId("flow_deadlineToNotSigned"), EndEventNotSigned.INSTANCE); + } + } + } - public static final BpmnFlow FLOW_TRIGGER_REVERSAL_TO_CONFIRMATION = new BpmnFlow("flow_triggerReversalToConfirmation", null, "event_triggerReversal", "serviceTask_confirmContractCancellation", null, false); + public static final class EventSignatureReminder extends AbstractFlowNode implements HasSuccessors, BoundaryEvent, TimerEvent { + public static final String ELEMENT_ID = "event_signatureReminder"; - public static final BpmnFlow FLOW_WITHDRAWAL_ELAPSED_TO_ACTIVE = new BpmnFlow("flow_withdrawalElapsedToActive", null, "event_withdrawalPeriodElapsed", "serviceTask_activateLeasing", null, false); + public static final EventSignatureReminder INSTANCE = new EventSignatureReminder(); - public static final BpmnFlow FLOW_WITHDRAWAL_TO_REVERSAL = new BpmnFlow("flow_withdrawalToReversal", null, "startEvent_applicationWithdrawn", "event_reverseApplication", null, false); - } + private EventSignatureReminder() { + super(new ElementId(ELEMENT_ID), BpmnElementType.BOUNDARY_EVENT, "7 days"); + } - /** - * Per-element graph metadata (elementType / previousElements / followingElements / parentId / boundary attachments). - * Intended for tooling and tests, not worker runtime code. - */ - public static final class Relations { - public static final BpmnRelations BUSINESS_RULE_TASK_CHECK_CREDIT_RATING = new BpmnRelations("Check credit rating", List.of("startEvent_leasingRequestReceived"), List.of("gateway_isSolvent"), null, null, List.of(), "BUSINESS_RULE_TASK"); + @Override + public BpmnEventType getEventType() { + return BpmnEventType.TIMER; + } + + @Override + public BpmnTimer getTimer() { + return new BpmnTimer(TimerType.DURATION, "P7D"); + } + + @Override + public SubProcessConcludeContract getAttachedTo() { + return SubProcessConcludeContract.INSTANCE; + } + + @Override + public boolean isInterrupting() { + return false; + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows serviceTaskSendReminderMail() { + return SequenceFlows.single(new ElementId("flow_reminderToMail"), ServiceTaskSendReminderMail.INSTANCE); + } + } + } + + public static final class EventTriggerReversal extends AbstractFlowNode implements HasSuccessors, Event, CompensationThrowEvent { + public static final String ELEMENT_ID = "event_triggerReversal"; + + public static final EventTriggerReversal INSTANCE = new EventTriggerReversal(); + + private EventTriggerReversal() { + super(new ElementId(ELEMENT_ID), BpmnElementType.INTERMEDIATE_THROW_EVENT, "Trigger reversal"); + } + + @Override + public BpmnEventType getEventType() { + return BpmnEventType.COMPENSATION; + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows serviceTaskConfirmContractCancellation() { + return SequenceFlows.single(new ElementId("flow_triggerReversalToConfirmation"), ServiceTaskConfirmContractCancellation.INSTANCE); + } + } + } + + public static final class EventWithdrawalPeriodElapsed extends AbstractFlowNode implements HasSuccessors, Event, TimerEvent { + public static final String ELEMENT_ID = "event_withdrawalPeriodElapsed"; + + public static final EventWithdrawalPeriodElapsed INSTANCE = new EventWithdrawalPeriodElapsed(); + + private EventWithdrawalPeriodElapsed() { + super(new ElementId(ELEMENT_ID), BpmnElementType.INTERMEDIATE_CATCH_EVENT, "Await end of withdrawal period"); + } + + @Override + public BpmnEventType getEventType() { + return BpmnEventType.TIMER; + } + + @Override + public BpmnTimer getTimer() { + return new BpmnTimer(TimerType.DURATION, "P14D"); + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows serviceTaskActivateLeasing() { + return SequenceFlows.single(new ElementId("flow_withdrawalElapsedToActive"), ServiceTaskActivateLeasing.INSTANCE); + } + } + } + + public static final class GatewayAlternativeFound extends AbstractFlowNode implements HasSuccessors { + public static final String ELEMENT_ID = "gateway_alternativeFound"; + + public static final GatewayAlternativeFound INSTANCE = new GatewayAlternativeFound(); + + private GatewayAlternativeFound() { + super(new ElementId(ELEMENT_ID), BpmnElementType.EXCLUSIVE_GATEWAY, "Alternative found?"); + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows eventTriggerReversal() { + return SequenceFlows.single(new ElementId("flow_noAlternativeFound"), "No", "${!alternativeFound}", false, EventTriggerReversal.INSTANCE); + } + + public SequenceFlows gatewayBikeSourceJoin() { + return SequenceFlows.single(new ElementId("flow_alternativeFound"), "Yes", null, true, GatewayBikeSourceJoin.INSTANCE); + } + } + } + + public static final class GatewayAwaitSignature extends AbstractFlowNode implements HasSuccessors { + public static final String ELEMENT_ID = "gateway_awaitSignature"; + + public static final GatewayAwaitSignature INSTANCE = new GatewayAwaitSignature(); + + private GatewayAwaitSignature() { + super(new ElementId(ELEMENT_ID), BpmnElementType.EVENT_BASED_GATEWAY); + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows eventContractSigned() { + return SequenceFlows.single(new ElementId("flow_awaitToSigned"), EventContractSigned.INSTANCE); + } + + public SequenceFlows eventSignatureDeadline() { + return SequenceFlows.single(new ElementId("flow_awaitToDeadline"), EventSignatureDeadline.INSTANCE); + } + } + } + + public static final class GatewayBikeSourceJoin extends AbstractFlowNode implements HasSuccessors { + public static final String ELEMENT_ID = "gateway_bikeSourceJoin"; + + public static final GatewayBikeSourceJoin INSTANCE = new GatewayBikeSourceJoin(); + + private GatewayBikeSourceJoin() { + super(new ElementId(ELEMENT_ID), BpmnElementType.EXCLUSIVE_GATEWAY); + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows serviceTaskOrderBike() { + return SequenceFlows.single(new ElementId("flow_bikeSourceToOrder"), ServiceTaskOrderBike.INSTANCE); + } + } + } + + public static final class GatewayFork extends AbstractFlowNode implements HasSuccessors { + public static final String ELEMENT_ID = "gateway_fork"; + + public static final GatewayFork INSTANCE = new GatewayFork(); + + private GatewayFork() { + super(new ElementId(ELEMENT_ID), BpmnElementType.PARALLEL_GATEWAY); + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows gatewayBikeSourceJoin() { + return SequenceFlows.single(new ElementId("flow_forkToBikeSource"), GatewayBikeSourceJoin.INSTANCE); + } + + public SequenceFlows serviceTaskIssueInsurancePolicy() { + return SequenceFlows.single(new ElementId("flow_forkToInsurance"), ServiceTaskIssueInsurancePolicy.INSTANCE); + } + } + } + + public static final class GatewayIsSolvent extends AbstractFlowNode implements HasSuccessors { + public static final String ELEMENT_ID = "gateway_isSolvent"; + + public static final GatewayIsSolvent INSTANCE = new GatewayIsSolvent(); + + private GatewayIsSolvent() { + super(new ElementId(ELEMENT_ID), BpmnElementType.EXCLUSIVE_GATEWAY, "Solvent?"); + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows gatewayRejectionJoin() { + return SequenceFlows.single(new ElementId("flow_notSolvent"), "No", "${!solvent}", false, GatewayRejectionJoin.INSTANCE); + } + + public SequenceFlows subProcessConcludeContract() { + return SequenceFlows.single(new ElementId("flow_solvent"), null, null, true, SubProcessConcludeContract.INSTANCE); + } + } + } + + public static final class GatewayJoin extends AbstractFlowNode implements HasSuccessors { + public static final String ELEMENT_ID = "gateway_join"; + + public static final GatewayJoin INSTANCE = new GatewayJoin(); + + private GatewayJoin() { + super(new ElementId(ELEMENT_ID), BpmnElementType.PARALLEL_GATEWAY); + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows eventHandoverReported() { + return SequenceFlows.single(new ElementId("flow_joinToHandover"), EventHandoverReported.INSTANCE); + } + } + } + + public static final class GatewayRejectionJoin extends AbstractFlowNode implements HasSuccessors { + public static final String ELEMENT_ID = "gateway_rejectionJoin"; + + public static final GatewayRejectionJoin INSTANCE = new GatewayRejectionJoin(); + + private GatewayRejectionJoin() { + super(new ElementId(ELEMENT_ID), BpmnElementType.EXCLUSIVE_GATEWAY, "Rejection reason"); + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows serviceTaskSendRejection() { + return SequenceFlows.single(new ElementId("flow_rejectionJoined"), ServiceTaskSendRejection.INSTANCE); + } + } + } + + public static final class ServiceTaskActivateLeasing extends AbstractFlowNode implements HasSuccessors, HasJobType { + public static final String ELEMENT_ID = "serviceTask_activateLeasing"; + + public static final ServiceTaskActivateLeasing INSTANCE = new ServiceTaskActivateLeasing(); + + private ServiceTaskActivateLeasing() { + super(new ElementId(ELEMENT_ID), BpmnElementType.SERVICE_TASK, "Activate leasing"); + } + + @Override + public String getJobType() { + return ServiceTasks.ACTIVATE_LEASING; + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows endEventLeasingActive() { + return SequenceFlows.single(new ElementId("flow_activateToLeasingActive"), EndEventLeasingActive.INSTANCE); + } + } + } + + public static final class ServiceTaskCancelContract extends AbstractFlowNode implements HasJobType { + public static final String ELEMENT_ID = "serviceTask_cancelContract"; + + public static final ServiceTaskCancelContract INSTANCE = new ServiceTaskCancelContract(); + + private ServiceTaskCancelContract() { + super(new ElementId(ELEMENT_ID), BpmnElementType.SERVICE_TASK, "Cancel contract"); + } + + @Override + public String getJobType() { + return ServiceTasks.CANCEL_CONTRACT; + } + } + + public static final class ServiceTaskCancelPolicy extends AbstractFlowNode implements HasJobType { + public static final String ELEMENT_ID = "serviceTask_cancelPolicy"; + + public static final ServiceTaskCancelPolicy INSTANCE = new ServiceTaskCancelPolicy(); + + private ServiceTaskCancelPolicy() { + super(new ElementId(ELEMENT_ID), BpmnElementType.SERVICE_TASK, "Cancel policy"); + } + + @Override + public String getJobType() { + return ServiceTasks.CANCEL_POLICY; + } + } + + public static final class ServiceTaskConfirmContractCancellation extends AbstractFlowNode implements HasSuccessors, HasJobType { + public static final String ELEMENT_ID = "serviceTask_confirmContractCancellation"; + + public static final ServiceTaskConfirmContractCancellation INSTANCE = new ServiceTaskConfirmContractCancellation(); + + private ServiceTaskConfirmContractCancellation() { + super(new ElementId(ELEMENT_ID), BpmnElementType.SERVICE_TASK, "Send cancellation confirmation"); + } + + @Override + public String getJobType() { + return ServiceTasks.SEND_CANCELLATION_CONFIRMATION; + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows endEventContractCancelled() { + return SequenceFlows.single(new ElementId("flow_confirmationToContractCancelled"), EndEventContractCancelled.INSTANCE); + } + } + } + + public static final class ServiceTaskIssueInsurancePolicy extends AbstractFlowNode implements HasSuccessors, HasJobType { + public static final String ELEMENT_ID = "serviceTask_issueInsurancePolicy"; + + public static final ServiceTaskIssueInsurancePolicy INSTANCE = new ServiceTaskIssueInsurancePolicy(); + + private ServiceTaskIssueInsurancePolicy() { + super(new ElementId(ELEMENT_ID), BpmnElementType.SERVICE_TASK, "Issue insurance policy"); + } + + @Override + public String getJobType() { + return ServiceTasks.ISSUE_INSURANCE_POLICY; + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public AttachedBoundaryEvent eventCompensateInsurance() { + return new AttachedBoundaryEvent<>(EventCompensateInsurance.INSTANCE); + } + + public SequenceFlows gatewayJoin() { + return SequenceFlows.single(new ElementId("flow_insuranceToJoin"), GatewayJoin.INSTANCE); + } + } + } + + public static final class ServiceTaskOrderBike extends AbstractFlowNode implements HasSuccessors, HasJobType, HasVariables { + public static final String ELEMENT_ID = "serviceTask_orderBike"; + + public static final ServiceTaskOrderBike INSTANCE = new ServiceTaskOrderBike(); + + private static final Variables VARIABLES = new Variables(); + + private ServiceTaskOrderBike() { + super(new ElementId(ELEMENT_ID), BpmnElementType.SERVICE_TASK, "Order bike from dealer"); + } + + @Override + public String getJobType() { + return ServiceTasks.ORDER_BIKE; + } + + @Override + public Variables getVariables() { + return VARIABLES; + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Variables extends VariableDefinitions { + public static final VariableName.Input BIKE_ID = new VariableName.Input(ProcessVariables.BIKE_ID); + + public static final VariableName.Output ORDER_ID = new VariableName.Output(ProcessVariables.ORDER_ID); + + private Variables() { + } + + @Override + public List getAll() { + return List.of(BIKE_ID, ORDER_ID); + } + } + + public static final class Next { + public AttachedBoundaryEvent eventBikeUnavailable() { + return new AttachedBoundaryEvent<>(EventBikeUnavailable.INSTANCE); + } + + public AttachedBoundaryEvent eventCompensateOrder() { + return new AttachedBoundaryEvent<>(EventCompensateOrder.INSTANCE); + } + + public SequenceFlows gatewayJoin() { + return SequenceFlows.single(new ElementId("flow_orderedToJoin"), GatewayJoin.INSTANCE); + } + } + } + + public static final class ServiceTaskSendCancellationConfirmation extends AbstractFlowNode implements HasSuccessors, HasJobType { + public static final String ELEMENT_ID = "serviceTask_sendCancellationConfirmation"; + + public static final ServiceTaskSendCancellationConfirmation INSTANCE = new ServiceTaskSendCancellationConfirmation(); + + private ServiceTaskSendCancellationConfirmation() { + super(new ElementId(ELEMENT_ID), BpmnElementType.SERVICE_TASK, "Send cancellation confirmation"); + } + + @Override + public String getJobType() { + return ServiceTasks.SEND_CANCELLATION_CONFIRMATION; + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows endEventApplicationCancelled() { + return SequenceFlows.single(new ElementId("flow_confirmationToCancelled"), EndEventApplicationCancelled.INSTANCE); + } + } + } + + public static final class ServiceTaskSendContract extends AbstractFlowNode implements HasSuccessors, HasJobType { + public static final String ELEMENT_ID = "serviceTask_sendContract"; + + public static final ServiceTaskSendContract INSTANCE = new ServiceTaskSendContract(); + + private ServiceTaskSendContract() { + super(new ElementId(ELEMENT_ID), BpmnElementType.SERVICE_TASK, "Send contract"); + } + + @Override + public String getJobType() { + return ServiceTasks.SEND_CONTRACT; + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows gatewayAwaitSignature() { + return SequenceFlows.single(new ElementId("flow_contractSentToAwait"), GatewayAwaitSignature.INSTANCE); + } + } + } + + public static final class ServiceTaskSendRejection extends AbstractFlowNode implements HasSuccessors, HasJobType { + public static final String ELEMENT_ID = "serviceTask_sendRejection"; + + public static final ServiceTaskSendRejection INSTANCE = new ServiceTaskSendRejection(); + + private ServiceTaskSendRejection() { + super(new ElementId(ELEMENT_ID), BpmnElementType.SERVICE_TASK, "Send rejection"); + } + + @Override + public String getJobType() { + return ServiceTasks.SEND_REJECTION; + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows endEventApplicationRejected() { + return SequenceFlows.single(new ElementId("flow_rejectionSent"), EndEventApplicationRejected.INSTANCE); + } + } + } - public static final BpmnRelations CALL_ACTIVITY_CANCEL_BIKE_ORDER = new BpmnRelations("Cancel bike order", List.of(), List.of(), null, null, List.of(), "CALL_ACTIVITY"); + public static final class ServiceTaskSendReminderMail extends AbstractFlowNode implements HasSuccessors, HasJobType { + public static final String ELEMENT_ID = "serviceTask_sendReminderMail"; - public static final BpmnRelations END_EVENT_APPLICATION_CANCELLED = new BpmnRelations("Leasing cancelled", List.of("serviceTask_sendCancellationConfirmation"), List.of(), "subProcess_applicationWithdrawn", null, List.of(), "END_EVENT"); + public static final ServiceTaskSendReminderMail INSTANCE = new ServiceTaskSendReminderMail(); - public static final BpmnRelations END_EVENT_APPLICATION_REJECTED = new BpmnRelations("Application rejected", List.of("serviceTask_sendRejection"), List.of(), null, null, List.of(), "END_EVENT"); + private ServiceTaskSendReminderMail() { + super(new ElementId(ELEMENT_ID), BpmnElementType.SERVICE_TASK, "Send reminder mail"); + } - public static final BpmnRelations END_EVENT_CONTRACT_CANCELLED = new BpmnRelations("Contract cancelled", List.of("serviceTask_confirmContractCancellation"), List.of(), null, null, List.of(), "END_EVENT"); + @Override + public String getJobType() { + return ServiceTasks.SEND_REMINDER_MAIL; + } - public static final BpmnRelations END_EVENT_CONTRACT_VALID = new BpmnRelations("Contract valid", List.of("event_contractSigned"), List.of(), "subProcess_concludeContract", null, List.of(), "END_EVENT"); + @Override + public Next getNext() { + return new Next(); + } - public static final BpmnRelations END_EVENT_LEASING_ACTIVE = new BpmnRelations("Leasing active", List.of("serviceTask_activateLeasing"), List.of(), null, null, List.of(), "END_EVENT"); + public static final class Next { + public SequenceFlows endEventProspectReminded() { + return SequenceFlows.single(new ElementId("flow_mailToProspectReminded"), EndEventProspectReminded.INSTANCE); + } + } + } - public static final BpmnRelations END_EVENT_NOT_SIGNED = new BpmnRelations("Not signed", List.of("event_signatureDeadline"), List.of(), "subProcess_concludeContract", null, List.of(), "ESCALATION_END_EVENT"); + public static final class StartEventApplicationWithdrawn extends AbstractFlowNode implements HasSuccessors, Event, HasMessage { + public static final String ELEMENT_ID = "startEvent_applicationWithdrawn"; - public static final BpmnRelations END_EVENT_PROSPECT_REMINDED = new BpmnRelations("Prospect reminded", List.of("serviceTask_sendReminderMail"), List.of(), null, null, List.of(), "END_EVENT"); + public static final StartEventApplicationWithdrawn INSTANCE = new StartEventApplicationWithdrawn(); - public static final BpmnRelations EVENT_BIKE_UNAVAILABLE = new BpmnRelations("Bike unavailable", List.of(), List.of("userTask_clarifyAlternative"), null, "serviceTask_orderBike", List.of(), "ERROR_BOUNDARY_EVENT"); + private StartEventApplicationWithdrawn() { + super(new ElementId(ELEMENT_ID), BpmnElementType.START_EVENT, "Request withdrawn"); + } - public static final BpmnRelations EVENT_COMPENSATE_CONTRACT = new BpmnRelations("Compensate contract", List.of(), List.of(), null, "subProcess_concludeContract", List.of(), "COMPENSATION_BOUNDARY_EVENT"); + @Override + public BpmnEventType getEventType() { + return BpmnEventType.MESSAGE; + } - public static final BpmnRelations EVENT_COMPENSATE_INSURANCE = new BpmnRelations("Compensate policy", List.of(), List.of(), null, "serviceTask_issueInsurancePolicy", List.of(), "COMPENSATION_BOUNDARY_EVENT"); + @Override + public MessageName getMessage() { + return Messages.MIRAVELO_APPLICATION_WITHDRAWN; + } - public static final BpmnRelations EVENT_COMPENSATE_ORDER = new BpmnRelations("Compensate order", List.of(), List.of(), null, "serviceTask_orderBike", List.of(), "COMPENSATION_BOUNDARY_EVENT"); + public boolean isInterrupting() { + return true; + } - public static final BpmnRelations EVENT_CONTRACT_NOT_SIGNED = new BpmnRelations("Contract not signed", List.of(), List.of("gateway_rejectionJoin"), null, "subProcess_concludeContract", List.of(), "ESCALATION_BOUNDARY_EVENT"); + @Override + public Next getNext() { + return new Next(); + } - public static final BpmnRelations EVENT_CONTRACT_SIGNED = new BpmnRelations("Contract signed", List.of("gateway_awaitSignature"), List.of("endEvent_contractValid"), "subProcess_concludeContract", null, List.of(), "MESSAGE_INTERMEDIATE_CATCH_EVENT"); + public static final class Next { + public SequenceFlows eventReverseApplication() { + return SequenceFlows.single(new ElementId("flow_withdrawalToReversal"), EventReverseApplication.INSTANCE); + } + } + } - public static final BpmnRelations EVENT_HANDOVER_REPORTED = new BpmnRelations("Handover reported", List.of("gateway_join"), List.of("event_withdrawalPeriodElapsed"), null, null, List.of(), "MESSAGE_INTERMEDIATE_CATCH_EVENT"); + public static final class StartEventCustomerEligible extends AbstractFlowNode implements HasSuccessors, Event { + public static final String ELEMENT_ID = "startEvent_customerEligible"; - public static final BpmnRelations EVENT_REVERSE_APPLICATION = new BpmnRelations("Reverse application", List.of("startEvent_applicationWithdrawn"), List.of("serviceTask_sendCancellationConfirmation"), "subProcess_applicationWithdrawn", null, List.of(), "COMPENSATION_INTERMEDIATE_THROW_EVENT"); + public static final StartEventCustomerEligible INSTANCE = new StartEventCustomerEligible(); - public static final BpmnRelations EVENT_SIGNATURE_DEADLINE = new BpmnRelations("14 days", List.of("gateway_awaitSignature"), List.of("endEvent_notSigned"), "subProcess_concludeContract", null, List.of(), "TIMER_INTERMEDIATE_CATCH_EVENT"); + private StartEventCustomerEligible() { + super(new ElementId(ELEMENT_ID), BpmnElementType.START_EVENT, "Customer eligible"); + } - public static final BpmnRelations EVENT_SIGNATURE_REMINDER = new BpmnRelations("7 days", List.of(), List.of("serviceTask_sendReminderMail"), null, "subProcess_concludeContract", List.of(), "TIMER_BOUNDARY_EVENT"); + @Override + public BpmnEventType getEventType() { + return BpmnEventType.NONE; + } - public static final BpmnRelations EVENT_TRIGGER_REVERSAL = new BpmnRelations("Trigger reversal", List.of("gateway_alternativeFound"), List.of("serviceTask_confirmContractCancellation"), null, null, List.of(), "COMPENSATION_INTERMEDIATE_THROW_EVENT"); + @Override + public Next getNext() { + return new Next(); + } - public static final BpmnRelations EVENT_WITHDRAWAL_PERIOD_ELAPSED = new BpmnRelations("Await end of withdrawal period", List.of("event_handoverReported"), List.of("serviceTask_activateLeasing"), null, null, List.of(), "TIMER_INTERMEDIATE_CATCH_EVENT"); + public static final class Next { + public SequenceFlows serviceTaskSendContract() { + return SequenceFlows.single(new ElementId("flow_eligibleToSendContract"), ServiceTaskSendContract.INSTANCE); + } + } + } - public static final BpmnRelations GATEWAY_ALTERNATIVE_FOUND = new BpmnRelations("Alternative found?", List.of("userTask_clarifyAlternative"), List.of("gateway_bikeSourceJoin", "event_triggerReversal"), null, null, List.of(), "EXCLUSIVE_GATEWAY"); + public static final class StartEventLeasingRequestReceived extends AbstractFlowNode implements HasSuccessors, Event, HasMessage, HasVariables { + public static final String ELEMENT_ID = "startEvent_leasingRequestReceived"; - public static final BpmnRelations GATEWAY_AWAIT_SIGNATURE = new BpmnRelations(null, List.of("serviceTask_sendContract"), List.of("event_contractSigned", "event_signatureDeadline"), "subProcess_concludeContract", null, List.of(), "EVENT_BASED_GATEWAY"); + public static final StartEventLeasingRequestReceived INSTANCE = new StartEventLeasingRequestReceived(); - public static final BpmnRelations GATEWAY_BIKE_SOURCE_JOIN = new BpmnRelations(null, List.of("gateway_fork", "gateway_alternativeFound"), List.of("serviceTask_orderBike"), null, null, List.of(), "EXCLUSIVE_GATEWAY"); + private static final Variables VARIABLES = new Variables(); - public static final BpmnRelations GATEWAY_FORK = new BpmnRelations(null, List.of("subProcess_concludeContract"), List.of("gateway_bikeSourceJoin", "serviceTask_issueInsurancePolicy"), null, null, List.of(), "PARALLEL_GATEWAY"); + private StartEventLeasingRequestReceived() { + super(new ElementId(ELEMENT_ID), BpmnElementType.START_EVENT, "Leasing request received"); + } - public static final BpmnRelations GATEWAY_IS_SOLVENT = new BpmnRelations("Solvent?", List.of("businessRuleTask_checkCreditRating"), List.of("subProcess_concludeContract", "gateway_rejectionJoin"), null, null, List.of(), "EXCLUSIVE_GATEWAY"); + @Override + public BpmnEventType getEventType() { + return BpmnEventType.MESSAGE; + } - public static final BpmnRelations GATEWAY_JOIN = new BpmnRelations(null, List.of("serviceTask_issueInsurancePolicy", "serviceTask_orderBike"), List.of("event_handoverReported"), null, null, List.of(), "PARALLEL_GATEWAY"); + @Override + public MessageName getMessage() { + return Messages.MIRAVELO_LEASING_REQUEST_RECEIVED; + } - public static final BpmnRelations GATEWAY_REJECTION_JOIN = new BpmnRelations("Rejection reason", List.of("gateway_isSolvent", "event_contractNotSigned"), List.of("serviceTask_sendRejection"), null, null, List.of(), "EXCLUSIVE_GATEWAY"); + @Override + public Variables getVariables() { + return VARIABLES; + } - public static final BpmnRelations SERVICE_TASK_ACTIVATE_LEASING = new BpmnRelations("Activate leasing", List.of("event_withdrawalPeriodElapsed"), List.of("endEvent_leasingActive"), null, null, List.of(), "SERVICE_TASK"); + @Override + public Next getNext() { + return new Next(); + } - public static final BpmnRelations SERVICE_TASK_CANCEL_CONTRACT = new BpmnRelations("Cancel contract", List.of(), List.of(), null, null, List.of(), "SERVICE_TASK"); + public static final class Variables extends VariableDefinitions { + public static final VariableName.Input AGE = new VariableName.Input(ProcessVariables.AGE); - public static final BpmnRelations SERVICE_TASK_CANCEL_POLICY = new BpmnRelations("Cancel policy", List.of(), List.of(), null, null, List.of(), "SERVICE_TASK"); + public static final VariableName.Input APPLICATION_ID = new VariableName.Input(ProcessVariables.APPLICATION_ID); - public static final BpmnRelations SERVICE_TASK_CONFIRM_CONTRACT_CANCELLATION = new BpmnRelations("Send cancellation confirmation", List.of("event_triggerReversal"), List.of("endEvent_contractCancelled"), null, null, List.of(), "SERVICE_TASK"); + public static final VariableName.Input BIKE_ID = new VariableName.Input(ProcessVariables.BIKE_ID); - public static final BpmnRelations SERVICE_TASK_ISSUE_INSURANCE_POLICY = new BpmnRelations("Issue insurance policy", List.of("gateway_fork"), List.of("gateway_join"), null, null, List.of("event_compensateInsurance"), "SERVICE_TASK"); + public static final VariableName.Input MONTHLY_NET_INCOME = new VariableName.Input(ProcessVariables.MONTHLY_NET_INCOME); - public static final BpmnRelations SERVICE_TASK_ORDER_BIKE = new BpmnRelations("Order bike from dealer", List.of("gateway_bikeSourceJoin"), List.of("gateway_join"), null, null, List.of("event_bikeUnavailable", "event_compensateOrder"), "SERVICE_TASK"); + private Variables() { + } - public static final BpmnRelations SERVICE_TASK_SEND_CANCELLATION_CONFIRMATION = new BpmnRelations("Send cancellation confirmation", List.of("event_reverseApplication"), List.of("endEvent_applicationCancelled"), "subProcess_applicationWithdrawn", null, List.of(), "SERVICE_TASK"); + @Override + public List getAll() { + return List.of(AGE, APPLICATION_ID, BIKE_ID, MONTHLY_NET_INCOME); + } + } - public static final BpmnRelations SERVICE_TASK_SEND_CONTRACT = new BpmnRelations("Send contract", List.of("startEvent_customerEligible"), List.of("gateway_awaitSignature"), "subProcess_concludeContract", null, List.of(), "SERVICE_TASK"); + public static final class Next { + public SequenceFlows businessRuleTaskCheckCreditRating() { + return SequenceFlows.single(new ElementId("flow_requestToCreditCheck"), BusinessRuleTaskCheckCreditRating.INSTANCE); + } + } + } - public static final BpmnRelations SERVICE_TASK_SEND_REJECTION = new BpmnRelations("Send rejection", List.of("gateway_rejectionJoin"), List.of("endEvent_applicationRejected"), null, null, List.of(), "SERVICE_TASK"); + public static final class SubProcessApplicationWithdrawn extends AbstractFlowNode implements FlowScope { + public static final String ELEMENT_ID = "subProcess_applicationWithdrawn"; - public static final BpmnRelations SERVICE_TASK_SEND_REMINDER_MAIL = new BpmnRelations("Send reminder mail", List.of("event_signatureReminder"), List.of("endEvent_prospectReminded"), null, null, List.of(), "SERVICE_TASK"); + public static final SubProcessApplicationWithdrawn INSTANCE = new SubProcessApplicationWithdrawn(); - public static final BpmnRelations START_EVENT_APPLICATION_WITHDRAWN = new BpmnRelations("Request withdrawn", List.of(), List.of("event_reverseApplication"), "subProcess_applicationWithdrawn", null, List.of(), "MESSAGE_START_EVENT"); + private SubProcessApplicationWithdrawn() { + super(new ElementId(ELEMENT_ID), BpmnElementType.EVENT_SUB_PROCESS, "Application withdrawn"); + } - public static final BpmnRelations START_EVENT_CUSTOMER_ELIGIBLE = new BpmnRelations("Customer eligible", List.of(), List.of("serviceTask_sendContract"), "subProcess_concludeContract", null, List.of(), "START_EVENT"); + @Override + public Start getStartEvents() { + return new Start(); + } - public static final BpmnRelations START_EVENT_LEASING_REQUEST_RECEIVED = new BpmnRelations("Leasing request received", List.of(), List.of("businessRuleTask_checkCreditRating"), null, null, List.of(), "MESSAGE_START_EVENT"); + public static final class Start { + public StartEventApplicationWithdrawn startEventApplicationWithdrawn() { + return StartEventApplicationWithdrawn.INSTANCE; + } + } + } - public static final BpmnRelations SUB_PROCESS_APPLICATION_WITHDRAWN = new BpmnRelations("Application withdrawn", List.of(), List.of(), null, null, List.of(), "EVENT_SUB_PROCESS"); + public static final class SubProcessConcludeContract extends AbstractFlowNode implements HasSuccessors, FlowScope { + public static final String ELEMENT_ID = "subProcess_concludeContract"; - public static final BpmnRelations SUB_PROCESS_CONCLUDE_CONTRACT = new BpmnRelations("Conclude contract", List.of("gateway_isSolvent"), List.of("gateway_fork"), null, null, List.of("event_compensateContract", "event_contractNotSigned", "event_signatureReminder"), "SUB_PROCESS"); + public static final SubProcessConcludeContract INSTANCE = new SubProcessConcludeContract(); - public static final BpmnRelations USER_TASK_CLARIFY_ALTERNATIVE = new BpmnRelations("Clarify alternative with customer", List.of("event_bikeUnavailable"), List.of("gateway_alternativeFound"), null, null, List.of(), "USER_TASK"); + private SubProcessConcludeContract() { + super(new ElementId(ELEMENT_ID), BpmnElementType.SUB_PROCESS, "Conclude contract"); + } + + @Override + public Next getNext() { + return new Next(); + } + + @Override + public Start getStartEvents() { + return new Start(); + } + + public static final class Next { + public AttachedBoundaryEvent eventCompensateContract() { + return new AttachedBoundaryEvent<>(EventCompensateContract.INSTANCE); + } + + public AttachedBoundaryEvent eventContractNotSigned() { + return new AttachedBoundaryEvent<>(EventContractNotSigned.INSTANCE); + } + + public AttachedBoundaryEvent eventSignatureReminder() { + return new AttachedBoundaryEvent<>(EventSignatureReminder.INSTANCE); + } + + public SequenceFlows gatewayFork() { + return SequenceFlows.single(new ElementId("flow_contractConcludedToFork"), GatewayFork.INSTANCE); + } + } + + public static final class Start { + public StartEventCustomerEligible startEventCustomerEligible() { + return StartEventCustomerEligible.INSTANCE; + } + } + } + + public static final class UserTaskClarifyAlternative extends AbstractFlowNode implements HasSuccessors, HasVariables { + public static final String ELEMENT_ID = "userTask_clarifyAlternative"; + + public static final UserTaskClarifyAlternative INSTANCE = new UserTaskClarifyAlternative(); + + private static final Variables VARIABLES = new Variables(); + + private UserTaskClarifyAlternative() { + super(new ElementId(ELEMENT_ID), BpmnElementType.USER_TASK, "Clarify alternative with customer"); + } + + @Override + public Variables getVariables() { + return VARIABLES; + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Variables extends VariableDefinitions { + public static final VariableName.Output ALTERNATIVE_FOUND = new VariableName.Output(ProcessVariables.ALTERNATIVE_FOUND); + + public static final VariableName.Output BIKE_ID = new VariableName.Output(ProcessVariables.BIKE_ID); + + private Variables() { + } + + @Override + public List getAll() { + return List.of(ALTERNATIVE_FOUND, BIKE_ID); + } + } + + public static final class Next { + public SequenceFlows gatewayAlternativeFound() { + return SequenceFlows.single(new ElementId("flow_clarifyToAlternativeGateway"), GatewayAlternativeFound.INSTANCE); + } + } + } } } diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/process/CancelBikeOrderProcessApi.java b/service/app/src/main/java/io/miragon/blueprint/adapter/process/CancelBikeOrderProcessApi.java index c34852e..ae4ae11 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/process/CancelBikeOrderProcessApi.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/process/CancelBikeOrderProcessApi.java @@ -1,13 +1,20 @@ // Generated by bpmn-to-code package io.miragon.blueprint.adapter.process; +import io.miragon.bpmn.runtime.AbstractFlowNode; +import io.miragon.bpmn.runtime.BpmnElementType; import io.miragon.bpmn.runtime.BpmnEngine; -import io.miragon.bpmn.runtime.BpmnFlow; -import io.miragon.bpmn.runtime.BpmnRelations; +import io.miragon.bpmn.runtime.BpmnEventType; import io.miragon.bpmn.runtime.ElementId; +import io.miragon.bpmn.runtime.Event; +import io.miragon.bpmn.runtime.FlowNode; +import io.miragon.bpmn.runtime.HasJobType; +import io.miragon.bpmn.runtime.HasSuccessors; +import io.miragon.bpmn.runtime.HasVariables; import io.miragon.bpmn.runtime.ProcessId; +import io.miragon.bpmn.runtime.SequenceFlows; +import io.miragon.bpmn.runtime.VariableDefinitions; import io.miragon.bpmn.runtime.VariableName; -import java.lang.String; import java.util.List; public final class CancelBikeOrderProcessApi { @@ -15,92 +22,253 @@ public final class CancelBikeOrderProcessApi { public static final BpmnEngine PROCESS_ENGINE = BpmnEngine.CAMUNDA_7; + private CancelBikeOrderProcessApi() { + } + /** - * BPMN element ids as declared in the source model. - * Typically used in process-level tests or when searching for tasks. - * Worker runtime code rarely needs these. + * Typed navigation over the process flow: one nested class per BPMN element. */ - public static final class Elements { - public static final ElementId END_EVENT_ORDER_REVERSED = new ElementId("endEvent_orderReversed"); + public static final class FlowNodes { + private FlowNodes() { + } - public static final ElementId GATEWAY_CANCELLATION_POSSIBLE = new ElementId("gateway_cancellationPossible"); + public static EndEventOrderReversed endEventOrderReversed() { + return EndEventOrderReversed.INSTANCE; + } - public static final ElementId GATEWAY_JOIN = new ElementId("gateway_join"); + public static GatewayCancellationPossible gatewayCancellationPossible() { + return GatewayCancellationPossible.INSTANCE; + } - public static final ElementId SERVICE_TASK_BOOK_COSTS = new ElementId("serviceTask_bookCosts"); + public static GatewayJoin gatewayJoin() { + return GatewayJoin.INSTANCE; + } - public static final ElementId SERVICE_TASK_REQUEST_CANCELLATION = new ElementId("serviceTask_requestCancellation"); + public static ServiceTaskBookCosts serviceTaskBookCosts() { + return ServiceTaskBookCosts.INSTANCE; + } - public static final ElementId START_EVENT_CANCELLATION_REQUIRED = new ElementId("startEvent_cancellationRequired"); + public static ServiceTaskRequestCancellation serviceTaskRequestCancellation() { + return ServiceTaskRequestCancellation.INSTANCE; + } - public static final ElementId USER_TASK_CLARIFY_RETURN = new ElementId("userTask_clarifyReturn"); - } + public static StartEventCancellationRequired startEventCancellationRequired() { + return StartEventCancellationRequired.INSTANCE; + } - /** - * Job worker task types used in {@code @JobWorker(type = ServiceTasks.X)} annotations. - * Kept as {@code public static final String} because annotation arguments must be compile-time constants. - */ - public static final class ServiceTasks { - public static final String BOOK_COSTS = "bookCosts"; + public static UserTaskClarifyReturn userTaskClarifyReturn() { + return UserTaskClarifyReturn.INSTANCE; + } - public static final String REQUEST_CANCELLATION = "requestCancellation"; - } + public static List all() { + return List.of( + EndEventOrderReversed.INSTANCE, + GatewayCancellationPossible.INSTANCE, + GatewayJoin.INSTANCE, + ServiceTaskBookCosts.INSTANCE, + ServiceTaskRequestCancellation.INSTANCE, + StartEventCancellationRequired.INSTANCE, + UserTaskClarifyReturn.INSTANCE); + } - /** - * Process variables grouped by the BPMN element that declares them. - * Direction is encoded in each variable's wrapper type: {@code VariableName.Input}, {@code VariableName.Output}, or {@code VariableName.InOut} when the variable is both read and written by the same element. - * Consumer APIs that take a specific subtype (for example, a method accepting {@code VariableName.Output}) get compile-time direction enforcement. - */ - public static final class Variables { - public static final class ServiceTaskRequestCancellation { - public static final VariableName.Output CANCELLATION_POSSIBLE = new VariableName.Output("cancellationPossible"); + public static final class EndEventOrderReversed extends AbstractFlowNode implements Event { + public static final String ELEMENT_ID = "endEvent_orderReversed"; + + public static final EndEventOrderReversed INSTANCE = new EndEventOrderReversed(); + + private EndEventOrderReversed() { + super(new ElementId(ELEMENT_ID), BpmnElementType.END_EVENT, "Order reversed"); + } + + @Override + public BpmnEventType getEventType() { + return BpmnEventType.NONE; + } } - public static final class StartEventCancellationRequired { - public static final VariableName.Input BIKE_ID = new VariableName.Input("bikeId"); + public static final class GatewayCancellationPossible extends AbstractFlowNode implements HasSuccessors { + public static final String ELEMENT_ID = "gateway_cancellationPossible"; + + public static final GatewayCancellationPossible INSTANCE = new GatewayCancellationPossible(); + + private GatewayCancellationPossible() { + super(new ElementId(ELEMENT_ID), BpmnElementType.EXCLUSIVE_GATEWAY, "Cancellation possible?"); + } + + @Override + public Next getNext() { + return new Next(); + } - public static final VariableName.Input ORDER_ID = new VariableName.Input("orderId"); + public static final class Next { + public SequenceFlows gatewayJoin() { + return SequenceFlows.single(new ElementId("flow_cancellationPossible"), "Yes", null, true, GatewayJoin.INSTANCE); + } + + public SequenceFlows userTaskClarifyReturn() { + return SequenceFlows.single(new ElementId("flow_cancellationNotPossible"), "No", "${cancellationPossible}", false, UserTaskClarifyReturn.INSTANCE); + } + } } - } - /** - * Sequence flows between BPMN elements. - * Mainly useful for process-model tooling, tests, and AI-agent consumers reasoning about the process shape. - * Worker code typically does not need these. - */ - public static final class Flows { - public static final BpmnFlow FLOW_BOOK_COSTS_TO_JOIN = new BpmnFlow("flow_bookCostsToJoin", null, "serviceTask_bookCosts", "gateway_join", null, false); + public static final class GatewayJoin extends AbstractFlowNode implements HasSuccessors { + public static final String ELEMENT_ID = "gateway_join"; - public static final BpmnFlow FLOW_CANCELLATION_NOT_POSSIBLE = new BpmnFlow("flow_cancellationNotPossible", "No", "gateway_cancellationPossible", "userTask_clarifyReturn", "${cancellationPossible}", false); + public static final GatewayJoin INSTANCE = new GatewayJoin(); - public static final BpmnFlow FLOW_CANCELLATION_POSSIBLE = new BpmnFlow("flow_cancellationPossible", "Yes", "gateway_cancellationPossible", "gateway_join", null, true); + private GatewayJoin() { + super(new ElementId(ELEMENT_ID), BpmnElementType.EXCLUSIVE_GATEWAY); + } - public static final BpmnFlow FLOW_CLARIFY_TO_BOOK_COSTS = new BpmnFlow("flow_clarifyToBookCosts", null, "userTask_clarifyReturn", "serviceTask_bookCosts", null, false); + @Override + public Next getNext() { + return new Next(); + } - public static final BpmnFlow FLOW_JOIN_TO_REVERSED = new BpmnFlow("flow_joinToReversed", null, "gateway_join", "endEvent_orderReversed", null, false); + public static final class Next { + public SequenceFlows endEventOrderReversed() { + return SequenceFlows.single(new ElementId("flow_joinToReversed"), EndEventOrderReversed.INSTANCE); + } + } + } - public static final BpmnFlow FLOW_REQUEST_TO_POSSIBLE_GATEWAY = new BpmnFlow("flow_requestToPossibleGateway", null, "serviceTask_requestCancellation", "gateway_cancellationPossible", null, false); + public static final class ServiceTaskBookCosts extends AbstractFlowNode implements HasSuccessors, HasJobType { + public static final String ELEMENT_ID = "serviceTask_bookCosts"; - public static final BpmnFlow FLOW_REQUIRED_TO_REQUEST = new BpmnFlow("flow_requiredToRequest", null, "startEvent_cancellationRequired", "serviceTask_requestCancellation", null, false); - } + public static final ServiceTaskBookCosts INSTANCE = new ServiceTaskBookCosts(); - /** - * Per-element graph metadata (elementType / previousElements / followingElements / parentId / boundary attachments). - * Intended for tooling and tests, not worker runtime code. - */ - public static final class Relations { - public static final BpmnRelations END_EVENT_ORDER_REVERSED = new BpmnRelations("Order reversed", List.of("gateway_join"), List.of(), null, null, List.of(), "END_EVENT"); + private ServiceTaskBookCosts() { + super(new ElementId(ELEMENT_ID), BpmnElementType.SERVICE_TASK, "Book costs"); + } + + @Override + public String getJobType() { + return ServiceTasks.BOOK_COSTS; + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows gatewayJoin() { + return SequenceFlows.single(new ElementId("flow_bookCostsToJoin"), GatewayJoin.INSTANCE); + } + } + } + + public static final class ServiceTaskRequestCancellation extends AbstractFlowNode implements HasSuccessors, HasJobType, HasVariables { + public static final String ELEMENT_ID = "serviceTask_requestCancellation"; + + public static final ServiceTaskRequestCancellation INSTANCE = new ServiceTaskRequestCancellation(); + + private static final Variables VARIABLES = new Variables(); + + private ServiceTaskRequestCancellation() { + super(new ElementId(ELEMENT_ID), BpmnElementType.SERVICE_TASK, "Request cancellation"); + } + + @Override + public String getJobType() { + return ServiceTasks.REQUEST_CANCELLATION; + } + + @Override + public Variables getVariables() { + return VARIABLES; + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Variables extends VariableDefinitions { + public static final VariableName.Output CANCELLATION_POSSIBLE = new VariableName.Output(ProcessVariables.CANCELLATION_POSSIBLE); + + private Variables() { + } + + @Override + public List getAll() { + return List.of(CANCELLATION_POSSIBLE); + } + } - public static final BpmnRelations GATEWAY_CANCELLATION_POSSIBLE = new BpmnRelations("Cancellation possible?", List.of("serviceTask_requestCancellation"), List.of("userTask_clarifyReturn", "gateway_join"), null, null, List.of(), "EXCLUSIVE_GATEWAY"); + public static final class Next { + public SequenceFlows gatewayCancellationPossible() { + return SequenceFlows.single(new ElementId("flow_requestToPossibleGateway"), GatewayCancellationPossible.INSTANCE); + } + } + } + + public static final class StartEventCancellationRequired extends AbstractFlowNode implements HasSuccessors, Event, HasVariables { + public static final String ELEMENT_ID = "startEvent_cancellationRequired"; + + public static final StartEventCancellationRequired INSTANCE = new StartEventCancellationRequired(); + + private static final Variables VARIABLES = new Variables(); + + private StartEventCancellationRequired() { + super(new ElementId(ELEMENT_ID), BpmnElementType.START_EVENT, "Cancellation required"); + } + + @Override + public BpmnEventType getEventType() { + return BpmnEventType.NONE; + } + + @Override + public Variables getVariables() { + return VARIABLES; + } + + @Override + public Next getNext() { + return new Next(); + } - public static final BpmnRelations GATEWAY_JOIN = new BpmnRelations(null, List.of("gateway_cancellationPossible", "serviceTask_bookCosts"), List.of("endEvent_orderReversed"), null, null, List.of(), "EXCLUSIVE_GATEWAY"); + public static final class Variables extends VariableDefinitions { + public static final VariableName.Input BIKE_ID = new VariableName.Input(ProcessVariables.BIKE_ID); - public static final BpmnRelations SERVICE_TASK_BOOK_COSTS = new BpmnRelations("Book costs", List.of("userTask_clarifyReturn"), List.of("gateway_join"), null, null, List.of(), "SERVICE_TASK"); + public static final VariableName.Input ORDER_ID = new VariableName.Input(ProcessVariables.ORDER_ID); - public static final BpmnRelations SERVICE_TASK_REQUEST_CANCELLATION = new BpmnRelations("Request cancellation", List.of("startEvent_cancellationRequired"), List.of("gateway_cancellationPossible"), null, null, List.of(), "SERVICE_TASK"); + private Variables() { + } - public static final BpmnRelations START_EVENT_CANCELLATION_REQUIRED = new BpmnRelations("Cancellation required", List.of(), List.of("serviceTask_requestCancellation"), null, null, List.of(), "START_EVENT"); + @Override + public List getAll() { + return List.of(BIKE_ID, ORDER_ID); + } + } - public static final BpmnRelations USER_TASK_CLARIFY_RETURN = new BpmnRelations("Clarify return with supplier", List.of("gateway_cancellationPossible"), List.of("serviceTask_bookCosts"), null, null, List.of(), "USER_TASK"); + public static final class Next { + public SequenceFlows serviceTaskRequestCancellation() { + return SequenceFlows.single(new ElementId("flow_requiredToRequest"), ServiceTaskRequestCancellation.INSTANCE); + } + } + } + + public static final class UserTaskClarifyReturn extends AbstractFlowNode implements HasSuccessors { + public static final String ELEMENT_ID = "userTask_clarifyReturn"; + + public static final UserTaskClarifyReturn INSTANCE = new UserTaskClarifyReturn(); + + private UserTaskClarifyReturn() { + super(new ElementId(ELEMENT_ID), BpmnElementType.USER_TASK, "Clarify return with supplier"); + } + + @Override + public Next getNext() { + return new Next(); + } + + public static final class Next { + public SequenceFlows serviceTaskBookCosts() { + return SequenceFlows.single(new ElementId("flow_clarifyToBookCosts"), ServiceTaskBookCosts.INSTANCE); + } + } + } } } diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/process/EngineApiConfiguration.java b/service/app/src/main/java/io/miragon/blueprint/adapter/process/EngineApiConfiguration.java index aead8dd..06b3efa 100644 --- a/service/app/src/main/java/io/miragon/blueprint/adapter/process/EngineApiConfiguration.java +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/process/EngineApiConfiguration.java @@ -4,7 +4,7 @@ import dev.bpmcrafters.processengineapi.adapter.operaton.embedded.shared.EngineCommandExecutor; import dev.bpmcrafters.processengineapi.task.TaskSubscriptionApi; import dev.bpmcrafters.processengineapi.task.support.UserTaskSupport; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.Elements; +import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.FlowNodes; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -34,7 +34,7 @@ public UserTaskSupport clarifyAlternativeUserTaskSupport(TaskSubscriptionApi tas userTaskSupport.subscribe( taskSubscriptionApi, CommonRestrictions.builder().build(), - Elements.USER_TASK_CLARIFY_ALTERNATIVE.getValue(), + FlowNodes.UserTaskClarifyAlternative.ELEMENT_ID, null ); return userTaskSupport; diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/process/Errors.java b/service/app/src/main/java/io/miragon/blueprint/adapter/process/Errors.java new file mode 100644 index 0000000..dad12e0 --- /dev/null +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/process/Errors.java @@ -0,0 +1,20 @@ +// Generated by bpmn-to-code +package io.miragon.blueprint.adapter.process; + +import io.miragon.bpmn.runtime.BpmnErrorDefinition; +import java.util.List; + +/** + * BPMN error definitions with name and code, as thrown and caught by the processes. + */ +public final class Errors { + public static final BpmnErrorDefinition BIKE_UNAVAILABLE = new BpmnErrorDefinition("Bike_Unavailable", "bikeUnavailable"); + + private Errors() { + } + + public static List all() { + return List.of( + BIKE_UNAVAILABLE); + } +} diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/process/Escalations.java b/service/app/src/main/java/io/miragon/blueprint/adapter/process/Escalations.java new file mode 100644 index 0000000..db86a9d --- /dev/null +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/process/Escalations.java @@ -0,0 +1,20 @@ +// Generated by bpmn-to-code +package io.miragon.blueprint.adapter.process; + +import io.miragon.bpmn.runtime.BpmnEscalationDefinition; +import java.util.List; + +/** + * BPMN escalation definitions with name and code, as thrown and caught by the processes. + */ +public final class Escalations { + public static final BpmnEscalationDefinition CONTRACT_NOT_SIGNED = new BpmnEscalationDefinition("Contract_Not_Signed", "contractNotSigned"); + + private Escalations() { + } + + public static List all() { + return List.of( + CONTRACT_NOT_SIGNED); + } +} diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/process/Messages.java b/service/app/src/main/java/io/miragon/blueprint/adapter/process/Messages.java new file mode 100644 index 0000000..dea436f --- /dev/null +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/process/Messages.java @@ -0,0 +1,29 @@ +// Generated by bpmn-to-code +package io.miragon.blueprint.adapter.process; + +import io.miragon.bpmn.runtime.MessageName; +import java.util.List; + +/** + * BPMN message names used to correlate messages to running process instances. + */ +public final class Messages { + public static final MessageName MIRAVELO_APPLICATION_WITHDRAWN = new MessageName("miravelo.applicationWithdrawn"); + + public static final MessageName MIRAVELO_CONTRACT_SIGNED = new MessageName("miravelo.contractSigned"); + + public static final MessageName MIRAVELO_HANDOVER_REPORTED = new MessageName("miravelo.handoverReported"); + + public static final MessageName MIRAVELO_LEASING_REQUEST_RECEIVED = new MessageName("miravelo.leasingRequestReceived"); + + private Messages() { + } + + public static List all() { + return List.of( + MIRAVELO_APPLICATION_WITHDRAWN, + MIRAVELO_CONTRACT_SIGNED, + MIRAVELO_HANDOVER_REPORTED, + MIRAVELO_LEASING_REQUEST_RECEIVED); + } +} diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/process/ProcessVariables.java b/service/app/src/main/java/io/miragon/blueprint/adapter/process/ProcessVariables.java new file mode 100644 index 0000000..086570d --- /dev/null +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/process/ProcessVariables.java @@ -0,0 +1,38 @@ +// Generated by bpmn-to-code +package io.miragon.blueprint.adapter.process; + +import java.util.List; + +/** + * Names of the process variables used in {@code @Variable(name = ProcessVariables.X)} annotations. + * Kept as {@code public static final String} because annotation arguments must be compile-time constants. + */ +public final class ProcessVariables { + public static final String AGE = "age"; + + public static final String ALTERNATIVE_FOUND = "alternativeFound"; + + public static final String APPLICATION_ID = "applicationId"; + + public static final String BIKE_ID = "bikeId"; + + public static final String CANCELLATION_POSSIBLE = "cancellationPossible"; + + public static final String MONTHLY_NET_INCOME = "monthlyNetIncome"; + + public static final String ORDER_ID = "orderId"; + + private ProcessVariables() { + } + + public static List all() { + return List.of( + AGE, + ALTERNATIVE_FOUND, + APPLICATION_ID, + BIKE_ID, + CANCELLATION_POSSIBLE, + MONTHLY_NET_INCOME, + ORDER_ID); + } +} diff --git a/service/app/src/main/java/io/miragon/blueprint/adapter/process/ServiceTasks.java b/service/app/src/main/java/io/miragon/blueprint/adapter/process/ServiceTasks.java new file mode 100644 index 0000000..4ad0b79 --- /dev/null +++ b/service/app/src/main/java/io/miragon/blueprint/adapter/process/ServiceTasks.java @@ -0,0 +1,50 @@ +// Generated by bpmn-to-code +package io.miragon.blueprint.adapter.process; + +import java.util.List; + +/** + * Job worker task types used in {@code @JobWorker(type = ServiceTasks.X)} annotations. + * Kept as {@code public static final String} because annotation arguments must be compile-time constants. + */ +public final class ServiceTasks { + public static final String ACTIVATE_LEASING = "activateLeasing"; + + public static final String BOOK_COSTS = "bookCosts"; + + public static final String CANCEL_CONTRACT = "cancelContract"; + + public static final String CANCEL_POLICY = "cancelPolicy"; + + public static final String ISSUE_INSURANCE_POLICY = "issueInsurancePolicy"; + + public static final String ORDER_BIKE = "orderBike"; + + public static final String REQUEST_CANCELLATION = "requestCancellation"; + + public static final String SEND_CANCELLATION_CONFIRMATION = "sendCancellationConfirmation"; + + public static final String SEND_CONTRACT = "sendContract"; + + public static final String SEND_REJECTION = "sendRejection"; + + public static final String SEND_REMINDER_MAIL = "sendReminderMail"; + + private ServiceTasks() { + } + + public static List all() { + return List.of( + ACTIVATE_LEASING, + BOOK_COSTS, + CANCEL_CONTRACT, + CANCEL_POLICY, + ISSUE_INSURANCE_POLICY, + ORDER_BIKE, + REQUEST_CANCELLATION, + SEND_CANCELLATION_CONFIRMATION, + SEND_CONTRACT, + SEND_REJECTION, + SEND_REMINDER_MAIL); + } +} diff --git a/service/app/src/test/java/io/miragon/blueprint/adapter/outbound/operaton/LeasingProcessAdapterTest.java b/service/app/src/test/java/io/miragon/blueprint/adapter/outbound/operaton/LeasingProcessAdapterTest.java index aada2ea..880ab9a 100644 --- a/service/app/src/test/java/io/miragon/blueprint/adapter/outbound/operaton/LeasingProcessAdapterTest.java +++ b/service/app/src/test/java/io/miragon/blueprint/adapter/outbound/operaton/LeasingProcessAdapterTest.java @@ -11,8 +11,8 @@ import dev.bpmcrafters.processengineapi.task.TaskInformation; import dev.bpmcrafters.processengineapi.task.UserTaskCompletionApi; import dev.bpmcrafters.processengineapi.task.support.UserTaskSupport; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.Elements; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.Messages; +import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.FlowNodes; +import io.miragon.blueprint.adapter.process.Messages; import io.miragon.blueprint.domain.bike.BikeId; import io.miragon.blueprint.domain.leasing.ApplicationId; import java.util.List; @@ -81,7 +81,7 @@ void completeAlternativeClarificationResolvesTheTaskByApplicationIdAndCompletesI // given: an open clarify-alternative task delivered to the user-task pool for this application var task = new TaskInformation( "task-1", - Map.of(CommonRestrictions.ACTIVITY_ID, Elements.USER_TASK_CLARIFY_ALTERNATIVE.getValue()) + Map.of(CommonRestrictions.ACTIVITY_ID, FlowNodes.UserTaskClarifyAlternative.ELEMENT_ID) ); given(userTaskSupport.getAllTasks()).willReturn(List.of(task)); given(userTaskSupport.getPayload("task-1")).willReturn(Map.of("applicationId", id.value().toString())); @@ -238,7 +238,7 @@ void correlateApplicationWithdrawnCorrelatesTheMessageByTheGlobalCorrelationKey( private TaskInformation clarifyAlternativeTask(String taskId) { return new TaskInformation( taskId, - Map.of(CommonRestrictions.ACTIVITY_ID, Elements.USER_TASK_CLARIFY_ALTERNATIVE.getValue()) + Map.of(CommonRestrictions.ACTIVITY_ID, FlowNodes.UserTaskClarifyAlternative.ELEMENT_ID) ); } diff --git a/service/app/src/test/java/io/miragon/blueprint/adapter/outbound/operaton/TaskInboxAdapterTest.java b/service/app/src/test/java/io/miragon/blueprint/adapter/outbound/operaton/TaskInboxAdapterTest.java index 8111ced..0c01ad7 100644 --- a/service/app/src/test/java/io/miragon/blueprint/adapter/outbound/operaton/TaskInboxAdapterTest.java +++ b/service/app/src/test/java/io/miragon/blueprint/adapter/outbound/operaton/TaskInboxAdapterTest.java @@ -1,6 +1,6 @@ package io.miragon.blueprint.adapter.outbound.operaton; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.Elements; +import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.FlowNodes; import io.miragon.blueprint.domain.leasing.ApplicationId; import java.util.Date; import java.util.List; @@ -44,7 +44,7 @@ void translatesOpenClarifyAlternativeTasksIntoTheirApplicationBusinessKeys() { // then: the open task surfaces as its application id, queried by the clarify-alternative key assertThat(result).hasSize(1); assertThat(result.getFirst().applicationId()).isEqualTo(ApplicationId.of(applicationId)); - then(taskQuery).should().taskDefinitionKey(Elements.USER_TASK_CLARIFY_ALTERNATIVE.getValue()); + then(taskQuery).should().taskDefinitionKey(FlowNodes.UserTaskClarifyAlternative.ELEMENT_ID); } @Test diff --git a/service/app/src/test/java/io/miragon/blueprint/process/BikeLeasingProcessTest.java b/service/app/src/test/java/io/miragon/blueprint/process/BikeLeasingProcessTest.java index 08acadf..9e781f1 100644 --- a/service/app/src/test/java/io/miragon/blueprint/process/BikeLeasingProcessTest.java +++ b/service/app/src/test/java/io/miragon/blueprint/process/BikeLeasingProcessTest.java @@ -1,7 +1,6 @@ package io.miragon.blueprint.process; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.Elements; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.Variables; +import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.FlowNodes; import io.miragon.blueprint.adapter.process.CancelBikeOrderProcessApi; import io.miragon.blueprint.application.port.inbound.ActivateLeasingUseCase; import io.miragon.blueprint.application.port.inbound.BookCancellationCostsUseCase; @@ -136,23 +135,23 @@ public void happyPathContractSignedBikeAvailableLeasingBecomesActive() { process.correlateHandoverReported(id); // -> withdrawal-period timer continueToNextWaitState(processEngine); - fireTimer(processEngine, Elements.EVENT_WITHDRAWAL_PERIOD_ELAPSED); + fireTimer(processEngine, FlowNodes.EventWithdrawalPeriodElapsed.INSTANCE); continueToNextWaitState(processEngine); assertThat(instance) .isEnded() .hasPassedInOrder( - Elements.BUSINESS_RULE_TASK_CHECK_CREDIT_RATING.getValue(), - Elements.SERVICE_TASK_SEND_CONTRACT.getValue(), - Elements.SERVICE_TASK_ISSUE_INSURANCE_POLICY.getValue(), - Elements.EVENT_HANDOVER_REPORTED.getValue(), - Elements.SERVICE_TASK_ACTIVATE_LEASING.getValue(), - Elements.END_EVENT_LEASING_ACTIVE.getValue()) + FlowNodes.BusinessRuleTaskCheckCreditRating.ELEMENT_ID, + FlowNodes.ServiceTaskSendContract.ELEMENT_ID, + FlowNodes.ServiceTaskIssueInsurancePolicy.ELEMENT_ID, + FlowNodes.EventHandoverReported.ELEMENT_ID, + FlowNodes.ServiceTaskActivateLeasing.ELEMENT_ID, + FlowNodes.EndEventLeasingActive.ELEMENT_ID) .hasNotPassed( - Elements.EVENT_BIKE_UNAVAILABLE.getValue(), - Elements.END_EVENT_APPLICATION_REJECTED.getValue(), - Elements.END_EVENT_APPLICATION_CANCELLED.getValue(), - Elements.END_EVENT_CONTRACT_CANCELLED.getValue()); + FlowNodes.EventBikeUnavailable.ELEMENT_ID, + FlowNodes.EndEventApplicationRejected.ELEMENT_ID, + FlowNodes.EndEventApplicationCancelled.ELEMENT_ID, + FlowNodes.EndEventContractCancelled.ELEMENT_ID); then(sendContractUseCase).should(times(1)).sendContract(id); then(issueInsurancePolicyUseCase).should(times(1)).issuePolicy(id); @@ -167,17 +166,17 @@ public void escalationContractNotSignedInTimeIsEscalatedAndRejected() { continueToNextWaitState(processEngine); // parks on the signature wait state - fireTimer(processEngine, Elements.EVENT_SIGNATURE_DEADLINE); // deadline -> escalation -> rejection + fireTimer(processEngine, FlowNodes.EventSignatureDeadline.INSTANCE); // deadline -> escalation -> rejection continueToNextWaitState(processEngine); assertThat(instance) .isEnded() .hasPassed( - Elements.EVENT_SIGNATURE_DEADLINE.getValue(), - Elements.EVENT_CONTRACT_NOT_SIGNED.getValue(), - Elements.SERVICE_TASK_SEND_REJECTION.getValue(), - Elements.END_EVENT_APPLICATION_REJECTED.getValue()) - .hasNotPassed(Elements.END_EVENT_LEASING_ACTIVE.getValue()); + FlowNodes.EventSignatureDeadline.ELEMENT_ID, + FlowNodes.EventContractNotSigned.ELEMENT_ID, + FlowNodes.ServiceTaskSendRejection.ELEMENT_ID, + FlowNodes.EndEventApplicationRejected.ELEMENT_ID) + .hasNotPassed(FlowNodes.EndEventLeasingActive.ELEMENT_ID); then(rejectApplicationUseCase).should(times(1)).reject(id); } @@ -215,7 +214,7 @@ public void abortWithdrawingTheApplicationCompensatesTheCompletedSteps() { Task task = taskService .createTaskQuery() - .taskDefinitionKey(CancelBikeOrderProcessApi.Elements.USER_TASK_CLARIFY_RETURN.getValue()) + .taskDefinitionKey(CancelBikeOrderProcessApi.FlowNodes.UserTaskClarifyReturn.ELEMENT_ID) .singleResult(); taskService.complete(task.getId(), Map.of("returnClarified", true)); continueToNextWaitState(processEngine); @@ -223,12 +222,12 @@ public void abortWithdrawingTheApplicationCompensatesTheCompletedSteps() { assertThat(instance) .isEnded() .hasPassed( - Elements.SERVICE_TASK_CANCEL_CONTRACT.getValue(), - Elements.SERVICE_TASK_CANCEL_POLICY.getValue(), - Elements.CALL_ACTIVITY_CANCEL_BIKE_ORDER.getValue(), - Elements.SERVICE_TASK_SEND_CANCELLATION_CONFIRMATION.getValue(), - Elements.END_EVENT_APPLICATION_CANCELLED.getValue()) - .hasNotPassed(Elements.END_EVENT_LEASING_ACTIVE.getValue()); + FlowNodes.ServiceTaskCancelContract.ELEMENT_ID, + FlowNodes.ServiceTaskCancelPolicy.ELEMENT_ID, + FlowNodes.CallActivityCancelBikeOrder.ELEMENT_ID, + FlowNodes.ServiceTaskSendCancellationConfirmation.ELEMENT_ID, + FlowNodes.EndEventApplicationCancelled.ELEMENT_ID) + .hasNotPassed(FlowNodes.EndEventLeasingActive.ELEMENT_ID); // External-task delivery is at-least-once: while compensation runs several handlers in // parallel, an async continuation firing on the test thread can force an optimistic-locking @@ -251,23 +250,23 @@ public void bikeUnavailableClarifyingAnAlternativeReOrdersAndLeasingBecomesActiv continueToNextWaitState(processEngine); // re-order succeeds -> parallel join -> handover wait state assertThat(instance) .variables() - .containsEntry(Variables.UserTaskClarifyAlternative.BIKE_ID.getValue(), "BIKE-ALT"); + .containsEntry(FlowNodes.UserTaskClarifyAlternative.Variables.BIKE_ID.getValue(), "BIKE-ALT"); process.correlateHandoverReported(id); continueToNextWaitState(processEngine); - fireTimer(processEngine, Elements.EVENT_WITHDRAWAL_PERIOD_ELAPSED); + fireTimer(processEngine, FlowNodes.EventWithdrawalPeriodElapsed.INSTANCE); continueToNextWaitState(processEngine); assertThat(instance) .isEnded() .hasPassed( - Elements.EVENT_BIKE_UNAVAILABLE.getValue(), - Elements.USER_TASK_CLARIFY_ALTERNATIVE.getValue(), - Elements.SERVICE_TASK_ORDER_BIKE.getValue(), - Elements.END_EVENT_LEASING_ACTIVE.getValue()) + FlowNodes.EventBikeUnavailable.ELEMENT_ID, + FlowNodes.UserTaskClarifyAlternative.ELEMENT_ID, + FlowNodes.ServiceTaskOrderBike.ELEMENT_ID, + FlowNodes.EndEventLeasingActive.ELEMENT_ID) .hasNotPassed( - Elements.END_EVENT_CONTRACT_CANCELLED.getValue(), - Elements.END_EVENT_APPLICATION_REJECTED.getValue()); + FlowNodes.EndEventContractCancelled.ELEMENT_ID, + FlowNodes.EndEventApplicationRejected.ELEMENT_ID); InOrder orders = inOrder(orderBikeUseCase); then(orderBikeUseCase).should(orders).orderBike(id, new BikeId("BIKE-TEST")); @@ -286,14 +285,14 @@ public void bikeUnavailableDecliningTheAlternativeReversesContractAndPolicyWitho assertThat(instance) .isEnded() .hasPassed( - Elements.EVENT_TRIGGER_REVERSAL.getValue(), - Elements.SERVICE_TASK_CANCEL_CONTRACT.getValue(), - Elements.SERVICE_TASK_CANCEL_POLICY.getValue(), - Elements.SERVICE_TASK_CONFIRM_CONTRACT_CANCELLATION.getValue(), - Elements.END_EVENT_CONTRACT_CANCELLED.getValue()) + FlowNodes.EventTriggerReversal.ELEMENT_ID, + FlowNodes.ServiceTaskCancelContract.ELEMENT_ID, + FlowNodes.ServiceTaskCancelPolicy.ELEMENT_ID, + FlowNodes.ServiceTaskConfirmContractCancellation.ELEMENT_ID, + FlowNodes.EndEventContractCancelled.ELEMENT_ID) .hasNotPassed( - Elements.CALL_ACTIVITY_CANCEL_BIKE_ORDER.getValue(), - Elements.END_EVENT_LEASING_ACTIVE.getValue()); + FlowNodes.CallActivityCancelBikeOrder.ELEMENT_ID, + FlowNodes.EndEventLeasingActive.ELEMENT_ID); then(sendCancellationConfirmationUseCase).should(atLeast(1)).sendCancellationConfirmation(id); then(requestOrderCancellationUseCase).should(never()).requestCancellation(any()); @@ -311,11 +310,11 @@ public void abortWithdrawingWhileClarifyingAnAlternativeCompensatesContractAndPo assertThat(instance) .isEnded() .hasPassed( - Elements.SERVICE_TASK_CANCEL_CONTRACT.getValue(), - Elements.SERVICE_TASK_CANCEL_POLICY.getValue(), - Elements.SERVICE_TASK_SEND_CANCELLATION_CONFIRMATION.getValue(), - Elements.END_EVENT_APPLICATION_CANCELLED.getValue()) - .hasNotPassed(Elements.CALL_ACTIVITY_CANCEL_BIKE_ORDER.getValue()); + FlowNodes.ServiceTaskCancelContract.ELEMENT_ID, + FlowNodes.ServiceTaskCancelPolicy.ELEMENT_ID, + FlowNodes.ServiceTaskSendCancellationConfirmation.ELEMENT_ID, + FlowNodes.EndEventApplicationCancelled.ELEMENT_ID) + .hasNotPassed(FlowNodes.CallActivityCancelBikeOrder.ELEMENT_ID); then(requestOrderCancellationUseCase).should(never()).requestCancellation(any()); } @@ -338,12 +337,12 @@ public void abortWithdrawingAfterAnAcceptedAlternativeCancelsTheOnePlacedOrderEx Task task = taskService .createTaskQuery() - .taskDefinitionKey(CancelBikeOrderProcessApi.Elements.USER_TASK_CLARIFY_RETURN.getValue()) + .taskDefinitionKey(CancelBikeOrderProcessApi.FlowNodes.UserTaskClarifyReturn.ELEMENT_ID) .singleResult(); taskService.complete(task.getId(), Map.of("returnClarified", true)); continueToNextWaitState(processEngine); - assertThat(instance).isEnded().hasPassed(Elements.END_EVENT_APPLICATION_CANCELLED.getValue()); + assertThat(instance).isEnded().hasPassed(FlowNodes.EndEventApplicationCancelled.ELEMENT_ID); long orderCancellations = historyService .createHistoricProcessInstanceQuery() diff --git a/service/app/src/test/java/io/miragon/blueprint/process/BikeUnavailableTransactionTest.java b/service/app/src/test/java/io/miragon/blueprint/process/BikeUnavailableTransactionTest.java index b01950d..6704082 100644 --- a/service/app/src/test/java/io/miragon/blueprint/process/BikeUnavailableTransactionTest.java +++ b/service/app/src/test/java/io/miragon/blueprint/process/BikeUnavailableTransactionTest.java @@ -1,7 +1,6 @@ package io.miragon.blueprint.process; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.Elements; -import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.Variables; +import io.miragon.blueprint.adapter.process.BikeLeasingProcessProcessApi.FlowNodes; import io.miragon.blueprint.application.port.outbound.LeasingApplicationRepository; import io.miragon.blueprint.application.port.outbound.LeasingProcess; import io.miragon.blueprint.domain.bike.BikeId; @@ -84,8 +83,8 @@ public void bikeUnavailableTheBpmnErrorRaisedByTheRealOrderServiceReachesTheEngi continueToNextWaitState(processEngine); // fork -> order raises bikeUnavailable -> parks on clarify-alternative assertThat(instance) - .isWaitingAt(Elements.USER_TASK_CLARIFY_ALTERNATIVE.getValue()) - .hasPassed(Elements.EVENT_BIKE_UNAVAILABLE.getValue()); + .isWaitingAt(FlowNodes.UserTaskClarifyAlternative.ELEMENT_ID) + .hasPassed(FlowNodes.EventBikeUnavailable.ELEMENT_ID); Assertions.assertThat(runtimeService.createIncidentQuery().processInstanceId(instance.getId()).count()) .isZero(); } @@ -104,16 +103,16 @@ public void alternativeViaTasklistTheBikeTheFormSubmitsIsOrderedAndStoredOnTheAp taskService .createTaskQuery() .processInstanceId(instance.getId()) - .taskDefinitionKey(Elements.USER_TASK_CLARIFY_ALTERNATIVE.getValue()) + .taskDefinitionKey(FlowNodes.UserTaskClarifyAlternative.ELEMENT_ID) .singleResult(); taskService.complete( task.getId(), Map.of( - Variables.UserTaskClarifyAlternative.ALTERNATIVE_FOUND.getValue(), true, - Variables.UserTaskClarifyAlternative.BIKE_ID.getValue(), "BIKE-900")); + FlowNodes.UserTaskClarifyAlternative.Variables.ALTERNATIVE_FOUND.getValue(), true, + FlowNodes.UserTaskClarifyAlternative.Variables.BIKE_ID.getValue(), "BIKE-900")); continueToNextWaitState(processEngine); // re-order succeeds -> parallel join -> handover wait state - assertThat(instance).isWaitingAt(Elements.EVENT_HANDOVER_REPORTED.getValue()); + assertThat(instance).isWaitingAt(FlowNodes.EventHandoverReported.ELEMENT_ID); LeasingApplication stored = repository.findById(application.id()); Assertions.assertThat(stored.bikeId()).isEqualTo(new BikeId("BIKE-900")); Assertions.assertThat(stored.status()).isEqualTo(LeasingStatus.ORDERED); @@ -129,7 +128,7 @@ public void bikeUnavailableTheBikeTheProcessCarriesStaysOnTheApplicationAlthough signContractAndRunIntoTheUnavailableBike(application.id()); - assertThat(instance).isWaitingAt(Elements.USER_TASK_CLARIFY_ALTERNATIVE.getValue()); + assertThat(instance).isWaitingAt(FlowNodes.UserTaskClarifyAlternative.ELEMENT_ID); Assertions.assertThat(repository.findById(application.id()).bikeId()).isEqualTo(new BikeId("BIKE-OOS")); } diff --git a/service/app/src/test/java/io/miragon/blueprint/process/model/BikeLeasingModelValidationTest.java b/service/app/src/test/java/io/miragon/blueprint/process/model/BikeLeasingModelValidationTest.java index 756263d..efd4658 100644 --- a/service/app/src/test/java/io/miragon/blueprint/process/model/BikeLeasingModelValidationTest.java +++ b/service/app/src/test/java/io/miragon/blueprint/process/model/BikeLeasingModelValidationTest.java @@ -1,7 +1,7 @@ package io.miragon.blueprint.process.model; import io.miragon.bpmn.domain.shared.ProcessEngine; -import io.miragon.bpmn.domain.validation.SingleModelValidationRule; +import io.miragon.bpmn.domain.validation.ValidationRule; import io.miragon.bpmn.testing.BpmnRules; import io.miragon.bpmn.testing.BpmnValidator; import org.junit.jupiter.api.DisplayName; @@ -20,7 +20,7 @@ class BikeLeasingModelValidationTest { @Test @DisplayName("the bpmn models satisfy all rules and only use external task topics") void theBpmnModelsSatisfyAllRulesAndOnlyUseExternalTaskTopics() { - List rules = new ArrayList<>(BpmnRules.all()); + List rules = new ArrayList<>(BpmnRules.all()); rules.add(new ServiceTaskExternalTopicRule()); BpmnValidator diff --git a/service/app/src/test/java/io/miragon/blueprint/process/model/ServiceTaskExternalTopicRule.java b/service/app/src/test/java/io/miragon/blueprint/process/model/ServiceTaskExternalTopicRule.java index fea4b9c..d6885d2 100644 --- a/service/app/src/test/java/io/miragon/blueprint/process/model/ServiceTaskExternalTopicRule.java +++ b/service/app/src/test/java/io/miragon/blueprint/process/model/ServiceTaskExternalTopicRule.java @@ -1,6 +1,7 @@ package io.miragon.blueprint.process.model; import io.miragon.bpmn.domain.shared.ServiceTaskDefinition; +import io.miragon.bpmn.domain.shared.TaskImplementation; import io.miragon.bpmn.domain.validation.SingleModelValidationRule; import io.miragon.bpmn.domain.validation.model.Severity; import io.miragon.bpmn.domain.validation.model.SingleModelValidationContext; @@ -19,8 +20,6 @@ */ public class ServiceTaskExternalTopicRule implements SingleModelValidationRule { - private static final String EXTERNAL_TASK_KIND = "EXTERNAL_TASK"; - @Override public String getId() { return "SERVICE_TASK_MUST_USE_EXTERNAL_TOPIC"; @@ -46,7 +45,6 @@ public List validate(SingleModelValidationContext context) } private boolean usesExternalTask(ServiceTaskDefinition task) { - return task.getEngineSpecificProperties().get(ServiceTaskDefinition.IMPL_KIND_KEY) instanceof String kind - && EXTERNAL_TASK_KIND.equals(kind); + return task.getImplementation() instanceof TaskImplementation.ExternalTask; } } diff --git a/service/app/src/test/java/io/miragon/blueprint/process/util/TimerUtils.java b/service/app/src/test/java/io/miragon/blueprint/process/util/TimerUtils.java index c49dbe0..63dfd72 100644 --- a/service/app/src/test/java/io/miragon/blueprint/process/util/TimerUtils.java +++ b/service/app/src/test/java/io/miragon/blueprint/process/util/TimerUtils.java @@ -1,6 +1,6 @@ package io.miragon.blueprint.process.util; -import io.miragon.bpmn.runtime.ElementId; +import io.miragon.bpmn.runtime.FlowNode; import org.operaton.bpm.engine.ProcessEngine; import org.operaton.bpm.engine.runtime.Job; @@ -14,15 +14,15 @@ private TimerUtils() { * Replaces clock manipulation: the tests verify that the timer path is wired correctly, not the * real-world waiting duration. */ - public static void fireTimer(ProcessEngine engine, ElementId timerActivityId) { + public static void fireTimer(ProcessEngine engine, FlowNode timerEvent) { Job timer = engine .getManagementService() .createJobQuery() .timers() - .activityId(timerActivityId.getValue()) + .activityId(timerEvent.getId().getValue()) .singleResult(); if (timer == null) { - throw new IllegalArgumentException("no timer job found for activity '" + timerActivityId.getValue() + "'"); + throw new IllegalArgumentException("no timer job found for activity '" + timerEvent.getId().getValue() + "'"); } engine.getManagementService().executeJob(timer.getId()); }