eva4j 1.0.17 → 1.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/AGENTS.md +2 -0
  2. package/DOMAIN_YAML_GUIDE.md +3 -1
  3. package/QUICK_REFERENCE.md +8 -4
  4. package/bin/eva4j.js +70 -2
  5. package/config/defaults.json +1 -0
  6. package/docs/CAMUNDA_DMN_GUIDE.md +1380 -0
  7. package/docs/KAFKA_PRODUCTION_CONFIG.md +441 -0
  8. package/docs/RABBITMQ_PRODUCTION_CONFIG.md +227 -0
  9. package/docs/commands/ADD_RABBITMQ_CLIENT.md +192 -0
  10. package/docs/commands/EVALUATE_SYSTEM.md +272 -8
  11. package/docs/commands/GENERATE_RABBITMQ_EVENT.md +341 -0
  12. package/docs/commands/GENERATE_RABBITMQ_LISTENER.md +595 -0
  13. package/docs/commands/GENERATE_TEMPORAL_FLOW.md +52 -12
  14. package/docs/commands/INDEX.md +27 -3
  15. package/docs/prototype/TEMPORAL_COMMUNICATION_PATTERNS.md +731 -0
  16. package/docs/prototype/TEMPORAL_DESIGN_METHODOLOGY.md +740 -0
  17. package/docs/prototype/system/RISKS.md +277 -0
  18. package/docs/prototype/system/customers.yaml +133 -0
  19. package/docs/prototype/system/inventory.yaml +109 -0
  20. package/docs/prototype/system/notifications.yaml +131 -0
  21. package/docs/prototype/system/orders.yaml +241 -0
  22. package/docs/prototype/system/payments.yaml +256 -0
  23. package/docs/prototype/system/products.yaml +168 -0
  24. package/docs/prototype/system/system.yaml +269 -0
  25. package/examples/domain-endpoints-multi-aggregate.yaml +140 -0
  26. package/examples/domain-read-models.yaml +2 -2
  27. package/examples/system/customer.yaml +89 -0
  28. package/examples/system/orders.yaml +119 -0
  29. package/examples/system/product.yaml +27 -0
  30. package/examples/system/system.yaml +80 -0
  31. package/package.json +1 -1
  32. package/src/agents/design-gap-analyst-temporal.agent.md +452 -0
  33. package/src/agents/design-gap-analyst.agent.md +383 -0
  34. package/src/agents/design-reviewer-temporal.agent.md +412 -0
  35. package/src/agents/design-reviewer.agent.md +31 -5
  36. package/src/agents/implement-use-cases.prompt.md +179 -0
  37. package/src/agents/ux-gap-analyst.agent.md +412 -0
  38. package/src/commands/add-rabbitmq-client.js +261 -0
  39. package/src/commands/add-temporal-client.js +22 -2
  40. package/src/commands/build.js +267 -11
  41. package/src/commands/evaluate-system.js +700 -13
  42. package/src/commands/generate-entities.js +308 -16
  43. package/src/commands/generate-rabbitmq-event.js +665 -0
  44. package/src/commands/generate-rabbitmq-listener.js +205 -0
  45. package/src/commands/generate-temporal-activity.js +968 -34
  46. package/src/commands/generate-temporal-flow.js +95 -38
  47. package/src/commands/generate-temporal-system.js +708 -0
  48. package/src/skills/build-system-yaml/SKILL.md +222 -2
  49. package/src/skills/build-system-yaml/references/domain-yaml-spec.md +50 -4
  50. package/src/skills/build-system-yaml/references/module-spec.md +57 -8
  51. package/src/skills/build-temporal-system/SKILL.md +752 -0
  52. package/src/skills/build-temporal-system/references/temporal-communication-patterns.md +167 -0
  53. package/src/skills/build-temporal-system/references/temporal-domain-yaml-spec.md +449 -0
  54. package/src/skills/build-temporal-system/references/temporal-module-spec.md +353 -0
  55. package/src/skills/build-temporal-system/references/temporal-system-yaml-spec.md +326 -0
  56. package/src/skills/implement-use-case/SKILL.md +350 -0
  57. package/src/skills/implement-use-case/references/use-case-patterns.md +980 -0
  58. package/src/skills/requirements-elicitation/SKILL.md +228 -0
  59. package/src/skills/requirements-elicitation/references/interview-framework.md +260 -0
  60. package/src/skills/requirements-elicitation/references/output-templates.md +368 -0
  61. package/src/utils/bounded-context-diagram.js +844 -0
  62. package/src/utils/domain-validator.js +266 -4
  63. package/src/utils/naming.js +10 -0
  64. package/src/utils/system-validator.js +169 -11
  65. package/src/utils/system-yaml-parser.js +318 -0
  66. package/src/utils/temporal-validator.js +497 -0
  67. package/src/utils/yaml-to-entity.js +10 -7
  68. package/templates/aggregate/DomainEventHandler.java.ejs +116 -22
  69. package/templates/aggregate/JpaAggregateRoot.java.ejs +2 -2
  70. package/templates/aggregate/JpaEntity.java.ejs +2 -2
  71. package/templates/base/docker/rabbitmq-services.yaml.ejs +12 -0
  72. package/templates/base/resources/parameters/develop/kafka.yaml.ejs +5 -0
  73. package/templates/base/resources/parameters/develop/rabbitmq.yaml.ejs +15 -0
  74. package/templates/base/resources/parameters/develop/temporal.yaml.ejs +0 -3
  75. package/templates/base/resources/parameters/local/kafka.yaml.ejs +5 -0
  76. package/templates/base/resources/parameters/local/rabbitmq.yaml.ejs +15 -0
  77. package/templates/base/resources/parameters/local/temporal.yaml.ejs +0 -3
  78. package/templates/base/resources/parameters/production/kafka.yaml.ejs +39 -8
  79. package/templates/base/resources/parameters/production/rabbitmq.yaml.ejs +32 -0
  80. package/templates/base/resources/parameters/production/temporal.yaml.ejs +0 -3
  81. package/templates/base/resources/parameters/test/kafka.yaml.ejs +12 -6
  82. package/templates/base/resources/parameters/test/rabbitmq.yaml.ejs +15 -0
  83. package/templates/base/resources/parameters/test/temporal.yaml.ejs +0 -3
  84. package/templates/base/root/AGENTS.md.ejs +1 -1
  85. package/templates/crud/EndpointsController.java.ejs +1 -1
  86. package/templates/crud/ScaffoldCommand.java.ejs +5 -2
  87. package/templates/crud/ScaffoldCommandHandler.java.ejs +3 -1
  88. package/templates/crud/ScaffoldQuery.java.ejs +5 -2
  89. package/templates/crud/ScaffoldQueryHandler.java.ejs +3 -1
  90. package/templates/crud/SubEntityRemoveCommand.java.ejs +1 -1
  91. package/templates/evaluate/report.html.ejs +1447 -90
  92. package/templates/kafka-event/KafkaConfigBean.java.ejs +1 -1
  93. package/templates/kafka-event/KafkaMessageBroker.java.ejs +3 -3
  94. package/templates/ports/PortAclMapper.java.ejs +35 -0
  95. package/templates/ports/PortFeignAdapter.java.ejs +7 -22
  96. package/templates/ports/PortFeignClient.java.ejs +4 -0
  97. package/templates/ports/PortResponseDto.java.ejs +1 -1
  98. package/templates/rabbitmq-event/RabbitConfigBean.java.ejs +33 -0
  99. package/templates/rabbitmq-event/RabbitConfigExchange.java.ejs +12 -0
  100. package/templates/rabbitmq-event/RabbitMessageBroker.java.ejs +35 -0
  101. package/templates/rabbitmq-event/RabbitMessageBrokerMethod.java.ejs +9 -0
  102. package/templates/rabbitmq-listener/RabbitConfigConsumerBean.java.ejs +33 -0
  103. package/templates/rabbitmq-listener/RabbitConfigConsumerExchange.java.ejs +12 -0
  104. package/templates/rabbitmq-listener/RabbitListenerClass.java.ejs +82 -0
  105. package/templates/rabbitmq-listener/RabbitListenerSimple.java.ejs +56 -0
  106. package/templates/read-model/ReadModelJpa.java.ejs +1 -1
  107. package/templates/read-model/ReadModelJpaRepository.java.ejs +2 -0
  108. package/templates/read-model/ReadModelRabbitListener.java.ejs +71 -0
  109. package/templates/read-model/ReadModelRepositoryImpl.java.ejs +9 -5
  110. package/templates/read-model/ReadModelSyncHandler.java.ejs +2 -0
  111. package/templates/shared/configurations/kafkaConfig/KafkaConfig.java.ejs +18 -4
  112. package/templates/shared/configurations/rabbitmqConfig/RabbitMQConfig.java.ejs +100 -0
  113. package/templates/shared/configurations/temporalConfig/TemporalConfig.java.ejs +2 -64
  114. package/templates/shared/configurations/temporalConfig/TemporalWorkerFactoryLifecycle.java.ejs +41 -0
  115. package/templates/temporal-activity/ActivityImpl.java.ejs +68 -2
  116. package/templates/temporal-activity/ActivityInput.java.ejs +14 -0
  117. package/templates/temporal-activity/ActivityInterface.java.ejs +7 -1
  118. package/templates/temporal-activity/ActivityOutput.java.ejs +14 -0
  119. package/templates/temporal-activity/NestedType.java.ejs +12 -0
  120. package/templates/temporal-activity/SharedActivityInput.java.ejs +14 -0
  121. package/templates/temporal-activity/SharedActivityInterface.java.ejs +15 -0
  122. package/templates/temporal-activity/SharedActivityOutput.java.ejs +14 -0
  123. package/templates/temporal-activity/SharedNestedType.java.ejs +12 -0
  124. package/templates/temporal-flow/ModuleHeavyActivity.java.ejs +6 -0
  125. package/templates/temporal-flow/ModuleLightActivity.java.ejs +6 -0
  126. package/templates/temporal-flow/ModuleTemporalWorkerConfig.java.ejs +58 -0
  127. package/templates/temporal-flow/WorkFlowImpl.java.ejs +172 -12
  128. package/templates/temporal-flow/WorkFlowInput.java.ejs +11 -0
  129. package/templates/temporal-flow/WorkFlowInterface.java.ejs +5 -4
  130. package/templates/temporal-flow/WorkFlowService.java.ejs +42 -12
  131. package/COMMAND_EVALUATION.md +0 -911
  132. package/test-c2010.js +0 -49
  133. package/test-update-compat.js +0 -109
  134. package/test-update-lifecycle.js +0 -121
