refacil-sdd-ai 1.0.0
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 +145 -0
- package/bin/cli.js +207 -0
- package/config/openspec-config.yaml +8 -0
- package/package.json +36 -0
- package/skills/apply/SKILL.md +48 -0
- package/skills/archive/SKILL.md +72 -0
- package/skills/bug/SKILL.md +128 -0
- package/skills/explore/SKILL.md +42 -0
- package/skills/guide/SKILL.md +141 -0
- package/skills/propose/SKILL.md +63 -0
- package/skills/review/SKILL.md +104 -0
- package/skills/review/checklist.md +62 -0
- package/skills/setup/SKILL.md +145 -0
- package/skills/test/SKILL.md +113 -0
- package/skills/test/testing-patterns.md +150 -0
- package/skills/verify/SKILL.md +65 -0
- package/templates/claude-md.md +23 -0
- package/templates/cursorrules.md +21 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Patrones de Testing del Equipo
|
|
2
|
+
|
|
3
|
+
## Estructura de archivos de test
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
archivo.ts → archivo.spec.ts (en la misma carpeta)
|
|
7
|
+
mi-servicio.ts → mi-servicio.spec.ts
|
|
8
|
+
product.mapper.ts → product.mapper.spec.ts
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Patron para servicios NestJS
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { Test, TestingModule } from '@nestjs/testing';
|
|
15
|
+
import { MiServicio } from './mi-servicio';
|
|
16
|
+
|
|
17
|
+
// Mocks declarados fuera del describe
|
|
18
|
+
const mockDependencia = {
|
|
19
|
+
metodo1: jest.fn(),
|
|
20
|
+
metodo2: jest.fn(),
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
describe('MiServicio', () => {
|
|
24
|
+
let service: MiServicio;
|
|
25
|
+
|
|
26
|
+
beforeEach(async () => {
|
|
27
|
+
jest.clearAllMocks();
|
|
28
|
+
|
|
29
|
+
const module: TestingModule = await Test.createTestingModule({
|
|
30
|
+
providers: [
|
|
31
|
+
MiServicio,
|
|
32
|
+
{ provide: 'DEPENDENCIA_PORT', useValue: mockDependencia },
|
|
33
|
+
],
|
|
34
|
+
}).compile();
|
|
35
|
+
|
|
36
|
+
service = module.get<MiServicio>(MiServicio);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('metodoPublico', () => {
|
|
40
|
+
it('should [resultado esperado] when [condicion]', async () => {
|
|
41
|
+
// Arrange
|
|
42
|
+
mockDependencia.metodo1.mockResolvedValue({ /* datos */ });
|
|
43
|
+
|
|
44
|
+
// Act
|
|
45
|
+
const result = await service.metodoPublico(/* params */);
|
|
46
|
+
|
|
47
|
+
// Assert
|
|
48
|
+
expect(result).toEqual(/* esperado */);
|
|
49
|
+
expect(mockDependencia.metodo1).toHaveBeenCalledWith(/* params */);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Patron para funciones utilitarias (puras)
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { miFuncion } from './mi-util';
|
|
59
|
+
|
|
60
|
+
describe('miFuncion', () => {
|
|
61
|
+
it('should [resultado] with valid input', () => {
|
|
62
|
+
expect(miFuncion('input')).toBe('expected');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should handle null input', () => {
|
|
66
|
+
expect(miFuncion(null)).toBeNull();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('should handle edge case [X]', () => {
|
|
70
|
+
expect(miFuncion('')).toBe('default');
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Patron para mappers
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { MiMapper } from './mi.mapper';
|
|
79
|
+
|
|
80
|
+
describe('MiMapper', () => {
|
|
81
|
+
describe('toDomain', () => {
|
|
82
|
+
it('should map ORM entity to domain entity', () => {
|
|
83
|
+
const ormEntity = { id: '123', name: 'test', status: 'ACTIVE' };
|
|
84
|
+
const result = MiMapper.toDomain(ormEntity);
|
|
85
|
+
|
|
86
|
+
expect(result.id).toBe('123');
|
|
87
|
+
expect(result.name).toBe('test');
|
|
88
|
+
expect(result.status).toBe('ACTIVE');
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('toOrm', () => {
|
|
93
|
+
it('should map domain entity to ORM entity', () => {
|
|
94
|
+
// ...
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Patron para mocks de gRPC
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
const mockGrpcClient = {
|
|
104
|
+
getService: jest.fn().mockReturnValue({
|
|
105
|
+
metodoGrpc: jest.fn().mockReturnValue(
|
|
106
|
+
of({ data: 'response' }) // Observable
|
|
107
|
+
),
|
|
108
|
+
}),
|
|
109
|
+
};
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Patron para mocks de BullMQ
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
const mockQueue = {
|
|
116
|
+
add: jest.fn().mockResolvedValue({ id: 'job-1' }),
|
|
117
|
+
getJob: jest.fn(),
|
|
118
|
+
process: jest.fn(),
|
|
119
|
+
};
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Patron para mocks de Logger
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
const mockLogger = {
|
|
126
|
+
log: jest.fn(),
|
|
127
|
+
error: jest.fn(),
|
|
128
|
+
warn: jest.fn(),
|
|
129
|
+
debug: jest.fn(),
|
|
130
|
+
};
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Naming conventions
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
// Formato: should [verbo] [resultado] when [condicion]
|
|
137
|
+
it('should return product request when valid id is provided', () => {});
|
|
138
|
+
it('should throw NotFoundException when product does not exist', () => {});
|
|
139
|
+
it('should update status to SOLD when payment is confirmed', () => {});
|
|
140
|
+
it('should create refund when sale fails after successful topup', () => {});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Anti-patrones a evitar
|
|
144
|
+
|
|
145
|
+
- NO testear propiedades privadas directamente
|
|
146
|
+
- NO testear implementacion interna (orden de llamadas) a menos que sea critico
|
|
147
|
+
- NO crear tests sin assertions (expect)
|
|
148
|
+
- NO crear tests que dependan del orden de ejecucion
|
|
149
|
+
- NO mockear todo — solo los limites del sistema
|
|
150
|
+
- NO crear tests fragiles que se rompen con cambios cosmeticos
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: refacil:verify
|
|
3
|
+
description: Validar que la implementacion cumple con las specs — verifica completitud, correccion y coherencia del cambio
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# refacil:verify — Verificacion de Implementacion
|
|
8
|
+
|
|
9
|
+
Este comando envuelve la funcionalidad de OpenSpec verify y agrega verificacion de tests.
|
|
10
|
+
|
|
11
|
+
## Antes de empezar
|
|
12
|
+
|
|
13
|
+
Si existe `AGENTS.md` en la raiz del proyecto, leelo para entender las convenciones.
|
|
14
|
+
Si NO existe `AGENTS.md`, informa al usuario: "No se encontro AGENTS.md. Ejecuta /refacil:setup para generarlo." y detente.
|
|
15
|
+
|
|
16
|
+
## Instrucciones
|
|
17
|
+
|
|
18
|
+
### Paso 1: Delegar a OpenSpec verify
|
|
19
|
+
|
|
20
|
+
Ejecuta internamente las instrucciones de la skill `openspec-verify-change` que esta instalada en `.claude/skills/openspec-verify-change/SKILL.md` (o `.cursor/skills/openspec-verify-change/SKILL.md`).
|
|
21
|
+
|
|
22
|
+
Lee esa skill y sigue sus instrucciones pasandole el argumento del usuario: **$ARGUMENTS**
|
|
23
|
+
|
|
24
|
+
Esto generara un reporte de verificacion con issues CRITICAL/WARNING/SUGGESTION.
|
|
25
|
+
|
|
26
|
+
### Paso 2: Verificar tests (aporte Refacil)
|
|
27
|
+
|
|
28
|
+
Ademas de la verificacion de OpenSpec, ejecuta `npm test` y verifica:
|
|
29
|
+
- Todos los tests pasan
|
|
30
|
+
- Los tests cubren los criterios de aceptacion de la spec
|
|
31
|
+
- No hay tests faltantes para requisitos clave
|
|
32
|
+
- Si hay un comando de coverage (`npm run test:cov`), ejecutalo y reporta el porcentaje
|
|
33
|
+
|
|
34
|
+
### Paso 3: Reporte combinado (aporte Refacil)
|
|
35
|
+
|
|
36
|
+
Combina el reporte de OpenSpec con la verificacion de tests en un reporte unificado:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
=== Reporte de Verificacion ===
|
|
40
|
+
|
|
41
|
+
--- OpenSpec Verify ---
|
|
42
|
+
[Resultados del reporte de OpenSpec: CRITICAL, WARNING, SUGGESTION]
|
|
43
|
+
|
|
44
|
+
--- Tests (Refacil) ---
|
|
45
|
+
[PASS/FAIL] Tests ejecutados: [N]
|
|
46
|
+
[PASS/FAIL] Tests pasaron: [N]
|
|
47
|
+
[PASS/FAIL] Coverage: [X]% (minimo requerido: 80%)
|
|
48
|
+
|
|
49
|
+
RESULTADO: APROBADO / REQUIERE CORRECCIONES
|
|
50
|
+
|
|
51
|
+
Correcciones necesarias:
|
|
52
|
+
1. [issues de OpenSpec]
|
|
53
|
+
2. [issues de tests]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Paso 4: Siguiente paso
|
|
57
|
+
|
|
58
|
+
- Si APROBADO: "Ejecuta `/refacil:review` para el review con checklist del equipo."
|
|
59
|
+
- Si REQUIERE CORRECCIONES: "Corrige los issues listados y ejecuta `/refacil:verify` de nuevo."
|
|
60
|
+
|
|
61
|
+
## Reglas
|
|
62
|
+
|
|
63
|
+
- NO modificar codigo durante la verificacion
|
|
64
|
+
- Ser estricto con los criterios de la spec
|
|
65
|
+
- Si algo no esta en la spec pero parece necesario, mencionarlo como observacion, no como fallo
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
Las instrucciones completas del proyecto estan en [AGENTS.md](AGENTS.md).
|
|
4
|
+
Si AGENTS.md no existe, ejecuta `/refacil:setup` para generarlo automaticamente.
|
|
5
|
+
|
|
6
|
+
## Metodologia SDD-AI (Refacil)
|
|
7
|
+
|
|
8
|
+
Este proyecto usa la metodologia SDD-AI. Skills disponibles:
|
|
9
|
+
|
|
10
|
+
| Comando | Descripcion |
|
|
11
|
+
|---------|-------------|
|
|
12
|
+
| `/refacil:setup` | Instalar OpenSpec y generar AGENTS.md |
|
|
13
|
+
| `/refacil:guide` | Guia interactiva — que comando usar |
|
|
14
|
+
| `/refacil:explore` | Explorar el codebase sin cambios |
|
|
15
|
+
| `/refacil:propose` | Crear propuesta de cambio |
|
|
16
|
+
| `/refacil:apply` | Implementar tasks del cambio |
|
|
17
|
+
| `/refacil:test` | Generar tests unitarios |
|
|
18
|
+
| `/refacil:verify` | Validar implementacion vs specs |
|
|
19
|
+
| `/refacil:review` | Review con checklist de calidad |
|
|
20
|
+
| `/refacil:archive` | Archivar cambio completado |
|
|
21
|
+
| `/refacil:bug` | Flujo guiado de bugfix |
|
|
22
|
+
|
|
23
|
+
Flujo: `setup` → `propose` → `apply` → `test` → `verify` → `review` → `archive`
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Cursor Rules
|
|
2
|
+
|
|
3
|
+
Las instrucciones completas del proyecto estan en AGENTS.md.
|
|
4
|
+
Si AGENTS.md no existe, ejecuta /refacil:setup para generarlo automaticamente.
|
|
5
|
+
|
|
6
|
+
## Metodologia SDD-AI (Refacil)
|
|
7
|
+
|
|
8
|
+
Skills disponibles en .cursor/skills/refacil-*/:
|
|
9
|
+
|
|
10
|
+
- /refacil:setup — Instalar OpenSpec y generar AGENTS.md
|
|
11
|
+
- /refacil:guide — Guia interactiva
|
|
12
|
+
- /refacil:explore — Explorar codebase
|
|
13
|
+
- /refacil:propose — Crear propuesta de cambio
|
|
14
|
+
- /refacil:apply — Implementar tasks
|
|
15
|
+
- /refacil:test — Generar tests unitarios
|
|
16
|
+
- /refacil:verify — Validar vs specs
|
|
17
|
+
- /refacil:review — Review con checklist
|
|
18
|
+
- /refacil:archive — Archivar cambio
|
|
19
|
+
- /refacil:bug — Flujo guiado de bugfix
|
|
20
|
+
|
|
21
|
+
Flujo: setup → propose → apply → test → verify → review → archive
|