@ronaldjdevfs/forge 1.3.0-beta → 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 +1 -1
- package/package.json +1 -1
- package/skills/forge/SKILL.md +57 -128
- 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 +2 -2
- package/skills/forge/scripts/forgeSentinel.mjs +2 -2
- package/skills/forge/scripts/forgeSmith.mjs +2 -2
- 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/posttool.mjs +211 -17
- package/skills/forge/scripts/recommendation-engine.mjs +125 -0
- package/skills/forge/scripts/rollback.mjs +5 -3
- 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 +288 -4
- package/src/cli.js +26 -13
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<img src="favicon.svg" alt="Forge Logo" width="100" height="100">
|
|
2
2
|
|
|
3
|
-
> **v1.3.
|
|
3
|
+
> **v1.3.1** — Bugfixes, New Templates & Interactive Flags
|
|
4
4
|
|
|
5
5
|
## Forge — Backend Architecture Operating System
|
|
6
6
|
|
package/package.json
CHANGED
package/skills/forge/SKILL.md
CHANGED
|
@@ -70,57 +70,55 @@ En esencia:
|
|
|
70
70
|
|
|
71
71
|
---
|
|
72
72
|
|
|
73
|
-
## Boot Sequence
|
|
73
|
+
## Boot Sequence
|
|
74
74
|
|
|
75
|
-
ANTES de cualquier acción, Forge DEBE ejecutar
|
|
76
|
-
|
|
77
|
-
1. **context.mjs** — Detectar stack, platform, features, shared, infra, grafo, estado
|
|
78
|
-
2. **armorer.mjs** — Detectar ownership, huérfanos, duplicados, mal ubicados
|
|
79
|
-
3. **profile.mjs** — Determinar perfil tecnológico
|
|
80
|
-
4. **graph.mjs** — Construir grafo arquitectónico global (4 capas + 9 reglas)
|
|
81
|
-
5. **chain.mjs** — Analizar dependencias multi-capa
|
|
82
|
-
6. **inspect.mjs** — Auditoría completa con ownership + platform
|
|
83
|
-
7. **architecture.mjs** — Generar/actualizar ARCHITECTURE.md
|
|
84
|
-
8. **Ejecutar comando solicitado** — cast, quench, temper, etc.
|
|
85
|
-
9. **forgeSentinel** — Verificar cambios tras escritura (`scripts/forgeSentinel.mjs --reminder`)
|
|
86
|
-
10. **Actualizar ARCHITECTURE.md** — Reflejar nuevo estado
|
|
75
|
+
ANTES de cualquier acción, Forge DEBE ejecutar `forge-boot.mjs` con la profundidad adecuada al comando:
|
|
87
76
|
|
|
88
77
|
```bash
|
|
89
|
-
|
|
90
|
-
ctx=$(node .opencode/skills/forge/scripts/context.mjs --json 2>/dev/null)
|
|
91
|
-
armorer=$(node .opencode/skills/forge/scripts/armorer.mjs --json 2>/dev/null)
|
|
92
|
-
profile=$(node .opencode/skills/forge/scripts/profile.mjs --extended 2>/dev/null)
|
|
93
|
-
graph=$(node .opencode/skills/forge/scripts/graph.mjs --json 2>/dev/null)
|
|
94
|
-
deps=$(node .opencode/skills/forge/scripts/chain.mjs --json 2>/dev/null)
|
|
95
|
-
inspect=$(node .opencode/skills/forge/scripts/inspect.mjs --json 2>/dev/null)
|
|
78
|
+
boot=$(node .opencode/skills/forge/scripts/forge-boot.mjs --depth <depth> --json 2>/dev/null)
|
|
96
79
|
```
|
|
97
80
|
|
|
81
|
+
La profundidad (`--depth`) depende del comando (ver Execution Flow):
|
|
82
|
+
- **minimal** → context + profile (cast, temper, smelt, relocate, reforge, inscribe)
|
|
83
|
+
- **standard** → minimal + graph + chain (chain, graph, forge hook)
|
|
84
|
+
- **full** → standard + ownership + inspect (inspect, quench, default)
|
|
85
|
+
|
|
86
|
+
Si `$boot` contiene datos cacheados en `.forge/cache/` se reusan automáticamente. Pasa `--force` para regenerar.
|
|
87
|
+
|
|
98
88
|
---
|
|
99
89
|
|
|
100
90
|
## Command Routing
|
|
101
91
|
|
|
102
|
-
|
|
|
92
|
+
| Intención | Comando | Referencia |
|
|
103
93
|
|---|---|---|
|
|
104
|
-
|
|
|
105
|
-
|
|
|
106
|
-
|
|
|
107
|
-
|
|
|
108
|
-
|
|
|
109
|
-
|
|
|
110
|
-
|
|
|
111
|
-
|
|
|
112
|
-
|
|
|
113
|
-
|
|
|
114
|
-
|
|
|
115
|
-
|
|
|
116
|
-
|
|
|
117
|
-
|
|
|
118
|
-
|
|
|
119
|
-
|
|
|
120
|
-
|
|
|
121
|
-
|
|
|
122
|
-
|
|
|
123
|
-
|
|
|
94
|
+
| Ayuda | `forge --help` | `reference/help.md` |
|
|
95
|
+
| Setup inicial | `forge` | `reference/forge.md` |
|
|
96
|
+
| Crear feature | `cast` | `reference/cast.md` |
|
|
97
|
+
| Auditar | `inspect` | `reference/inspect.md` |
|
|
98
|
+
| Relocalizar feature | `relocate` | `reference/relocate.md` |
|
|
99
|
+
| Refactorizar | `reforge` | `reference/reforge.md` |
|
|
100
|
+
| Verificar violaciones | `quench` | `reference/quench.md` |
|
|
101
|
+
| Endurecer | `temper` | `reference/temper.md` |
|
|
102
|
+
| Dependencias | `chain` | `scripts/chain.mjs` |
|
|
103
|
+
| Inscribir ARCHITECTURE.md | `inscribe` | `reference/inscribe.md` |
|
|
104
|
+
| Grafo arquitectónico | `graph` | `scripts/graph.mjs` |
|
|
105
|
+
| Fundir a shared | `smelt` | `reference/smelt.md` |
|
|
106
|
+
| Atajo / pin | `nail` / `unnail` | `scripts/pin.mjs` |
|
|
107
|
+
| Git hook | `forge hook` | `reference/hooks.md` |
|
|
108
|
+
| API design | `forge api` | `scripts/forge-api.mjs` |
|
|
109
|
+
| Rollback | `forge rollback` | `scripts/rollback.mjs` |
|
|
110
|
+
| Estado | `forge state` | `scripts/forge-state.mjs` |
|
|
111
|
+
| Ensayo cualitativo | `assay` | `reference/assay.md` |
|
|
112
|
+
| Bounded context | `forge` | `reference/bounded-contexts.md` |
|
|
113
|
+
| Modular monolith | `forge` | `reference/modular-monolith.md` |
|
|
114
|
+
| ADR | `inscribe` | `reference/adr.md` |
|
|
115
|
+
| Anti-corruption layer | `relocate` | `reference/anti-corruption-layer.md` |
|
|
116
|
+
| Evolutionary arch | `reforge` | `reference/evolutionary-architecture.md` |
|
|
117
|
+
| CQRS | `cast` | `reference/cqrs.md` |
|
|
118
|
+
| Sagas | `cast` | `reference/sagas.md` |
|
|
119
|
+
| Outbox | `cast` | `reference/transactional-outbox.md` |
|
|
120
|
+
| Idempotencia | `forge` | `reference/idempotency.md` |
|
|
121
|
+
| API versioning | `forge api` | `reference/api-versioning.md` |
|
|
124
122
|
|
|
125
123
|
---
|
|
126
124
|
|
|
@@ -128,15 +126,17 @@ inspect=$(node .opencode/skills/forge/scripts/inspect.mjs --json 2>/dev/null)
|
|
|
128
126
|
|
|
129
127
|
Para cada comando, Forge sigue este flujo:
|
|
130
128
|
|
|
131
|
-
1. **
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
129
|
+
1. **Boot condicional**: Ejecutar `forge-boot.mjs --depth <depth>` donde depth es:
|
|
130
|
+
- `minimal` para cast, temper, smelt, relocate, reforge, inscribe
|
|
131
|
+
- `standard` para chain, graph, forge hook
|
|
132
|
+
- `full` para inspect, quench, o cualquier otro comando
|
|
133
|
+
2. **Referencia**: Cargar `reference/<command>.md`
|
|
134
|
+
3. **Ejecutar**: Aplicar el flujo definido en la referencia
|
|
135
|
+
4. **Verificar**: Ejecutar `detect.mjs --summary` (resumen compacto)
|
|
136
|
+
5. **Actualizar ARCHITECTURE.md**: `architecture.mjs` (solo en full)
|
|
137
|
+
6. **Reportar**: Mostrar resultado al usuario con severidades
|
|
138
|
+
|
|
139
|
+
El boot usa caché de `.forge/cache/`. Si los archivos `src/` no cambiaron, los datos se reusan. Usa `forge-boot.mjs --force` para regenerar todo.
|
|
140
140
|
|
|
141
141
|
---
|
|
142
142
|
|
|
@@ -169,87 +169,13 @@ import { crossFeature } from "../other-feature/domain/Entity"; // ← R1 y R8 ig
|
|
|
169
169
|
|
|
170
170
|
## ARCHITECTURE.md
|
|
171
171
|
|
|
172
|
-
Forge mantiene
|
|
173
|
-
|
|
174
|
-
```md
|
|
175
|
-
# Architecture State
|
|
176
|
-
|
|
177
|
-
- Project Name: <name>
|
|
178
|
-
- Framework: <detectado>
|
|
179
|
-
- Runtime: <detectado>
|
|
180
|
-
- Database: <detectado>
|
|
181
|
-
- ORM: <detectado>
|
|
182
|
-
- DI Strategy: <detectado>
|
|
183
|
-
- Profile: <detectado>
|
|
184
|
-
- Architecture: hexagonal-feature (Platform + Features + Shared + Infra)
|
|
185
|
-
- Last Audit: <fecha> (score: <puntaje>)
|
|
186
|
-
|
|
187
|
-
## Platform
|
|
188
|
-
- platform/config/
|
|
189
|
-
- platform/server/
|
|
190
|
-
...
|
|
191
|
-
|
|
192
|
-
## Features
|
|
193
|
-
- features/users/
|
|
194
|
-
...
|
|
195
|
-
|
|
196
|
-
## Shared
|
|
197
|
-
- shared/errors/
|
|
198
|
-
...
|
|
199
|
-
|
|
200
|
-
## Infrastructure
|
|
201
|
-
- infra/prisma/
|
|
202
|
-
...
|
|
203
|
-
|
|
204
|
-
## Ownership
|
|
205
|
-
- Health: healthy | degraded | critical
|
|
206
|
-
- Score: 0-100
|
|
207
|
-
- Orphans: 0
|
|
208
|
-
- Duplicates: 0
|
|
209
|
-
- Misplaced: 0
|
|
210
|
-
|
|
211
|
-
## Architecture Graph
|
|
212
|
-
...
|
|
213
|
-
|
|
214
|
-
## Dependency Health
|
|
215
|
-
...
|
|
216
|
-
```
|
|
172
|
+
Forge mantiene `ARCHITECTURE.md` en la raíz con el estado persistente del proyecto (framework, DB, features, ownership, graph). Se genera y actualiza con `architecture.mjs`.
|
|
217
173
|
|
|
218
|
-
El agente DEBE leer este archivo al inicio de cada interacción y actualizarlo al finalizar cada comando.
|
|
174
|
+
El agente DEBE leer este archivo al inicio de cada interacción y actualizarlo al finalizar cada comando. Ver `scripts/architecture.mjs` para el formato completo.
|
|
219
175
|
|
|
220
176
|
---
|
|
221
177
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
| Módulo | Propósito |
|
|
225
|
-
|---|---|
|
|
226
|
-
| `reference/principles.md` | Manifiesto y 12 principios inquebrantables |
|
|
227
|
-
| `reference/patterns.md` | Convenciones de nomenclatura globales (PascalCase.artifact, kebab dirs, etc.) |
|
|
228
|
-
| `reference/errors.md` | Manejo de errores tipados en dominio y aplicación |
|
|
229
|
-
| `reference/di-strategies.md` | Estrategias de inyección de dependencias según tamaño |
|
|
230
|
-
| `reference/testing-patterns.md` | Pirámide de tests, unit mocks, integration tests |
|
|
231
|
-
| `reference/api-design.md` | REST / GraphQL, paginación, validación, contratos |
|
|
232
|
-
| `reference/observability.md` | Logging, tracing, métricas, health checks |
|
|
233
|
-
| `reference/data-patterns.md` | Repository, Unit of Work, CQRS, Event Sourcing |
|
|
234
|
-
| `reference/security-patterns.md` | AuthN, AuthZ, RBAC, rate limiting, validación |
|
|
235
|
-
| `reference/events.md` | Eventos de dominio, outbox pattern, sagas |
|
|
236
|
-
| `reference/hooks.md` | Git pre-commit hook para validación arquitectónica |
|
|
237
|
-
| `reference/help.md` | Lista completa de comandos y flags de Forge |
|
|
238
|
-
| `reference/assay.md` | Ensayo arquitectónico multi-persona — interpretación cualitativa del audit |
|
|
239
|
-
| `profiles/` | Perfiles tecnológicos detallados (Express, Fastify, NestJS, etc.) |
|
|
240
|
-
| `scripts/` | Scripts: context, detect, inspect, chain, profile, graph, architecture, armorer, bootstrap, forge-config, forge-signals, forge-state, forge-api, pin, update, rollback, hook, forgeSentinel, forgeSentinel-lib, forgeSmith, forgeSmith-admin, formatter, assay, registry/rules |
|
|
241
|
-
| `scripts/registry/rules.mjs` | Anti-pattern rule registry (R1-R9 + custom rules desacopladas de detect.mjs) |
|
|
242
|
-
| `scripts/formatter.mjs` | Output formatter unificado (JSON, tabla, severidad coloreada, scoreBar, formatCheck, formatViolation) |
|
|
243
|
-
| `scripts/forgeSentinel.mjs` | PostToolUse hook — analiza archivos modificados tras escritura y reporta violaciones |
|
|
244
|
-
| `scripts/forgeSentinel-lib.mjs` | Lógica compartida para hooks forgeSentinel y forgeSmith |
|
|
245
|
-
| `scripts/forgeSmith.mjs` | preToolUse gate — previene escrituras con violaciones CRITICAL/ERROR (Cursor) |
|
|
246
|
-
| `scripts/forgeSmith-admin.mjs` | Gestión de hooks (on/off/status) |
|
|
247
|
-
| `scripts/assay.mjs` | Motor de ensayo arquitectónico multi-persona (Bezos, Fowler, Hacker, PM, Arquitecta Senior) |
|
|
248
|
-
| `templates/feature/` | Templates de feature (entity, repository, uc, controller, routes, schema, mapper) |
|
|
249
|
-
| `templates/platform/` | Templates de platform (config, server, database, logger, http, di) |
|
|
250
|
-
| `templates/shared/` | Templates de shared (errors, contracts, types, utils) |
|
|
251
|
-
| `templates/infra/` | Templates de infra (prisma, mongodb, redis, mail) |
|
|
252
|
-
| `command/forge.md` | Definición del comando `/forge` para opencode |
|
|
178
|
+
> 📚 Todas las referencias están en `reference/`. La tabla de routing arriba mapea cada comando a su referencia. Ver `reference/help.md` para la lista completa de flags.
|
|
253
179
|
|
|
254
180
|
### Tests
|
|
255
181
|
|
|
@@ -269,8 +195,11 @@ node --test .opencode/skills/forge/tests/core.test.mjs
|
|
|
269
195
|
| `formatter.mjs` | 4 | Output format, colores, JSON |
|
|
270
196
|
| `registry/rules.mjs` | 4 | R1-R9, evaluación, custom rules |
|
|
271
197
|
| `detect.mjs` (inline ignores) | 5 | parseInlineIgnores, isIgnored |
|
|
272
|
-
| `
|
|
198
|
+
| `posttool.mjs` | 1 | PostToolUse hook |
|
|
273
199
|
| `assay.mjs` | 4 | Personas, generateAssay, opiniones |
|
|
200
|
+
| transactional-outbox | 5 | Entry lifecycle, retry, DLQ, required fields, pending |
|
|
201
|
+
| idempotency | 5 | UUID validation, cached response, different keys, TTL, method filter |
|
|
202
|
+
| anti-corruption-layer | 5 | DTO mapping (2 dirs), null handling, 404, delegation order |
|
|
274
203
|
|
|
275
204
|
### Flags adicionales
|
|
276
205
|
|
|
@@ -1,29 +1,51 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Forge — Backend Architecture OS.
|
|
2
|
+
description: Forge — Backend Architecture OS. Comandos: forge, cast, inspect, assay, quench, chain, graph, armorer, inscribe, smelt, relocate, reforge, temper.
|
|
3
3
|
agent: build
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
Ejecuta herramientas de Forge según el subcomando especificado en $ARGUMENTS.
|
|
7
7
|
|
|
8
|
+
Si el subcomando NO tiene flags en $ARGUMENTS y tiene flags disponibles (ver tabla abajo), pregunta al usuario cuáles quiere usar con la `question` tool (tipo checkboxes múltiples). Si el usuario no selecciona ninguna, ejecuta sin flags.
|
|
9
|
+
|
|
10
|
+
| Comando | Flags disponibles |
|
|
11
|
+
|---------|------------------|
|
|
12
|
+
| `forge` | Sin flags |
|
|
13
|
+
| `cast` | Sin flags (pide nombre del feature interactivamente) |
|
|
14
|
+
| `inspect` | `--json`, `--diff`, `--full`, `--summary`, `--severity=<nivel>`, `--force` |
|
|
15
|
+
| `assay` | `--persona=<id>`, `--json`, `--save`, `history` |
|
|
16
|
+
| `quench` | `--fix`, `--show-ignores`, `--severity=<nivel>`, `--json` |
|
|
17
|
+
| `chain` | `--json` |
|
|
18
|
+
| `graph` | `--json` |
|
|
19
|
+
| `armorer` | Sin flags |
|
|
20
|
+
| `inscribe` | `--output=<path>` |
|
|
21
|
+
| `smelt` | Sin flags (pide qué extraer interactivamente) |
|
|
22
|
+
| `relocate` | Sin flags (pide feature y destino) |
|
|
23
|
+
| `reforge` | `--cycles` |
|
|
24
|
+
| `temper` | Sin flags |
|
|
25
|
+
|
|
8
26
|
## Build
|
|
9
27
|
|
|
10
28
|
### forge
|
|
11
29
|
|
|
12
|
-
Inicializa el proyecto arquitectónicamente
|
|
30
|
+
Inicializa el proyecto arquitectónicamente. Ejecuta context + bootstrap + profile + armorer + graph + chain + inscribe.
|
|
13
31
|
|
|
14
32
|
```
|
|
15
33
|
node .opencode/skills/forge/scripts/context.mjs
|
|
16
34
|
node .opencode/skills/forge/scripts/bootstrap.mjs
|
|
35
|
+
node .opencode/skills/forge/scripts/profile.mjs
|
|
17
36
|
node .opencode/skills/forge/scripts/armorer.mjs
|
|
37
|
+
node .opencode/skills/forge/scripts/graph.mjs
|
|
38
|
+
node .opencode/skills/forge/scripts/chain.mjs
|
|
39
|
+
node .opencode/skills/forge/scripts/architecture.mjs
|
|
18
40
|
```
|
|
19
41
|
|
|
20
42
|
### cast
|
|
21
43
|
|
|
22
|
-
Crea un nuevo feature
|
|
44
|
+
Crea un nuevo feature. Primero verifica que platform/shared/infra existan; si falta, llama a bootstrap.
|
|
23
45
|
|
|
24
46
|
### relocate
|
|
25
47
|
|
|
26
|
-
Migra un feature existente.
|
|
48
|
+
Migra un feature existente. Puede targetizar platform/, shared/, infra/ o features/.
|
|
27
49
|
|
|
28
50
|
### inscribe
|
|
29
51
|
|
|
@@ -33,9 +55,9 @@ Genera ARCHITECTURE.md con grafo arquitectónico, ownership y platform.
|
|
|
33
55
|
node .opencode/skills/forge/scripts/architecture.mjs
|
|
34
56
|
```
|
|
35
57
|
|
|
36
|
-
###
|
|
58
|
+
### graph
|
|
37
59
|
|
|
38
|
-
Construye el grafo arquitectónico del proyecto (4 capas: platform, feature, shared, infra).
|
|
60
|
+
Construye el grafo arquitectónico del proyecto (4 capas: platform, feature, shared, infra) con reglas R1-R9.
|
|
39
61
|
|
|
40
62
|
```
|
|
41
63
|
node .opencode/skills/forge/scripts/graph.mjs
|
|
@@ -49,11 +71,11 @@ node .opencode/skills/forge/scripts/graph.mjs --json
|
|
|
49
71
|
|
|
50
72
|
### smelt
|
|
51
73
|
|
|
52
|
-
Extrae código reutilizable a shared
|
|
74
|
+
Extrae código reutilizable a shared/ (solo código puro, sin dependencias infra/feature).
|
|
53
75
|
|
|
54
76
|
### bootstrap
|
|
55
77
|
|
|
56
|
-
Inicializa platform, shared e infra layers (interno, se ejecuta automáticamente).
|
|
78
|
+
Inicializa platform, shared e infra layers (uso interno, se ejecuta automáticamente).
|
|
57
79
|
|
|
58
80
|
```
|
|
59
81
|
node .opencode/skills/forge/scripts/bootstrap.mjs
|
|
@@ -63,7 +85,7 @@ node .opencode/skills/forge/scripts/bootstrap.mjs
|
|
|
63
85
|
|
|
64
86
|
### inspect
|
|
65
87
|
|
|
66
|
-
|
|
88
|
+
Audita la conformidad arquitectónica completa. 6 categorías: structure(20), layers(20), ownership(20), platform(15), dependencies(15), graph(20).
|
|
67
89
|
|
|
68
90
|
```
|
|
69
91
|
node .opencode/skills/forge/scripts/inspect.mjs
|
|
@@ -75,9 +97,26 @@ Para salida JSON:
|
|
|
75
97
|
node .opencode/skills/forge/scripts/inspect.mjs --json
|
|
76
98
|
```
|
|
77
99
|
|
|
100
|
+
### assay
|
|
101
|
+
|
|
102
|
+
Ensayo arquitectónico multi-persona. Interpretación cualitativa del audit desde 5 perspectivas (Bezos, Fowler, Hacker, PM, Arquitecta Senior).
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
node .opencode/skills/forge/scripts/assay.mjs
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Filtros:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
node .opencode/skills/forge/scripts/assay.mjs --persona=bezos
|
|
112
|
+
node .opencode/skills/forge/scripts/assay.mjs --json
|
|
113
|
+
node .opencode/skills/forge/scripts/assay.mjs --save
|
|
114
|
+
node .opencode/skills/forge/scripts/assay.mjs history
|
|
115
|
+
```
|
|
116
|
+
|
|
78
117
|
### quench
|
|
79
118
|
|
|
80
|
-
|
|
119
|
+
Valida reglas arquitectónicas R1-R9.
|
|
81
120
|
|
|
82
121
|
```
|
|
83
122
|
node .opencode/skills/forge/scripts/detect.mjs
|
|
@@ -85,15 +124,21 @@ node .opencode/skills/forge/scripts/detect.mjs
|
|
|
85
124
|
|
|
86
125
|
### chain
|
|
87
126
|
|
|
88
|
-
|
|
127
|
+
Orden topológico de dependencias multi-capa (platform, features, shared, infra).
|
|
89
128
|
|
|
90
129
|
```
|
|
91
130
|
node .opencode/skills/forge/scripts/chain.mjs
|
|
92
131
|
```
|
|
93
132
|
|
|
133
|
+
Para salida JSON:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
node .opencode/skills/forge/scripts/chain.mjs --json
|
|
137
|
+
```
|
|
138
|
+
|
|
94
139
|
### armorer
|
|
95
140
|
|
|
96
|
-
|
|
141
|
+
Reporte de ownership: huérfanos, duplicados, componentes mal ubicados.
|
|
97
142
|
|
|
98
143
|
```
|
|
99
144
|
node .opencode/skills/forge/scripts/armorer.mjs
|
|
@@ -103,8 +148,8 @@ node .opencode/skills/forge/scripts/armorer.mjs
|
|
|
103
148
|
|
|
104
149
|
### reforge
|
|
105
150
|
|
|
106
|
-
Refactoriza la arquitectura de un feature.
|
|
151
|
+
Refactoriza la arquitectura de un feature considerando las 4 capas.
|
|
107
152
|
|
|
108
153
|
### temper
|
|
109
154
|
|
|
110
|
-
Fortalece la arquitectura
|
|
155
|
+
Fortalece la arquitectura: constructor injection, sin service locators.
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# Architecture Decision Records (ADR)
|
|
2
|
+
|
|
3
|
+
Las decisiones arquitectónicas son el activo más valioso de un proyecto a largo plazo. Sin registro, cada nueva incorporación al equipo redescubre lo mismo. Los ADRs capturan el qué, el por qué y las consecuencias de cada decisión.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Formato ADR Estándar
|
|
8
|
+
|
|
9
|
+
Cada ADR es un archivo en `docs/adr/` con el formato `NNNN-title-with-dashes.md`.
|
|
10
|
+
|
|
11
|
+
```md
|
|
12
|
+
# NNNN — Título corto pero descriptivo
|
|
13
|
+
|
|
14
|
+
**Estado:** [Proposed | Accepted | Deprecated | Superseded | Amended]
|
|
15
|
+
**Fecha:** YYYY-MM-DD
|
|
16
|
+
**Decisores:** [lista de personas que tomaron la decisión]
|
|
17
|
+
|
|
18
|
+
## Contexto
|
|
19
|
+
|
|
20
|
+
Describe el problema o situación que motiva la decisión. Incluye:
|
|
21
|
+
- Restricciones técnicas o de negocio
|
|
22
|
+
- Alternativas consideradas brevemente
|
|
23
|
+
- Por qué el status quo no es aceptable
|
|
24
|
+
- Enlaces a ADRs relacionados
|
|
25
|
+
|
|
26
|
+
## Decisión
|
|
27
|
+
|
|
28
|
+
La decisión que se tomó. Debe ser específica, no genérica.
|
|
29
|
+
|
|
30
|
+
> Adoptamos Prisma como ORM para la capa de infra, con esquemas separados
|
|
31
|
+
> por schema de base de datos Postgres, mapeando cada feature a un schema.
|
|
32
|
+
|
|
33
|
+
## Consecuencias
|
|
34
|
+
|
|
35
|
+
Lo que cambia a partir de esta decisión:
|
|
36
|
+
|
|
37
|
+
- **Positivas:**
|
|
38
|
+
- Type-safe queries sin runtime validation
|
|
39
|
+
- Migraciones automáticas con `prisma migrate`
|
|
40
|
+
- Schemas por feature como primer paso hacia microservicios
|
|
41
|
+
- **Negativas:**
|
|
42
|
+
- Vendor lock-in con Prisma (cambiar de ORM requiere reescribir repos)
|
|
43
|
+
- Migraciones lentas en bases de datos con millones de registros
|
|
44
|
+
- Dependencia de `prisma generate` como paso de build
|
|
45
|
+
- **Neutrales:**
|
|
46
|
+
- El equipo necesita aprender Prisma (curva de 1-2 semanas)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Variantes
|
|
52
|
+
|
|
53
|
+
### ADR Completo (recomendado para decisiones fundacionales)
|
|
54
|
+
|
|
55
|
+
Incluye Contexto + Decisión + Consecuencias + Alternativas evaluadas.
|
|
56
|
+
|
|
57
|
+
```md
|
|
58
|
+
## Alternativas Consideradas
|
|
59
|
+
|
|
60
|
+
| Alternativa | Pros | Contras | Veredicto |
|
|
61
|
+
|---|---|---|---|
|
|
62
|
+
| TypeORM | Maduro, Decorators | Performance pobre en joins complejos | ❌ |
|
|
63
|
+
| Drizzle | SQL-like, sin decorators | Ecosistema más pequeño | ❌ |
|
|
64
|
+
| Prisma | Type-safe, Migraciones, Schemas | Vendor lock-in, generate step | ✅ |
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### ADR Ligero (para decisiones tácticas)
|
|
68
|
+
|
|
69
|
+
```md
|
|
70
|
+
# 0012 — Usar tRPC para endpoints internos
|
|
71
|
+
|
|
72
|
+
**Estado:** Accepted
|
|
73
|
+
**Fecha:** 2026-05-10
|
|
74
|
+
|
|
75
|
+
**Contexto:** Los endpoints entre features dentro del monolith
|
|
76
|
+
necesitan type-safety sin overhead de serialización REST.
|
|
77
|
+
|
|
78
|
+
**Decisión:** Los endpoints internos en platform/http usarán tRPC.
|
|
79
|
+
Los endpoints públicos siguen siendo REST con OpenAPI.
|
|
80
|
+
|
|
81
|
+
**Consecuencias:** Type-safety extremo entre features pero
|
|
82
|
+
acoplamiento a tRPC en la capa de plataforma.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### ADR de Excepción (para decisiones que violan una regla de Forge)
|
|
86
|
+
|
|
87
|
+
```md
|
|
88
|
+
# 0023 — Ignorar R1 temporalmente en ReportEngine
|
|
89
|
+
|
|
90
|
+
**Estado:** Accepted
|
|
91
|
+
**Fecha:** 2026-06-15
|
|
92
|
+
**Expira:** 2026-09-15
|
|
93
|
+
|
|
94
|
+
**Contexto:** ReportEngine necesita acceso directo a datos de infra
|
|
95
|
+
para generar reportes en tiempo real. Extraer a servicio separado
|
|
96
|
+
requiere 3 sprints.
|
|
97
|
+
|
|
98
|
+
**Decisión:** Se permite `feature/reports → infra/prisma` como
|
|
99
|
+
excepción temporal, documentada en ADR y con `forge-ignore: R1`
|
|
100
|
+
en los imports afectados.
|
|
101
|
+
|
|
102
|
+
**Consecuencias:** Degradación arquitectónica controlada.
|
|
103
|
+
Se revertirá antes de la expiración.
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Estados de un ADR
|
|
109
|
+
|
|
110
|
+
```mermaid
|
|
111
|
+
stateDiagram-v2
|
|
112
|
+
[*] --> Proposed
|
|
113
|
+
Proposed --> Accepted
|
|
114
|
+
Proposed --> Rejected
|
|
115
|
+
Accepted --> Amended
|
|
116
|
+
Accepted --> Superseded
|
|
117
|
+
Accepted --> Deprecated
|
|
118
|
+
Deprecated --> [*]
|
|
119
|
+
Superseded --> [*]
|
|
120
|
+
Amended --> Accepted
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
| Estado | Significado |
|
|
124
|
+
|---|---|
|
|
125
|
+
| **Proposed** | Propuesto, en discusión |
|
|
126
|
+
| **Accepted** | Aprobado e implementado |
|
|
127
|
+
| **Rejected** | Descartado, se preserva para no repetir |
|
|
128
|
+
| **Deprecated** | Ya no se aplica, pero sigue vigente para sistemas existentes |
|
|
129
|
+
| **Superseded** | Reemplazado por otro ADR |
|
|
130
|
+
| **Amended** | Modificado parcialmente, el ADR original + amendment |
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Integración con Forge
|
|
135
|
+
|
|
136
|
+
### ADRs y ARCHITECTURE.md
|
|
137
|
+
|
|
138
|
+
`forge inscribe` debe incluir en ARCHITECTURE.md:
|
|
139
|
+
|
|
140
|
+
```md
|
|
141
|
+
## Architecture Decision Records
|
|
142
|
+
|
|
143
|
+
| ADR | Título | Estado | Fecha |
|
|
144
|
+
|---|---|---|---|
|
|
145
|
+
| 0001 | Adoptar Prisma como ORM | Accepted | 2025-12-01 |
|
|
146
|
+
| 0002 | Schemas separados por feature | Accepted | 2025-12-10 |
|
|
147
|
+
| 0003 | Event Bus asíncrono con RabbitMQ | Proposed | 2026-01-15 |
|
|
148
|
+
| 0004 | Feature Splits de Catalog a Search | Superseded por 0007 | 2026-02-01 |
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### ADRs y `forge assay`
|
|
152
|
+
|
|
153
|
+
El ensayo multi-persona (`assay`) debe considerar ADRs como fuente de información:
|
|
154
|
+
|
|
155
|
+
- **Bezos**: evalúa si la decisión es reversible o irreversible
|
|
156
|
+
- **Fowler**: evalúa la evolución de la decisión en el tiempo
|
|
157
|
+
- **Arquitecta Senior**: evalúa consistencia con el modelo arquitectónico
|
|
158
|
+
|
|
159
|
+
### ADRs y reglas inline ignore
|
|
160
|
+
|
|
161
|
+
Cuando se usa `forge-ignore` para excepcionar una regla, debe referenciar el ADR que la autoriza:
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
// forge-ignore: R1 — ver ADR-0023
|
|
165
|
+
import { PrismaClient } from "../../infra/prisma/client";
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### ADRs y `forge quench`
|
|
169
|
+
|
|
170
|
+
`forge quench` debe verificar que:
|
|
171
|
+
- Los ADRs aceptados tienen su decisión implementada
|
|
172
|
+
- Los ADRs con expiración no han vencido sin renovación
|
|
173
|
+
- No hay `forge-ignore` sin ADR asociado
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Cuándo escribir un ADR
|
|
178
|
+
|
|
179
|
+
| Situación | Ejemplo | ADR necesario |
|
|
180
|
+
|---|---|---|
|
|
181
|
+
| Decisión fundacional | Framework, ORM, BD, message broker | ✅ Obligatorio |
|
|
182
|
+
| Patrón arquitectónico | CQRS, Event Sourcing, Sagas | ✅ Recomendado |
|
|
183
|
+
| Cambio de regla de Forge | Ignorar R8 entre dos features | ✅ Obligatorio |
|
|
184
|
+
| Tecnología nueva | Adoptar Redis, Elasticsearch | ✅ Recomendado |
|
|
185
|
+
| Estándar de equipo | Formato de commits, naming conventions | ✅ Ligero |
|
|
186
|
+
| Excepción temporal | Ignorar R1 por 3 sprints | ✅ Obligatorio |
|
|
187
|
+
| Cambio de provider | Migrar de AWS a GCP | ✅ Obligatorio |
|
|
188
|
+
| Refactor mayor | Extraer Catalog como microservicio | ✅ Obligatorio |
|
|
189
|
+
| Dependencia externa | Adoptar librería X | ⚠️ Si tiene impacto arquitectónico |
|
|
190
|
+
| Bugfix complejo | Cambio en algoritmo de pricing | ❌ |
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Estructura de directorios
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
docs/
|
|
198
|
+
adr/
|
|
199
|
+
0001-adopt-prisma-orm.md
|
|
200
|
+
0002-separate-schemas-per-feature.md
|
|
201
|
+
0003-event-bus-rabbitmq.md
|
|
202
|
+
README.md ← index de ADRs activos
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
El `README.md` se genera automáticamente listando los ADRs activos:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# scripts/forge-adr.mjs (futuro)
|
|
209
|
+
node scripts/forge-adr.mjs list # lista todos los ADRs
|
|
210
|
+
node scripts/forge-adr.mjs new # crea nuevo ADR desde template
|
|
211
|
+
node scripts/forge-adr.mjs status # cambia estado de un ADR
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Anti-patrones
|
|
217
|
+
|
|
218
|
+
| Anti-patrón | Problema | Solución |
|
|
219
|
+
|---|---|---|
|
|
220
|
+
| **ADR sin contexto** | "Usamos Prisma". Sin por qué ni alternativas. | Incluir motivación y alternativas consideradas siempre. |
|
|
221
|
+
| **ADR sin consecuencia** | "Adoptamos Kafka" sin decir el costo operativo. | Documentar consecuencias positivas, negativas y neutrales. |
|
|
222
|
+
| **ADRs que nadie lee** | Se escriben y se archivan. Nadie los consulta. | Integrar en `forge inscribe`. Mencionar en code review cuando aplica. |
|
|
223
|
+
| **ADR sobre tecnología obvia** | "Usamos TypeScript" como ADR. | No todo es ADR. Si no hay trade-off significativo, no es ADR. |
|
|
224
|
+
| **ADR sin fecha** | No se sabe cuándo se tomó ni si sigue vigente. | Fecha obligatoria. Estados para ciclo de vida. |
|
|
225
|
+
| **Demasiados ADRs** | Cada PR tiene un ADR. Se deja de leer. | Solo decisiones con impacto arquitectónico. No para implementación cotidiana. |
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Conexión con Forge
|
|
230
|
+
|
|
231
|
+
| Comando | Acción |
|
|
232
|
+
|---|---|
|
|
233
|
+
| `forge inscribe` | Incluye ADRs activos en ARCHITECTURE.md |
|
|
234
|
+
| `forge assay` | Usa ADRs como insumo para el ensayo multi-persona |
|
|
235
|
+
| `forge quench` | Verifica que ADRs aceptados están implementados |
|
|
236
|
+
| `forge inspect` | Reporta ADRs vencidos o sin implementar |
|
|
237
|
+
| `forge reforge` | Sugiere crear ADR cuando se detecta un cambio arquitectónico |
|
|
238
|
+
|
|
239
|
+
## Ver también
|
|
240
|
+
|
|
241
|
+
- `reference/evolutionary-architecture.md` — fitness functions que los ADRs registran
|
|
242
|
+
- `reference/principles.md` — principios que los ADRs documentan como decisiones
|