@@ -0,0 +1,100 @@
1
+ package <%= packageName %>.shared.infrastructure.configurations.rabbitmqConfig;
2
+
3
+ import org.springframework.amqp.core.*;
4
+ import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
5
+ import org.springframework.amqp.rabbit.connection.ConnectionFactory;
6
+ import org.springframework.amqp.rabbit.core.RabbitAdmin;
7
+ import org.springframework.amqp.rabbit.core.RabbitTemplate;
8
+ import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
9
+ import org.springframework.amqp.support.converter.MessageConverter;
10
+ import org.springframework.beans.factory.annotation.Value;
11
+ import org.springframework.boot.ApplicationRunner;
12
+ import org.springframework.context.annotation.Bean;
13
+ import org.springframework.context.annotation.Configuration;
14
+ import org.springframework.amqp.rabbit.annotation.EnableRabbit;
15
+ import org.springframework.retry.backoff.ExponentialBackOffPolicy;
16
+ import org.springframework.retry.policy.SimpleRetryPolicy;
17
+ import org.springframework.retry.support.RetryTemplate;
18
+ import org.slf4j.Logger;
19
+ import org.slf4j.LoggerFactory;
20
+
21
+
22
+ @Configuration
23
+ @EnableRabbit
24
+ public class RabbitMQConfig {
25
+
26
+ private static final Logger log = LoggerFactory.getLogger(RabbitMQConfig.class);
27
+
28
+ @Value("${spring.rabbitmq.listener.simple.retry.max-attempts}")
29
+ private int maxAttempts;
30
+
31
+ @Value("${spring.rabbitmq.listener.simple.retry.initial-interval}")
32
+ private long initialInterval;
33
+
34
+ @Value("${spring.rabbitmq.listener.simple.retry.multiplier:1.0}")
35
+ private double multiplier;
36
+
37
+ @Value("${spring.rabbitmq.listener.simple.retry.max-interval:10000}")
38
+ private long maxInterval;
39
+
40
+ @Bean
41
+ public MessageConverter jackson2JsonMessageConverter() {
42
+ return new Jackson2JsonMessageConverter();
43
+ }
44
+
45
+ @Bean
46
+ public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
47
+ return new RabbitAdmin(connectionFactory);
48
+ }
49
+
50
+ @Bean
51
+ public ApplicationRunner rabbitInitializer(RabbitAdmin rabbitAdmin) {
52
+ return args -> rabbitAdmin.initialize();
53
+ }
54
+
55
+ @Bean
56
+ public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory,
57
+ MessageConverter jackson2JsonMessageConverter) {
58
+ RabbitTemplate template = new RabbitTemplate(connectionFactory);
59
+ template.setMessageConverter(jackson2JsonMessageConverter);
60
+ template.setMandatory(true);
61
+ template.setConfirmCallback((correlationData, ack, cause) -> {
62
+ if (!ack) {
63
+ log.error("Message not confirmed by broker: {}", cause);
64
+ }
65
+ });
66
+ template.setReturnsCallback(returned -> {
67
+ log.error("Message returned — unroutable: exchange={}, routingKey={}, replyText={}",
68
+ returned.getExchange(), returned.getRoutingKey(), returned.getReplyText());
69
+ });
70
+ return template;
71
+ }
72
+
73
+ @Bean
74
+ public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
75
+ ConnectionFactory connectionFactory,
76
+ MessageConverter jackson2JsonMessageConverter) {
77
+
78
+ SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
79
+ factory.setConnectionFactory(connectionFactory);
80
+ factory.setMessageConverter(jackson2JsonMessageConverter);
81
+ factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
82
+ factory.setDefaultRequeueRejected(false);
83
+
84
+ // Retry template with exponential backoff
85
+ RetryTemplate retryTemplate = new RetryTemplate();
86
+ SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
87
+ retryPolicy.setMaxAttempts(maxAttempts);
88
+ retryTemplate.setRetryPolicy(retryPolicy);
89
+
90
+ ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
91
+ backOffPolicy.setInitialInterval(initialInterval);
92
+ backOffPolicy.setMultiplier(multiplier);
93
+ backOffPolicy.setMaxInterval(maxInterval);
94
+ retryTemplate.setBackOffPolicy(backOffPolicy);
95
+
96
+ factory.setRetryTemplate(retryTemplate);
97
+
98
+ return factory;
99
+ }
100
+ }
@@ -1,19 +1,12 @@
1
1
  package <%= packageName %>.shared.infrastructure.configurations.temporalConfig;
