eva4j 1.0.16 → 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.
- package/AGENTS.md +220 -5
- package/DOMAIN_YAML_GUIDE.md +188 -3
- package/FUTURE_FEATURES.md +33 -52
- package/QUICK_REFERENCE.md +8 -4
- package/bin/eva4j.js +70 -2
- package/config/defaults.json +1 -0
- package/docs/CAMUNDA_DMN_GUIDE.md +1380 -0
- package/docs/KAFKA_PRODUCTION_CONFIG.md +441 -0
- package/docs/RABBITMQ_PRODUCTION_CONFIG.md +227 -0
- package/docs/commands/ADD_RABBITMQ_CLIENT.md +192 -0
- package/docs/commands/EVALUATE_SYSTEM.md +290 -10
- package/docs/commands/GENERATE_RABBITMQ_EVENT.md +341 -0
- package/docs/commands/GENERATE_RABBITMQ_LISTENER.md +595 -0
- package/docs/commands/GENERATE_TEMPORAL_FLOW.md +52 -12
- package/docs/commands/INDEX.md +27 -3
- package/docs/prototype/TEMPORAL_COMMUNICATION_PATTERNS.md +731 -0
- package/docs/prototype/TEMPORAL_DESIGN_METHODOLOGY.md +740 -0
- package/docs/prototype/system/RISKS.md +277 -0
- package/docs/prototype/system/customers.yaml +133 -0
- package/docs/prototype/system/inventory.yaml +109 -0
- package/docs/prototype/system/notifications.yaml +131 -0
- package/docs/prototype/system/orders.yaml +241 -0
- package/docs/prototype/system/payments.yaml +256 -0
- package/docs/prototype/system/products.yaml +168 -0
- package/docs/prototype/system/system.yaml +269 -0
- package/examples/domain-endpoints-multi-aggregate.yaml +140 -0
- package/examples/domain-events.yaml +26 -0
- package/examples/domain-read-models.yaml +113 -0
- package/examples/system/customer.yaml +89 -0
- package/examples/system/orders.yaml +119 -0
- package/examples/system/product.yaml +27 -0
- package/examples/system/system.yaml +80 -0
- package/package.json +1 -1
- package/read-model-spec.md +664 -0
- package/src/agents/design-gap-analyst-temporal.agent.md +452 -0
- package/src/agents/design-gap-analyst.agent.md +383 -0
- package/src/agents/design-reviewer-temporal.agent.md +412 -0
- package/src/agents/design-reviewer.agent.md +34 -5
- package/src/agents/implement-use-cases.prompt.md +179 -0
- package/src/agents/ux-gap-analyst.agent.md +412 -0
- package/src/commands/add-rabbitmq-client.js +261 -0
- package/src/commands/add-temporal-client.js +22 -2
- package/src/commands/build.js +267 -11
- package/src/commands/evaluate-system.js +700 -13
- package/src/commands/generate-entities.js +560 -24
- package/src/commands/generate-http-exchange.js +3 -0
- package/src/commands/generate-kafka-event.js +3 -0
- package/src/commands/generate-kafka-listener.js +3 -0
- package/src/commands/generate-rabbitmq-event.js +665 -0
- package/src/commands/generate-rabbitmq-listener.js +205 -0
- package/src/commands/generate-record.js +2 -2
- package/src/commands/generate-resource.js +4 -1
- package/src/commands/generate-temporal-activity.js +970 -33
- package/src/commands/generate-temporal-flow.js +98 -38
- package/src/commands/generate-temporal-system.js +708 -0
- package/src/commands/generate-usecase.js +4 -1
- package/src/skills/build-system-yaml/SKILL.md +343 -2
- package/src/skills/build-system-yaml/references/domain-yaml-spec.md +253 -26
- package/src/skills/build-system-yaml/references/module-spec.md +90 -9
- package/src/skills/build-system-yaml/references/system-yaml-spec.md +36 -0
- package/src/skills/build-temporal-system/SKILL.md +752 -0
- package/src/skills/build-temporal-system/references/temporal-communication-patterns.md +167 -0
- package/src/skills/build-temporal-system/references/temporal-domain-yaml-spec.md +449 -0
- package/src/skills/build-temporal-system/references/temporal-module-spec.md +353 -0
- package/src/skills/build-temporal-system/references/temporal-system-yaml-spec.md +326 -0
- package/src/skills/implement-use-case/SKILL.md +350 -0
- package/src/skills/implement-use-case/references/use-case-patterns.md +980 -0
- package/src/skills/requirements-elicitation/SKILL.md +228 -0
- package/src/skills/requirements-elicitation/references/interview-framework.md +260 -0
- package/src/skills/requirements-elicitation/references/output-templates.md +368 -0
- package/src/utils/bounded-context-diagram.js +844 -0
- package/src/utils/config-manager.js +4 -2
- package/src/utils/domain-validator.js +495 -17
- package/src/utils/naming.js +20 -0
- package/src/utils/system-validator.js +169 -11
- package/src/utils/system-yaml-parser.js +318 -0
- package/src/utils/temporal-validator.js +497 -0
- package/src/utils/validator.js +3 -1
- package/src/utils/yaml-to-entity.js +281 -9
- package/templates/aggregate/AggregateRepository.java.ejs +4 -0
- package/templates/aggregate/AggregateRepositoryImpl.java.ejs +8 -0
- package/templates/aggregate/AggregateRoot.java.ejs +38 -4
- package/templates/aggregate/DomainEventHandler.java.ejs +116 -22
- package/templates/aggregate/JpaAggregateRoot.java.ejs +4 -4
- package/templates/aggregate/JpaEntity.java.ejs +2 -2
- package/templates/base/docker/rabbitmq-services.yaml.ejs +12 -0
- package/templates/base/resources/parameters/develop/kafka.yaml.ejs +5 -0
- package/templates/base/resources/parameters/develop/rabbitmq.yaml.ejs +15 -0
- package/templates/base/resources/parameters/develop/temporal.yaml.ejs +0 -3
- package/templates/base/resources/parameters/local/kafka.yaml.ejs +5 -0
- package/templates/base/resources/parameters/local/rabbitmq.yaml.ejs +15 -0
- package/templates/base/resources/parameters/local/temporal.yaml.ejs +0 -3
- package/templates/base/resources/parameters/production/kafka.yaml.ejs +39 -8
- package/templates/base/resources/parameters/production/rabbitmq.yaml.ejs +32 -0
- package/templates/base/resources/parameters/production/temporal.yaml.ejs +0 -3
- package/templates/base/resources/parameters/test/kafka.yaml.ejs +12 -6
- package/templates/base/resources/parameters/test/rabbitmq.yaml.ejs +15 -0
- package/templates/base/resources/parameters/test/temporal.yaml.ejs +0 -3
- package/templates/base/root/AGENTS.md.ejs +1 -1
- package/templates/crud/DeleteCommandHandler.java.ejs +19 -1
- package/templates/crud/EndpointsController.java.ejs +1 -1
- package/templates/crud/ScaffoldCommand.java.ejs +5 -2
- package/templates/crud/ScaffoldCommandHandler.java.ejs +3 -1
- package/templates/crud/ScaffoldQuery.java.ejs +5 -2
- package/templates/crud/ScaffoldQueryHandler.java.ejs +3 -1
- package/templates/crud/SubEntityRemoveCommand.java.ejs +1 -1
- package/templates/crud/UpdateCommandHandler.java.ejs +53 -2
- package/templates/evaluate/report.html.ejs +1447 -90
- package/templates/kafka-event/KafkaConfigBean.java.ejs +1 -1
- package/templates/kafka-event/KafkaMessageBroker.java.ejs +3 -3
- package/templates/ports/PortAclMapper.java.ejs +35 -0
- package/templates/ports/PortFeignAdapter.java.ejs +7 -22
- package/templates/ports/PortFeignClient.java.ejs +4 -0
- package/templates/ports/PortResponseDto.java.ejs +1 -1
- package/templates/rabbitmq-event/RabbitConfigBean.java.ejs +33 -0
- package/templates/rabbitmq-event/RabbitConfigExchange.java.ejs +12 -0
- package/templates/rabbitmq-event/RabbitMessageBroker.java.ejs +35 -0
- package/templates/rabbitmq-event/RabbitMessageBrokerMethod.java.ejs +9 -0
- package/templates/rabbitmq-listener/RabbitConfigConsumerBean.java.ejs +33 -0
- package/templates/rabbitmq-listener/RabbitConfigConsumerExchange.java.ejs +12 -0
- package/templates/rabbitmq-listener/RabbitListenerClass.java.ejs +82 -0
- package/templates/rabbitmq-listener/RabbitListenerSimple.java.ejs +56 -0
- package/templates/read-model/ReadModelDomain.java.ejs +46 -0
- package/templates/read-model/ReadModelJpa.java.ejs +58 -0
- package/templates/read-model/ReadModelJpaRepository.java.ejs +13 -0
- package/templates/read-model/ReadModelKafkaListener.java.ejs +64 -0
- package/templates/read-model/ReadModelRabbitListener.java.ejs +71 -0
- package/templates/read-model/ReadModelRepository.java.ejs +42 -0
- package/templates/read-model/ReadModelRepositoryImpl.java.ejs +85 -0
- package/templates/read-model/ReadModelSyncHandler.java.ejs +54 -0
- package/templates/shared/configurations/kafkaConfig/KafkaConfig.java.ejs +18 -4
- package/templates/shared/configurations/rabbitmqConfig/RabbitMQConfig.java.ejs +100 -0
- package/templates/shared/configurations/temporalConfig/TemporalConfig.java.ejs +2 -64
- package/templates/shared/configurations/temporalConfig/TemporalWorkerFactoryLifecycle.java.ejs +41 -0
- package/templates/temporal-activity/ActivityImpl.java.ejs +68 -2
- package/templates/temporal-activity/ActivityInput.java.ejs +14 -0
- package/templates/temporal-activity/ActivityInterface.java.ejs +7 -1
- package/templates/temporal-activity/ActivityOutput.java.ejs +14 -0
- package/templates/temporal-activity/NestedType.java.ejs +12 -0
- package/templates/temporal-activity/SharedActivityInput.java.ejs +14 -0
- package/templates/temporal-activity/SharedActivityInterface.java.ejs +15 -0
- package/templates/temporal-activity/SharedActivityOutput.java.ejs +14 -0
- package/templates/temporal-activity/SharedNestedType.java.ejs +12 -0
- package/templates/temporal-flow/ModuleHeavyActivity.java.ejs +6 -0
- package/templates/temporal-flow/ModuleLightActivity.java.ejs +6 -0
- package/templates/temporal-flow/ModuleTemporalWorkerConfig.java.ejs +58 -0
- package/templates/temporal-flow/WorkFlowImpl.java.ejs +172 -12
- package/templates/temporal-flow/WorkFlowInput.java.ejs +11 -0
- package/templates/temporal-flow/WorkFlowInterface.java.ejs +5 -4
- package/templates/temporal-flow/WorkFlowService.java.ejs +42 -12
- package/COMMAND_EVALUATION.md +0 -911
package/COMMAND_EVALUATION.md
DELETED
|
@@ -1,911 +0,0 @@
|
|
|
1
|
-
# Evaluación del Comando `generate entities`
|
|
2
|
-
|
|
3
|
-
## 📊 Resumen Ejecutivo
|
|
4
|
-
|
|
5
|
-
| Aspecto | Estado | Cobertura |
|
|
6
|
-
|---------|--------|-----------|
|
|
7
|
-
| **Funcionalidades Básicas** | ✅ Completo | 100% |
|
|
8
|
-
| **DDD Patterns** | ✅ Completo | 90% |
|
|
9
|
-
| **Relaciones JPA** | ✅ Completo | 85% |
|
|
10
|
-
| **Validaciones** | ❌ Pendiente | 0% |
|
|
11
|
-
| **Auditoría** | ❌ Pendiente | 0% |
|
|
12
|
-
| **Performance** | 🟡 Básico | 60% |
|
|
13
|
-
| **Cobertura General** | ✅ Bueno | **78%** |
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## ✅ Funcionalidades Implementadas
|
|
18
|
-
|
|
19
|
-
### 1. Generación de Entidades de Dominio
|
|
20
|
-
|
|
21
|
-
**Estado**: ✅ Completamente implementado
|
|
22
|
-
|
|
23
|
-
#### Características
|
|
24
|
-
- ✅ Entidades puras Java (sin Lombok, sin JPA)
|
|
25
|
-
- ✅ Constructores manuales con todos los campos
|
|
26
|
-
- ✅ Getters y setters manuales
|
|
27
|
-
- ✅ Métodos de negocio automáticos para colecciones (add/remove)
|
|
28
|
-
- ✅ Soporte para relaciones OneToMany, ManyToOne, OneToOne
|
|
29
|
-
- ✅ Separación clara domain vs infrastructure
|
|
30
|
-
|
|
31
|
-
#### Calidad del Código Generado
|
|
32
|
-
```java
|
|
33
|
-
// ✅ Código generado de alta calidad
|
|
34
|
-
public class Order {
|
|
35
|
-
private String id;
|
|
36
|
-
private OrderStatus status;
|
|
37
|
-
private Money totalAmount;
|
|
38
|
-
private List<OrderItem> orderItems = new ArrayList<>();
|
|
39
|
-
|
|
40
|
-
// Constructor manual con todos los campos
|
|
41
|
-
public Order(String id, OrderStatus status, Money totalAmount) {
|
|
42
|
-
this.id = id;
|
|
43
|
-
this.status = status;
|
|
44
|
-
this.totalAmount = totalAmount;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Métodos de negocio automáticos
|
|
48
|
-
public void addOrderItem(OrderItem orderItem) {
|
|
49
|
-
this.orderItems.add(orderItem);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
**Cobertura**: 100% de los casos de uso comunes
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
### 2. Generación de Entidades JPA
|
|
59
|
-
|
|
60
|
-
**Estado**: ✅ Completamente implementado
|
|
61
|
-
|
|
62
|
-
#### Características
|
|
63
|
-
- ✅ Anotaciones JPA completas (@Entity, @Table, @Id, etc.)
|
|
64
|
-
- ✅ Lombok para reducir boilerplate (@Getter, @Setter, @Builder)
|
|
65
|
-
- ✅ Generación de IDs automática según tipo:
|
|
66
|
-
- String → `@GeneratedValue(strategy = GenerationType.UUID)`
|
|
67
|
-
- Long/Integer → `@GeneratedValue(strategy = GenerationType.IDENTITY)`
|
|
68
|
-
- ✅ Relaciones bidireccionales automáticas desde mappedBy
|
|
69
|
-
- ✅ Generación automática de lado inverso (OneToMany → ManyToOne)
|
|
70
|
-
- ✅ Cascade y Fetch configurables desde YAML
|
|
71
|
-
- ✅ Referencias correctas con sufijo "Jpa" (OrderJpa → OrderItemJpa)
|
|
72
|
-
|
|
73
|
-
#### Ejemplo Generado
|
|
74
|
-
```java
|
|
75
|
-
@Entity
|
|
76
|
-
@Table(name = "orders")
|
|
77
|
-
@Getter
|
|
78
|
-
@Setter
|
|
79
|
-
@NoArgsConstructor
|
|
80
|
-
@AllArgsConstructor
|
|
81
|
-
@Builder
|
|
82
|
-
public class OrderJpa {
|
|
83
|
-
@Id
|
|
84
|
-
@GeneratedValue(strategy = GenerationType.UUID)
|
|
85
|
-
private String id;
|
|
86
|
-
|
|
87
|
-
@Enumerated(EnumType.STRING)
|
|
88
|
-
private OrderStatus status;
|
|
89
|
-
|
|
90
|
-
@Embedded
|
|
91
|
-
private MoneyJpa totalAmount;
|
|
92
|
-
|
|
93
|
-
@OneToMany(mappedBy = "order", cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY)
|
|
94
|
-
@Builder.Default
|
|
95
|
-
private List<OrderItemJpa> orderItems = new ArrayList<>();
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
**Cobertura**: 95% (falta ManyToMany completo)
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
### 3. Value Objects
|
|
104
|
-
|
|
105
|
-
**Estado**: ✅ Completamente implementado
|
|
106
|
-
|
|
107
|
-
#### Características
|
|
108
|
-
- ✅ Inmutabilidad completa (final fields)
|
|
109
|
-
- ✅ Constructor con todos los campos
|
|
110
|
-
- ✅ Getters sin setters
|
|
111
|
-
- ✅ equals() y hashCode() automáticos basados en todos los campos
|
|
112
|
-
- ✅ Versión JPA embebida (@Embeddable)
|
|
113
|
-
- ✅ Detección automática en campos de entidades
|
|
114
|
-
- ✅ Soporte para List<ValueObject> con @ElementCollection
|
|
115
|
-
|
|
116
|
-
#### Calidad
|
|
117
|
-
```java
|
|
118
|
-
// Domain VO (inmutable)
|
|
119
|
-
public class Money {
|
|
120
|
-
private final BigDecimal amount;
|
|
121
|
-
private final String currency;
|
|
122
|
-
|
|
123
|
-
public Money(BigDecimal amount, String currency) {
|
|
124
|
-
this.amount = amount;
|
|
125
|
-
this.currency = currency;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Solo getters, sin setters
|
|
129
|
-
// equals() y hashCode() incluidos
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// JPA VO (embeddable)
|
|
133
|
-
@Embeddable
|
|
134
|
-
public class MoneyJpa {
|
|
135
|
-
private BigDecimal amount;
|
|
136
|
-
private String currency;
|
|
137
|
-
// Con Lombok
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
**Cobertura**: 100%
|
|
142
|
-
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
### 4. Enumeraciones
|
|
146
|
-
|
|
147
|
-
**Estado**: ✅ Completamente implementado
|
|
148
|
-
|
|
149
|
-
#### Características
|
|
150
|
-
- ✅ Generación automática desde YAML
|
|
151
|
-
- ✅ Detección automática en campos
|
|
152
|
-
- ✅ Importación automática en entidades que los usan
|
|
153
|
-
- ✅ Anotación @Enumerated(EnumType.STRING) en JPA
|
|
154
|
-
- ✅ Enums globales al módulo (compartibles entre agregados)
|
|
155
|
-
|
|
156
|
-
**Cobertura**: 100%
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
### 5. Mappers (Domain ↔ JPA)
|
|
161
|
-
|
|
162
|
-
**Estado**: ✅ Completamente implementado
|
|
163
|
-
|
|
164
|
-
#### Características
|
|
165
|
-
- ✅ Conversión bidireccional toDomain() / toJpa()
|
|
166
|
-
- ✅ Mapeo correcto de Value Objects
|
|
167
|
-
- ✅ Mapeo de colecciones (OneToMany)
|
|
168
|
-
- ✅ Referencias bidireccionales correctas
|
|
169
|
-
- ✅ Null-safe (validación de nulls)
|
|
170
|
-
- ✅ Uso de constructores para entidades de dominio
|
|
171
|
-
- ✅ Uso de builders para entidades JPA
|
|
172
|
-
- ✅ Nombres de getters correctos basados en nombres de campos
|
|
173
|
-
|
|
174
|
-
#### Calidad
|
|
175
|
-
```java
|
|
176
|
-
public Order toDomain(OrderJpa jpa) {
|
|
177
|
-
if (jpa == null) return null;
|
|
178
|
-
|
|
179
|
-
return new Order(
|
|
180
|
-
jpa.getId(),
|
|
181
|
-
jpa.getStatus(),
|
|
182
|
-
toDomainMoney(jpa.getTotalAmount())
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
**Cobertura**: 95% (casos edge pendientes)
|
|
188
|
-
|
|
189
|
-
---
|
|
190
|
-
|
|
191
|
-
### 6. Repositorios
|
|
192
|
-
|
|
193
|
-
**Estado**: ✅ Completamente implementado
|
|
194
|
-
|
|
195
|
-
#### Características
|
|
196
|
-
- ✅ Interfaz en capa de dominio (port)
|
|
197
|
-
- ✅ Implementación en infrastructure (adapter)
|
|
198
|
-
- ✅ Spring Data JPA Repository
|
|
199
|
-
- ✅ Métodos CRUD básicos (save, findById, findAll, deleteById, existsById)
|
|
200
|
-
- ✅ Tipo de ID dinámico según entidad (String, Long, Integer)
|
|
201
|
-
- ✅ Uso del mapper para conversiones
|
|
202
|
-
- ✅ Patrón Repository correctamente implementado
|
|
203
|
-
|
|
204
|
-
#### Ejemplo
|
|
205
|
-
```java
|
|
206
|
-
// Domain (puerto)
|
|
207
|
-
public interface OrderRepository {
|
|
208
|
-
Order save(Order order);
|
|
209
|
-
Optional<Order> findById(String id);
|
|
210
|
-
List<Order> findAll();
|
|
211
|
-
void deleteById(String id);
|
|
212
|
-
boolean existsById(String id);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Infrastructure (adaptador)
|
|
216
|
-
@Repository
|
|
217
|
-
@RequiredArgsConstructor
|
|
218
|
-
public class OrderRepositoryImpl implements OrderRepository {
|
|
219
|
-
private final OrderJpaRepository jpaRepository;
|
|
220
|
-
private final OrderMapper mapper;
|
|
221
|
-
|
|
222
|
-
@Override
|
|
223
|
-
public Order save(Order order) {
|
|
224
|
-
OrderJpa jpa = mapper.toJpa(order);
|
|
225
|
-
OrderJpa saved = jpaRepository.save(jpa);
|
|
226
|
-
return mapper.toDomain(saved);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
**Cobertura**: 80% (falta queries personalizados)
|
|
232
|
-
|
|
233
|
-
---
|
|
234
|
-
|
|
235
|
-
### 7. Relaciones JPA
|
|
236
|
-
|
|
237
|
-
**Estado**: ✅ Completo
|
|
238
|
-
|
|
239
|
-
#### Implementado
|
|
240
|
-
- ✅ OneToMany con cascade y fetch configurables
|
|
241
|
-
- ✅ **Relaciones bidireccionales automáticas desde mappedBy** 🆕
|
|
242
|
-
- ✅ Generación automática de ManyToOne inverso cuando OneToMany usa mappedBy
|
|
243
|
-
- ✅ ManyToOne con joinColumn (manual o autogenerado)
|
|
244
|
-
- ✅ OneToOne básico y con mappedBy
|
|
245
|
-
- ✅ Detección automática de colecciones
|
|
246
|
-
- ✅ mappedBy para relaciones bidireccionales
|
|
247
|
-
|
|
248
|
-
#### Cómo Funciona la Generación Automática
|
|
249
|
-
|
|
250
|
-
```yaml
|
|
251
|
-
# Solo defines el lado OneToMany
|
|
252
|
-
rootEntity:
|
|
253
|
-
name: order
|
|
254
|
-
relationships:
|
|
255
|
-
- type: OneToMany
|
|
256
|
-
target: OrderItem
|
|
257
|
-
mappedBy: order # ← eva4j genera automáticamente el ManyToOne
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
**eva4j genera automáticamente en OrderItem:**
|
|
261
|
-
|
|
262
|
-
```java
|
|
263
|
-
@ManyToOne(fetch = FetchType.LAZY)
|
|
264
|
-
@JoinColumn(name = "order_id")
|
|
265
|
-
private OrderJpa order;
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
**Ventajas:**
|
|
269
|
-
- No necesitas definir ambos lados manualmente
|
|
270
|
-
- Evita inconsistencias
|
|
271
|
-
- joinColumn se infiere automáticamente desde mappedBy
|
|
272
|
-
|
|
273
|
-
#### Pendiente
|
|
274
|
-
- ❌ ManyToMany con tabla intermedia
|
|
275
|
-
- ❌ OneToOne avanzado (orphanRemoval, optional)
|
|
276
|
-
- ❌ @JoinTable personalizada
|
|
277
|
-
- ❌ Composite keys
|
|
278
|
-
|
|
279
|
-
**Cobertura**: 85% (+15% con generación automática)
|
|
280
|
-
|
|
281
|
-
---
|
|
282
|
-
|
|
283
|
-
### 8. Tipos de Datos
|
|
284
|
-
|
|
285
|
-
**Estado**: ✅ Completamente implementado
|
|
286
|
-
|
|
287
|
-
#### Soportados
|
|
288
|
-
- ✅ Primitivos: String, Integer, Long, Double, Float, Boolean
|
|
289
|
-
- ✅ Decimales: BigDecimal
|
|
290
|
-
- ✅ Fechas: LocalDate, LocalDateTime, LocalTime
|
|
291
|
-
- ✅ UUID
|
|
292
|
-
- ✅ Enums personalizados
|
|
293
|
-
- ✅ Value Objects personalizados
|
|
294
|
-
- ✅ Colecciones: List<String>, List<VO>
|
|
295
|
-
|
|
296
|
-
#### Importaciones Automáticas
|
|
297
|
-
- ✅ BigDecimal → `import java.math.BigDecimal;`
|
|
298
|
-
- ✅ LocalDate → `import java.time.LocalDate;`
|
|
299
|
-
- ✅ Enums → `import ...enums.OrderStatus;`
|
|
300
|
-
- ✅ Sin imports innecesarios en entidades de dominio
|
|
301
|
-
|
|
302
|
-
**Cobertura**: 95%
|
|
303
|
-
|
|
304
|
-
---
|
|
305
|
-
|
|
306
|
-
### 9. Generación de Código Limpio
|
|
307
|
-
|
|
308
|
-
**Estado**: ✅ Excelente
|
|
309
|
-
|
|
310
|
-
#### Logros
|
|
311
|
-
- ✅ Espaciado uniforme (1 línea entre propiedades)
|
|
312
|
-
- ✅ Anotaciones compactas sin líneas vacías extras
|
|
313
|
-
- ✅ Imports organizados y sin duplicados
|
|
314
|
-
- ✅ Nombres de métodos consistentes (camelCase)
|
|
315
|
-
- ✅ Sin código comentado o placeholder
|
|
316
|
-
- ✅ Convenciones Java estándar
|
|
317
|
-
|
|
318
|
-
**Cobertura**: 100%
|
|
319
|
-
|
|
320
|
-
---
|
|
321
|
-
|
|
322
|
-
## ⚠️ Limitaciones Actuales
|
|
323
|
-
|
|
324
|
-
### 1. Validaciones (0% implementado)
|
|
325
|
-
|
|
326
|
-
**Impacto**: Alto - Requerido en el 90% de aplicaciones empresariales
|
|
327
|
-
|
|
328
|
-
#### Casos de Uso No Cubiertos
|
|
329
|
-
```yaml
|
|
330
|
-
# ❌ No soportado actualmente
|
|
331
|
-
fields:
|
|
332
|
-
- name: email
|
|
333
|
-
type: String
|
|
334
|
-
validations:
|
|
335
|
-
- type: Email
|
|
336
|
-
- type: NotBlank
|
|
337
|
-
- type: Size
|
|
338
|
-
min: 5
|
|
339
|
-
max: 100
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
#### Solución Temporal
|
|
343
|
-
Agregar manualmente en código generado:
|
|
344
|
-
```java
|
|
345
|
-
@Email(message = "Email inválido")
|
|
346
|
-
@NotBlank
|
|
347
|
-
@Size(min = 5, max = 100)
|
|
348
|
-
private String email;
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
**Esfuerzo para implementar**: Bajo (1-2 horas)
|
|
352
|
-
**Prioridad**: 🔥 Alta
|
|
353
|
-
|
|
354
|
-
---
|
|
355
|
-
|
|
356
|
-
### 2. Auditoría (0% implementado)
|
|
357
|
-
|
|
358
|
-
**Impacto**: Alto - Común en aplicaciones enterprise
|
|
359
|
-
|
|
360
|
-
#### Casos de Uso No Cubiertos
|
|
361
|
-
```yaml
|
|
362
|
-
# ❌ No soportado actualmente
|
|
363
|
-
rootEntity:
|
|
364
|
-
name: order
|
|
365
|
-
auditable: true # Debería agregar campos de auditoría
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
Requiere manualmente:
|
|
369
|
-
```java
|
|
370
|
-
@CreatedDate
|
|
371
|
-
private LocalDateTime createdAt;
|
|
372
|
-
|
|
373
|
-
@LastModifiedDate
|
|
374
|
-
private LocalDateTime updatedAt;
|
|
375
|
-
|
|
376
|
-
@CreatedBy
|
|
377
|
-
private String createdBy;
|
|
378
|
-
|
|
379
|
-
@LastModifiedBy
|
|
380
|
-
private String updatedBy;
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
**Esfuerzo para implementar**: Medio (3-4 horas)
|
|
384
|
-
**Prioridad**: 🔥 Alta
|
|
385
|
-
|
|
386
|
-
---
|
|
387
|
-
|
|
388
|
-
### 3. Query Methods Personalizados (0% implementado)
|
|
389
|
-
|
|
390
|
-
**Impacto**: Alto - Evita escribir queries manualmente
|
|
391
|
-
|
|
392
|
-
#### Casos de Uso No Cubiertos
|
|
393
|
-
```yaml
|
|
394
|
-
# ❌ No soportado actualmente
|
|
395
|
-
aggregates:
|
|
396
|
-
- name: Order
|
|
397
|
-
repositories:
|
|
398
|
-
customQueries:
|
|
399
|
-
- name: findByStatusAndCreatedAtAfter
|
|
400
|
-
returnType: List<Order>
|
|
401
|
-
parameters:
|
|
402
|
-
- name: status
|
|
403
|
-
type: OrderStatus
|
|
404
|
-
- name: date
|
|
405
|
-
type: LocalDateTime
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
**Solución Temporal**: Agregar manualmente en `OrderRepository`
|
|
409
|
-
|
|
410
|
-
**Esfuerzo para implementar**: Bajo (2-3 horas)
|
|
411
|
-
**Prioridad**: 🟡 Media
|
|
412
|
-
|
|
413
|
-
---
|
|
414
|
-
|
|
415
|
-
### 4. Soft Delete ✅ Implementado
|
|
416
|
-
|
|
417
|
-
**Impacto**: Medio - Común en apps business
|
|
418
|
-
|
|
419
|
-
#### Sintaxis
|
|
420
|
-
```yaml
|
|
421
|
-
# ✅ Soportado — solo en la entidad raíz (isRoot: true)
|
|
422
|
-
entities:
|
|
423
|
-
- name: order
|
|
424
|
-
isRoot: true
|
|
425
|
-
hasSoftDelete: true # Genera deletedAt, softDelete(), @SQLRestriction
|
|
426
|
-
```
|
|
427
|
-
|
|
428
|
-
**Estado**: Implementado en `yaml-to-entity.js` + templates `AggregateRoot`, `JpaAggregateRoot`, repositorios y `DeleteCommandHandler`.
|
|
429
|
-
|
|
430
|
-
---
|
|
431
|
-
|
|
432
|
-
### 5. Índices y Constraints (0% implementado)
|
|
433
|
-
|
|
434
|
-
**Impacto**: Medio - Importante para performance
|
|
435
|
-
|
|
436
|
-
#### Casos de Uso No Cubiertos
|
|
437
|
-
```yaml
|
|
438
|
-
# ❌ No soportado actualmente
|
|
439
|
-
rootEntity:
|
|
440
|
-
name: order
|
|
441
|
-
indexes:
|
|
442
|
-
- name: idx_order_number
|
|
443
|
-
columns: [orderNumber]
|
|
444
|
-
unique: true
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
**Solución Temporal**: Agregar manualmente o en migrations
|
|
448
|
-
|
|
449
|
-
**Esfuerzo para implementar**: Bajo (2-3 horas)
|
|
450
|
-
**Prioridad**: 🟡 Media
|
|
451
|
-
|
|
452
|
-
---
|
|
453
|
-
|
|
454
|
-
### 6. Herencia de Entidades (0% implementado)
|
|
455
|
-
|
|
456
|
-
**Impacto**: Bajo - Solo para dominios complejos
|
|
457
|
-
|
|
458
|
-
#### Casos de Uso No Cubiertos
|
|
459
|
-
```yaml
|
|
460
|
-
# ❌ No soportado actualmente
|
|
461
|
-
entities:
|
|
462
|
-
- name: Payment
|
|
463
|
-
inheritance:
|
|
464
|
-
strategy: JOINED
|
|
465
|
-
discriminatorColumn: payment_type
|
|
466
|
-
```
|
|
467
|
-
|
|
468
|
-
**Esfuerzo para implementar**: Alto (8-10 horas)
|
|
469
|
-
**Prioridad**: 🔵 Baja
|
|
470
|
-
|
|
471
|
-
---
|
|
472
|
-
|
|
473
|
-
### 7. DTOs Automáticos (0% implementado)
|
|
474
|
-
|
|
475
|
-
**Impacto**: Alto - Pero requiere más diseño
|
|
476
|
-
|
|
477
|
-
#### Casos de Uso No Cubiertos
|
|
478
|
-
```yaml
|
|
479
|
-
# ❌ No soportado actualmente
|
|
480
|
-
aggregates:
|
|
481
|
-
- name: Order
|
|
482
|
-
dtos:
|
|
483
|
-
- name: CreateOrderRequest
|
|
484
|
-
fields: [customerId, items]
|
|
485
|
-
```
|
|
486
|
-
|
|
487
|
-
**Esfuerzo para implementar**: Alto (12-15 horas)
|
|
488
|
-
**Prioridad**: 🔵 Baja (requiere análisis de diseño)
|
|
489
|
-
|
|
490
|
-
---
|
|
491
|
-
|
|
492
|
-
### 8. Eventos de Dominio (0% implementado)
|
|
493
|
-
|
|
494
|
-
**Impacto**: Medio - Para arquitecturas event-driven
|
|
495
|
-
|
|
496
|
-
**Esfuerzo para implementar**: Alto (10-12 horas)
|
|
497
|
-
**Prioridad**: 🔵 Baja
|
|
498
|
-
|
|
499
|
-
---
|
|
500
|
-
|
|
501
|
-
## 📈 Análisis de Cobertura por Escenarios
|
|
502
|
-
|
|
503
|
-
### Escenarios Completamente Cubiertos (✅)
|
|
504
|
-
|
|
505
|
-
1. ✅ **CRUD básico con agregados**
|
|
506
|
-
- Crear, leer, actualizar, eliminar
|
|
507
|
-
- Persistencia con JPA
|
|
508
|
-
- Mapeo domain ↔ infrastructure
|
|
509
|
-
|
|
510
|
-
2. ✅ **Relaciones padre-hijo (OneToMany/ManyToOne)**
|
|
511
|
-
- Order → OrderItems
|
|
512
|
-
- Post → Comments
|
|
513
|
-
- Account → Transactions
|
|
514
|
-
- **Generación automática de lado inverso con mappedBy**
|
|
515
|
-
|
|
516
|
-
3. ✅ **Relaciones bidireccionales**
|
|
517
|
-
- Definir solo un lado (OneToMany con mappedBy)
|
|
518
|
-
- eva4j genera automáticamente el ManyToOne inverso
|
|
519
|
-
- joinColumn inferido desde mappedBy
|
|
520
|
-
|
|
521
|
-
4. ✅ **Value Objects embebidos**
|
|
522
|
-
- Money (amount, currency)
|
|
523
|
-
- Address (street, city, state, zip, country)
|
|
524
|
-
- ContactInfo, etc.
|
|
525
|
-
|
|
526
|
-
5. ✅ **Enums para estados**
|
|
527
|
-
- OrderStatus, PaymentMethod, etc.
|
|
528
|
-
- Detección e importación automática
|
|
529
|
-
|
|
530
|
-
6. ✅ **IDs flexibles**
|
|
531
|
-
- String → UUID
|
|
532
|
-
- Long → IDENTITY
|
|
533
|
-
- Integer → IDENTITY
|
|
534
|
-
|
|
535
|
-
7. ✅ **Colecciones de primitivos y VOs**
|
|
536
|
-
- List<String> tags
|
|
537
|
-
- List<Address> addresses
|
|
538
|
-
|
|
539
|
-
---
|
|
540
|
-
|
|
541
|
-
### Escenarios Parcialmente Cubiertos (🟡)
|
|
542
|
-
|
|
543
|
-
1. 🟡 **Relaciones ManyToMany**
|
|
544
|
-
- Requiere configuración manual de @JoinTable
|
|
545
|
-
- Cobertura: 30%
|
|
546
|
-
|
|
547
|
-
2. 🟡 **OneToOne avanzado**
|
|
548
|
-
- Funciona básico con mappedBy, pero falta orphanRemoval, optional
|
|
549
|
-
- Cobertura: 70%
|
|
550
|
-
|
|
551
|
-
3. 🟡 **Queries personalizados**
|
|
552
|
-
- Solo CRUD básico, no queries específicos
|
|
553
|
-
- Cobertura: 20%
|
|
554
|
-
|
|
555
|
-
---
|
|
556
|
-
|
|
557
|
-
### Escenarios No Cubiertos (❌)
|
|
558
|
-
|
|
559
|
-
1. ❌ **Validaciones JSR-303** (0%)
|
|
560
|
-
2. ❌ **Auditoría (createdAt, updatedAt)** (0%)
|
|
561
|
-
3. ✅ **Soft delete** (implementado con `hasSoftDelete: true`)
|
|
562
|
-
4. ❌ **Índices y constraints** (0%)
|
|
563
|
-
5. ❌ **Herencia de entidades** (0%)
|
|
564
|
-
6. ❌ **DTOs de aplicación** (0%)
|
|
565
|
-
7. ❌ **Eventos de dominio** (0%)
|
|
566
|
-
8. ❌ **Composite keys** (0%)
|
|
567
|
-
|
|
568
|
-
---
|
|
569
|
-
|
|
570
|
-
## 🎯 Plan de Mejoras Priorizado
|
|
571
|
-
|
|
572
|
-
### ✅ Completado Recientemente
|
|
573
|
-
|
|
574
|
-
| # | Mejora | Estado | Impacto |
|
|
575
|
-
|---|--------|--------|---------|
|
|
576
|
-
| ✅ | **Relaciones bidireccionales automáticas** | Implementado | 🔥 Alto |
|
|
577
|
-
|
|
578
|
-
**Logro**: +15% cobertura en relaciones JPA (70% → 85%)
|
|
579
|
-
|
|
580
|
-
---
|
|
581
|
-
|
|
582
|
-
### Fase 1: Esenciales (1-2 semanas)
|
|
583
|
-
**Objetivo**: Llegar al 88% de cobertura global
|
|
584
|
-
|
|
585
|
-
| # | Mejora | Impacto | Esfuerzo | Prioridad |
|
|
586
|
-
|---|--------|---------|----------|-----------|
|
|
587
|
-
| 1 | Validaciones JSR-303 | 🔥 Alto | 2h | 🔥 Crítica |
|
|
588
|
-
| 2 | Auditoría automática | 🔥 Alto | 4h | 🔥 Crítica |
|
|
589
|
-
| 3 | Query methods personalizados | 🟡 Alto | 3h | 🔥 Alta |
|
|
590
|
-
| 4 | Índices y constraints | 🟡 Medio | 3h | 🟡 Media |
|
|
591
|
-
|
|
592
|
-
**Beneficio**: +10% cobertura global, cubre el 90% de proyectos reales
|
|
593
|
-
|
|
594
|
-
---
|
|
595
|
-
|
|
596
|
-
### Fase 2: Avanzadas (2-4 semanas)
|
|
597
|
-
**Objetivo**: Llegar al 93% de cobertura
|
|
598
|
-
|
|
599
|
-
| # | Mejora | Impacto | Esfuerzo | Prioridad |
|
|
600
|
-
|---|--------|---------|----------|-----------|
|
|
601
|
-
| 5 | ~~Soft delete~~ | ✅ Implementado | — | — |
|
|
602
|
-
| 6 | ManyToMany completo | 🟡 Medio | 6h | 🟡 Media |
|
|
603
|
-
| 7 | OneToOne avanzado | 🟡 Bajo | 4h | 🔵 Baja |
|
|
604
|
-
|
|
605
|
-
**Beneficio**: +5% cobertura, cubre casos avanzados
|
|
606
|
-
|
|
607
|
-
---
|
|
608
|
-
|
|
609
|
-
### Fase 3: Arquitectura (1-2 meses)
|
|
610
|
-
**Objetivo**: Funcionalidades enterprise
|
|
611
|
-
|
|
612
|
-
| # | Mejora | Impacto | Esfuerzo | Prioridad |
|
|
613
|
-
|---|--------|---------|----------|-----------|
|
|
614
|
-
| 8 | Eventos de dominio | 🟡 Alto | 12h | 🔵 Baja |
|
|
615
|
-
| 9 | DTOs automáticos | 🔥 Alto | 15h | 🔵 Baja |
|
|
616
|
-
| 10 | Herencia de entidades | 🔵 Bajo | 10h | 🔵 Baja |
|
|
617
|
-
|
|
618
|
-
**Beneficio**: +5% cobertura, arquitecturas avanzadas
|
|
619
|
-
|
|
620
|
-
---
|
|
621
|
-
|
|
622
|
-
## 💡 Recomendaciones
|
|
623
|
-
|
|
624
|
-
### Corto Plazo (Siguiente Sprint)
|
|
625
|
-
|
|
626
|
-
1. **Implementar Validaciones JSR-303** ⭐⭐⭐⭐⭐
|
|
627
|
-
- Máximo impacto, mínimo esfuerzo
|
|
628
|
-
- Requerido en casi todos los proyectos
|
|
629
|
-
- ROI: 10/10
|
|
630
|
-
|
|
631
|
-
2. **Implementar Auditoría** ⭐⭐⭐⭐
|
|
632
|
-
- Muy solicitado en enterprise
|
|
633
|
-
- Esfuerzo moderado
|
|
634
|
-
- ROI: 9/10
|
|
635
|
-
|
|
636
|
-
3. **Implementar Query Methods** ⭐⭐⭐⭐
|
|
637
|
-
- Ahorra tiempo en repositories
|
|
638
|
-
- Spring Data lo implementa automáticamente
|
|
639
|
-
- ROI: 8/10
|
|
640
|
-
|
|
641
|
-
### Mediano Plazo
|
|
642
|
-
|
|
643
|
-
4. ~~**Soft Delete**~~ ✅ Implementado con `hasSoftDelete: true`
|
|
644
|
-
|
|
645
|
-
5. **ManyToMany completo**
|
|
646
|
-
- Completa el soporte de relaciones JPA
|
|
647
|
-
|
|
648
|
-
### Largo Plazo
|
|
649
|
-
|
|
650
|
-
6. **DTOs y Eventos**
|
|
651
|
-
- Requiere más análisis de diseño
|
|
652
|
-
- Alto valor pero más complejo
|
|
653
|
-
|
|
654
|
-
---
|
|
655
|
-
|
|
656
|
-
## 📊 Métricas de Calidad
|
|
657
|
-
|
|
658
|
-
### Código Generado
|
|
659
|
-
|
|
660
|
-
| Métrica | Actual | Objetivo | Estado |
|
|
661
|
-
|---------|--------|----------|--------|
|
|
662
|
-
| Líneas de código por agregado | ~800 | <1000 | ✅ |
|
|
663
|
-
| Imports innecesarios | 0 | 0 | ✅ |
|
|
664
|
-
| Warnings de compilación | 0 | 0 | ✅ |
|
|
665
|
-
| Convenciones Java | 100% | 100% | ✅ |
|
|
666
|
-
| Tests generados | 0% | 80% | ❌ |
|
|
667
|
-
|
|
668
|
-
### Cobertura Funcional
|
|
669
|
-
|
|
670
|
-
| Categoría | Actual | Objetivo |
|
|
671
|
-
|-----------|--------|----------|
|
|
672
|
-
| DDD Patterns | 90% | 95% |
|
|
673
|
-
| JPA Features | 85% | 90% |
|
|
674
|
-
| Validaciones | 0% | 90% |
|
|
675
|
-
| Performance | 60% | 85% |
|
|
676
|
-
| **Total** | **78%** | **90%** |
|
|
677
|
-
|
|
678
|
-
---
|
|
679
|
-
|
|
680
|
-
## 🏆 Conclusiones
|
|
681
|
-
|
|
682
|
-
### Fortalezas Principales
|
|
683
|
-
|
|
684
|
-
1. ✅ **Excelente separación de capas**: Domain completamente libre de JPA
|
|
685
|
-
2. ✅ **Mappers robustos**: Conversión bidireccional correcta con manejo de relaciones inversas
|
|
686
|
-
3. ✅ **Relaciones bidireccionales automáticas**: Genera ManyToOne desde OneToMany con mappedBy
|
|
687
|
-
4. ✅ **Value Objects**: Implementación completa y correcta
|
|
688
|
-
5. ✅ **Código limpio**: Sin boilerplate, bien formateado
|
|
689
|
-
6. ✅ **Flexibilidad**: Soporta múltiples tipos de ID, relaciones, etc.
|
|
690
|
-
|
|
691
|
-
### Debilidades Principales
|
|
692
|
-
|
|
693
|
-
1. ❌ **Sin validaciones**: Requiere agregar manualmente @NotNull, @Email, etc.
|
|
694
|
-
2. ❌ **Sin auditoría**: Campos de auditoría deben agregarse manualmente
|
|
695
|
-
3. ❌ **Queries básicos**: Solo CRUD, sin queries personalizados
|
|
696
|
-
4. ❌ **Sin tests**: No genera tests unitarios ni de integración
|
|
697
|
-
|
|
698
|
-
### Veredicto Final
|
|
699
|
-
|
|
700
|
-
**El comando `generate entities` está en estado PRODUCCIÓN-READY para:**
|
|
701
|
-
- ✅ Proyectos greenfield con DDD
|
|
702
|
-
- ✅ Microservicios con hexagonal architecture
|
|
703
|
-
- ✅ CRUDs con relaciones OneToMany/ManyToOne bidireccionales
|
|
704
|
-
- ✅ Dominios con Value Objects y Enums
|
|
705
|
-
- ✅ Relaciones complejas con generación automática de lado inverso
|
|
706
|
-
|
|
707
|
-
**Requiere mejoras para:**
|
|
708
|
-
- 🟡 Aplicaciones enterprise con auditoría
|
|
709
|
-
- 🟡 Proyectos con validaciones complejas
|
|
710
|
-
- 🟡 Sistemas con queries específicos de negocio
|
|
711
|
-
|
|
712
|
-
**Cobertura Global**: **78%** (+3% con relaciones bidireccionales) → Objetivo recomendado: **90%**
|
|
713
|
-
|
|
714
|
-
**Siguiente paso sugerido**: Implementar **Validaciones JSR-303** (2 horas, alto impacto)
|
|
715
|
-
|
|
716
|
-
---
|
|
717
|
-
|
|
718
|
-
## 📅 Roadmap Sugerido
|
|
719
|
-
|
|
720
|
-
### Q1 2026
|
|
721
|
-
- ✅ ~~Generación básica de entidades~~
|
|
722
|
-
- ✅ ~~Relaciones bidireccionales automáticas~~
|
|
723
|
-
- 🔥 Validaciones JSR-303
|
|
724
|
-
- 🔥 Auditoría automática
|
|
725
|
-
|
|
726
|
-
### Q2 2026
|
|
727
|
-
- Query methods personalizados
|
|
728
|
-
- Soft delete
|
|
729
|
-
- Índices y constraints
|
|
730
|
-
|
|
731
|
-
### Q3 2026
|
|
732
|
-
- ManyToMany completo
|
|
733
|
-
- Eventos de dominio
|
|
734
|
-
- Tests automáticos
|
|
735
|
-
|
|
736
|
-
### Q4 2026
|
|
737
|
-
- DTOs automáticos
|
|
738
|
-
- Herencia de entidades
|
|
739
|
-
- Composite keys
|
|
740
|
-
|
|
741
|
-
---
|
|
742
|
-
|
|
743
|
-
**Última actualización**: Febrero 2, 2026
|
|
744
|
-
**Versión evaluada**: 1.0.0
|
|
745
|
-
**Evaluador**: Sistema de evaluación eva4j
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
### 1. Relaciones ManyToMany y OneToOne
|
|
749
|
-
|
|
750
|
-
```yaml
|
|
751
|
-
relationships:
|
|
752
|
-
- type: ManyToMany
|
|
753
|
-
target: Tag
|
|
754
|
-
joinTable:
|
|
755
|
-
name: order_tags
|
|
756
|
-
joinColumn: order_id
|
|
757
|
-
inverseJoinColumn: tag_id
|
|
758
|
-
```
|
|
759
|
-
|
|
760
|
-
**Implementación**: Ya está preparado en el parser, solo falta refinar templates.
|
|
761
|
-
|
|
762
|
-
---
|
|
763
|
-
|
|
764
|
-
### 2. Herencia de entidades
|
|
765
|
-
|
|
766
|
-
```yaml
|
|
767
|
-
entities:
|
|
768
|
-
- name: Payment
|
|
769
|
-
isRoot: true
|
|
770
|
-
inheritance:
|
|
771
|
-
strategy: JOINED # o SINGLE_TABLE, TABLE_PER_CLASS
|
|
772
|
-
discriminatorColumn: payment_type
|
|
773
|
-
|
|
774
|
-
- name: CreditCardPayment
|
|
775
|
-
extends: Payment
|
|
776
|
-
discriminatorValue: CREDIT_CARD
|
|
777
|
-
```
|
|
778
|
-
|
|
779
|
-
**Impacto**: Cubriría polimorfismo en dominios complejos.
|
|
780
|
-
|
|
781
|
-
---
|
|
782
|
-
|
|
783
|
-
### 3. Auditoría automática
|
|
784
|
-
|
|
785
|
-
```yaml
|
|
786
|
-
entities:
|
|
787
|
-
- name: Order
|
|
788
|
-
auditable: true # Agrega createdAt, updatedAt, createdBy, updatedBy
|
|
789
|
-
```
|
|
790
|
-
|
|
791
|
-
**Implementación**: Generar campos + `@EntityListeners(AuditingEntityListener.class)`.
|
|
792
|
-
|
|
793
|
-
---
|
|
794
|
-
|
|
795
|
-
### 4. Soft Delete ✅ Implementado
|
|
796
|
-
|
|
797
|
-
```yaml
|
|
798
|
-
entities:
|
|
799
|
-
- name: Order
|
|
800
|
-
isRoot: true
|
|
801
|
-
hasSoftDelete: true # Genera deletedAt, softDelete(), isDeleted(), @SQLRestriction
|
|
802
|
-
```
|
|
803
|
-
|
|
804
|
-
**Implementado**: `deletedAt` inyectado automáticamente, `@SQLRestriction("deleted_at IS NULL")` en JPA, `softDelete()` + `isDeleted()` en dominio, `DeleteCommandHandler` usa borrado lógico.
|
|
805
|
-
|
|
806
|
-
---
|
|
807
|
-
|
|
808
|
-
### 5. Validaciones JSR-303
|
|
809
|
-
|
|
810
|
-
```yaml
|
|
811
|
-
fields:
|
|
812
|
-
- name: email
|
|
813
|
-
type: String
|
|
814
|
-
validations:
|
|
815
|
-
- type: Email
|
|
816
|
-
message: "Email inválido"
|
|
817
|
-
- type: NotBlank
|
|
818
|
-
- type: Size
|
|
819
|
-
min: 5
|
|
820
|
-
max: 100
|
|
821
|
-
```
|
|
822
|
-
|
|
823
|
-
**Implementación**: Generar `@Email`, `@NotBlank`, `@Size` en entidades de dominio.
|
|
824
|
-
|
|
825
|
-
---
|
|
826
|
-
|
|
827
|
-
### 6. Índices y constraints personalizados
|
|
828
|
-
|
|
829
|
-
```yaml
|
|
830
|
-
entities:
|
|
831
|
-
- name: Order
|
|
832
|
-
tableName: orders
|
|
833
|
-
indexes:
|
|
834
|
-
- name: idx_order_number
|
|
835
|
-
columns: [orderNumber]
|
|
836
|
-
unique: true
|
|
837
|
-
- name: idx_customer_date
|
|
838
|
-
columns: [customerId, createdAt]
|
|
839
|
-
```
|
|
840
|
-
|
|
841
|
-
**Implementación**: Agregar `@Table(indexes = {...})`.
|
|
842
|
-
|
|
843
|
-
---
|
|
844
|
-
|
|
845
|
-
### 7. Métodos de negocio personalizados en YAML
|
|
846
|
-
|
|
847
|
-
```yaml
|
|
848
|
-
entities:
|
|
849
|
-
- name: Order
|
|
850
|
-
methods:
|
|
851
|
-
- name: applyDiscount
|
|
852
|
-
returnType: void
|
|
853
|
-
parameters:
|
|
854
|
-
- name: percentage
|
|
855
|
-
type: BigDecimal
|
|
856
|
-
body: |
|
|
857
|
-
BigDecimal discount = this.total.multiply(percentage).divide(new BigDecimal(100));
|
|
858
|
-
this.total = this.total.subtract(discount);
|
|
859
|
-
```
|
|
860
|
-
|
|
861
|
-
**Implementación**: Ya tienes infraestructura para value objects, extenderlo a entidades.
|
|
862
|
-
|
|
863
|
-
---
|
|
864
|
-
|
|
865
|
-
### 8. Query methods en repositorios
|
|
866
|
-
|
|
867
|
-
```yaml
|
|
868
|
-
aggregates:
|
|
869
|
-
- name: Order
|
|
870
|
-
repositories:
|
|
871
|
-
customQueries:
|
|
872
|
-
- name: findByStatusAndCreatedAtAfter
|
|
873
|
-
returnType: List<Order>
|
|
874
|
-
parameters:
|
|
875
|
-
- name: status
|
|
876
|
-
type: OrderStatus
|
|
877
|
-
- name: date
|
|
878
|
-
type: LocalDateTime
|
|
879
|
-
```
|
|
880
|
-
|
|
881
|
-
**Implementación**: Generar métodos en interface de repositorio (Spring Data los implementa automáticamente).
|
|
882
|
-
|
|
883
|
-
---
|
|
884
|
-
|
|
885
|
-
### 9. DTOs automáticos (Request/Response)
|
|
886
|
-
|
|
887
|
-
```yaml
|
|
888
|
-
aggregates:
|
|
889
|
-
- name: Order
|
|
890
|
-
dtos:
|
|
891
|
-
- name: CreateOrderRequest
|
|
892
|
-
fields: [customerId, items]
|
|
893
|
-
- name: OrderResponse
|
|
894
|
-
fields: [id, status, total, createdAt]
|
|
895
|
-
```
|
|
896
|
-
|
|
897
|
-
**Impacto**: Cubriría capa de aplicación completa.
|
|
898
|
-
|
|
899
|
-
---
|
|
900
|
-
|
|
901
|
-
### 10. Eventos de dominio
|
|
902
|
-
|
|
903
|
-
```yaml
|
|
904
|
-
entities:
|
|
905
|
-
- name: Order
|
|
906
|
-
events:
|
|
907
|
-
- OrderCreated
|
|
908
|
-
- OrderCancelled
|
|
909
|
-
```
|
|
910
|
-
|
|
911
|
-
**Implementación**: Generar clases de eventos + lógica para publicar con Spring Events.
|