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.
Files changed (106) hide show
  1. package/AGENTS.md +314 -10
  2. package/COMMAND_EVALUATION.md +15 -16
  3. package/DOMAIN_YAML_GUIDE.md +576 -10
  4. package/FUTURE_FEATURES.md +1627 -1168
  5. package/README.md +318 -13
  6. package/bin/eva4j.js +34 -0
  7. package/config/defaults.json +1 -0
  8. package/design-system.md +797 -0
  9. package/docs/commands/EVALUATE_SYSTEM.md +994 -0
  10. package/docs/commands/GENERATE_ENTITIES.md +795 -6
  11. package/docs/commands/INDEX.md +10 -1
  12. package/examples/domain-endpoints-relations.yaml +353 -0
  13. package/examples/domain-endpoints-versioned.yaml +144 -0
  14. package/examples/domain-endpoints.yaml +135 -0
  15. package/examples/domain-events.yaml +166 -20
  16. package/examples/domain-listeners.yaml +212 -0
  17. package/examples/domain-one-to-many.yaml +1 -0
  18. package/examples/domain-one-to-one.yaml +1 -0
  19. package/examples/domain-ports.yaml +414 -0
  20. package/examples/domain-soft-delete.yaml +47 -44
  21. package/examples/system/notification.yaml +147 -0
  22. package/examples/system/product.yaml +185 -0
  23. package/examples/system/system.yaml +112 -0
  24. package/examples/system-report.html +971 -0
  25. package/examples/system.yaml +332 -0
  26. package/package.json +2 -1
  27. package/src/commands/build.js +714 -0
  28. package/src/commands/create.js +7 -3
  29. package/src/commands/detach.js +1 -0
  30. package/src/commands/evaluate-system.js +610 -0
  31. package/src/commands/generate-entities.js +1331 -49
  32. package/src/commands/generate-http-exchange.js +2 -0
  33. package/src/commands/generate-kafka-event.js +98 -11
  34. package/src/generators/base-generator.js +8 -1
  35. package/src/generators/postman-generator.js +188 -0
  36. package/src/generators/shared-generator.js +10 -0
  37. package/src/utils/config-manager.js +54 -0
  38. package/src/utils/context-builder.js +1 -0
  39. package/src/utils/domain-diagram.js +192 -0
  40. package/src/utils/domain-validator.js +970 -0
  41. package/src/utils/fake-data.js +376 -0
  42. package/src/utils/naming.js +3 -2
  43. package/src/utils/system-validator.js +434 -0
  44. package/src/utils/yaml-to-entity.js +302 -8
  45. package/templates/aggregate/AggregateMapper.java.ejs +3 -2
  46. package/templates/aggregate/AggregateRepository.java.ejs +8 -2
  47. package/templates/aggregate/AggregateRepositoryImpl.java.ejs +13 -3
  48. package/templates/aggregate/AggregateRoot.java.ejs +60 -2
  49. package/templates/aggregate/DomainEventHandler.java.ejs +27 -20
  50. package/templates/aggregate/DomainEventRecord.java.ejs +24 -8
  51. package/templates/aggregate/DomainEventSnapshot.java.ejs +46 -0
  52. package/templates/aggregate/JpaAggregateRoot.java.ejs +6 -0
  53. package/templates/aggregate/JpaRepository.java.ejs +5 -0
  54. package/templates/base/gradle/build.gradle.ejs +3 -2
  55. package/templates/base/root/AGENTS.md.ejs +306 -45
  56. package/templates/base/root/skill-build-domain-yaml-references-generate-entities.md.ejs +1663 -0
  57. package/templates/base/root/skill-build-system-yaml.ejs +1446 -0
  58. package/templates/base/root/system.yaml.ejs +97 -0
  59. package/templates/crud/ApplicationMapper.java.ejs +4 -0
  60. package/templates/crud/Controller.java.ejs +4 -4
  61. package/templates/crud/CreateCommand.java.ejs +4 -0
  62. package/templates/crud/CreateItemDto.java.ejs +4 -0
  63. package/templates/crud/CreateValueObjectDto.java.ejs +4 -0
  64. package/templates/crud/DeleteCommandHandler.java.ejs +10 -2
  65. package/templates/crud/EndpointsController.java.ejs +178 -0
  66. package/templates/crud/FindByQuery.java.ejs +17 -0
  67. package/templates/crud/FindByQueryHandler.java.ejs +57 -0
  68. package/templates/crud/ListQuery.java.ejs +1 -1
  69. package/templates/crud/ListQueryHandler.java.ejs +8 -8
  70. package/templates/crud/ScaffoldCommand.java.ejs +12 -0
  71. package/templates/crud/ScaffoldCommandHandler.java.ejs +43 -0
  72. package/templates/crud/ScaffoldQuery.java.ejs +13 -0
  73. package/templates/crud/ScaffoldQueryHandler.java.ejs +41 -0
  74. package/templates/crud/SubEntityAddCommand.java.ejs +21 -0
  75. package/templates/crud/SubEntityAddCommandHandler.java.ejs +43 -0
  76. package/templates/crud/SubEntityRemoveCommand.java.ejs +9 -0
  77. package/templates/crud/SubEntityRemoveCommandHandler.java.ejs +42 -0
  78. package/templates/crud/TransitionCommand.java.ejs +9 -0
  79. package/templates/crud/TransitionCommandHandler.java.ejs +39 -0
  80. package/templates/crud/UpdateCommand.java.ejs +4 -0
  81. package/templates/evaluate/report.html.ejs +1363 -0
  82. package/templates/kafka-event/DomainEventHandlerMethod.ejs +3 -1
  83. package/templates/kafka-event/Event.java.ejs +16 -0
  84. package/templates/kafka-listener/KafkaController.java.ejs +1 -1
  85. package/templates/kafka-listener/KafkaListenerClass.java.ejs +1 -1
  86. package/templates/kafka-listener/ListenerClass.java.ejs +65 -0
  87. package/templates/kafka-listener/ListenerCommand.java.ejs +31 -0
  88. package/templates/kafka-listener/ListenerCommandHandler.java.ejs +23 -0
  89. package/templates/kafka-listener/ListenerIntegrationEvent.java.ejs +37 -0
  90. package/templates/kafka-listener/ListenerMethod.java.ejs +1 -1
  91. package/templates/kafka-listener/ListenerNestedType.java.ejs +28 -0
  92. package/templates/mock/MockEvent.java.ejs +10 -0
  93. package/templates/mock/MockMessageBrokerImpl.java.ejs +35 -0
  94. package/templates/mock/MockMessageBrokerImplMethod.java.ejs +6 -0
  95. package/templates/mock/SpringEventListener.java.ejs +61 -0
  96. package/templates/ports/PortDomainModel.java.ejs +35 -0
  97. package/templates/ports/PortFeignAdapter.java.ejs +67 -0
  98. package/templates/ports/PortFeignClient.java.ejs +45 -0
  99. package/templates/ports/PortFeignConfig.java.ejs +24 -0
  100. package/templates/ports/PortInterface.java.ejs +45 -0
  101. package/templates/ports/PortNestedType.java.ejs +28 -0
  102. package/templates/ports/PortRequestDto.java.ejs +30 -0
  103. package/templates/ports/PortResponseDto.java.ejs +28 -0
  104. package/templates/postman/Collection.json.ejs +1 -1
  105. package/templates/postman/UnifiedCollection.json.ejs +185 -0
  106. package/templates/shared/configurations/eventPublicationConfig/EventPublicationSchemaConfig.java.ejs +109 -0