2
2
 
3
- import <%= packageName %>.shared.domain.interfaces.HeavyActivity;
4
- import <%= packageName %>.shared.domain.interfaces.LightActivity;
5
3
  import io.temporal.client.WorkflowClient;
6
4
  import io.temporal.serviceclient.WorkflowServiceStubs;
7
- import io.temporal.worker.Worker;
8
5
  import io.temporal.worker.WorkerFactory;
9
- import io.temporal.worker.WorkerOptions;
10
- import jakarta.annotation.PreDestroy;
11
6
  import org.springframework.beans.factory.annotation.Value;
12
7
  import org.springframework.context.annotation.Bean;
13
8
  import org.springframework.context.annotation.Configuration;
14
9
 
15
- import java.util.List;
16
-
17
10
  @Configuration
18
11
  public class TemporalConfig {
19
12
 
@@ -23,26 +16,6 @@ public class TemporalConfig {
23
16
  @Value("${temporal.namespace}")
24
17
  private String namespace;
25
18
 
26
- @Value("${temporal.flow-queue}")
27
- private String flowQueue;
28
-
29
- @Value("${temporal.number-flow-worker}")
30
- private Integer numberFlowWorker;
31
-
32
- @Value("${temporal.heavy-queue}")
33
- private String heavyQueue;
34
-
35
- @Value("${temporal.number-heavy-worker}")
36
- private Integer numberHeavyWorker;
37
-
38
- @Value("${temporal.light-queue}")
39
- private String lightQueue;
40
-
41
- @Value("${temporal.number-light-worker}")
42
- private Integer numberLightWorker;
43
-
44
- private WorkerFactory workerFactory;
45
-
46
19
  @Bean
47
20
  public WorkflowServiceStubs workflowServiceStubs() {
48
21
  return WorkflowServiceStubs.newServiceStubs(
@@ -63,42 +36,7 @@ public class TemporalConfig {
63
36
  }
64
37
 
65
38
  @Bean
66
- public WorkerFactory workerFactory(WorkflowClient client,
67
- List<HeavyActivity> heavyActivities,
68
- List<LightActivity> lightActivities) {
69
-
70
- workerFactory = WorkerFactory.newInstance(client);
71
-
72
- // 1. WORKER DE FLUJO (Orquestador)
73
- WorkerOptions workflowOptions = WorkerOptions.newBuilder()
74
- .setMaxConcurrentWorkflowTaskExecutionSize(numberFlowWorker)
75
- .build();
76
- Worker workflowWorker = workerFactory.newWorker(flowQueue, workflowOptions);
77
- // TODO: register your workflow implementation types here
78
- // workflowWorker.registerWorkflowImplementationTypes(MyWorkflowImpl.class);
79
-
80
- // 2. WORKER PESADO (tareas complejas)
81
- WorkerOptions heavyOptions = WorkerOptions.newBuilder()
82
- .setMaxConcurrentActivityExecutionSize(numberHeavyWorker)
83
- .build();
84
- Worker heavyWorker = workerFactory.newWorker(heavyQueue, heavyOptions);
85
- heavyWorker.registerActivitiesImplementations(heavyActivities.toArray());
86
-
87
- // 3. WORKER LIGERO (tareas rápidas)
88
- WorkerOptions lightOptions = WorkerOptions.newBuilder()
89
- .setMaxConcurrentActivityExecutionSize(numberLightWorker)
90
- .build();
91
- Worker lightWorker = workerFactory.newWorker(lightQueue, lightOptions);
92
- lightWorker.registerActivitiesImplementations(lightActivities.toArray());
93
-
94
- workerFactory.start();
95
- return workerFactory;
96
- }
97
-
98
- @PreDestroy
99
- public void destroy() {
100
- if (workerFactory != null) {
101
- workerFactory.shutdown();
102
- }
39
+ public WorkerFactory workerFactory(WorkflowClient client) {
40
+ return WorkerFactory.newInstance(client);
103
41
  }
104
42
  }
@@ -0,0 +1,41 @@
1
+ package <%= packageName %>.shared.infrastructure.configurations.temporalConfig;
2
+
3
+ import io.temporal.worker.WorkerFactory;
4
+ import jakarta.annotation.PreDestroy;
5
+ import org.springframework.context.SmartLifecycle;
6
+ import org.springframework.stereotype.Component;
7
+
8
+ @Component
9
+ public class TemporalWorkerFactoryLifecycle implements SmartLifecycle {
10
+
11
+ private final WorkerFactory workerFactory;
12
+ private volatile boolean running = false;
13
+
14
+ public TemporalWorkerFactoryLifecycle(WorkerFactory workerFactory) {
15
+ this.workerFactory = workerFactory;
16
+ }
17
+
18
+ @Override
19
+ public void start() {
20
+ workerFactory.start();
21
+ running = true;
22
+ }
23
+
24
+ @Override
25
+ public void stop() {
26
+ if (workerFactory != null) {
27
+ workerFactory.shutdown();
28
+ }
29
+ running = false;
30
+ }
31
+
32
+ @Override
33
+ public boolean isRunning() {
34
+ return running;
35
+ }
36
+
37
+ @Override
38
+ public int getPhase() {
39
+ return Integer.MAX_VALUE;
40
+ }
41
+ }
@@ -1,14 +1,80 @@
1
1
  package <%= packageName %>.<%= moduleName %>.infrastructure.adapters.activities;
2
2
 
3
+ <% if (shared) { %>
4
+ import <%= packageName %>.shared.domain.contracts.<%= moduleName %>.<%= activityPascalCase %>Activity;
5
+ <% if (hasInput) { %>
6
+ import <%= packageName %>.shared.domain.contracts.<%= moduleName %>.<%= activityPascalCase %>Input;
7
+ <% } %>
8
+ <% if (hasOutput) { %>
9
+ import <%= packageName %>.shared.domain.contracts.<%= moduleName %>.<%= activityPascalCase %>Output;
10
+ <% } %>
11
+ <% } else { %>
3
12
  import <%= packageName %>.<%= moduleName %>.application.ports.<%= activityPascalCase %>Activity;
4
- import <%= packageName %>.shared.domain.interfaces.<%= activityCategory %>;
13
+ <% if (hasInput) { %>
14
+ import <%= packageName %>.<%= moduleName %>.application.dtos.temporal.<%= activityPascalCase %>Input;
15
+ <% } %>
16
+ <% if (hasOutput) { %>
17
+ import <%= packageName %>.<%= moduleName %>.application.dtos.temporal.<%= activityPascalCase %>Output;
18
+ <% } %>
19
+ <% } %>
20
+ import <%= packageName %>.<%= moduleName %>.domain.interfaces.<%= activityCategory %>;
21
+ <% if (isQueryActivity && queryMeta) { %>
22
+ import <%= packageName %>.<%= moduleName %>.domain.models.entities.<%= queryMeta.aggregateName %>;
23
+ import <%= packageName %>.<%= moduleName %>.domain.repositories.<%= queryMeta.aggregateName %>Repository;
24
+ import <%= packageName %>.shared.domain.customExceptions.NotFoundException;
25
+ <% if (queryMeta.voMappingImports && queryMeta.voMappingImports.length > 0) { -%>
26
+ <% queryMeta.voMappingImports.forEach(imp => { -%>
27
+ <%- imp %>
28
+ <% }); -%>
29
+ <% } -%>
30
+ <% } %>
5
31
  import org.springframework.stereotype.Component;
32
+ import org.springframework.transaction.annotation.Transactional;
6
33
 
7
34
  @Component
8
35
  public class <%= activityPascalCase %>ActivityImpl implements <%= activityPascalCase %>Activity, <%= activityCategory %> {
36
+ <% if (isQueryActivity && queryMeta) { %>
37
+
38
+ private final <%= queryMeta.aggregateName %>Repository repository;
39
+
40
+ public <%= activityPascalCase %>ActivityImpl(<%= queryMeta.aggregateName %>Repository repository) {
41
+ this.repository = repository;
42
+ }
43
+
44
+ @Override
45
+ @Transactional(readOnly = true)
46
+ public <%= activityPascalCase %>Output execute(<%= activityPascalCase %>Input input) {
47
+ <% const findMethod = (queryMeta.needsEagerLoad && queryMeta.eagerLoadField)
48
+ ? 'findByIdWith' + queryMeta.eagerLoadField.fieldPascal
49
+ : 'findById'; -%>
50
+ <%= queryMeta.aggregateName %> entity = repository.<%= findMethod %>(<%= queryMeta.idFieldAccessor %>)
51
+ .orElseThrow(() -> new NotFoundException("<%= queryMeta.aggregateName %> not found with id: " + <%= queryMeta.idFieldAccessor %>));
52
+ <% if (queryMeta.outputMappings.some(m => m.preDeclaration)) { -%>
53
+ <% queryMeta.outputMappings.filter(m => m.preDeclaration).forEach(m => { %>
54
+ <%- m.preDeclaration.varType %> <%- m.preDeclaration.varName %> = <%- m.preDeclaration.getter %> != null
55
+ ? new <%- m.preDeclaration.varType %>(
56
+ <% m.preDeclaration.ntArgs.forEach((arg, ai) => { -%>
57
+ <%- arg %><%= ai < m.preDeclaration.ntArgs.length - 1 ? ',' : '' %>
58
+ <% }); -%>
59
+ )
60
+ : null;
61
+ <% }); -%>
62
+ <% } -%>
63
+ return new <%= activityPascalCase %>Output(
64
+ <% queryMeta.outputMappings.forEach((m, i) => { -%>
65
+ <%- m.accessor %><%= i < queryMeta.outputMappings.length - 1 ? ',' : '' %>
66
+ <% }); -%>
67
+ );
68
+ }
69
+ <% } else { %>
9
70
 
10
71
  @Override
11
- public void execute(String flowId) {
72
+ @Transactional
73
+ public <%= hasOutput ? activityPascalCase + 'Output' : 'void' %> execute(<%= hasInput ? activityPascalCase + 'Input input' : '' %>) {
12
74
  //todo: implement the logic
75
+ <% if (hasOutput) { %>
76
+ throw new UnsupportedOperationException("Not implemented yet");
77
+ <% } %>
13
78
  }
79
+ <% } %>
14
80
  }
@@ -0,0 +1,14 @@
1
+ package <%= packageName %>.<%= moduleName %>.application.dtos.temporal;
2
+ <%
3
+ const _allImports = [...(imports || []), ...((typeof nestedTypeImportLines !== 'undefined' ? nestedTypeImportLines : []) || [])];
4
+ if (_allImports.length > 0) { %>
5
+
6
+ <%= _allImports.join('\n') %>
7
+ <% } %>
8
+
9
+ public record <%= activityPascalCase %>Input(
10
+ <% inputFields.forEach((field, index) => { %>
11
+ <%- field.javaType %> <%= field.name %><%= index < inputFields.length - 1 ? ',' : '' %>
12
+ <% }); %>
13
+ ) {
14
+ }
@@ -2,10 +2,16 @@ package <%= packageName %>.<%= moduleName %>.application.ports;
2
2
 
3
3
  import io.temporal.activity.ActivityInterface;
4
4
  import io.temporal.activity.ActivityMethod;
5
+ <% if (hasInput) { %>
6
+ import <%= packageName %>.<%= moduleName %>.application.dtos.temporal.<%= activityPascalCase %>Input;
7
+ <% } %>
8
+ <% if (hasOutput) { %>
9
+ import <%= packageName %>.<%= moduleName %>.application.dtos.temporal.<%= activityPascalCase %>Output;
10
+ <% } %>
5
11
 
6
12
  @ActivityInterface
7
13
  public interface <%= activityPascalCase %>Activity {
8
14
 
9
15
  @ActivityMethod(name = "<%= activityPascalCase %>")
10
- void execute(String flowId);
16
+ <%= hasOutput ? activityPascalCase + 'Output' : 'void' %> execute(<%= hasInput ? activityPascalCase + 'Input input' : '' %>);
11
17
  }
@@ -0,0 +1,14 @@
1
+ package <%= packageName %>.<%= moduleName %>.application.dtos.temporal;
2
+ <%
3
+ const _allImports = [...(imports || []), ...((typeof nestedTypeImportLines !== 'undefined' ? nestedTypeImportLines : []) || [])];
4
+ if (_allImports.length > 0) { %>
5
+
6
+ <%= _allImports.join('\n') %>
7
+ <% } %>
8
+
9
+ public record <%= activityPascalCase %>Output(
10
+ <% outputFields.forEach((field, index) => { %>
11
+ <%- field.javaType %> <%= field.name %><%= index < outputFields.length - 1 ? ',' : '' %>
12
+ <% }); %>
13
+ ) {
14
+ }
@@ -0,0 +1,12 @@
1
+ package <%= packageName %>.<%= moduleName %>.application.dtos.temporal;
2
+ <% if (imports.length > 0) { %>
3
+
4
+ <%= imports.join('\n') %>
5
+ <% } %>
6
+
7
+ public record <%= typeName %>(
8
+ <% fields.forEach((field, index) => { %>
9
+ <%- field.javaType %> <%= field.name %><%= index < fields.length - 1 ? ',' : '' %>
10
+ <% }); %>
11
+ ) {
12
+ }
@@ -0,0 +1,14 @@
1
+ package <%= packageName %>.shared.domain.contracts.<%= targetModule %>;
2
+ <%
3
+ const _allImports = [...(imports || []), ...((typeof nestedTypeImportLines !== 'undefined' ? nestedTypeImportLines : []) || [])];
4
+ if (_allImports.length > 0) { %>
5
+
6
+ <%= _allImports.join('\n') %>
7
+ <% } %>
8
+
9
+ public record <%= activityPascalCase %>Input(
10
+ <% inputFields.forEach((field, index) => { %>
11
+ <%- field.javaType %> <%= field.name %><%= index < inputFields.length - 1 ? ',' : '' %>
12
+ <% }); %>
13
+ ) {
14
+ }
@@ -0,0 +1,15 @@
1
+ package <%= packageName %>.shared.domain.contracts.<%= targetModule %>;
2
+
3
+ import io.temporal.activity.ActivityInterface;
4
+ import io.temporal.activity.ActivityMethod;
5
+ <% if (hasInput) { %>
6
+ <% } %>
7
+ <% if (hasOutput) { %>
8
+ <% } %>
9
+
10
+ @ActivityInterface
11
+ public interface <%= activityPascalCase %>Activity {
12
+
13
+ @ActivityMethod(name = "<%= activityPascalCase %>")
14
+ <%= hasOutput ? activityPascalCase + 'Output' : 'void' %> execute(<%= hasInput ? activityPascalCase + 'Input input' : '' %>);
15
+ }
@@ -0,0 +1,14 @@
1
+ package <%= packageName %>.shared.domain.contracts.<%= targetModule %>;
2
+ <%
3
+ const _allImports = [...(imports || []), ...((typeof nestedTypeImportLines !== 'undefined' ? nestedTypeImportLines : []) || [])];
4
+ if (_allImports.length > 0) { %>
5
+
6
+ <%= _allImports.join('\n') %>
7
+ <% } %>
8
+
9
+ public record <%= activityPascalCase %>Output(
10
+ <% outputFields.forEach((field, index) => { %>
11
+ <%- field.javaType %> <%= field.name %><%= index < outputFields.length - 1 ? ',' : '' %>
12
+ <% }); %>
13
+ ) {
14
+ }
@@ -0,0 +1,12 @@
1
+ package <%= packageName %>.shared.domain.contracts.<%= targetModule %>;
2
+ <% if (imports.length > 0) { %>
3
+
4
+ <%= imports.join('\n') %>
5
+ <% } %>
6
+
7
+ public record <%= typeName %>(
8
+ <% fields.forEach((field, index) => { %>
9
+ <%- field.javaType %> <%= field.name %><%= index < fields.length - 1 ? ',' : '' %>
10
+ <% }); %>
11
+ ) {
12
+ }
@@ -0,0 +1,6 @@
1
+ package <%= packageName %>.<%= moduleName %>.domain.interfaces;
2
+
3
+ import <%= packageName %>.shared.domain.interfaces.HeavyActivity;
4
+
5
+ public interface <%= modulePascalCase %>HeavyActivity extends HeavyActivity {
6
+ }
@@ -0,0 +1,6 @@
1
+ package <%= packageName %>.<%= moduleName %>.domain.interfaces;
2
+
3
+ import <%= packageName %>.shared.domain.interfaces.LightActivity;
4
+
5
+ public interface <%= modulePascalCase %>LightActivity extends LightActivity {
6
+ }
@@ -0,0 +1,58 @@
1
+ package <%= packageName %>.<%= moduleName %>.infrastructure.configurations;
2
+
3
+ import <%= packageName %>.<%= moduleName %>.domain.interfaces.<%= modulePascalCase %>HeavyActivity;
4
+ import <%= packageName %>.<%= moduleName %>.domain.interfaces.<%= modulePascalCase %>LightActivity;
5
+ import io.temporal.worker.Worker;
6
+ import io.temporal.worker.WorkerFactory;
7
+ import io.temporal.worker.WorkerOptions;
8
+ import org.springframework.beans.factory.annotation.Value;
9
+ import org.springframework.context.annotation.Bean;
10
+ import org.springframework.context.annotation.Configuration;
11
+
12
+ import java.util.List;
13
+
14
+ @Configuration
15
+ public class <%= modulePascalCase %>TemporalWorkerConfig {
16
+
17
+ @Value("${temporal.number-flow-worker}")
18
+ private Integer numberFlowWorker;
19
+
20
+ @Value("${temporal.number-heavy-worker}")
21
+ private Integer numberHeavyWorker;
22
+
23
+ @Value("${temporal.number-light-worker}")
24
+ private Integer numberLightWorker;
25
+
26
+ public static final String FLOW_QUEUE = "<%= moduleScreamingSnake %>_WORKFLOW_QUEUE";
27
+ public static final String HEAVY_QUEUE = "<%= moduleScreamingSnake %>_HEAVY_TASK_QUEUE";
28
+ public static final String LIGHT_QUEUE = "<%= moduleScreamingSnake %>_LIGHT_TASK_QUEUE";
29
+
30
+ @Bean
31
+ public Worker <%= moduleCamelCase %>WorkflowWorker(WorkerFactory workerFactory,
32
+ List<<%= modulePascalCase %>HeavyActivity> heavyActivities,
33
+ List<<%= modulePascalCase %>LightActivity> lightActivities) {
34
+
35
+ // 1. WORKER DE FLUJO (Orquestador)
36
+ WorkerOptions workflowOptions = WorkerOptions.newBuilder()
37
+ .setMaxConcurrentWorkflowTaskExecutionSize(numberFlowWorker)
38
+ .build();
39
+ Worker workflowWorker = workerFactory.newWorker(FLOW_QUEUE, workflowOptions);
40
+ // registered by eva g temporal-flow
41
+
42
+ // 2. WORKER PESADO (tareas complejas)
43
+ WorkerOptions heavyOptions = WorkerOptions.newBuilder()
44
+ .setMaxConcurrentActivityExecutionSize(numberHeavyWorker)
45
+ .build();
46
+ Worker heavyWorker = workerFactory.newWorker(HEAVY_QUEUE, heavyOptions);
47
+ heavyWorker.registerActivitiesImplementations(heavyActivities.toArray());
48
+
49
+ // 3. WORKER LIGERO (tareas rápidas)
50
+ WorkerOptions lightOptions = WorkerOptions.newBuilder()
51
+ .setMaxConcurrentActivityExecutionSize(numberLightWorker)
52
+ .build();
53
+ Worker lightWorker = workerFactory.newWorker(LIGHT_QUEUE, lightOptions);
54
+ lightWorker.registerActivitiesImplementations(lightActivities.toArray());
55
+
56
+ return workflowWorker;
57
+ }
58
+ }