eva4j 1.0.13 → 1.0.15
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.
- package/AGENTS.md +314 -10
- package/COMMAND_EVALUATION.md +15 -16
- package/DOMAIN_YAML_GUIDE.md +576 -10
- package/FUTURE_FEATURES.md +1627 -1168
- package/README.md +318 -13
- package/bin/eva4j.js +34 -0
- package/config/defaults.json +1 -0
- package/design-system.md +797 -0
- package/docs/commands/EVALUATE_SYSTEM.md +994 -0
- package/docs/commands/GENERATE_ENTITIES.md +795 -6
- package/docs/commands/INDEX.md +10 -1
- package/examples/domain-endpoints-relations.yaml +353 -0
- package/examples/domain-endpoints-versioned.yaml +144 -0
- package/examples/domain-endpoints.yaml +135 -0
- package/examples/domain-events.yaml +166 -20
- package/examples/domain-listeners.yaml +212 -0
- package/examples/domain-one-to-many.yaml +1 -0
- package/examples/domain-one-to-one.yaml +1 -0
- package/examples/domain-ports.yaml +414 -0
- package/examples/domain-soft-delete.yaml +47 -44
- package/examples/system/notification.yaml +147 -0
- package/examples/system/product.yaml +185 -0
- package/examples/system/system.yaml +112 -0
- package/examples/system-report.html +971 -0
- package/examples/system.yaml +332 -0
- package/package.json +2 -1
- package/src/commands/build.js +714 -0
- package/src/commands/create.js +7 -3
- package/src/commands/detach.js +1 -0
- package/src/commands/evaluate-system.js +610 -0
- package/src/commands/generate-entities.js +1331 -49
- package/src/commands/generate-http-exchange.js +2 -0
- package/src/commands/generate-kafka-event.js +98 -11
- package/src/generators/base-generator.js +8 -1
- package/src/generators/postman-generator.js +188 -0
- package/src/generators/shared-generator.js +10 -0
- package/src/utils/config-manager.js +54 -0
- package/src/utils/context-builder.js +1 -0
- package/src/utils/domain-diagram.js +192 -0
- package/src/utils/domain-validator.js +970 -0
- package/src/utils/fake-data.js +376 -0
- package/src/utils/naming.js +3 -2
- package/src/utils/system-validator.js +434 -0
- package/src/utils/yaml-to-entity.js +302 -8
- package/templates/aggregate/AggregateMapper.java.ejs +3 -2
- package/templates/aggregate/AggregateRepository.java.ejs +8 -2
- package/templates/aggregate/AggregateRepositoryImpl.java.ejs +13 -3
- package/templates/aggregate/AggregateRoot.java.ejs +60 -2
- package/templates/aggregate/DomainEventHandler.java.ejs +27 -20
- package/templates/aggregate/DomainEventRecord.java.ejs +24 -8
- package/templates/aggregate/DomainEventSnapshot.java.ejs +46 -0
- package/templates/aggregate/JpaAggregateRoot.java.ejs +6 -0
- package/templates/aggregate/JpaRepository.java.ejs +5 -0
- package/templates/base/gradle/build.gradle.ejs +3 -2
- package/templates/base/root/AGENTS.md.ejs +306 -45
- package/templates/base/root/skill-build-domain-yaml-references-generate-entities.md.ejs +1663 -0
- package/templates/base/root/skill-build-system-yaml.ejs +1446 -0
- package/templates/base/root/system.yaml.ejs +97 -0
- package/templates/crud/ApplicationMapper.java.ejs +4 -0
- package/templates/crud/Controller.java.ejs +4 -4
- package/templates/crud/CreateCommand.java.ejs +4 -0
- package/templates/crud/CreateItemDto.java.ejs +4 -0
- package/templates/crud/CreateValueObjectDto.java.ejs +4 -0
- package/templates/crud/DeleteCommandHandler.java.ejs +10 -2
- package/templates/crud/EndpointsController.java.ejs +178 -0
- package/templates/crud/FindByQuery.java.ejs +17 -0
- package/templates/crud/FindByQueryHandler.java.ejs +57 -0
- package/templates/crud/ListQuery.java.ejs +1 -1
- package/templates/crud/ListQueryHandler.java.ejs +8 -8
- package/templates/crud/ScaffoldCommand.java.ejs +12 -0
- package/templates/crud/ScaffoldCommandHandler.java.ejs +43 -0
- package/templates/crud/ScaffoldQuery.java.ejs +13 -0
- package/templates/crud/ScaffoldQueryHandler.java.ejs +41 -0
- package/templates/crud/SubEntityAddCommand.java.ejs +21 -0
- package/templates/crud/SubEntityAddCommandHandler.java.ejs +43 -0
- package/templates/crud/SubEntityRemoveCommand.java.ejs +9 -0
- package/templates/crud/SubEntityRemoveCommandHandler.java.ejs +42 -0
- package/templates/crud/TransitionCommand.java.ejs +9 -0
- package/templates/crud/TransitionCommandHandler.java.ejs +39 -0
- package/templates/crud/UpdateCommand.java.ejs +4 -0
- package/templates/evaluate/report.html.ejs +1363 -0
- package/templates/kafka-event/DomainEventHandlerMethod.ejs +3 -1
- package/templates/kafka-event/Event.java.ejs +16 -0
- package/templates/kafka-listener/KafkaController.java.ejs +1 -1
- package/templates/kafka-listener/KafkaListenerClass.java.ejs +1 -1
- package/templates/kafka-listener/ListenerClass.java.ejs +65 -0
- package/templates/kafka-listener/ListenerCommand.java.ejs +31 -0
- package/templates/kafka-listener/ListenerCommandHandler.java.ejs +23 -0
- package/templates/kafka-listener/ListenerIntegrationEvent.java.ejs +37 -0
- package/templates/kafka-listener/ListenerMethod.java.ejs +1 -1
- package/templates/kafka-listener/ListenerNestedType.java.ejs +28 -0
- package/templates/mock/MockEvent.java.ejs +10 -0
- package/templates/mock/MockMessageBrokerImpl.java.ejs +35 -0
- package/templates/mock/MockMessageBrokerImplMethod.java.ejs +6 -0
- package/templates/mock/SpringEventListener.java.ejs +61 -0
- package/templates/ports/PortDomainModel.java.ejs +35 -0
- package/templates/ports/PortFeignAdapter.java.ejs +67 -0
- package/templates/ports/PortFeignClient.java.ejs +45 -0
- package/templates/ports/PortFeignConfig.java.ejs +24 -0
- package/templates/ports/PortInterface.java.ejs +45 -0
- package/templates/ports/PortNestedType.java.ejs +28 -0
- package/templates/ports/PortRequestDto.java.ejs +30 -0
- package/templates/ports/PortResponseDto.java.ejs +28 -0
- package/templates/postman/Collection.json.ejs +1 -1
- package/templates/postman/UnifiedCollection.json.ejs +185 -0
- package/templates/shared/configurations/eventPublicationConfig/EventPublicationSchemaConfig.java.ejs +109 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
package <%= packageName %>.<%= moduleName %>.application.usecases;
|
|
2
|
+
|
|
3
|
+
import <%= packageName %>.<%= moduleName %>.application.dtos.<%= aggregateName %>ResponseDto;
|
|
4
|
+
import <%= packageName %>.<%= moduleName %>.application.queries.<%= useCaseName %>Query;
|
|
5
|
+
import <%= packageName %>.<%= moduleName %>.domain.repositories.<%= aggregateName %>Repository;
|
|
6
|
+
import <%= packageName %>.shared.domain.annotations.ApplicationComponent;
|
|
7
|
+
import <%= packageName %>.shared.domain.interfaces.QueryHandler;
|
|
8
|
+
import lombok.extern.slf4j.Slf4j;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* <%= useCaseName %>QueryHandler
|
|
12
|
+
* TODO: Implement the query logic for "<%= useCaseName %>".
|
|
13
|
+
*
|
|
14
|
+
* Suggested steps:
|
|
15
|
+
* 1. Read parameters from the query record
|
|
16
|
+
* 2. Retrieve data from the repository
|
|
17
|
+
* 3. Map the result to a DTO and return it
|
|
18
|
+
*/
|
|
19
|
+
@Slf4j
|
|
20
|
+
@ApplicationComponent
|
|
21
|
+
public class <%= useCaseName %>QueryHandler implements QueryHandler<<%= useCaseName %>Query, <%= aggregateName %>ResponseDto> {
|
|
22
|
+
|
|
23
|
+
private final <%= aggregateName %>Repository repository;
|
|
24
|
+
|
|
25
|
+
public <%= useCaseName %>QueryHandler(<%= aggregateName %>Repository repository) {
|
|
26
|
+
this.repository = repository;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@Override
|
|
30
|
+
public <%= aggregateName %>ResponseDto handle(<%= useCaseName %>Query query) {
|
|
31
|
+
log.info("Handling <%= useCaseName %>Query: {}", query);
|
|
32
|
+
|
|
33
|
+
// TODO: Implement query logic
|
|
34
|
+
// Example:
|
|
35
|
+
// return repository.findById(query.id())
|
|
36
|
+
// .map(mapper::toDto)
|
|
37
|
+
// .orElseThrow(() -> new EntityNotFoundException("<%= aggregateName %> not found"));
|
|
38
|
+
|
|
39
|
+
throw new UnsupportedOperationException("<%= useCaseName %> not yet implemented");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package <%= packageName %>.<%= moduleName %>.application.commands;
|
|
2
|
+
|
|
3
|
+
<% (imports || []).forEach(imp => { %>
|
|
4
|
+
<%- imp %>
|
|
5
|
+
<% }); %>
|
|
6
|
+
import <%= packageName %>.shared.domain.interfaces.Command;
|
|
7
|
+
import io.swagger.v3.oas.annotations.media.Schema;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* <%= useCaseName %>Command
|
|
11
|
+
* Adds a new <%= entityName %> to the <%= aggregateName %> aggregate.
|
|
12
|
+
*/
|
|
13
|
+
public record <%= useCaseName %>Command(
|
|
14
|
+
<%- idType %> id<% if (entityFields && entityFields.length > 0) { %>,<% } %>
|
|
15
|
+
<% (entityFields || []).forEach(function(field, idx) { %>
|
|
16
|
+
<% if (field.schemaExample) { %>
|
|
17
|
+
@Schema(example = "<%= field.schemaExample %>")
|
|
18
|
+
<% } %>
|
|
19
|
+
<%- field.javaType %> <%= field.name %><% if (idx < entityFields.length - 1) { %>,<% } %>
|
|
20
|
+
<% }); %>
|
|
21
|
+
) implements Command {}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
package <%= packageName %>.<%= moduleName %>.application.usecases;
|
|
2
|
+
|
|
3
|
+
import <%= packageName %>.<%= moduleName %>.application.commands.<%= useCaseName %>Command;
|
|
4
|
+
import <%= packageName %>.<%= moduleName %>.domain.models.entities.<%= aggregateName %>;
|
|
5
|
+
import <%= packageName %>.<%= moduleName %>.domain.models.entities.<%= entityName %>;
|
|
6
|
+
import <%= packageName %>.<%= moduleName %>.domain.repositories.<%= aggregateName %>Repository;
|
|
7
|
+
import <%= packageName %>.shared.domain.annotations.ApplicationComponent;
|
|
8
|
+
import <%= packageName %>.shared.domain.customExceptions.NotFoundException;
|
|
9
|
+
import <%= packageName %>.shared.domain.interfaces.CommandHandler;
|
|
10
|
+
import lombok.extern.slf4j.Slf4j;
|
|
11
|
+
import org.springframework.transaction.annotation.Transactional;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* <%= useCaseName %>CommandHandler
|
|
15
|
+
* Loads the <%= aggregateName %> aggregate and adds a new <%= entityName %> to it.
|
|
16
|
+
*
|
|
17
|
+
* The aggregate root must expose: <%= addMethodName %>(<%= entityName %> item)
|
|
18
|
+
*/
|
|
19
|
+
@Slf4j
|
|
20
|
+
@ApplicationComponent
|
|
21
|
+
public class <%= useCaseName %>CommandHandler implements CommandHandler<<%= useCaseName %>Command> {
|
|
22
|
+
|
|
23
|
+
private final <%= aggregateName %>Repository repository;
|
|
24
|
+
|
|
25
|
+
public <%= useCaseName %>CommandHandler(<%= aggregateName %>Repository repository) {
|
|
26
|
+
this.repository = repository;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@Override
|
|
30
|
+
@Transactional
|
|
31
|
+
public void handle(<%= useCaseName %>Command command) {
|
|
32
|
+
log.info("Handling <%= useCaseName %>Command for <%= aggregateName %> id: {}", command.id());
|
|
33
|
+
|
|
34
|
+
<%= aggregateName %> entity = repository.findById(command.id())
|
|
35
|
+
.orElseThrow(() -> new NotFoundException("<%= aggregateName %> not found with id: " + command.id()));
|
|
36
|
+
|
|
37
|
+
<%= entityName %> item = new <%= entityName %>(<% (entityFields || []).forEach(function(field, idx) { %>command.<%= field.name %>()<% if (idx < entityFields.length - 1) { %>, <% } %><% }); %>);
|
|
38
|
+
entity.<%= addMethodName %>(item);
|
|
39
|
+
repository.save(entity);
|
|
40
|
+
|
|
41
|
+
log.info("<%= entityName %> added to <%= aggregateName %> id: {}", command.id());
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
package <%= packageName %>.<%= moduleName %>.application.commands;
|
|
2
|
+
|
|
3
|
+
import <%= packageName %>.shared.domain.interfaces.Command;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* <%= useCaseName %>Command
|
|
7
|
+
* Removes the <%= entityName %> identified by itemId from the <%= aggregateName %> aggregate.
|
|
8
|
+
*/
|
|
9
|
+
public record <%= useCaseName %>Command(<%- idType %> id, String itemId) implements Command {}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
package <%= packageName %>.<%= moduleName %>.application.usecases;
|
|
2
|
+
|
|
3
|
+
import <%= packageName %>.<%= moduleName %>.application.commands.<%= useCaseName %>Command;
|
|
4
|
+
import <%= packageName %>.<%= moduleName %>.domain.models.entities.<%= aggregateName %>;
|
|
5
|
+
import <%= packageName %>.<%= moduleName %>.domain.repositories.<%= aggregateName %>Repository;
|
|
6
|
+
import <%= packageName %>.shared.domain.annotations.ApplicationComponent;
|
|
7
|
+
import <%= packageName %>.shared.domain.customExceptions.NotFoundException;
|
|
8
|
+
import <%= packageName %>.shared.domain.interfaces.CommandHandler;
|
|
9
|
+
import lombok.extern.slf4j.Slf4j;
|
|
10
|
+
import org.springframework.transaction.annotation.Transactional;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* <%= useCaseName %>CommandHandler
|
|
14
|
+
* Loads the <%= aggregateName %> aggregate and removes the <%= entityName %> by itemId.
|
|
15
|
+
*
|
|
16
|
+
* The aggregate root must expose: <%= removeMethodName %>(String itemId)
|
|
17
|
+
*/
|
|
18
|
+
@Slf4j
|
|
19
|
+
@ApplicationComponent
|
|
20
|
+
public class <%= useCaseName %>CommandHandler implements CommandHandler<<%= useCaseName %>Command> {
|
|
21
|
+
|
|
22
|
+
private final <%= aggregateName %>Repository repository;
|
|
23
|
+
|
|
24
|
+
public <%= useCaseName %>CommandHandler(<%= aggregateName %>Repository repository) {
|
|
25
|
+
this.repository = repository;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@Override
|
|
29
|
+
@Transactional
|
|
30
|
+
public void handle(<%= useCaseName %>Command command) {
|
|
31
|
+
log.info("Handling <%= useCaseName %>Command for <%= aggregateName %> id: {}, itemId: {}",
|
|
32
|
+
command.id(), command.itemId());
|
|
33
|
+
|
|
34
|
+
<%= aggregateName %> entity = repository.findById(command.id())
|
|
35
|
+
.orElseThrow(() -> new NotFoundException("<%= aggregateName %> not found with id: " + command.id()));
|
|
36
|
+
|
|
37
|
+
entity.<%= removeMethodName %>(command.itemId());
|
|
38
|
+
repository.save(entity);
|
|
39
|
+
|
|
40
|
+
log.info("<%= entityName %> id: {} removed from <%= aggregateName %> id: {}", command.itemId(), command.id());
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
package <%= packageName %>.<%= moduleName %>.application.commands;
|
|
2
|
+
|
|
3
|
+
import <%= packageName %>.shared.domain.interfaces.Command;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* <%= useCaseName %>Command
|
|
7
|
+
* Triggers the '<%= domainMethod %>' state transition on the <%= aggregateName %> aggregate.
|
|
8
|
+
*/
|
|
9
|
+
public record <%= useCaseName %>Command(<%- idType %> id) implements Command {}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
package <%= packageName %>.<%= moduleName %>.application.usecases;
|
|
2
|
+
|
|
3
|
+
import <%= packageName %>.<%= moduleName %>.application.commands.<%= useCaseName %>Command;
|
|
4
|
+
import <%= packageName %>.<%= moduleName %>.domain.models.entities.<%= aggregateName %>;
|
|
5
|
+
import <%= packageName %>.<%= moduleName %>.domain.repositories.<%= aggregateName %>Repository;
|
|
6
|
+
import <%= packageName %>.shared.domain.annotations.ApplicationComponent;
|
|
7
|
+
import <%= packageName %>.shared.domain.customExceptions.NotFoundException;
|
|
8
|
+
import <%= packageName %>.shared.domain.interfaces.CommandHandler;
|
|
9
|
+
import lombok.extern.slf4j.Slf4j;
|
|
10
|
+
import org.springframework.transaction.annotation.Transactional;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* <%= useCaseName %>CommandHandler
|
|
14
|
+
* Loads the <%= aggregateName %> aggregate and calls entity.<%= domainMethod %>() to execute the transition.
|
|
15
|
+
*/
|
|
16
|
+
@Slf4j
|
|
17
|
+
@ApplicationComponent
|
|
18
|
+
public class <%= useCaseName %>CommandHandler implements CommandHandler<<%= useCaseName %>Command> {
|
|
19
|
+
|
|
20
|
+
private final <%= aggregateName %>Repository repository;
|
|
21
|
+
|
|
22
|
+
public <%= useCaseName %>CommandHandler(<%= aggregateName %>Repository repository) {
|
|
23
|
+
this.repository = repository;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@Override
|
|
27
|
+
@Transactional
|
|
28
|
+
public void handle(<%= useCaseName %>Command command) {
|
|
29
|
+
log.info("Handling <%= useCaseName %>Command for id: {}", command.id());
|
|
30
|
+
|
|
31
|
+
<%= aggregateName %> entity = repository.findById(command.id())
|
|
32
|
+
.orElseThrow(() -> new NotFoundException("<%= aggregateName %> not found with id: " + command.id()));
|
|
33
|
+
|
|
34
|
+
entity.<%= domainMethod %>();
|
|
35
|
+
repository.save(entity);
|
|
36
|
+
|
|
37
|
+
log.info("<%= aggregateName %> id: {} transitioned via <%= domainMethod %>()", command.id());
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package <%= packageName %>.<%= moduleName %>.application.commands;
|
|
2
2
|
|
|
3
3
|
import <%= packageName %>.shared.domain.interfaces.Command;
|
|
4
|
+
import io.swagger.v3.oas.annotations.media.Schema;
|
|
4
5
|
<% if (hasValueObjects) { %>
|
|
5
6
|
import <%= packageName %>.<%= moduleName %>.domain.models.valueObjects.*;
|
|
6
7
|
<% } %>
|
|
@@ -34,6 +35,9 @@ import <%= packageName %>.<%= moduleName %>.application.dtos.Create<%= rel.targe
|
|
|
34
35
|
public record Update<%= aggregateName %>Command(
|
|
35
36
|
<%- idType %> id<% if (commandFields && commandFields.length > 0) { %>,<% } %>
|
|
36
37
|
<% commandFields.forEach((field, idx) => { %>
|
|
38
|
+
<% if (field.schemaExample) { %>
|
|
39
|
+
@Schema(example = "<%= field.schemaExample %>")
|
|
40
|
+
<% } %>
|
|
37
41
|
<%- field.javaType %> <%= field.name %><% if (idx < commandFields.length - 1 || (oneToManyRelationships && oneToManyRelationships.length > 0) || (oneToOneRelationships && oneToOneRelationships.length > 0)) { %>,<% } %>
|
|
38
42
|
<% }); %>
|
|
39
43
|
<% if (oneToManyRelationships && oneToManyRelationships.length > 0) { %>
|