@ronaldjdevfs/forge 1.2.0 → 1.3.1
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/README.md +36 -21
- package/package.json +7 -2
- package/skills/forge/SKILL.md +56 -122
- package/skills/forge/command/forge.md +59 -14
- package/skills/forge/reference/adr.md +242 -0
- package/skills/forge/reference/anti-corruption-layer.md +340 -0
- package/skills/forge/reference/api-design.md +7 -0
- package/skills/forge/reference/api-versioning.md +354 -0
- package/skills/forge/reference/architectural-depth-checklist.md +311 -0
- package/skills/forge/reference/architecture-template.md +41 -0
- package/skills/forge/reference/assay.md +6 -0
- package/skills/forge/reference/bounded-contexts.md +311 -0
- package/skills/forge/reference/chain.md +6 -0
- package/skills/forge/reference/cohesion-checklist.md +256 -0
- package/skills/forge/reference/cqrs.md +286 -0
- package/skills/forge/reference/data-patterns.md +6 -0
- package/skills/forge/reference/di-strategies.md +6 -0
- package/skills/forge/reference/errors.md +5 -0
- package/skills/forge/reference/events.md +8 -0
- package/skills/forge/reference/evolutionary-architecture.md +300 -0
- package/skills/forge/reference/forge.md +7 -0
- package/skills/forge/reference/hooks.md +6 -0
- package/skills/forge/reference/idempotency.md +283 -0
- package/skills/forge/reference/inscribe.md +5 -0
- package/skills/forge/reference/inspect.md +6 -0
- package/skills/forge/reference/modular-monolith.md +252 -0
- package/skills/forge/reference/observability.md +5 -0
- package/skills/forge/reference/quench.md +5 -0
- package/skills/forge/reference/relocate.md +6 -0
- package/skills/forge/reference/sagas.md +359 -0
- package/skills/forge/reference/security-patterns.md +6 -0
- package/skills/forge/reference/smelt.md +6 -0
- package/skills/forge/reference/temper.md +6 -0
- package/skills/forge/reference/testing-patterns.md +6 -0
- package/skills/forge/reference/transactional-outbox.md +311 -0
- package/skills/forge/scripts/architecture.mjs +10 -5
- package/skills/forge/scripts/assay.mjs +2 -2
- package/skills/forge/scripts/chain.mjs +31 -5
- package/skills/forge/scripts/context.mjs +24 -4
- package/skills/forge/scripts/detect.mjs +39 -30
- package/skills/forge/scripts/forge-boot.mjs +108 -0
- package/skills/forge/scripts/forge-config.mjs +182 -3
- package/skills/forge/scripts/forge-state.mjs +1 -1
- package/skills/forge/scripts/forgeSentinel-lib.mjs +86 -0
- package/skills/forge/scripts/forgeSentinel.mjs +184 -0
- package/skills/forge/scripts/forgeSmith-admin.mjs +104 -0
- package/skills/forge/scripts/forgeSmith.mjs +164 -0
- package/skills/forge/scripts/graph.mjs +65 -9
- package/skills/forge/scripts/hook.mjs +2 -2
- package/skills/forge/scripts/inspect.mjs +56 -48
- package/skills/forge/scripts/parse-imports.mjs +0 -2
- package/skills/forge/scripts/pin.mjs +10 -3
- package/skills/forge/scripts/posttool.mjs +2 -2
- package/skills/forge/scripts/recommendation-engine.mjs +125 -0
- package/skills/forge/scripts/rollback.mjs +5 -3
- package/skills/forge/templates/agents/SKILL.md.template +283 -0
- package/skills/forge/templates/agents/agents/hooks.json +18 -0
- package/skills/forge/templates/agents/claude/CLAUDE.md +17 -16
- package/skills/forge/templates/agents/claude/settings.local.json +18 -0
- package/skills/forge/templates/agents/codex/hooks.json +18 -0
- package/skills/forge/templates/agents/cursor/.cursorrules +22 -5
- package/skills/forge/templates/agents/cursor/hooks.json +11 -0
- package/skills/forge/templates/agents/gemini/SKILL.md +13 -0
- package/skills/forge/templates/feature/acl-gateway.ts.md +52 -0
- package/skills/forge/templates/feature/acl-repository.ts.md +36 -0
- package/skills/forge/templates/feature/acl-translator.ts.md +24 -0
- package/skills/forge/templates/feature/cqrs-query.ts.md +40 -0
- package/skills/forge/templates/feature/outbox-repository.ts.md +36 -0
- package/skills/forge/templates/feature/saga-orchestrator.ts.md +72 -0
- package/skills/forge/templates/platform/outbox-relayer.ts.md +80 -0
- package/skills/forge/tests/core.test.mjs +284 -0
- package/src/agents.mjs +35 -2
- package/src/cli.js +112 -39
- package/src/wizard.mjs +142 -90
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Architecture State
|
|
2
|
+
|
|
3
|
+
- Project Name: <name>
|
|
4
|
+
- Framework: <detectado>
|
|
5
|
+
- Runtime: <detectado>
|
|
6
|
+
- Database: <detectado>
|
|
7
|
+
- ORM: <detectado>
|
|
8
|
+
- DI Strategy: <detectado>
|
|
9
|
+
- Profile: <detectado>
|
|
10
|
+
- Architecture: hexagonal-feature (Platform + Features + Shared + Infra)
|
|
11
|
+
- Last Audit: <fecha> (score: <puntaje>)
|
|
12
|
+
|
|
13
|
+
## Platform
|
|
14
|
+
- platform/config/
|
|
15
|
+
- platform/server/
|
|
16
|
+
...
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
- features/users/
|
|
20
|
+
...
|
|
21
|
+
|
|
22
|
+
## Shared
|
|
23
|
+
- shared/errors/
|
|
24
|
+
...
|
|
25
|
+
|
|
26
|
+
## Infrastructure
|
|
27
|
+
- infra/prisma/
|
|
28
|
+
...
|
|
29
|
+
|
|
30
|
+
## Ownership
|
|
31
|
+
- Health: healthy | degraded | critical
|
|
32
|
+
- Score: 0-100
|
|
33
|
+
- Orphans: 0
|
|
34
|
+
- Duplicates: 0
|
|
35
|
+
- Misplaced: 0
|
|
36
|
+
|
|
37
|
+
## Architecture Graph
|
|
38
|
+
...
|
|
39
|
+
|
|
40
|
+
## Dependency Health
|
|
41
|
+
...
|
|
@@ -80,3 +80,9 @@ Se recomienda:
|
|
|
80
80
|
3. Priorizar acciones basado en las recomendaciones
|
|
81
81
|
4. Refactorizar con `reforge`, `temper`, o `smelt`
|
|
82
82
|
5. Repetir el ciclo
|
|
83
|
+
|
|
84
|
+
## Ver también
|
|
85
|
+
|
|
86
|
+
- `reference/inspect.md` — el reporte que alimenta el ensayo
|
|
87
|
+
- `reference/adr.md` — ADRs como insumo para las opiniones de cada persona
|
|
88
|
+
- `reference/principles.md` — principios contra los que assay contrasta las decisiones
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
# Bounded Contexts — DDD Estratégico
|
|
2
|
+
|
|
3
|
+
Las features de Forge se corresponden con bounded contexts. Sin esta correspondencia, `src/features/<name>/` son solo directoríos con código agrupado por nombre, no unidades con integridad de dominio.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Fundamentos de DDD Estratégico
|
|
8
|
+
|
|
9
|
+
### Dominio y Subdominios
|
|
10
|
+
|
|
11
|
+
El **dominio** es el área de actividad que el sistema modela. Se divide en tres tipos de **subdominio**:
|
|
12
|
+
|
|
13
|
+
| Tipo | Características | Ejemplo en e-commerce |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| **Core** | Ventaja competitiva, complejo, hecho en casa | Pricing engine, recomendaciones |
|
|
16
|
+
| **Supporting** | Necesario pero no diferenciador, puede externalizarse | Inventario, catálogo |
|
|
17
|
+
| **Generic** | Commodity, comprar o usar OSS | Auth, notificaciones, pagos |
|
|
18
|
+
|
|
19
|
+
Un **bounded context** es un límite explícito dentro del cual un modelo de dominio específico es consistente. Fuera del contexto, el mismo término puede tener significado distinto.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
// En el contexto de "Catalog", Product tiene precio, descripción, imágenes
|
|
23
|
+
// En el contexto de "Inventory", Product tiene SKU, stock, warehouse location
|
|
24
|
+
// En el contexto de "Orders", Product tiene orderLine, quantity, status
|
|
25
|
+
// Son tres modelos distintos para el mismo concepto del mundo real
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Ubiquitous Language
|
|
29
|
+
|
|
30
|
+
Cada bounded context tiene su propio lenguaje ubicuo, compartido por el equipo de desarrollo y los expertos de negocio.
|
|
31
|
+
|
|
32
|
+
**Reglas del lenguaje ubicuo:**
|
|
33
|
+
- Los nombres de clases, métodos y módulos reflejan el lenguaje del negocio, no el lenguaje técnico
|
|
34
|
+
- No hay traducción entre "lo que el negocio dice" y "lo que el código llama"
|
|
35
|
+
- Si el negocio dice "Order" → la entidad se llama `OrderEntity`, no `OrderRecord` ni `OrderDoc`
|
|
36
|
+
- Si el negocio dice "cancelar pedido" → el caso de uso se llama `CancelOrderUseCase`, no `OrderDeleterService`
|
|
37
|
+
- Las discrepancias de lenguaje entre contexts son señales de límites válidos
|
|
38
|
+
|
|
39
|
+
**Conflicto de lenguaje como herramienta:** cuando dos personas del equipo usan la misma palabra con significado distinto (ej. "cliente" significa "usuario registrado" para marketing y "cuenta corporativa" para billing), hay dos bounded contexts esperando ser descubiertos.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Context Mapping
|
|
44
|
+
|
|
45
|
+
Cada bounded context se relaciona con otros mediante relaciones explícitas. Estos son los 8 patrones del Context Mapping:
|
|
46
|
+
|
|
47
|
+
### Partnership
|
|
48
|
+
|
|
49
|
+
Dos contexts cooperan para entregar un flujo. Si uno falla, el otro también.
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
[Orders] ←→ [Inventory]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
- Relación bidireccional
|
|
56
|
+
- Coordinación frecuente entre equipos
|
|
57
|
+
- Acoplamiento temporal tolerado
|
|
58
|
+
- Útil para flujos transaccionales críticos (checkout)
|
|
59
|
+
|
|
60
|
+
### Shared Kernel
|
|
61
|
+
|
|
62
|
+
Comparten un subconjunto pequeño y estable del modelo.
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
[Orders] ← kernel: Customer, Money → [Billing]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
- El kernel compartido está en `src/shared/contracts/`
|
|
69
|
+
- Solo datos, no lógica de negocio
|
|
70
|
+
- El kernel se mantiene por acuerdo entre equipos
|
|
71
|
+
- Cambios requieren coordinación y tests
|
|
72
|
+
- Si crece demasiado, es señal de que los contexts deberían fusionarse
|
|
73
|
+
|
|
74
|
+
### Customer-Supplier
|
|
75
|
+
|
|
76
|
+
Un contexto upstream provee datos que el downstream consume. El upstream gana.
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
[CRM] → [Marketing] (CRM dicta el contrato)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- Upstream (supplier) define el contrato
|
|
83
|
+
- Downstream (customer) se adapta
|
|
84
|
+
- El downstream debe implementar una ACL si el upstream no cubre sus necesidades
|
|
85
|
+
- Relación unidireccional
|
|
86
|
+
|
|
87
|
+
### Conformist
|
|
88
|
+
|
|
89
|
+
El downstream acepta el modelo del upstream sin cuestionarlo.
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
[SAP] → [Reporting] (Reporting se adapta al modelo de SAP)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- Sin traducción: el downstream usa el modelo del upstream directamente
|
|
96
|
+
- Útil cuando el upstream es un sistema externo commodity
|
|
97
|
+
- Riesgo de corrupción del modelo de dominio downstream si el upstream cambia
|
|
98
|
+
|
|
99
|
+
### Anti-Corruption Layer (ACL)
|
|
100
|
+
|
|
101
|
+
El downstream protege su modelo con una capa de traducción.
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
[CRM Legacy] → [ACL] → [Orders]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- La ACL traduce del modelo legacy al modelo de dominio de Orders
|
|
108
|
+
- Ver `reference/anti-corruption-layer.md`
|
|
109
|
+
- Patrón obligatorio cuando se integra un sistema legacy o externo en un core domain
|
|
110
|
+
|
|
111
|
+
### Open-Host Service
|
|
112
|
+
|
|
113
|
+
El upstream expone un protocolo/shareable al que los downstreams se suscriben.
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
[Catalog] ── OHS (Published Language) ──→ [Search]
|
|
117
|
+
──→ [Recommendations]
|
|
118
|
+
──→ [Pricing]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
- El upstream publica un Published Language (API, eventos, contratos compartidos)
|
|
122
|
+
- Múltiples downstreams consumen sin coordinar entre sí
|
|
123
|
+
- Es la relación ideal para la capa `adapter/out/` de una feature exponiendo eventos
|
|
124
|
+
|
|
125
|
+
### Published Language
|
|
126
|
+
|
|
127
|
+
El lenguaje compartido que el OHS usa. Puede ser:
|
|
128
|
+
- Contratos TypeScript en `src/shared/contracts/`
|
|
129
|
+
- Eventos de dominio con schema versionado
|
|
130
|
+
- OpenAPI spec como contrato HTTP
|
|
131
|
+
- Protobuf / Avro schemas
|
|
132
|
+
|
|
133
|
+
Los contratos publicados deben ser:
|
|
134
|
+
- Versionados (`src/shared/contracts/catalog/v1/`, `v2/`)
|
|
135
|
+
- Inmutables una vez publicados
|
|
136
|
+
- Documentados con ejemplos
|
|
137
|
+
- Validados con tests de compatibilidad
|
|
138
|
+
|
|
139
|
+
### Separate Ways
|
|
140
|
+
|
|
141
|
+
Dos contexts no tienen relación. Cada uno modela su solución independientemente.
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
[Notifications] [Analytics]
|
|
145
|
+
(no se hablan)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
- Válido cuando no hay solapamiento funcional
|
|
149
|
+
- Forzado por R8 (no imports directos entre features): por defecto, toda feature que no comparte contratos está en Separate Ways con las demás
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Identificación de Bounded Contexts
|
|
154
|
+
|
|
155
|
+
### Heurísticas prácticas
|
|
156
|
+
|
|
157
|
+
| Señal | Pregunta guía |
|
|
158
|
+
|---|---|
|
|
159
|
+
| **Equipo** | ¿Otro equipo podría ser dueño de esto? |
|
|
160
|
+
| **Lenguaje** | ¿Usan las mismas palabras con el mismo significado? |
|
|
161
|
+
| **Modelo** | ¿La misma entidad tiene atributos o comportamientos distintos? |
|
|
162
|
+
| **Frecuencia de cambio** | ¿Una parte del sistema cambia a ritmo distinto que otra? |
|
|
163
|
+
| **Base de datos** | ¿Podría tener su propio schema o base de datos? |
|
|
164
|
+
| **Deploy** | ¿Podría deployarse independientemente? |
|
|
165
|
+
| **Fallo** | ¿Un fallo aquí no debería afectar a otras partes? |
|
|
166
|
+
|
|
167
|
+
### Regla práctica de Forge
|
|
168
|
+
|
|
169
|
+
Si puedes nombrar un directorio `src/features/<name>/` y describir qué hace sin usar términos de otra feature, tienes un bounded context candidato.
|
|
170
|
+
|
|
171
|
+
Si necesitas decir "esto es parte de X pero usa el modelo de Y" o "comparte la BD con Z", el context mapping está mal definido.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Mapeo Visual
|
|
176
|
+
|
|
177
|
+
Un diagrama de contextos muestra los bounded contexts como cajas y las relaciones como flechas etiquetadas.
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
┌──────────────────────────────────────────────────────┐
|
|
181
|
+
│ E-Commerce System │
|
|
182
|
+
│ │
|
|
183
|
+
│ ┌──────────┐ SK ┌──────────┐ OHS ┌──────────┐ │
|
|
184
|
+
│ │ Orders │◄────►│ Catalog ├────────►│ Search │ │
|
|
185
|
+
│ └────┬─────┘ └──────────┘ └──────────┘ │
|
|
186
|
+
│ │ │ │
|
|
187
|
+
│ │PS │PL │
|
|
188
|
+
│ ▼ ▼ │
|
|
189
|
+
│ ┌──────────┐ ┌──────────┐ │
|
|
190
|
+
│ │Inventory │ │ Pricing │ │
|
|
191
|
+
│ └──────────┘ └──────────┘ │
|
|
192
|
+
│ │ │
|
|
193
|
+
│ │CS │
|
|
194
|
+
│ ▼ │
|
|
195
|
+
│ ┌──────────┐ │
|
|
196
|
+
│ │Shipping │ │
|
|
197
|
+
│ └──────────┘ │
|
|
198
|
+
│ │
|
|
199
|
+
│ ┌──────────┐ SW ┌──────────┐ │
|
|
200
|
+
│ │ Auth │ │Analytics │ │
|
|
201
|
+
│ └──────────┘ └──────────┘ │
|
|
202
|
+
└────────────────────────────────────────────────────────┘
|
|
203
|
+
|
|
204
|
+
Leyenda:
|
|
205
|
+
SK = Shared Kernel
|
|
206
|
+
OHS = Open-Host Service (vía Published Language)
|
|
207
|
+
PS = Partnership
|
|
208
|
+
PL = Published Language (unidirectional OHS)
|
|
209
|
+
CS = Customer-Supplier
|
|
210
|
+
SW = Separate Ways
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Relación con el Modelo de Forge
|
|
216
|
+
|
|
217
|
+
Cada `src/features/<name>/` mapea a (parte de) un bounded context.
|
|
218
|
+
|
|
219
|
+
| Regla | Relación con bounded contexts |
|
|
220
|
+
|---|---|
|
|
221
|
+
| **R8** (no cross-feature imports) | Enforces Separate Ways entre contexts. Si dos features necesitan comunicarse, debe ser vía Published Language (contratos en shared/) o Partnership (interfaces inyectadas). |
|
|
222
|
+
| **R9** (no ciclos) | Los ciclos entre contexts indican que el context mapping está mal: dos contexts que se necesitan mutuamente deberían fusionarse o introducir un tercer contexto mediador. |
|
|
223
|
+
| **R2** (platform → feature) | Platform es un contexto genérico que sirve a todos. No debe invertirse. |
|
|
224
|
+
| **R4** (shared → infra) | Shared kernel debe ser puro. Si shared necesita infra, el kernel está contaminado. |
|
|
225
|
+
|
|
226
|
+
### La feature como bounded context implementado
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
src/features/orders/
|
|
230
|
+
domain/ ← Modelo del contexto Orders
|
|
231
|
+
entities/
|
|
232
|
+
events/
|
|
233
|
+
repositories/ ← Puertos
|
|
234
|
+
application/
|
|
235
|
+
use-cases/ ← Flujos del contexto Orders
|
|
236
|
+
mappers/ ← Traducción dentro del contexto
|
|
237
|
+
adapters/
|
|
238
|
+
in/http/ ← Entrada: Open-Host Service (API REST)
|
|
239
|
+
out/persistence/ ← Salida: repositorio concreto
|
|
240
|
+
out/events/ ← Salida: eventos publicados (Published Language)
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Anti-patrones
|
|
246
|
+
|
|
247
|
+
| Anti-patrón | Problema | Solución |
|
|
248
|
+
|---|---|---|
|
|
249
|
+
| **Contexto gigante (Orphan Core)** | Un solo contexto contiene todo el core domain. No hay límites. | Dividir por subdominio. Si duele partir, empezar por los flujos que cambian a ritmo distinto. |
|
|
250
|
+
| **Contexto fantasma** | Un bounded context declarado que no tiene modelo propio. Solo llama APIs de otros contexts. | Fusionar con el contexto que realmente tiene el modelo o eliminarlo. |
|
|
251
|
+
| **Contexto sin lenguaje** | El código usa nombres técnicos (UserService, DataManager, TransactionHelper). No hay rastro del lenguaje del negocio. | Hacer event storming con el equipo de negocio. Renombrar todo para reflejar el lenguaje ubícuo. |
|
|
252
|
+
| **Shared Kernel gigante** | Los contratos compartidos crecen sin control porque es más fácil poner algo en shared que diseñar el límite. | Forzar revisión en cada PR de shared/contracts/. Shared kernel debe ser minimalista y estable. |
|
|
253
|
+
| **Contexto anémico** | Un contexto que solo tiene CRUD y getters/setters. Sin reglas de negocio ni invariantes. | Preguntar: ¿qué reglas de negocio existen aquí? Si la respuesta es "ninguna", probablemente el contexto debería ser un subdominio genérico resuelto con infraestructura (CRUD framework). |
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Ejemplo Completo
|
|
258
|
+
|
|
259
|
+
Sistema de e-commerce con 4 bounded contexts:
|
|
260
|
+
|
|
261
|
+
**Catalog** (Supporting)
|
|
262
|
+
- Modelo: `Product`, `Category`, `Price`
|
|
263
|
+
- Lenguaje: producto, categoría, precio de lista, variante
|
|
264
|
+
- Persistencia: PostgreSQL
|
|
265
|
+
- Relaciones: OHS → Search (Published Language), CS → Pricing (provee precios base)
|
|
266
|
+
|
|
267
|
+
**Orders** (Core)
|
|
268
|
+
- Modelo: `Order`, `OrderLine`, `Payment`, `Shipment`
|
|
269
|
+
- Lenguaje: pedido, línea, pago, envío, cancelación, reembolso
|
|
270
|
+
- Persistencia: PostgreSQL (propio schema)
|
|
271
|
+
- Relaciones: Partnership ↔ Inventory, CS → Shipping, consume eventos de Catalog (Published Language)
|
|
272
|
+
|
|
273
|
+
**Inventory** (Supporting)
|
|
274
|
+
- Modelo: `Stock`, `Warehouse`, `Movement`
|
|
275
|
+
- Lenguaje: stock, almacén, entrada, salida, reserva
|
|
276
|
+
- Persistencia: PostgreSQL
|
|
277
|
+
- Relaciones: Partnership ↔ Orders, CS → Shipping (provee peso/volumen)
|
|
278
|
+
|
|
279
|
+
**Search** (Generic, con Elasticsearch)
|
|
280
|
+
- Modelo: `SearchableProduct` (read model desnormalizado de Catalog)
|
|
281
|
+
- Lenguaje: búsqueda, filtro, índice, relevancia
|
|
282
|
+
- Persistencia: Elasticsearch
|
|
283
|
+
- Relaciones: consume OHS de Catalog
|
|
284
|
+
- No tiene relaciones de salida: es puramente un contexto de lectura
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
Decisiones arquitectónicas reflejadas:
|
|
288
|
+
- Catalog y Search están separados porque tienen distinta frecuencia de cambio y stack
|
|
289
|
+
- Orders e Inventory en Partnership porque el checkout necesita coordinación transaccional
|
|
290
|
+
- Catalog como OHS permite que Search, Pricing y Recommendations consuman sin acoplar
|
|
291
|
+
- No hay ACL porque ningún legacy está involucrado (todos los contexts son nuevos)
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Conexión con Forge
|
|
297
|
+
|
|
298
|
+
| Comando | Acción |
|
|
299
|
+
|---|---|
|
|
300
|
+
| `forge cast` | Crea una nueva feature que se corresponde con un nuevo bounded context o subdomino |
|
|
301
|
+
| `forge inspect` | Detecta violaciones de límites entre contexts (R8, R9) |
|
|
302
|
+
| `forge graph` | Visualiza los bounded contexts y sus relaciones como grafo arquitectónico |
|
|
303
|
+
| `forge relocate` | Migra código entre contexts o extrae un contexto de un monolito legacy |
|
|
304
|
+
| `forge assay` | Evalúa cualitativamente la integridad de los límites entre contexts |
|
|
305
|
+
|
|
306
|
+
## Ver también
|
|
307
|
+
|
|
308
|
+
- `reference/modular-monolith.md` — contexto como unidad del monolith
|
|
309
|
+
- `reference/anti-corruption-layer.md` — protección de límites entre contexts
|
|
310
|
+
- `reference/cqrs.md` — separación command/query dentro de un context
|
|
311
|
+
- `reference/sagas.md` — coordinación entre contexts
|
|
@@ -71,3 +71,9 @@ node .opencode/skills/forge/scripts/architecture.mjs
|
|
|
71
71
|
- Si hay ciclo, extraer la interfaz común a shared/
|
|
72
72
|
- Documentar dependencias en ARCHITECTURE.md
|
|
73
73
|
- Revisar dependencias después de cada migración
|
|
74
|
+
|
|
75
|
+
## Ver también
|
|
76
|
+
|
|
77
|
+
- `scripts/graph.mjs` — el grafo que chain analiza topológicamente
|
|
78
|
+
- `reference/evolutionary-architecture.md` — fitness functions de dependencias
|
|
79
|
+
- `reference/modular-monolith.md` — ciclo de dependencias como señal de split
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# Cohesion — Checklist de Referencias Cruzadas
|
|
2
|
+
|
|
3
|
+
Checklist para llevar la cohesión del corpus de referencias de ~8.5/10 a 10/10. Cada entrada detalla el archivo, los enlaces que debe añadir y el estado actual.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Estado actual
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
[x] F1 — Enlazar 7 archivos huérfanos (0 entrantes + 0 salientes)
|
|
11
|
+
[x] F2 — Completar backlinks de las 10 referencias estratégicas
|
|
12
|
+
[x] F3 — Cerrar 6 lagunas de referenciación
|
|
13
|
+
[x] F4 — Asegurar bidireccionalidad entre pares
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## F1 — Huérfanos con "Ver también"
|
|
19
|
+
|
|
20
|
+
7 archivos que actualmente tienen 0 enlaces entrantes y 0 enlaces salientes dentro del corpus.
|
|
21
|
+
|
|
22
|
+
### F1.1 — `assay.md`
|
|
23
|
+
|
|
24
|
+
- [ ] Añadir "Ver también" al final:
|
|
25
|
+
- `reference/inspect.md` — el reporte que assay evalúa cualitativamente
|
|
26
|
+
- `reference/adr.md` — ADRs como insumo para las opiniones de cada persona
|
|
27
|
+
- `reference/principles.md` — principios contra los que assay contrasta las decisiones
|
|
28
|
+
- `reference/sagas.md`, `reference/cqrs.md` — patrones que assay puede evaluar
|
|
29
|
+
|
|
30
|
+
### F1.2 — `chain.md`
|
|
31
|
+
|
|
32
|
+
- [ ] Añadir "Ver también" al final:
|
|
33
|
+
- `scripts/graph.mjs` — el grafo que chain analiza topológicamente
|
|
34
|
+
- `reference/evolutionary-architecture.md` — fitness functions de dependencias
|
|
35
|
+
- `reference/modular-monolith.md` — ciclo de dependencias como señal de split
|
|
36
|
+
|
|
37
|
+
### F1.3 — `di-strategies.md`
|
|
38
|
+
|
|
39
|
+
- [ ] Añadir "Ver también" al final:
|
|
40
|
+
- `reference/temper.md` — endurecimiento de DI (complemento directo)
|
|
41
|
+
- `reference/patterns.md` — naming y convenciones de contenedor DI
|
|
42
|
+
- `reference/testing-patterns.md` — mocks y DI testing
|
|
43
|
+
|
|
44
|
+
### F1.4 — `forge.md`
|
|
45
|
+
|
|
46
|
+
- [ ] Añadir "Ver también" al final:
|
|
47
|
+
- `reference/bounded-contexts.md` — identificación de contexts al inicializar
|
|
48
|
+
- `reference/modular-monolith.md` — decisión de estructura al iniciar proyecto
|
|
49
|
+
- `reference/principles.md` — principios que guían la inicialización
|
|
50
|
+
- `reference/evolutionary-architecture.md` — bootstrap como primer paso evolutivo
|
|
51
|
+
|
|
52
|
+
### F1.5 — `hooks.md`
|
|
53
|
+
|
|
54
|
+
- [ ] Añadir "Ver también" al final:
|
|
55
|
+
- `reference/quench.md` — validación que el hook ejecuta en pre-commit
|
|
56
|
+
- `reference/evolutionary-architecture.md` — fitness functions como hook
|
|
57
|
+
- `reference/adr.md` — ADRs como insumo para validación en hook
|
|
58
|
+
- `reference/detect.mjs` — script que el hook invoca
|
|
59
|
+
|
|
60
|
+
### F1.6 — `smelt.md`
|
|
61
|
+
|
|
62
|
+
- [ ] Añadir "Ver también" al final:
|
|
63
|
+
- `reference/relocate.md` — operación similar de extracción
|
|
64
|
+
- `reference/data-patterns.md` — identificación de qué extraer a shared
|
|
65
|
+
- `reference/errors.md` — errores tipados como candidatos a smelt
|
|
66
|
+
|
|
67
|
+
### F1.7 — `temper.md`
|
|
68
|
+
|
|
69
|
+
- [ ] Añadir "Ver también" al final:
|
|
70
|
+
- `reference/di-strategies.md` — selección de estrategia DI antes de temperar
|
|
71
|
+
- `reference/patterns.md` — convenciones de naming en DI
|
|
72
|
+
- `reference/testing-patterns.md` — testabilidad que DI disciplinada habilita
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## F2 — Backlinks de referencias estratégicas
|
|
77
|
+
|
|
78
|
+
Backlinks faltantes desde las referencias existentes hacia las 10 nuevas.
|
|
79
|
+
|
|
80
|
+
### F2.1 — `modular-monolith.md`
|
|
81
|
+
|
|
82
|
+
Backlinks esperados: relocate, reforge, cast
|
|
83
|
+
|
|
84
|
+
| Desde | Estado | Acción |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `relocate.md` | ✅ Ya enlaza | — |
|
|
87
|
+
| `reforge.md` | ✅ Ya enlaza | — |
|
|
88
|
+
| `cast.md` | ✅ Ya enlaza | — |
|
|
89
|
+
|
|
90
|
+
### F2.2 — `adr.md`
|
|
91
|
+
|
|
92
|
+
Backlinks esperados: reforge, cast, inscribe
|
|
93
|
+
|
|
94
|
+
| Desde | Estado | Acción |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| `reforge.md` | ✅ Ya enlaza | — |
|
|
97
|
+
| `cast.md` | ✅ Ya enlaza | — |
|
|
98
|
+
| `inscribe.md` | ✅ Ya enlaza | — |
|
|
99
|
+
|
|
100
|
+
### F2.3 — `anti-corruption-layer.md`
|
|
101
|
+
|
|
102
|
+
Backlinks esperados: relocate, reforge, cast
|
|
103
|
+
|
|
104
|
+
| Desde | Estado | Acción |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| `relocate.md` | ✅ Ya enlaza | — |
|
|
107
|
+
| `reforge.md` | ✅ Ya enlaza | — |
|
|
108
|
+
| `cast.md` | ✅ Ya enlaza | — |
|
|
109
|
+
|
|
110
|
+
### F2.4 — `evolutionary-architecture.md`
|
|
111
|
+
|
|
112
|
+
Backlinks esperados: inspect, reforge, quench, graph
|
|
113
|
+
|
|
114
|
+
| Desde | Estado | Acción |
|
|
115
|
+
|---|---|---|
|
|
116
|
+
| `inspect.md` | ✅ Ya enlaza | — |
|
|
117
|
+
| `reforge.md` | ✅ Ya enlaza | — |
|
|
118
|
+
| `quench.md` | ✅ Ya enlaza | — |
|
|
119
|
+
| `graph.md` | ✅ No existe en reference/ | No-op |
|
|
120
|
+
|
|
121
|
+
### F2.5 — `cqrs.md`
|
|
122
|
+
|
|
123
|
+
Backlinks esperados: data-patterns, events, cast
|
|
124
|
+
|
|
125
|
+
| Desde | Estado | Acción |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| `data-patterns.md` | ✅ Ya enlaza | — |
|
|
128
|
+
| `events.md` | ✅ Ya enlaza | — |
|
|
129
|
+
| `cast.md` | ✅ Ya enlaza | — |
|
|
130
|
+
|
|
131
|
+
### F2.6 — `sagas.md`
|
|
132
|
+
|
|
133
|
+
Backlinks esperados: events, cast
|
|
134
|
+
|
|
135
|
+
| Desde | Estado | Acción |
|
|
136
|
+
|---|---|---|
|
|
137
|
+
| `events.md` | ✅ Ya enlaza | — |
|
|
138
|
+
| `cast.md` | ✅ Ya enlaza | — |
|
|
139
|
+
|
|
140
|
+
### F2.7 — `transactional-outbox.md`
|
|
141
|
+
|
|
142
|
+
Backlinks esperados: events, idempotency, sagas
|
|
143
|
+
|
|
144
|
+
| Desde | Estado | Acción |
|
|
145
|
+
|---|---|---|
|
|
146
|
+
| `events.md` | ✅ Ya enlaza | — |
|
|
147
|
+
| `idempotency.md` | ✅ Ya enlaza | — |
|
|
148
|
+
| `sagas.md` | ✅ Ya enlaza | — |
|
|
149
|
+
|
|
150
|
+
### F2.8 — `idempotency.md`
|
|
151
|
+
|
|
152
|
+
Backlinks esperados: api-design, events, sagas, transactional-outbox
|
|
153
|
+
|
|
154
|
+
| Desde | Estado | Acción |
|
|
155
|
+
|---|---|---|
|
|
156
|
+
| `api-design.md` | ✅ Ya enlaza | — |
|
|
157
|
+
| `events.md` | ✅ Ya enlaza | — |
|
|
158
|
+
| `sagas.md` | ✅ Ya enlaza | — |
|
|
159
|
+
| `transactional-outbox.md` | ✅ Ya enlaza | — |
|
|
160
|
+
|
|
161
|
+
### F2.9 — `api-versioning.md`
|
|
162
|
+
|
|
163
|
+
Backlinks esperados: api-design, patterns, cast, reforge
|
|
164
|
+
|
|
165
|
+
| Desde | Estado | Acción |
|
|
166
|
+
|---|---|---|
|
|
167
|
+
| `api-design.md` | ✅ Ya enlaza | — |
|
|
168
|
+
| `patterns.md` | ✅ Ya enlaza | — |
|
|
169
|
+
| `cast.md` | ✅ Ya enlaza | — |
|
|
170
|
+
| `reforge.md` | ✅ Ya enlaza | — |
|
|
171
|
+
|
|
172
|
+
### F2.10 — `bounded-contexts.md`
|
|
173
|
+
|
|
174
|
+
Backlinks esperados: modular-monolith, anti-corruption-layer, cqrs, sagas, cast, reforge, relocate
|
|
175
|
+
|
|
176
|
+
| Desde | Estado | Acción |
|
|
177
|
+
|---|---|---|
|
|
178
|
+
| `modular-monolith.md` | ✅ Ya enlaza | — |
|
|
179
|
+
| `anti-corruption-layer.md` | ✅ Ya enlaza | — |
|
|
180
|
+
| `cqrs.md` | ✅ Ya enlaza | — |
|
|
181
|
+
| `sagas.md` | ✅ Ya enlaza | — |
|
|
182
|
+
| `cast.md` | ✅ Ya enlaza | — |
|
|
183
|
+
| `reforge.md` | ✅ Ya enlaza | — |
|
|
184
|
+
| `relocate.md` | ✅ Ya enlaza | — |
|
|
185
|
+
|
|
186
|
+
**Único pendiente F2:**
|
|
187
|
+
- [x] `graph.md` → no existe en reference/ — no-op
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## F3 — Lagunas de referenciación
|
|
192
|
+
|
|
193
|
+
Conceptos mencionados en una referencia pero sin enlace a la referencia dedicada.
|
|
194
|
+
|
|
195
|
+
### F3.1 — `assay.md`
|
|
196
|
+
|
|
197
|
+
- [ ] Donde menciona "violaciones" y "auditoría", enlazar a `reference/inspect.md`
|
|
198
|
+
|
|
199
|
+
### F3.2 — `chain.md`
|
|
200
|
+
|
|
201
|
+
- [ ] Donde habla de "dependencias" y "ciclos", enlazar a `scripts/graph.mjs` y `reference/evolutionary-architecture.md`
|
|
202
|
+
|
|
203
|
+
### F3.3 — `forge.md`
|
|
204
|
+
|
|
205
|
+
- [ ] Donde menciona "perfil tecnológico" y "bootstrapping", enlazar a `reference/bounded-contexts.md` y `reference/modular-monolith.md`
|
|
206
|
+
|
|
207
|
+
### F3.4 — `hooks.md`
|
|
208
|
+
|
|
209
|
+
- [ ] Donde menciona "validación arquitectónica" y "pre-commit", enlazar a `reference/quench.md` y `reference/evolutionary-architecture.md`
|
|
210
|
+
|
|
211
|
+
### F3.5 — `security-patterns.md`
|
|
212
|
+
|
|
213
|
+
- [ ] Donde menciona "middleware" y "AuthN/AuthZ", enlazar a `reference/api-design.md`
|
|
214
|
+
|
|
215
|
+
### F3.6 — `testing-patterns.md`
|
|
216
|
+
|
|
217
|
+
- [ ] Donde menciona "tests de adapters" y "ACL", enlazar a `reference/anti-corruption-layer.md`
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## F4 — Bidireccionalidad
|
|
222
|
+
|
|
223
|
+
Pares donde existe enlace A→B pero falta B→A.
|
|
224
|
+
|
|
225
|
+
### Pares incompletos
|
|
226
|
+
|
|
227
|
+
| A | B | A→B | B→A | Acción |
|
|
228
|
+
|---|---|---|---|---|
|
|
229
|
+
| `bounded-contexts.md` | `anti-corruption-layer.md` | ✅ | ✅ | — |
|
|
230
|
+
| `bounded-contexts.md` | `modular-monolith.md` | ✅ | ✅ | — |
|
|
231
|
+
| `bounded-contexts.md` | `cqrs.md` | ✅ | ✅ | — |
|
|
232
|
+
| `bounded-contexts.md` | `sagas.md` | ✅ | ✅ | — |
|
|
233
|
+
| `modular-monolith.md` | `evolutionary-architecture.md` | ✅ | ✅ | — |
|
|
234
|
+
| `sagas.md` | `transactional-outbox.md` | ✅ | ✅ | — |
|
|
235
|
+
| `sagas.md` | `idempotency.md` | ✅ | ✅ | — |
|
|
236
|
+
| `idempotency.md` | `transactional-outbox.md` | ✅ | ✅ | — |
|
|
237
|
+
| `evol-arch.md` | `adr.md` | ✅ | ✅ | — |
|
|
238
|
+
| `api-design.md` | `api-versioning.md` | ✅ | ✅ | — |
|
|
239
|
+
|
|
240
|
+
- [x] **Verificar que todos los pares anteriores son bidireccionales.** Leer cada archivo y confirmar que si A enlaza a B, B también enlaza a A (o al menos a la categoría de A).
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Criterio de completitud (10/10)
|
|
245
|
+
|
|
246
|
+
- [x] **Cero enlaces rotos** — ✅
|
|
247
|
+
- [x] **Cero huérfanos** — ✅ (33/35 archivos tienen ≥1 enlace saliente a otro reference/; solo help.md y architectural-depth-checklist.md, ambos intencionales)
|
|
248
|
+
- [x] **Cero backlinks perdidos** — ✅ (todas las referencias estratégicas tienen backlinks)
|
|
249
|
+
- [x] **Formato consistente** — ✅ (28 archivos con `## Ver también`, 0 con inline `Ver también:`)
|
|
250
|
+
- [x] **Bidireccionalidad ≥ 90%** — ✅ (33/35 archivos tienen backlinks)
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Integración en SKILL.md
|
|
255
|
+
|
|
256
|
+
- [x] Añadir `reference/cohesion-checklist.md` al Module Index
|