eva4j 1.0.13 → 1.0.14
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 +51 -9
- package/DOMAIN_YAML_GUIDE.md +150 -0
- package/bin/eva4j.js +31 -1
- package/design-system.md +797 -0
- package/docs/commands/EVALUATE_SYSTEM.md +542 -0
- package/docs/commands/GENERATE_ENTITIES.md +196 -0
- 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/system.yaml +289 -0
- package/package.json +1 -1
- package/src/commands/create.js +6 -3
- package/src/commands/evaluate-system.js +384 -0
- package/src/commands/generate-entities.js +677 -14
- package/src/commands/generate-kafka-event.js +59 -5
- package/src/commands/generate-system.js +243 -0
- package/src/generators/base-generator.js +9 -1
- package/src/utils/naming.js +3 -2
- package/src/utils/system-validator.js +314 -0
- package/src/utils/yaml-to-entity.js +31 -2
- package/templates/aggregate/AggregateRepository.java.ejs +5 -0
- package/templates/aggregate/AggregateRepositoryImpl.java.ejs +9 -0
- package/templates/aggregate/DomainEventHandler.java.ejs +24 -20
- package/templates/aggregate/JpaRepository.java.ejs +5 -0
- package/templates/base/root/skill-build-domain-yaml-references-generate-entities.md.ejs +1103 -0
- package/templates/base/root/skill-build-domain-yaml.ejs +292 -0
- package/templates/base/root/skill-build-system-yaml.ejs +252 -0
- package/templates/base/root/system.yaml.ejs +97 -0
- 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/ScaffoldCommand.java.ejs +12 -0
- package/templates/crud/ScaffoldCommandHandler.java.ejs +43 -0
- package/templates/crud/ScaffoldQuery.java.ejs +12 -0
- package/templates/crud/ScaffoldQueryHandler.java.ejs +40 -0
- package/templates/crud/SubEntityAddCommand.java.ejs +17 -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/evaluate/report.html.ejs +971 -0
- package/templates/kafka-event/Event.java.ejs +7 -0
package/AGENTS.md
CHANGED
|
@@ -457,9 +457,13 @@ aggregates:
|
|
|
457
457
|
fields:
|
|
458
458
|
- name: userId
|
|
459
459
|
type: String
|
|
460
|
-
#
|
|
460
|
+
# Nota: el flag kafka: true ya no es necesario.
|
|
461
|
+
# Si el proyecto tiene un broker instalado (eva add kafka-client),
|
|
462
|
+
# eva g entities cablea automáticamente todos los eventos declarados.
|
|
461
463
|
```
|
|
462
464
|
|
|
465
|
+
El `domain.yaml` también soporta una sección `endpoints:` opcional (sibling de `aggregates:`) para declarar los endpoints REST. Ver sección [⚡ Características Avanzadas](#-características-avanzadas-del-domainyaml) para detalles.
|
|
466
|
+
|
|
463
467
|
---
|
|
464
468
|
|
|
465
469
|
## ⚡ Características Avanzadas del domain.yaml
|
|
@@ -523,26 +527,51 @@ aggregates:
|
|
|
523
527
|
- name: Order
|
|
524
528
|
entities: [...]
|
|
525
529
|
events:
|
|
526
|
-
- name:
|
|
530
|
+
- name: OrderConfirmed
|
|
527
531
|
fields:
|
|
528
532
|
- name: orderId
|
|
529
533
|
type: String
|
|
530
534
|
- name: confirmedAt
|
|
531
535
|
type: LocalDateTime
|
|
532
|
-
kafka: true # opcional — genera publicación a MessageBroker
|
|
533
536
|
```
|
|
534
537
|
|
|
535
|
-
Genera `
|
|
538
|
+
Genera `OrderConfirmed.java` (en `domain/models/events/`) que extiende `DomainEvent`, y `OrderDomainEventHandler.java` (en `application/usecases/`) con `@TransactionalEventListener(AFTER_COMMIT)`.
|
|
539
|
+
|
|
540
|
+
**Auto-wiring de broker:** Si el proyecto tiene un broker de mensajería instalado (`eva add kafka-client`), `eva g entities` genera automáticamente la capa de Integration Events para **todos** los eventos declarados — sin necesidad de ejecutar `eva g kafka-event` por separado:
|
|
541
|
+
|
|
542
|
+
| Archivo generado | Descripción |
|
|
543
|
+
|---|---|
|
|
544
|
+
| `application/events/OrderConfirmedIntegrationEvent.java` | Record broker-facing (Integration Event) |
|
|
545
|
+
| `application/ports/MessageBroker.java` | Puerto broker-agnóstico (creado/actualizado) |
|
|
546
|
+
| `infrastructure/adapters/kafkaMessageBroker/…` | Adaptador Kafka (creado/actualizado) |
|
|
547
|
+
| `shared/…/kafkaConfig/KafkaConfig.java` | Bean `NewTopic` (actualizado) |
|
|
548
|
+
| `parameters/*/kafka.yaml` | Configuración de topic (actualizada) |
|
|
549
|
+
|
|
550
|
+
**Domain Event vs Integration Event:**
|
|
551
|
+
- **Domain Event** (`domain/models/events/OrderConfirmed.java`) — señal interna del bounded context. Nunca depende de infraestructura.
|
|
552
|
+
- **Integration Event** (`application/events/OrderConfirmedIntegrationEvent.java`) — proyección para el broker. Cambiar de Kafka a RabbitMQ solo requiere cambiar el adaptador `MessageBroker`; los Domain Events no se modifican nunca.
|
|
553
|
+
|
|
554
|
+
El `DomainEventHandler` mapea un Domain Event a un Integration Event:
|
|
555
|
+
```java
|
|
556
|
+
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
|
|
557
|
+
public void onOrderConfirmed(OrderConfirmed event) {
|
|
558
|
+
messageBroker.publishOrderConfirmedIntegrationEvent(
|
|
559
|
+
new OrderConfirmedIntegrationEvent(event.getOrderId(), event.getConfirmedAt())
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
```
|
|
536
563
|
|
|
537
564
|
Publicar desde la entidad raíz usando `raise()` heredado:
|
|
538
565
|
|
|
539
566
|
```java
|
|
540
567
|
public void confirm() {
|
|
541
568
|
this.status = this.status.transitionTo(OrderStatus.CONFIRMED);
|
|
542
|
-
raise(new
|
|
569
|
+
raise(new OrderConfirmed(this.id, LocalDateTime.now()));
|
|
543
570
|
}
|
|
544
571
|
```
|
|
545
572
|
|
|
573
|
+
**Nota:** el flag `kafka: true` por evento ya no es necesario — todos los eventos se cablearán automáticamente cuando haya un broker instalado.
|
|
574
|
+
|
|
546
575
|
---
|
|
547
576
|
|
|
548
577
|
## �️ Soft Delete
|
|
@@ -956,7 +985,18 @@ private String customerId;
|
|
|
956
985
|
2. **SI** el módulo requiere ciclo de vida → usar `transitions` + `initialValue` en el enum
|
|
957
986
|
3. **SI** un valor tiene lógica de negocio → declararlo como `valueObject` con `methods`
|
|
958
987
|
4. **SI** ocurren hechos relevantes de negocio → declarar `events[]` en el agregado
|
|
959
|
-
5. **
|
|
988
|
+
5. **SI** el módulo expone endpoints REST específicos → declarar `endpoints:` con versiones y operaciones
|
|
989
|
+
6. **DESPUÉS** de generar el `domain.yaml` → ejecutar `eva g entities <module>`
|
|
990
|
+
|
|
991
|
+
### Al Usar `endpoints:` en domain.yaml
|
|
992
|
+
|
|
993
|
+
1. **SIEMPRE** declarar `endpoints:` cuando el API REST tiene comportamientos custom (confirmar, cancelar, activar, etc.)
|
|
994
|
+
2. **NUNCA** usar `endpoints:` si solo necesitas CRUD estándar — el flujo interactivo es más simple
|
|
995
|
+
3. **SIEMPRE** usar PascalCase para los nombres de `useCase` (ej: `ConfirmOrder`, no `confirmOrder`)
|
|
996
|
+
4. **CONOCER** cuáles son los 5 use cases estándar por aggregate: `Create{E}`, `Update{E}`, `Delete{E}`, `Get{E}`, `FindAll{E}s` — estos generan implementación completa
|
|
997
|
+
5. **SABER** que cualquier otro nombre genera un **scaffold** con `UnsupportedOperationException` — el desarrollador debe implementar el handler
|
|
998
|
+
6. **APLICAR** la regla anti-duplicado: si el mismo useCase aparece en v1 y v2, se genera solo una vez
|
|
999
|
+
7. **NOMBRAR** los controladores según la convención: `{Aggregate}{VersionCapitalized}Controller` (ej: `OrderV1Controller`)
|
|
960
1000
|
|
|
961
1001
|
### Al Generar Código de Dominio
|
|
962
1002
|
|
|
@@ -1188,10 +1228,12 @@ Al generar o modificar código, verificar:
|
|
|
1188
1228
|
- [ ] Enum con ciclo de vida → usar `transitions` + `initialValue`, no setters manuales
|
|
1189
1229
|
- [ ] Value Object con comportamiento → declarar `methods` en lugar de lógica en entidad
|
|
1190
1230
|
- [ ] Evento de dominio → declarar en `events[]`, publicar con `raise()` en método de negocio
|
|
1191
|
-
- [ ] Evento con
|
|
1231
|
+
- [ ] Evento con broker → **no** usar `kafka: true`; si `eva add kafka-client` está instalado, `eva g entities` auto-cablea todos los eventos
|
|
1232
|
+
- [ ] Distinguir entre Domain Event (`domain/models/events/X.java`) e Integration Event (`application/events/XIntegrationEvent.java`) — cambios de broker solo afectan al adaptador `MessageBroker`
|
|
1233
|
+
- [ ] Endpoints REST específicos → declarar `endpoints:` con versiones y operaciones; usar nombres estándar para implementación completa
|
|
1192
1234
|
|
|
1193
1235
|
---
|
|
1194
1236
|
|
|
1195
|
-
**Última actualización:** 2026-03-
|
|
1196
|
-
**Versión de eva4j:** 1.0.
|
|
1237
|
+
**Última actualización:** 2026-03-11
|
|
1238
|
+
**Versión de eva4j:** 1.0.13
|
|
1197
1239
|
**Estado:** Documento de referencia para agentes IA
|
package/DOMAIN_YAML_GUIDE.md
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
- [Validaciones JSR-303](#validaciones-jsr-303)
|
|
14
14
|
- [Relaciones](#relaciones)
|
|
15
15
|
- [Tipos de Datos](#tipos-de-datos)
|
|
16
|
+
- [Sección endpoints](#sección-endpoints)
|
|
16
17
|
- [Ejemplos Completos](#ejemplos-completos)
|
|
17
18
|
|
|
18
19
|
---
|
|
@@ -2441,6 +2442,155 @@ private List<AddressJpa> addresses = new ArrayList<>();
|
|
|
2441
2442
|
|
|
2442
2443
|
---
|
|
2443
2444
|
|
|
2445
|
+
## Sección endpoints
|
|
2446
|
+
|
|
2447
|
+
La sección `endpoints:` es **opcional** y se declara como clave hermana de `aggregates:` en el YAML. Cuando está presente, controla **qué use cases y controladores REST se generan**. Cuando está ausente, el generador usa el flujo interactivo tradicional (5 CRUD fijos por aggregate root).
|
|
2448
|
+
|
|
2449
|
+
### Comportamiento condicional
|
|
2450
|
+
|
|
2451
|
+
| Condición | Comportamiento |
|
|
2452
|
+
|-----------|---------------|
|
|
2453
|
+
| `endpoints:` **ausente** | Pregunta interactiva "¿Generar CRUD?" → genera 5 use cases estándar |
|
|
2454
|
+
| `endpoints:` **presente** | Genera automáticamente solo los use cases declarados en `operations[]` |
|
|
2455
|
+
|
|
2456
|
+
### Sintaxis
|
|
2457
|
+
|
|
2458
|
+
```yaml
|
|
2459
|
+
# Sección endpoints: sibling de aggregates:
|
|
2460
|
+
endpoints:
|
|
2461
|
+
basePath: /orders # Ruta base (incluida en @RequestMapping "/api/{version}{basePath}")
|
|
2462
|
+
versions:
|
|
2463
|
+
- version: v1 # Versión del API (ej: v1, v2, v1-beta)
|
|
2464
|
+
operations:
|
|
2465
|
+
- method: GET # HTTP method (GET, POST, PUT, PATCH, DELETE)
|
|
2466
|
+
path: /{id} # Path relativo al basePath (/ para la raíz)
|
|
2467
|
+
useCase: GetOrder # Nombre del use case (PascalCase)
|
|
2468
|
+
description: "Obtener pedido por ID" # Descripción para Swagger
|
|
2469
|
+
```
|
|
2470
|
+
|
|
2471
|
+
### Campos de `endpoints:`
|
|
2472
|
+
|
|
2473
|
+
| Campo | Tipo | Requerido | Descripción |
|
|
2474
|
+
|-------|------|-----------|-------------|
|
|
2475
|
+
| `basePath` | String | Sí | Ruta base del recurso (ej: `/orders`) |
|
|
2476
|
+
| `versions` | Array | Sí | Lista de versiones de API |
|
|
2477
|
+
| `versions[].version` | String | Sí | Identificador de versión (ej: `v1`) |
|
|
2478
|
+
| `versions[].operations` | Array | Sí | Lista de endpoints a generar |
|
|
2479
|
+
| `operations[].method` | String | Sí | Verbo HTTP: `GET`, `POST`, `PUT`, `PATCH`, `DELETE` |
|
|
2480
|
+
| `operations[].path` | String | Sí | Path relativo (ej: `/`, `/{id}`, `/{id}/confirm`) |
|
|
2481
|
+
| `operations[].useCase` | String | Sí | Nombre del use case en PascalCase |
|
|
2482
|
+
| `operations[].description` | String | No | Descripción para la anotación `@Operation` de Swagger |
|
|
2483
|
+
|
|
2484
|
+
### Tipo inferido (`type`)
|
|
2485
|
+
|
|
2486
|
+
El tipo del use case se infiere automáticamente del método HTTP:
|
|
2487
|
+
|
|
2488
|
+
| HTTP method | Tipo inferido | Genera |
|
|
2489
|
+
|-------------|--------------|--------|
|
|
2490
|
+
| `GET` | `query` | `{UseCaseName}Query` + `{UseCaseName}QueryHandler` |
|
|
2491
|
+
| `POST`, `PUT`, `PATCH`, `DELETE` | `command` | `{UseCaseName}Command` + `{UseCaseName}CommandHandler` |
|
|
2492
|
+
|
|
2493
|
+
### Use cases estándar vs. scaffold
|
|
2494
|
+
|
|
2495
|
+
| Categoría | Nombres Match | Generado |
|
|
2496
|
+
|-----------|---------------|---------|
|
|
2497
|
+
| **Estándar** | `Create{Aggregate}`, `Update{Aggregate}`, `Delete{Aggregate}`, `Get{Aggregate}`, `FindAll{Aggregate}s` | Implementación completa con lógica de repositorio |
|
|
2498
|
+
| **Scaffold** | Cualquier otro nombre (`ConfirmOrder`, `ActivateProduct`, etc.) | Clase con `// TODO` — el desarrollador completa la lógica |
|
|
2499
|
+
|
|
2500
|
+
Los use cases estándar reutilizan los templates CRUD existentes (implementación idéntica al flujo sin `endpoints:`). Los scaffolds generan archivos con `UnsupportedOperationException` y comentarios guía.
|
|
2501
|
+
|
|
2502
|
+
### Regla anti-duplicado (multi-versión)
|
|
2503
|
+
|
|
2504
|
+
Cuando el mismo `useCase` aparece en múltiples versiones (ej: `CreateProduct` en v1 y v2), el generador crea el Command/Query + Handler **solo una vez** (en la primera versión donde aparece). Los controladores de las versiones posteriores importan y referencian el mismo use case sin regenerarlo.
|
|
2505
|
+
|
|
2506
|
+
```yaml
|
|
2507
|
+
endpoints:
|
|
2508
|
+
basePath: /products
|
|
2509
|
+
versions:
|
|
2510
|
+
- version: v1
|
|
2511
|
+
operations:
|
|
2512
|
+
- { method: POST, path: /, useCase: CreateProduct } # ← genera CreateProductCommand + Handler
|
|
2513
|
+
|
|
2514
|
+
- version: v2
|
|
2515
|
+
operations:
|
|
2516
|
+
- { method: POST, path: /, useCase: CreateProduct } # ← NO regenera, solo referencia en V2Controller
|
|
2517
|
+
- { method: PUT, path: /{id}/activate, useCase: ActivateProduct } # ← nuevo scaffold
|
|
2518
|
+
```
|
|
2519
|
+
|
|
2520
|
+
### Nombres de controladores generados
|
|
2521
|
+
|
|
2522
|
+
Con `endpoints:`, el controlador se nombra `{Aggregate}{VersionCapitalized}Controller`:
|
|
2523
|
+
|
|
2524
|
+
| Aggregate | Version | Clase generada | Archivo |
|
|
2525
|
+
|-----------|---------|---------------|---------|
|
|
2526
|
+
| `Order` | `v1` | `OrderV1Controller` | `controllers/order/v1/OrderV1Controller.java` |
|
|
2527
|
+
| `Product` | `v2` | `ProductV2Controller` | `controllers/product/v2/ProductV2Controller.java` |
|
|
2528
|
+
|
|
2529
|
+
> Sin `endpoints:`, el controlador se llama `{Aggregate}Controller` y usa la versión ingresada en el prompt.
|
|
2530
|
+
|
|
2531
|
+
### Ejemplo básico (una versión)
|
|
2532
|
+
|
|
2533
|
+
```yaml
|
|
2534
|
+
aggregates:
|
|
2535
|
+
- name: Order
|
|
2536
|
+
entities:
|
|
2537
|
+
- name: order
|
|
2538
|
+
isRoot: true
|
|
2539
|
+
tableName: orders
|
|
2540
|
+
fields:
|
|
2541
|
+
- { name: id, type: String }
|
|
2542
|
+
- { name: orderNumber, type: String }
|
|
2543
|
+
- { name: status, type: OrderStatus, readOnly: true }
|
|
2544
|
+
|
|
2545
|
+
enums:
|
|
2546
|
+
- name: OrderStatus
|
|
2547
|
+
initialValue: PENDING
|
|
2548
|
+
values: [PENDING, CONFIRMED, SHIPPED, CANCELLED]
|
|
2549
|
+
|
|
2550
|
+
endpoints:
|
|
2551
|
+
basePath: /orders
|
|
2552
|
+
versions:
|
|
2553
|
+
- version: v1
|
|
2554
|
+
operations:
|
|
2555
|
+
- { method: GET, path: /{id}, useCase: GetOrder, description: "Obtener pedido" }
|
|
2556
|
+
- { method: GET, path: /, useCase: FindAllOrders, description: "Listar pedidos" }
|
|
2557
|
+
- { method: POST, path: /, useCase: CreateOrder, description: "Crear pedido" }
|
|
2558
|
+
- { method: DELETE, path: /{id}, useCase: DeleteOrder, description: "Eliminar pedido" }
|
|
2559
|
+
- { method: PUT, path: /{id}/confirm, useCase: ConfirmOrder, description: "Confirmar pedido" }
|
|
2560
|
+
```
|
|
2561
|
+
|
|
2562
|
+
**Archivos generados:**
|
|
2563
|
+
```
|
|
2564
|
+
application/
|
|
2565
|
+
commands/
|
|
2566
|
+
CreateOrderCommand.java ← estándar (completo)
|
|
2567
|
+
DeleteOrderCommand.java ← estándar (completo)
|
|
2568
|
+
ConfirmOrderCommand.java ← scaffold (TODO)
|
|
2569
|
+
queries/
|
|
2570
|
+
GetOrderQuery.java ← estándar (completo)
|
|
2571
|
+
FindAllOrdersQuery.java ← NOTA: no es estándar (estándar sería FindAllOrders s)
|
|
2572
|
+
→ scaffold (TODO)
|
|
2573
|
+
usecases/
|
|
2574
|
+
CreateOrderCommandHandler.java ← estándar
|
|
2575
|
+
DeleteOrderCommandHandler.java ← estándar
|
|
2576
|
+
ConfirmOrderCommandHandler.java ← scaffold
|
|
2577
|
+
GetOrderQueryHandler.java ← estándar
|
|
2578
|
+
FindAllOrdersQueryHandler.java ← scaffold
|
|
2579
|
+
dtos/
|
|
2580
|
+
OrderResponseDto.java
|
|
2581
|
+
mappers/
|
|
2582
|
+
OrderApplicationMapper.java
|
|
2583
|
+
infrastructure/rest/controllers/order/
|
|
2584
|
+
v1/
|
|
2585
|
+
OrderV1Controller.java ← controller con 5 métodos declarados
|
|
2586
|
+
```
|
|
2587
|
+
|
|
2588
|
+
### Ejemplo multi-versión
|
|
2589
|
+
|
|
2590
|
+
Ver [`examples/domain-endpoints-versioned.yaml`](examples/domain-endpoints-versioned.yaml) para un ejemplo completo con v1 y v2, incluyendo la regla anti-duplicado y scaffolds.
|
|
2591
|
+
|
|
2592
|
+
---
|
|
2593
|
+
|
|
2444
2594
|
## Ejemplos Completos
|
|
2445
2595
|
|
|
2446
2596
|
### Ejemplo 1: E-Commerce (Order)
|
package/bin/eva4j.js
CHANGED
|
@@ -16,6 +16,8 @@ const generateRecordCommand = require('../src/commands/generate-record');
|
|
|
16
16
|
const generateEntitiesCommand = require('../src/commands/generate-entities');
|
|
17
17
|
const generateTemporalFlowCommand = require('../src/commands/generate-temporal-flow');
|
|
18
18
|
const generateTemporalActivityCommand = require('../src/commands/generate-temporal-activity');
|
|
19
|
+
const generateSystemCommand = require('../src/commands/generate-system');
|
|
20
|
+
const evaluateSystemCommand = require('../src/commands/evaluate-system');
|
|
19
21
|
const infoCommand = require('../src/commands/info');
|
|
20
22
|
const detachCommand = require('../src/commands/detach');
|
|
21
23
|
|
|
@@ -254,6 +256,16 @@ program
|
|
|
254
256
|
return;
|
|
255
257
|
}
|
|
256
258
|
|
|
259
|
+
if (type === 'system') {
|
|
260
|
+
try {
|
|
261
|
+
await generateSystemCommand();
|
|
262
|
+
} catch (error) {
|
|
263
|
+
console.error(chalk.red('Error:'), error.message);
|
|
264
|
+
process.exit(1);
|
|
265
|
+
}
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
257
269
|
console.error(chalk.red(`❌ Unknown type: ${type}`));
|
|
258
270
|
console.log(chalk.yellow('\nUsage:'));
|
|
259
271
|
console.log(chalk.gray(' eva4j generate usecase <name> <module>'));
|
|
@@ -265,6 +277,7 @@ program
|
|
|
265
277
|
console.log(chalk.gray(' eva4j generate resource <module>'));
|
|
266
278
|
console.log(chalk.gray(' eva4j generate record'));
|
|
267
279
|
console.log(chalk.gray(' eva4j generate entities <module>'));
|
|
280
|
+
console.log(chalk.gray(' eva4j generate system'));
|
|
268
281
|
console.log(chalk.gray('\nExamples:'));
|
|
269
282
|
console.log(chalk.gray(' eva4j generate usecase create-provider provider'));
|
|
270
283
|
console.log(chalk.gray(' eva4j g http-exchange user-service-port user'));
|
|
@@ -274,10 +287,26 @@ program
|
|
|
274
287
|
console.log(chalk.gray(' eva4j g temporal-activity order register-order'));
|
|
275
288
|
console.log(chalk.gray(' eva4j g resource product'));
|
|
276
289
|
console.log(chalk.gray(' eva4j g record # Reads JSON from clipboard'));
|
|
277
|
-
console.log(chalk.gray(' eva4j g entities order # Generates from domain.yaml
|
|
290
|
+
console.log(chalk.gray(' eva4j g entities order # Generates from domain.yaml'));
|
|
291
|
+
console.log(chalk.gray(' eva4j g system # Bootstrap from system.yaml\n'));
|
|
278
292
|
process.exit(1);
|
|
279
293
|
});
|
|
280
294
|
|
|
295
|
+
// Evaluate command
|
|
296
|
+
program
|
|
297
|
+
.command('evaluate <type>')
|
|
298
|
+
.description('Validate and visualize project artifacts. type: system')
|
|
299
|
+
.option('--port <port>', 'Port for the web server (default: 3000)')
|
|
300
|
+
.option('--output <path>', 'Output path for the HTML report (default: ./system-report.html)')
|
|
301
|
+
.action(async (type, options) => {
|
|
302
|
+
try {
|
|
303
|
+
await evaluateSystemCommand(type, options);
|
|
304
|
+
} catch (error) {
|
|
305
|
+
console.error(chalk.red('Error:'), error.message);
|
|
306
|
+
process.exit(1);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
|
|
281
310
|
// Info command
|
|
282
311
|
program
|
|
283
312
|
.command('info')
|
|
@@ -322,6 +351,7 @@ program.on('--help', () => {
|
|
|
322
351
|
console.log(chalk.gray(' $ eva4j g record'));
|
|
323
352
|
console.log(chalk.gray(' $ eva4j detach user'));
|
|
324
353
|
console.log(chalk.gray(' $ eva4j info'));
|
|
354
|
+
console.log(chalk.gray(' $ eva4j evaluate system'));
|
|
325
355
|
console.log('');
|
|
326
356
|
console.log(chalk.blue('For more information, visit:'));
|
|
327
357
|
console.log(chalk.gray(' https://github.com/your-repo/eva4j'));
|