@@ -0,0 +1,332 @@
1
+ system:
2
+ name: test-eva
3
+ groupId: com.example
4
+ javaVersion: 21
5
+ springBootVersion: 3.5.5
6
+ database: postgresql
7
+
8
+ messaging:
9
+ enabled: true
10
+ broker: kafka
11
+ kafka:
12
+ bootstrapServers: localhost:9092
13
+ defaultGroupId: test-eva
14
+ topicPrefix: cinema
15
+
16
+ modules:
17
+
18
+ # ─────────────────────────────────────────────
19
+ # CATÁLOGO
20
+ # ─────────────────────────────────────────────
21
+
22
+ - name: movies
23
+ description: "Catálogo de películas: títulos, géneros, clasificaciones, sinopsis y duración"
24
+ exposes:
25
+ - method: GET
26
+ path: /movies
27
+ useCase: FindAllMovies
28
+ description: "Listar películas con filtros por género, clasificación y estado de estreno"
29
+ - method: GET
30
+ path: /movies/{id}
31
+ useCase: GetMovie
32
+ description: "Obtener detalle completo de una película"
33
+ - method: POST
34
+ path: /movies
35
+ useCase: CreateMovie
36
+ description: "Registrar nueva película en el catálogo"
37
+ - method: PUT
38
+ path: /movies/{id}
39
+ useCase: UpdateMovie
40
+ description: "Actualizar información de una película"
41
+ - method: DELETE
42
+ path: /movies/{id}
43
+ useCase: DeleteMovie
44
+ description: "Retirar una película del catálogo"
45
+
46
+ - name: theaters
47
+ description: "Salas de cine: configuración de capacidad, tipo de sala (2D, 3D, IMAX) y mapa de asientos"
48
+ exposes:
49
+ - method: GET
50
+ path: /theaters
51
+ useCase: FindAllTheaters
52
+ description: "Listar todas las salas disponibles"
53
+ - method: GET
54
+ path: /theaters/{id}
55
+ useCase: GetTheater
56
+ description: "Obtener configuración y capacidad de una sala"
57
+ - method: POST
58
+ path: /theaters
59
+ useCase: CreateTheater
60
+ description: "Registrar nueva sala de cine"
61
+ - method: PUT
62
+ path: /theaters/{id}
63
+ useCase: UpdateTheater
64
+ description: "Actualizar configuración de una sala"
65
+
66
+ # ─────────────────────────────────────────────
67
+ # PROGRAMACIÓN
68
+ # ─────────────────────────────────────────────
69
+
70
+ - name: screenings
71
+ description: "Funciones programadas: asocia película + sala + horario, gestiona disponibilidad, precios y bloqueo exclusivo para eventos privados"
72
+ exposes:
73
+ - method: GET
74
+ path: /screenings
75
+ useCase: FindAllScreenings
76
+ description: "Listar funciones con filtros por película, sala y fecha"
77
+ - method: GET
78
+ path: /screenings/{id}
79
+ useCase: GetScreening
80
+ description: "Obtener detalle de una función (película, sala, horario, precio base)"
81
+ - method: GET
82
+ path: /screenings/{id}/seats
83
+ useCase: GetAvailableSeats
84
+ description: "Consultar mapa de asientos con disponibilidad en tiempo real"
85
+ - method: POST
86
+ path: /screenings
87
+ useCase: ScheduleScreening
88
+ description: "Programar una nueva función"
89
+ - method: PUT
90
+ path: /screenings/{id}/cancel
91
+ useCase: CancelScreening
92
+ description: "Cancelar una función programada y liberar todas las reservas"
93
+ - method: GET
94
+ path: /screenings/{id}/private-event-availability
95
+ useCase: CheckPrivateEventAvailability
96
+ description: "Verificar si la sala completa está libre de reservas individuales y puede ser bloqueada para un evento privado" # ★ NUEVO
97
+ - method: PUT
98
+ path: /screenings/{id}/lock
99
+ useCase: LockScreeningForPrivateEvent
100
+ description: "Bloquear toda la sala para un evento privado, impidiendo nuevas reservas individuales sobre esa función" # ★ NUEVO
101
+
102
+ # ─────────────────────────────────────────────
103
+ # CLIENTES
104
+ # ─────────────────────────────────────────────
105
+
106
+ - name: customers
107
+ description: "Registro y perfil de clientes: datos personales, historial de compras e historial de puntos"
108
+ exposes:
109
+ - method: POST
110
+ path: /customers
111
+ useCase: CreateCustomer
112
+ description: "Registrar nuevo cliente"
113
+ - method: GET
114
+ path: /customers/{id}
115
+ useCase: GetCustomer
116
+ description: "Obtener perfil del cliente"
117
+ - method: GET
118
+ path: /customers
119
+ useCase: FindAllCustomers
120
+ description: "Listar clientes con filtros"
121
+ - method: PUT
122
+ path: /customers/{id}
123
+ useCase: UpdateCustomer
124
+ description: "Actualizar datos personales del cliente"
125
+
126
+ # ─────────────────────────────────────────────
127
+ # RESERVAS
128
+ # ─────────────────────────────────────────────
129
+
130
+ - name: reservations
131
+ description: "Ciclo de vida de la reserva: selección y bloqueo de asientos, confirmación, cancelación y reserva exclusiva de sala completa para eventos privados"
132
+ exposes:
133
+ - method: POST
134
+ path: /reservations
135
+ useCase: CreateReservation
136
+ description: "Iniciar reserva: seleccionar función y asientos, bloqueo temporal (15 min)"
137
+ - method: GET
138
+ path: /reservations/{id}
139
+ useCase: GetReservation
140
+ description: "Consultar estado e información de una reserva"
141
+ - method: GET
142
+ path: /reservations
143
+ useCase: FindAllReservations
144
+ description: "Listar reservas con filtros por cliente, función y estado"
145
+ - method: PUT
146
+ path: /reservations/{id}/confirm
147
+ useCase: ConfirmReservation
148
+ description: "Confirmar la reserva después de recibir pago aprobado"
149
+ - method: PUT
150
+ path: /reservations/{id}/cancel
151
+ useCase: CancelReservation
152
+ description: "Cancelar la reserva y liberar los asientos seleccionados"
153
+ - method: PUT
154
+ path: /reservations/{id}/expire
155
+ useCase: ExpireReservation
156
+ description: "Expirar reserva no pagada dentro del tiempo límite de bloqueo"
157
+ - method: POST
158
+ path: /reservations/private-events
159
+ useCase: CreatePrivateEventReservation
160
+ description: "Reservar toda la sala para un evento privado: ocupa la capacidad total de la función de forma exclusiva" # ★ NUEVO
161
+
162
+ # ─────────────────────────────────────────────
163
+ # PAGOS
164
+ # ─────────────────────────────────────────────
165
+
166
+ - name: payments
167
+ description: "Procesamiento de pagos: integración con pasarela externa, aprobaciones y reembolsos"
168
+ exposes:
169
+ - method: POST
170
+ path: /payments
171
+ useCase: InitiatePayment
172
+ description: "Iniciar proceso de pago vinculado a una reserva"
173
+ - method: GET
174
+ path: /payments/{id}
175
+ useCase: GetPayment
176
+ description: "Consultar estado de un pago"
177
+ - method: GET
178
+ path: /payments
179
+ useCase: FindAllPayments
180
+ description: "Listar pagos con filtros por estado y fecha"
181
+ - method: PUT
182
+ path: /payments/{id}/approve
183
+ useCase: ApprovePayment
184
+ description: "Registrar aprobación de pago recibida desde la pasarela"
185
+ - method: PUT
186
+ path: /payments/{id}/reject
187
+ useCase: RejectPayment
188
+ description: "Registrar rechazo de pago recibido desde la pasarela"
189
+ - method: PUT
190
+ path: /payments/{id}/refund
191
+ useCase: ProcessRefund
192
+ description: "Procesar reembolso por cancelación de reserva o función"
193
+
194
+ # ─────────────────────────────────────────────
195
+ # NOTIFICACIONES
196
+ # ─────────────────────────────────────────────
197
+
198
+ - name: notifications
199
+ description: "Envío de notificaciones por email y SMS: confirmaciones, tickets QR, recordatorios y alertas de cancelación"
200
+
201
+ integrations:
202
+ async:
203
+ # Reserva creada → pago espera cobro; notificación informa el bloqueo de asientos
204
+ - event: ReservationCreatedEvent
205
+ producer: reservations
206
+ topic: RESERVATION_CREATED
207
+ consumers:
208
+ - module: payments
209
+ useCase: HandleReservationCreated
210
+ - module: notifications
211
+ useCase: NotifyReservationCreated
212
+
213
+ # Pago aprobado → reserva debe confirmarse; cliente recibe confirmación
214
+ - event: PaymentApprovedEvent
215
+ producer: payments
216
+ topic: PAYMENT_APPROVED
217
+ consumers:
218
+ - module: reservations
219
+ useCase: ConfirmReservation
220
+ - module: notifications
221
+ useCase: NotifyPaymentApproved
222
+
223
+ # Pago rechazado → reserva debe expirar y liberar asientos; cliente recibe aviso
224
+ - event: PaymentRejectedEvent
225
+ producer: payments
226
+ topic: PAYMENT_REJECTED
227
+ consumers:
228
+ - module: reservations
229
+ useCase: ExpireReservation
230
+ - module: notifications
231
+ useCase: NotifyPaymentRejected
232
+
233
+ # Reserva confirmada → se emiten los tickets QR y se envían al cliente; cliente acumula puntos de fidelidad
234
+ - event: ReservationConfirmedEvent
235
+ producer: reservations
236
+ topic: RESERVATION_CONFIRMED
237
+ consumers:
238
+ - module: notifications
239
+ useCase: NotifyReservationConfirmed
240
+ - module: customers # acumula loyalty points al confirmar reserva
241
+ useCase: AccumulateLoyaltyPoints
242
+
243
+ # Reserva cancelada → pagos evalúa reembolso; screenings libera asientos; cliente recibe notificación
244
+ - event: ReservationCancelledEvent
245
+ producer: reservations
246
+ topic: RESERVATION_CANCELLED
247
+ consumers:
248
+ - module: payments # evalúa si aplica reembolso
249
+ useCase: ProcessRefund
250
+ - module: screenings # libera ScreeningSeats → AVAILABLE (también cubre unlock de sala privada)
251
+ useCase: ReleaseScreeningSeats
252
+ - module: notifications
253
+ useCase: NotifyReservationCancelled
254
+
255
+ # Reserva expirada por timeout (sin pago) → screenings libera asientos; cliente recibe aviso (sin reembolso)
256
+ - event: ReservationExpiredEvent
257
+ producer: reservations
258
+ topic: RESERVATION_EXPIRED
259
+ consumers:
260
+ - module: screenings # libera ScreeningSeats → AVAILABLE
261
+ useCase: ReleaseScreeningSeats
262
+ - module: notifications # avisa al cliente que su tiempo de bloqueo expiró
263
+ useCase: NotifyReservationExpired
264
+
265
+ # Función cancelada → reservas libera asientos y expira reservas activas; clientes notificados
266
+ - event: ScreeningCancelledEvent
267
+ producer: screenings
268
+ topic: SCREENING_CANCELLED
269
+ consumers:
270
+ - module: reservations
271
+ useCase: CancelReservationsByScreening
272
+ - module: notifications
273
+ useCase: NotifyScreeningCancelled
274
+
275
+ # ★ NUEVO — Reserva de evento privado creada → screenings bloquea la sala; payments inicia cobro total; notifications avisa
276
+ - event: PrivateEventReservationCreatedEvent
277
+ producer: reservations
278
+ topic: PRIVATE_EVENT_RESERVATION_CREATED
279
+ consumers:
280
+ - module: screenings
281
+ useCase: LockScreeningForPrivateEvent
282
+ - module: payments
283
+ useCase: InitiatePrivateEventPayment
284
+ - module: notifications
285
+ useCase: NotifyPrivateEventReservationCreated
286
+
287
+ # ★ NUEVO — Sala bloqueada exitosamente → notifications confirma al organizador del evento
288
+ - event: TheaterLockedForPrivateEventEvent
289
+ producer: screenings
290
+ topic: THEATER_LOCKED_FOR_PRIVATE_EVENT
291
+ consumers:
292
+ - module: notifications
293
+ useCase: NotifyTheaterLockedForPrivateEvent
294
+
295
+ sync:
296
+ # Al programar una función se valida que la película esté activa y se obtiene su duración
297
+ - caller: screenings
298
+ calls: movies
299
+ port: MovieService
300
+ using:
301
+ - GET /movies/{id}
302
+
303
+ # Al programar una función se valida que la sala esté activa y se copian los asientos al mapa de la función
304
+ - caller: screenings
305
+ calls: theaters
306
+ port: TheaterService
307
+ using:
308
+ - GET /theaters/{id}
309
+
310
+ # Al crear una reserva se consulta la función para validar disponibilidad y precio
311
+ # ★ MODIFICADO — se agrega consulta de disponibilidad para evento privado
312
+ - caller: reservations
313
+ calls: screenings
314
+ port: ScreeningService
315
+ using:
316
+ - GET /screenings/{id}
317
+ - GET /screenings/{id}/seats
318
+ - GET /screenings/{id}/private-event-availability # ★ NUEVO
319
+
320
+ # Al crear una reserva se verifica que el cliente exista y esté activo
321
+ - caller: reservations
322
+ calls: customers
323
+ port: CustomerService
324
+ using:
325
+ - GET /customers/{id}
326
+
327
+ # Al iniciar un pago se obtiene el detalle de la reserva para calcular el monto
328
+ - caller: payments
329
+ calls: reservations
330
+ port: ReservationService
331
+ using:
332
+ - GET /reservations/{id}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eva4j",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "description": "A powerful Node.js CLI for generating Spring Boot projects with modular architecture that enables efficient monolith-first development with seamless transition to microservices",
5
5
  "main": "bin/eva4j.js",
6
6
  "bin": {
@@ -41,6 +41,7 @@
41
41
  },
42
42
  "homepage": "https://github.com/asuridev/eva4j#readme",
43
43
  "dependencies": {
44
+ "@faker-js/faker": "^10.3.0",
44
45
  "chalk": "^4.1.2",
45
46
  "clipboardy": "^2.3.0",
46
47
  "commander": "^11.1.0",