eva4j 1.0.14 → 1.0.16
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/skills/skill-creator/LICENSE.txt +202 -0
- package/.agents/skills/skill-creator/SKILL.md +485 -0
- package/.agents/skills/skill-creator/agents/analyzer.md +274 -0
- package/.agents/skills/skill-creator/agents/comparator.md +202 -0
- package/.agents/skills/skill-creator/agents/grader.md +223 -0
- package/.agents/skills/skill-creator/assets/eval_review.html +146 -0
- package/.agents/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/.agents/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/.agents/skills/skill-creator/references/schemas.md +430 -0
- package/.agents/skills/skill-creator/scripts/__init__.py +0 -0
- package/.agents/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/.agents/skills/skill-creator/scripts/generate_report.py +326 -0
- package/.agents/skills/skill-creator/scripts/improve_description.py +247 -0
- package/.agents/skills/skill-creator/scripts/package_skill.py +136 -0
- package/.agents/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/.agents/skills/skill-creator/scripts/run_eval.py +310 -0
- package/.agents/skills/skill-creator/scripts/run_loop.py +328 -0
- package/.agents/skills/skill-creator/scripts/utils.py +47 -0
- package/AGENTS.md +268 -6
- package/COMMAND_EVALUATION.md +15 -16
- package/DOMAIN_YAML_GUIDE.md +430 -14
- package/FUTURE_FEATURES.md +1627 -1168
- package/README.md +461 -13
- package/bin/eva4j.js +32 -14
- package/config/defaults.json +1 -0
- package/docs/commands/EVALUATE_SYSTEM.md +746 -261
- package/docs/commands/EXPORT_DIAGRAM.md +153 -0
- package/docs/commands/GENERATE_ENTITIES.md +599 -6
- package/docs/commands/INDEX.md +7 -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 +46 -3
- package/package.json +2 -1
- package/src/agents/design-reviewer.agent.md +163 -0
- package/src/commands/build.js +714 -0
- package/src/commands/create.js +1 -0
- package/src/commands/detach.js +149 -108
- package/src/commands/evaluate-system.js +234 -8
- package/src/commands/export-diagram.js +522 -0
- package/src/commands/generate-entities.js +685 -66
- package/src/commands/generate-http-exchange.js +2 -0
- package/src/commands/generate-kafka-event.js +43 -10
- package/src/generators/base-generator.js +18 -6
- package/src/generators/postman-generator.js +188 -0
- package/src/generators/shared-generator.js +12 -2
- package/src/skills/build-system-yaml/SKILL.md +323 -0
- package/src/skills/build-system-yaml/references/domain-yaml-spec.md +410 -0
- package/src/skills/build-system-yaml/references/module-spec.md +367 -0
- package/src/skills/build-system-yaml/references/system-yaml-spec.md +178 -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 +1020 -0
- package/src/utils/fake-data.js +376 -0
- package/src/utils/system-validator.js +319 -199
- package/src/utils/yaml-to-entity.js +272 -7
- package/templates/aggregate/AggregateMapper.java.ejs +3 -2
- package/templates/aggregate/AggregateRepository.java.ejs +3 -2
- package/templates/aggregate/AggregateRepositoryImpl.java.ejs +6 -5
- package/templates/aggregate/AggregateRoot.java.ejs +60 -2
- package/templates/aggregate/DomainEventHandler.java.ejs +4 -1
- 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/base/docker/Dockerfile.ejs +21 -0
- package/templates/base/gradle/build.gradle.ejs +3 -2
- package/templates/base/root/AGENTS.md.ejs +306 -45
- 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/CreateCommandHandler.java.ejs +3 -6
- package/templates/crud/CreateItemDto.java.ejs +4 -0
- package/templates/crud/CreateValueObjectDto.java.ejs +4 -0
- package/templates/crud/DeleteCommandHandler.java.ejs +12 -6
- package/templates/crud/EndpointsController.java.ejs +6 -6
- package/templates/crud/FindByQuery.java.ejs +1 -1
- package/templates/crud/FindByQueryHandler.java.ejs +3 -9
- package/templates/crud/GetQueryHandler.java.ejs +2 -5
- package/templates/crud/ListQuery.java.ejs +1 -1
- package/templates/crud/ListQueryHandler.java.ejs +8 -14
- package/templates/crud/ScaffoldCommandHandler.java.ejs +2 -4
- package/templates/crud/ScaffoldQuery.java.ejs +3 -2
- package/templates/crud/ScaffoldQueryHandler.java.ejs +5 -6
- package/templates/crud/SubEntityAddCommand.java.ejs +4 -0
- package/templates/crud/SubEntityAddCommandHandler.java.ejs +2 -6
- package/templates/crud/SubEntityRemoveCommandHandler.java.ejs +2 -7
- package/templates/crud/TransitionCommandHandler.java.ejs +2 -6
- package/templates/crud/UpdateCommand.java.ejs +4 -0
- package/templates/crud/UpdateCommandHandler.java.ejs +2 -5
- package/templates/evaluate/report.html.ejs +394 -2
- package/templates/kafka-event/DomainEventHandlerMethod.ejs +3 -1
- package/templates/kafka-event/Event.java.ejs +9 -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 +25 -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/annotations/LogAfter.java.ejs +2 -0
- package/templates/shared/annotations/LogBefore.java.ejs +2 -0
- package/templates/shared/annotations/LogExceptions.java.ejs +2 -0
- package/templates/shared/annotations/LogLevel.java.ejs +8 -0
- package/templates/shared/annotations/LogTimer.java.ejs +1 -0
- package/templates/shared/annotations/Loggable.java.ejs +17 -0
- package/templates/shared/configurations/eventPublicationConfig/EventPublicationSchemaConfig.java.ejs +109 -0
- package/templates/shared/configurations/loggerConfig/HandlerLogs.java.ejs +120 -32
- package/templates/shared/errorMessage/ErrorResponse.java.ejs +23 -0
- package/templates/shared/handlerException/HandlerExceptions.java.ejs +99 -79
- package/src/commands/generate-system.js +0 -243
- package/templates/base/root/skill-build-domain-yaml-references-generate-entities.md.ejs +0 -1103
- package/templates/base/root/skill-build-domain-yaml.ejs +0 -292
- package/templates/base/root/skill-build-system-yaml.ejs +0 -252
- package/templates/shared/errorMessage/ErrorMessage.java.ejs +0 -5
- package/templates/shared/errorMessage/FullErrorMessage.java.ejs +0 -9
- package/templates/shared/errorMessage/ShortErrorMessage.java.ejs +0 -6
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: build-system-yaml
|
|
3
|
+
description: 'Construir o actualizar el system.yaml de un proyecto eva4j. Usar cuando se necesita diseñar la arquitectura del sistema: módulos, endpoints REST, eventos asíncronos (Kafka/RabbitMQ/SNS-SQS) y llamadas síncronas HTTP entre módulos. Invoca este skill al describir un nuevo sistema, al agregar módulos, al rediseñar integraciones entre servicios, o cuando el usuario pida diagramas C4 de contexto o contenedores del sistema. USE FOR: system architecture design, adding modules, designing async event flows, sync HTTP calls between modules, generating C4 diagrams, building system.yaml + domain YAML + module specifications.'
|
|
4
|
+
argument-hint: 'Describe el sistema o los módulos que necesitas (ej: tienda online con pedidos, pagos y notificaciones)'
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Build System YAML
|
|
8
|
+
|
|
9
|
+
Eres dos roles simultáneos:
|
|
10
|
+
|
|
11
|
+
1. **Arquitecto de software** experto en DDD y arquitectura hexagonal. Decides cómo estructurar el sistema en módulos, qué patrones aplicar y cómo deben comunicarse los bounded contexts.
|
|
12
|
+
|
|
13
|
+
2. **Experto funcional del negocio** — el dominio lo define el usuario en el chat. Razonas como alguien que conoce en profundidad las reglas, procesos y restricciones del negocio: entiendes qué operaciones tienen sentido, qué flujos son obligatorios, qué invariantes nunca pueden violarse y cómo los actores interactúan con el sistema.
|
|
14
|
+
|
|
15
|
+
> **Principio de claridad:** cuando detectes ambigüedades que podrían afectar decisiones de diseño, **pregunta al usuario** antes de continuar. Nunca más de 3–5 preguntas a la vez. Solo preguntas genuinamente funcionales.
|
|
16
|
+
|
|
17
|
+
## Descubrimiento del proyecto
|
|
18
|
+
|
|
19
|
+
Antes de generar nada, lee estos archivos del proyecto para obtener contexto:
|
|
20
|
+
- `system/system.yaml` — si existe, el proyecto ya tiene arquitectura definida; léelo primero
|
|
21
|
+
- El `package.json` o configuración del proyecto para nombre, groupId, versiones
|
|
22
|
+
- [AGENTS.md](/AGENTS.md) — patrones y convenciones de eva4j
|
|
23
|
+
|
|
24
|
+
## Idioma de los archivos generados
|
|
25
|
+
|
|
26
|
+
> **REGLA ABSOLUTA — SIEMPRE EN INGLÉS:**
|
|
27
|
+
> Todo contenido en archivos `.yaml` y `.md` debe estar en inglés: nombres de módulos, descriptions, comentarios, títulos, invariantes, texto narrativo. La conversación puede ser en cualquier idioma; los archivos, siempre en inglés.
|
|
28
|
+
|
|
29
|
+
## Cuándo usar este skill
|
|
30
|
+
|
|
31
|
+
- Diseñar la arquitectura inicial de un sistema nuevo
|
|
32
|
+
- Agregar módulos a un proyecto existente
|
|
33
|
+
- Definir integraciones asíncronas (Kafka/RabbitMQ) entre módulos
|
|
34
|
+
- Definir llamadas síncronas HTTP entre módulos
|
|
35
|
+
- Revisar o refactorizar la estructura de módulos
|
|
36
|
+
- Generar diagramas C4 del sistema
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Workflow — secuencia completa de pasos
|
|
41
|
+
|
|
42
|
+
| Paso | Archivo generado | Referencia |
|
|
43
|
+
|------|------------------|------------|
|
|
44
|
+
| 1 | _(recopilación de info)_ | Este archivo |
|
|
45
|
+
| 2–5 | `system/system.yaml` | Este archivo + `references/system-yaml-spec.md` |
|
|
46
|
+
| 6 | `system/system.md` | `references/module-spec.md` (sección system.md) |
|
|
47
|
+
| 6.5 | `system/c4-context.mmd` + `system/c4-container.mmd` | Este archivo (sección C4) |
|
|
48
|
+
| 7 | `system/{module}.yaml` (uno por módulo) | `references/domain-yaml-spec.md` |
|
|
49
|
+
| 8 | `system/{module}.md` (uno por módulo) | `references/module-spec.md` |
|
|
50
|
+
|
|
51
|
+
Ejecuta **todos** los pasos en orden antes de devolver el control al usuario.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Paso 1 — Recopilar información
|
|
56
|
+
|
|
57
|
+
Si el usuario no proveyó todos los datos, **pregunta** antes de generar:
|
|
58
|
+
|
|
59
|
+
0. **Contexto del negocio** — ¿Cuál es el dominio? Actores, procesos clave, reglas importantes.
|
|
60
|
+
1. **¿Usa mensajería asíncrona?** `kafka` | `rabbitmq` | `sns-sqs`
|
|
61
|
+
2. **Lista de módulos** con su responsabilidad (plural, kebab-case)
|
|
62
|
+
3. **Endpoints REST** por módulo (método + path + caso de uso)
|
|
63
|
+
4. **Flujos async**: evento → productor → consumidores + `useCase` de cada consumidor
|
|
64
|
+
5. **Llamadas sync**: caller → destino → endpoints usados
|
|
65
|
+
|
|
66
|
+
> Si `system/system.yaml` ya existe, léelo y pregunta solo por cambios.
|
|
67
|
+
|
|
68
|
+
Aplica el rol funcional: sugiere módulos necesarios no mencionados, propone flujos async coherentes, anticipa invariantes. Confirma antes de agregar elementos no solicitados.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Paso 2 — Estructura del system.yaml
|
|
73
|
+
|
|
74
|
+
Lee `references/system-yaml-spec.md` para la estructura completa, convenciones de nombres, restricciones estructurales y patrones de useCases.
|
|
75
|
+
|
|
76
|
+
**Estructura clave:**
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
system:
|
|
80
|
+
name: project-name
|
|
81
|
+
groupId: com.example
|
|
82
|
+
javaVersion: 21
|
|
83
|
+
springBootVersion: 3.5.5
|
|
84
|
+
database: postgresql
|
|
85
|
+
|
|
86
|
+
messaging: # Omitir si no hay mensajería
|
|
87
|
+
enabled: true
|
|
88
|
+
broker: kafka
|
|
89
|
+
kafka:
|
|
90
|
+
bootstrapServers: localhost:9092
|
|
91
|
+
defaultGroupId: project-name
|
|
92
|
+
topicPrefix: project-name
|
|
93
|
+
|
|
94
|
+
modules:
|
|
95
|
+
- name: orders
|
|
96
|
+
description: "Order lifecycle management"
|
|
97
|
+
exposes:
|
|
98
|
+
- method: POST
|
|
99
|
+
path: /orders
|
|
100
|
+
useCase: CreateOrder
|
|
101
|
+
description: "Create a new order"
|
|
102
|
+
|
|
103
|
+
integrations:
|
|
104
|
+
async:
|
|
105
|
+
- event: OrderPlacedEvent
|
|
106
|
+
producer: orders
|
|
107
|
+
topic: ORDER_PLACED
|
|
108
|
+
consumers:
|
|
109
|
+
- module: payments
|
|
110
|
+
useCase: HandleOrderPlaced
|
|
111
|
+
sync:
|
|
112
|
+
- caller: orders
|
|
113
|
+
calls: customers
|
|
114
|
+
port: OrderCustomerService
|
|
115
|
+
using:
|
|
116
|
+
- GET /customers/{id}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Paso 3 — Reglas obligatorias (resumen)
|
|
122
|
+
|
|
123
|
+
| Elemento | Convención | Ejemplo |
|
|
124
|
+
|---|---|---|
|
|
125
|
+
| Módulos | plural, kebab-case | `orders`, `product-catalog` |
|
|
126
|
+
| Eventos | PascalCase + pasado + `Event` | `OrderPlacedEvent` |
|
|
127
|
+
| Topics | SCREAMING_SNAKE_CASE sin prefix | `ORDER_PLACED` |
|
|
128
|
+
| Ports | PascalCase + `Service` único/módulo | `OrderCustomerService` |
|
|
129
|
+
| useCases | PascalCase, verbo+sustantivo | `CreateOrder`, `ConfirmOrder` |
|
|
130
|
+
|
|
131
|
+
**Restricciones críticas:**
|
|
132
|
+
- Sin dependencias circulares síncronas
|
|
133
|
+
- Sin campos de dominio en system.yaml
|
|
134
|
+
- Sin port names genéricos compartidos entre módulos
|
|
135
|
+
- `consumers[].useCase` siempre presente y en PascalCase
|
|
136
|
+
- `calls.using:` solo referencia endpoints de `exposes:` del destino
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Paso 4 — Checklist de validación
|
|
141
|
+
|
|
142
|
+
Antes de proponer el `system.yaml`, verifica:
|
|
143
|
+
|
|
144
|
+
- [ ] Módulos en plural kebab-case
|
|
145
|
+
- [ ] Eventos en tiempo pasado con sufijo `Event`
|
|
146
|
+
- [ ] Sin dependencias circulares síncronas
|
|
147
|
+
- [ ] Todos los `consumers[].module` existen en `modules:`
|
|
148
|
+
- [ ] Todos los `consumers[].useCase` presentes y en PascalCase
|
|
149
|
+
- [ ] Todos los `calls.using:` existen en `exposes:` del destino
|
|
150
|
+
- [ ] Módulos pasivos no son `caller`
|
|
151
|
+
- [ ] Todo en inglés
|
|
152
|
+
- [ ] Archivo en `system/system.yaml`
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Paso 5 — Presentar y continuar
|
|
157
|
+
|
|
158
|
+
1. Crea `system/` si no existe
|
|
159
|
+
2. Guarda `system/system.yaml`
|
|
160
|
+
3. Muestra el YAML completo
|
|
161
|
+
4. Explica decisiones no obvias
|
|
162
|
+
5. Menciona advertencias (acoplamiento, responsabilidades difusas)
|
|
163
|
+
6. Indica: `eva generate system`
|
|
164
|
+
7. Procede inmediatamente a los pasos 6 → 6.5 → 7 → 8
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Paso 6 — Crear system.md
|
|
169
|
+
|
|
170
|
+
Lee `references/module-spec.md` (sección "Estructura del system.md") para la estructura obligatoria.
|
|
171
|
+
|
|
172
|
+
El `system/system.md` es la **especificación técnica narrativa** del sistema. Una sección `##` por módulo con: rol detallado, casos de uso, endpoints, eventos emitidos, puertos síncronos.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Paso 6.5 — Diagramas C4 (Context + Container)
|
|
177
|
+
|
|
178
|
+
Inmediatamente después del `system.md`, genera **dos archivos Mermaid** con diagramas C4:
|
|
179
|
+
|
|
180
|
+
### `system/c4-context.mmd` — Diagrama de Contexto
|
|
181
|
+
|
|
182
|
+
Muestra el sistema como una **caja única** rodeada de actores y sistemas externos. Responde: "¿Qué construimos y quién/qué interactúa con ello?"
|
|
183
|
+
|
|
184
|
+
```mermaid
|
|
185
|
+
C4Context
|
|
186
|
+
title System Context diagram for {System Name}
|
|
187
|
+
|
|
188
|
+
Person(user, "User", "Primary user who interacts with the system")
|
|
189
|
+
Person(admin, "Administrator", "Manages system configuration")
|
|
190
|
+
|
|
191
|
+
System(system, "{System Name}", "Core platform that manages {domain description}")
|
|
192
|
+
|
|
193
|
+
System_Ext(emailSys, "Email Service", "Sends transactional emails")
|
|
194
|
+
System_Ext(paymentGw, "Payment Gateway", "Processes credit card payments")
|
|
195
|
+
|
|
196
|
+
Rel(user, system, "Places orders, checks status", "HTTPS")
|
|
197
|
+
Rel(admin, system, "Manages catalog and configuration", "HTTPS")
|
|
198
|
+
Rel(system, emailSys, "Sends notifications", "SMTP")
|
|
199
|
+
Rel(system, paymentGw, "Processes payments", "HTTPS")
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Reglas del Context diagram:**
|
|
203
|
+
- El sistema completo es **un solo nodo** `System()` — no descomponer en módulos aquí
|
|
204
|
+
- `Person()` para cada actor humano que interactúa con la API
|
|
205
|
+
- `System_Ext()` para cada sistema externo (pasarelas de pago, email, servicios terceros)
|
|
206
|
+
- Derivar sistemas externos de `integrations.sync[]` donde `calls` apunta a un servicio externo (no un módulo del propio sistema)
|
|
207
|
+
- `Rel()` describe la relación con verbo + protocolo
|
|
208
|
+
- Solo incluir actores y sistemas que realmente aparecen en `system.yaml`
|
|
209
|
+
|
|
210
|
+
### `system/c4-container.mmd` — Diagrama de Contenedores
|
|
211
|
+
|
|
212
|
+
Descompone el sistema en **contenedores**: cada módulo es un Container, el broker es un ContainerQueue, las bases de datos son ContainerDb.
|
|
213
|
+
|
|
214
|
+
```mermaid
|
|
215
|
+
C4Container
|
|
216
|
+
title Container diagram for {System Name}
|
|
217
|
+
|
|
218
|
+
Person(user, "User", "Primary user of the system")
|
|
219
|
+
|
|
220
|
+
System_Boundary(boundary, "{System Name}") {
|
|
221
|
+
Container(orders, "orders", "Spring Boot Module", "Order lifecycle management")
|
|
222
|
+
Container(payments, "payments", "Spring Boot Module", "Payment processing")
|
|
223
|
+
Container(notifications, "notifications", "Spring Boot Module", "Email and SMS notifications")
|
|
224
|
+
|
|
225
|
+
ContainerDb(db, "Database", "PostgreSQL", "Stores all module data")
|
|
226
|
+
ContainerQueue(broker, "Message Broker", "Apache Kafka", "Async event streaming between modules")
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
System_Ext(paymentGw, "Payment Gateway", "External payment processing service")
|
|
230
|
+
System_Ext(emailSvc, "Email Service", "Transactional email delivery")
|
|
231
|
+
|
|
232
|
+
Rel(user, orders, "Places orders", "REST/HTTPS")
|
|
233
|
+
Rel(user, payments, "Views payment status", "REST/HTTPS")
|
|
234
|
+
|
|
235
|
+
Rel(orders, broker, "Publishes", "OrderPlacedEvent")
|
|
236
|
+
Rel(broker, payments, "Delivers", "OrderPlacedEvent")
|
|
237
|
+
Rel(broker, notifications, "Delivers", "OrderPlacedEvent")
|
|
238
|
+
|
|
239
|
+
Rel(payments, broker, "Publishes", "PaymentApprovedEvent")
|
|
240
|
+
Rel(broker, orders, "Delivers", "PaymentApprovedEvent")
|
|
241
|
+
Rel(broker, notifications, "Delivers", "PaymentApprovedEvent")
|
|
242
|
+
|
|
243
|
+
Rel(orders, db, "Reads/Writes", "JDBC")
|
|
244
|
+
Rel(payments, db, "Reads/Writes", "JDBC")
|
|
245
|
+
Rel(notifications, db, "Reads/Writes", "JDBC")
|
|
246
|
+
|
|
247
|
+
Rel(payments, paymentGw, "Processes payment", "HTTPS")
|
|
248
|
+
Rel(notifications, emailSvc, "Sends email", "SMTP")
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
**Reglas del Container diagram:**
|
|
252
|
+
|
|
253
|
+
- `System_Boundary()` agrupa todos los contenedores internos del sistema
|
|
254
|
+
- Un `Container()` por cada módulo en `modules:` — usar el nombre del módulo como id y label
|
|
255
|
+
- La tecnología es `"Spring Boot Module"` y la descripción viene de `modules[].description`
|
|
256
|
+
- `ContainerDb()` para la base de datos — derivar el tipo de `system.database`
|
|
257
|
+
- `ContainerQueue()` para el broker — solo si `messaging.enabled: true`; usar el tipo de `messaging.broker`
|
|
258
|
+
- `System_Ext()` fuera del boundary para servicios externos
|
|
259
|
+
- **Flechas async siempre pasan por el broker**: `producer → broker` y `broker → consumer`, nunca directo
|
|
260
|
+
- **Flechas sync** directas entre containers: de caller a callee con label del port name
|
|
261
|
+
- Los `Rel()` de eventos incluyen el nombre del evento en el campo `technology`/label
|
|
262
|
+
- Derivar actores `Person()` de quienes consumen los `exposes[]`
|
|
263
|
+
|
|
264
|
+
### Correspondencia system.yaml → C4
|
|
265
|
+
|
|
266
|
+
| Fuente en system.yaml | C4 Context | C4 Container |
|
|
267
|
+
|---|---|---|
|
|
268
|
+
| `system.name` | `System()` título | `System_Boundary()` |
|
|
269
|
+
| `modules[]` | _(no aparece)_ | `Container()` uno por módulo |
|
|
270
|
+
| `modules[].exposes[]` | `Rel(Person→System)` | `Rel(Person→Container)` |
|
|
271
|
+
| `integrations.async[]` | _(no aparece)_ | `Rel()` via `ContainerQueue` |
|
|
272
|
+
| `integrations.sync[]` (interno) | _(no aparece)_ | `Rel()` directo entre Containers |
|
|
273
|
+
| `integrations.sync[]` (externo) | `System_Ext()` + `Rel()` | `System_Ext()` + `Rel()` |
|
|
274
|
+
| `messaging.broker` | _(no aparece)_ | `ContainerQueue()` |
|
|
275
|
+
| `system.database` | _(no aparece)_ | `ContainerDb()` |
|
|
276
|
+
|
|
277
|
+
### Checklist de los diagramas C4
|
|
278
|
+
|
|
279
|
+
Antes de guardar, verifica:
|
|
280
|
+
|
|
281
|
+
**Context (`c4-context.mmd`):**
|
|
282
|
+
- [ ] Sistema representado como un solo nodo `System()`
|
|
283
|
+
- [ ] Un `Person()` por cada tipo de actor
|
|
284
|
+
- [ ] Un `System_Ext()` por cada servicio externo real
|
|
285
|
+
- [ ] Relaciones con verbo descriptivo + protocolo
|
|
286
|
+
- [ ] No contiene módulos internos — eso es Container
|
|
287
|
+
|
|
288
|
+
**Container (`c4-container.mmd`):**
|
|
289
|
+
- [ ] `System_Boundary` agrupa todos los containers
|
|
290
|
+
- [ ] Un `Container()` por cada módulo en `modules:`
|
|
291
|
+
- [ ] `ContainerDb` con tipo de BD del proyecto
|
|
292
|
+
- [ ] `ContainerQueue` si hay mensajería (tipo de broker correcto)
|
|
293
|
+
- [ ] Flujos async pasan por el queue: `module → broker → consumer`
|
|
294
|
+
- [ ] Flujos sync son directos: `caller → callee`
|
|
295
|
+
- [ ] Servicios externos fuera del boundary como `System_Ext()`
|
|
296
|
+
- [ ] Todo en inglés
|
|
297
|
+
- [ ] Cada archivo contiene **solo** el bloque Mermaid
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## Paso 7 — Crear domain.yaml por módulo
|
|
302
|
+
|
|
303
|
+
Lee `references/domain-yaml-spec.md` para la especificación completa de estructura, reglas, restricciones y checklist del `system/{module}.yaml`.
|
|
304
|
+
|
|
305
|
+
Para cada módulo en `modules:`, genera `system/{nombre-del-modulo}.yaml` con: aggregates, entities, valueObjects, enums (con transitions si aplica), events, endpoints, listeners y ports — todo inferido del `system.yaml`.
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## Paso 8 — Crear especificación técnica por módulo
|
|
310
|
+
|
|
311
|
+
Lee `references/module-spec.md` para la estructura obligatoria del `system/{module}.md`.
|
|
312
|
+
|
|
313
|
+
Para cada módulo, genera `system/{nombre-del-modulo}.md` con: rol del módulo, invariantes, máquina de estados, diagrama de interacciones, diagrama de secuencia, casos de uso detallados, endpoints, eventos y puertos.
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Ciclo de refinamiento
|
|
318
|
+
|
|
319
|
+
Después de entregar v1, si el usuario pide ajustes:
|
|
320
|
+
- Aplica el **cambio mínimo** necesario
|
|
321
|
+
- Revalida el checklist del Paso 4
|
|
322
|
+
- Actualiza `system.md`, `c4-context.mmd`, `c4-container.mmd`, `{module}.yaml` y `{module}.md` afectados
|
|
323
|
+
- Entrega solo el diff explicado
|