siesa-agents 2.1.52 → 2.1.54
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/bmad/bmm/workflows/3-solutioning/create-architecture/data/company-standards/architecture-patterns.md +8 -3
- package/bmad/bmm/workflows/3-solutioning/create-architecture/data/company-standards/frontend-standards.md +26 -1
- package/bmad/bmm/workflows/3-solutioning/create-architecture/data/company-standards/vite-config-standard.md +535 -0
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +42 -1
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +66 -2
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +15 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/README.md +635 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/data/excel-structure-guide.md +255 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/steps/step-01-init.md +1175 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/steps/step-01b-continue.md +333 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/steps/step-02-build-traceability.md +488 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/steps/step-03-interpret-tests.md +1047 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/steps/step-04-generate-plans.md +937 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/steps/step-05-export.md +261 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/templates/README.md +256 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/templates/epic-test-plan-template.md +215 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/templates/test-cases-reference.csv +11 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/templates/test-cases-structure.md +568 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/templates/test-cases-summary-template.md +74 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/templates/test-cases-template.csv +11 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/templates/traceability-map-template.md +59 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/workflow.md +290 -0
- package/bmad/bmm/workflows/4-implementation/traceability-and-testing/workflow.yaml +138 -0
- package/bmad/bmm/workflows/generate-project-context/steps/step-01-discover.md +2 -1
- package/claude/commands/bmad/bmm/workflows/traceability-and-testing.md +5 -0
- package/gemini/commands/bmad-workflow-bmm-traceability-and-testing.toml +4 -0
- package/package.json +1 -1
|
@@ -131,9 +131,14 @@ Use MCP to install Shadcn components instead of creating manually.
|
|
|
131
131
|
|
|
132
132
|
**Default**: Always use Vite + TanStack Router with TypeScript.
|
|
133
133
|
|
|
134
|
-
**Microfrontends**:
|
|
135
|
-
|
|
136
|
-
**
|
|
134
|
+
**Microfrontends**:
|
|
135
|
+
- **DEFAULT**: Vite + Single-SPA (`vite-plugin-single-spa` + `single-spa-react`) para todos los módulos de negocio
|
|
136
|
+
- **EXCEPCIÓN**: Vite + Module Federation SOLO para módulos transversales/compartidos explícitamente marcados por el ingeniero
|
|
137
|
+
|
|
138
|
+
**Reasoning**:
|
|
139
|
+
- Single-SPA proporciona aislamiento completo (CSS, JS, lifecycle), mejor hot reload, y error boundaries built-in
|
|
140
|
+
- Module Federation solo se usa cuando hay necesidad explícita de compartir código entre MFEs
|
|
141
|
+
- Ver `vite-config-standard.md` para configuración detallada
|
|
137
142
|
|
|
138
143
|
## Backend Architecture
|
|
139
144
|
|
|
@@ -92,7 +92,32 @@ Este documento define los estándares de desarrollo frontend para aplicaciones e
|
|
|
92
92
|
| Escenario | Framework | Razón |
|
|
93
93
|
|-----------|-----------|-------|
|
|
94
94
|
| **Default** | Vite + TanStack Router | Mejor DX, type-safety, preparado para microfrontends |
|
|
95
|
-
| **
|
|
95
|
+
| **MFE (Default)** | Vite + Single-SPA | Aislamiento completo, CSS lifecycle, error boundaries built-in |
|
|
96
|
+
| **Módulo Federable** | Vite + Module Federation | SOLO para módulos transversales explícitamente marcados |
|
|
97
|
+
|
|
98
|
+
### 2.3 Regla Crítica: Single-SPA vs Module Federation
|
|
99
|
+
|
|
100
|
+
> ⚠️ **IMPORTANTE**: Por defecto, todos los microfrontends usan **Single-SPA**. Module Federation se usa **SOLO** cuando el ingeniero define explícitamente que un módulo debe ser compartido/federable.
|
|
101
|
+
|
|
102
|
+
| Tipo | Tecnología | Uso |
|
|
103
|
+
|------|------------|-----|
|
|
104
|
+
| **MFE de Negocio** | `vite-plugin-single-spa` + `single-spa-react` | ✅ DEFAULT - finance, hr, inventory, etc. |
|
|
105
|
+
| **Módulo Compartido** | `@module-federation/vite` | ⚠️ SOLO cuando explícitamente requerido |
|
|
106
|
+
|
|
107
|
+
**Dependencias Single-SPA (DEFAULT):**
|
|
108
|
+
```bash
|
|
109
|
+
npm install single-spa-react
|
|
110
|
+
npm install vite-plugin-single-spa --save-dev
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Beneficios de Single-SPA:**
|
|
114
|
+
- CSS isolation automático via `cssLifecycleFactory`
|
|
115
|
+
- Error boundaries built-in
|
|
116
|
+
- Lifecycle completo (bootstrap, mount, unmount)
|
|
117
|
+
- Mejor hot reload
|
|
118
|
+
- Menor complejidad de configuración
|
|
119
|
+
|
|
120
|
+
Ver `vite-config-standard.md` para configuración detallada.
|
|
96
121
|
|
|
97
122
|
### 2.3 Herramientas de Desarrollo
|
|
98
123
|
|
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
# Vite Config - Estándar Microfrontends
|
|
2
|
+
|
|
3
|
+
Guía de configuración estándar para microfrontends usando Single-SPA (default) y Module Federation (solo módulos compartidos).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## REGLA CRÍTICA: Single-SPA vs Module Federation
|
|
8
|
+
|
|
9
|
+
| Tipo de Módulo | Tecnología | Cuándo Usar |
|
|
10
|
+
|----------------|------------|-------------|
|
|
11
|
+
| **MFE Estándar** | **Single-SPA** | ✅ DEFAULT - Todos los módulos de negocio (finance, hr, inventory, etc.) |
|
|
12
|
+
| **Módulo Transversal** | **Module Federation** | ⚠️ SOLO cuando el ingeniero define explícitamente que debe ser compartido |
|
|
13
|
+
|
|
14
|
+
### ¿Cuándo usar Module Federation?
|
|
15
|
+
|
|
16
|
+
Module Federation **SOLO** se usa para módulos que:
|
|
17
|
+
1. Son **transversales** (usados por múltiples MFEs)
|
|
18
|
+
2. El ingeniero los marca **explícitamente** como "federable"
|
|
19
|
+
3. Ejemplos: Componentes compartidos, utilidades comunes, design system
|
|
20
|
+
|
|
21
|
+
### ¿Cuándo usar Single-SPA?
|
|
22
|
+
|
|
23
|
+
Single-SPA es el **DEFAULT** para:
|
|
24
|
+
1. Todos los módulos de negocio (finance, hr, inventory, sales, etc.)
|
|
25
|
+
2. Cualquier MFE que no sea explícitamente marcado como federable
|
|
26
|
+
3. Widgets independientes
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Dependencias Requeridas
|
|
31
|
+
|
|
32
|
+
### Para MFE Single-SPA (DEFAULT)
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Core Single-SPA
|
|
36
|
+
npm install single-spa-react
|
|
37
|
+
|
|
38
|
+
# Vite Plugin (configura automáticamente entry points, externals, CSS)
|
|
39
|
+
npm install vite-plugin-single-spa --save-dev
|
|
40
|
+
|
|
41
|
+
# React (obligatorio)
|
|
42
|
+
npm install react react-dom
|
|
43
|
+
npm install @types/react @types/react-dom --save-dev
|
|
44
|
+
|
|
45
|
+
# Común
|
|
46
|
+
npm install @vitejs/plugin-react --save-dev
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Para Módulo Federable (SOLO si explícitamente requerido)
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Module Federation
|
|
53
|
+
npm install @module-federation/vite --save-dev
|
|
54
|
+
|
|
55
|
+
# TanStack Router (si aplica)
|
|
56
|
+
npm install @tanstack/react-router
|
|
57
|
+
|
|
58
|
+
# Común
|
|
59
|
+
npm install @vitejs/plugin-react --save-dev
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 1. Single-SPA (DEFAULT para todos los MFEs)
|
|
65
|
+
|
|
66
|
+
### 1.1 Configuración Vite (vite.config.ts)
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// modules/{module-name}/vite.config.ts
|
|
70
|
+
import { defineConfig } from 'vite';
|
|
71
|
+
import react from '@vitejs/plugin-react';
|
|
72
|
+
import vitePluginSingleSpa from 'vite-plugin-single-spa';
|
|
73
|
+
|
|
74
|
+
export default defineConfig({
|
|
75
|
+
plugins: [
|
|
76
|
+
react(),
|
|
77
|
+
vitePluginSingleSpa({
|
|
78
|
+
serverPort: 3001, // Puerto único por módulo
|
|
79
|
+
spaEntryPoints: 'src/spa.tsx', // Entry point Single-SPA
|
|
80
|
+
cssStrategy: 'singleMife', // CSS se inyecta/remueve en mount/unmount
|
|
81
|
+
projectId: '{module-name}-module', // ID único del proyecto
|
|
82
|
+
}),
|
|
83
|
+
],
|
|
84
|
+
server: {
|
|
85
|
+
port: 3001,
|
|
86
|
+
cors: true,
|
|
87
|
+
},
|
|
88
|
+
base: '/{module-name}/', // Prefijo de rutas
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 1.2 Entry Point Single-SPA (src/spa.tsx)
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// modules/{module-name}/src/spa.tsx
|
|
96
|
+
import React from 'react';
|
|
97
|
+
import ReactDOMClient from 'react-dom/client';
|
|
98
|
+
import singleSpaReact from 'single-spa-react';
|
|
99
|
+
import { cssLifecycleFactory } from 'vite-plugin-single-spa/ex';
|
|
100
|
+
import App from './App';
|
|
101
|
+
|
|
102
|
+
// Props que el App Shell puede pasar al MFE
|
|
103
|
+
export interface CustomProps {
|
|
104
|
+
i18n?: unknown;
|
|
105
|
+
eventBus?: unknown;
|
|
106
|
+
authContext?: unknown;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Error boundary para errores en el MFE
|
|
110
|
+
function ErrorFallback({ error }: { error: Error }) {
|
|
111
|
+
return (
|
|
112
|
+
<div className="flex items-center justify-center min-h-screen bg-red-50">
|
|
113
|
+
<div className="max-w-md p-6 bg-white rounded-lg shadow-lg">
|
|
114
|
+
<h2 className="text-xl font-semibold text-red-600 mb-2">
|
|
115
|
+
Error en módulo
|
|
116
|
+
</h2>
|
|
117
|
+
<p className="text-gray-600 mb-4">{error.message}</p>
|
|
118
|
+
<button
|
|
119
|
+
onClick={() => window.location.reload()}
|
|
120
|
+
className="px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700"
|
|
121
|
+
>
|
|
122
|
+
Recargar
|
|
123
|
+
</button>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Crear lifecycles con single-spa-react
|
|
130
|
+
const lifecycles = singleSpaReact({
|
|
131
|
+
React,
|
|
132
|
+
ReactDOMClient,
|
|
133
|
+
rootComponent: App,
|
|
134
|
+
errorBoundary: (err: Error) => <ErrorFallback error={err} />,
|
|
135
|
+
// CRÍTICO: Especificar el contenedor del App Shell donde se montará el MFE
|
|
136
|
+
domElementGetter: () => document.getElementById('single-spa-application')!,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// CSS lifecycle - inyecta CSS al montar, lo remueve al desmontar
|
|
140
|
+
const cssLc = cssLifecycleFactory('spa');
|
|
141
|
+
|
|
142
|
+
// ⚠️ REGLA CRÍTICA: domElementGetter
|
|
143
|
+
// -------------------------------------
|
|
144
|
+
// El App Shell de Siesa provee un contenedor específico donde se montan los MFEs:
|
|
145
|
+
// <div id="single-spa-application">
|
|
146
|
+
//
|
|
147
|
+
// Sin domElementGetter:
|
|
148
|
+
// - single-spa-react crea un <div> nuevo al final del <body>
|
|
149
|
+
// - El MFE se renderiza FUERA del layout del App Shell
|
|
150
|
+
// - El usuario NO verá el MFE aunque esté montado correctamente
|
|
151
|
+
//
|
|
152
|
+
// Con domElementGetter:
|
|
153
|
+
// - El MFE se monta dentro del contenedor del App Shell
|
|
154
|
+
// - Se integra correctamente con el layout (navegación, estilos)
|
|
155
|
+
// - El usuario ve el MFE en la ubicación correcta
|
|
156
|
+
//
|
|
157
|
+
// TODOS los MFEs Single-SPA deben incluir esta configuración.
|
|
158
|
+
|
|
159
|
+
// Exportar lifecycles combinados (CSS + React)
|
|
160
|
+
export const bootstrap = [cssLc.bootstrap, lifecycles.bootstrap];
|
|
161
|
+
export const mount = [cssLc.mount, lifecycles.mount];
|
|
162
|
+
export const unmount = [cssLc.unmount, lifecycles.unmount];
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### 1.3 Standalone Development (src/main.tsx)
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
// modules/{module-name}/src/main.tsx
|
|
169
|
+
// Para desarrollo standalone (sin App Shell)
|
|
170
|
+
import React from 'react';
|
|
171
|
+
import ReactDOM from 'react-dom/client';
|
|
172
|
+
import App from './App';
|
|
173
|
+
import './index.css';
|
|
174
|
+
|
|
175
|
+
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
176
|
+
<React.StrictMode>
|
|
177
|
+
<App />
|
|
178
|
+
</React.StrictMode>
|
|
179
|
+
);
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 1.4 App Shell - Registro de MFEs Single-SPA
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// app-shell/src/microfrontends/register.ts
|
|
186
|
+
import { registerApplication, start } from 'single-spa';
|
|
187
|
+
|
|
188
|
+
// Registrar cada MFE
|
|
189
|
+
registerApplication({
|
|
190
|
+
name: 'finance',
|
|
191
|
+
app: () => System.import('http://localhost:3001/finance/spa.js'),
|
|
192
|
+
activeWhen: ['/finance'],
|
|
193
|
+
customProps: {
|
|
194
|
+
i18n: i18nInstance,
|
|
195
|
+
eventBus: eventBus,
|
|
196
|
+
authContext: authStore.getState(),
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
registerApplication({
|
|
201
|
+
name: 'inventory',
|
|
202
|
+
app: () => System.import('http://localhost:3002/inventory/spa.js'),
|
|
203
|
+
activeWhen: ['/inventory'],
|
|
204
|
+
customProps: {
|
|
205
|
+
i18n: i18nInstance,
|
|
206
|
+
eventBus: eventBus,
|
|
207
|
+
authContext: authStore.getState(),
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
registerApplication({
|
|
212
|
+
name: 'hr',
|
|
213
|
+
app: () => System.import('http://localhost:3003/hr/spa.js'),
|
|
214
|
+
activeWhen: ['/hr'],
|
|
215
|
+
customProps: {
|
|
216
|
+
i18n: i18nInstance,
|
|
217
|
+
eventBus: eventBus,
|
|
218
|
+
authContext: authStore.getState(),
|
|
219
|
+
},
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// Iniciar Single-SPA
|
|
223
|
+
start();
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### 1.5 Import Map (index.html del App Shell)
|
|
227
|
+
|
|
228
|
+
```html
|
|
229
|
+
<!-- app-shell/index.html -->
|
|
230
|
+
<script type="systemjs-importmap">
|
|
231
|
+
{
|
|
232
|
+
"imports": {
|
|
233
|
+
"react": "https://cdn.jsdelivr.net/npm/react@18/umd/react.production.min.js",
|
|
234
|
+
"react-dom": "https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.production.min.js",
|
|
235
|
+
"single-spa": "https://cdn.jsdelivr.net/npm/single-spa@6/lib/system/single-spa.min.js"
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
</script>
|
|
239
|
+
<script src="https://cdn.jsdelivr.net/npm/systemjs@6/dist/system.min.js"></script>
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 2. Module Federation (SOLO para módulos transversales explícitos)
|
|
245
|
+
|
|
246
|
+
> ⚠️ **IMPORTANTE**: Solo usar Module Federation cuando el ingeniero defina explícitamente que un módulo debe ser compartido/federable.
|
|
247
|
+
|
|
248
|
+
### 2.1 Exponer un Módulo Federable (Remote)
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
// shared-components/vite.config.ts
|
|
252
|
+
import { defineConfig } from 'vite';
|
|
253
|
+
import react from '@vitejs/plugin-react';
|
|
254
|
+
import { federation } from '@module-federation/vite';
|
|
255
|
+
|
|
256
|
+
export default defineConfig({
|
|
257
|
+
plugins: [
|
|
258
|
+
react(),
|
|
259
|
+
federation({
|
|
260
|
+
name: 'sharedComponents', // Nombre único del módulo federable
|
|
261
|
+
filename: 'remoteEntry.js',
|
|
262
|
+
exposes: {
|
|
263
|
+
'./Button': './src/components/Button.tsx',
|
|
264
|
+
'./Modal': './src/components/Modal.tsx',
|
|
265
|
+
'./DataTable': './src/components/DataTable.tsx',
|
|
266
|
+
},
|
|
267
|
+
shared: {
|
|
268
|
+
react: { singleton: true, requiredVersion: '^18.3.1' },
|
|
269
|
+
'react-dom': { singleton: true, requiredVersion: '^18.3.1' },
|
|
270
|
+
'siesa-ui-kit': { singleton: true },
|
|
271
|
+
},
|
|
272
|
+
}),
|
|
273
|
+
],
|
|
274
|
+
server: {
|
|
275
|
+
port: 3010,
|
|
276
|
+
strictPort: true,
|
|
277
|
+
cors: true,
|
|
278
|
+
},
|
|
279
|
+
build: {
|
|
280
|
+
modulePreload: false,
|
|
281
|
+
target: 'esnext',
|
|
282
|
+
minify: false,
|
|
283
|
+
cssCodeSplit: false,
|
|
284
|
+
},
|
|
285
|
+
});
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### 2.2 Consumir Módulo Federable desde un MFE
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
// modules/finance/vite.config.ts (MFE que consume módulos federables)
|
|
292
|
+
import { defineConfig } from 'vite';
|
|
293
|
+
import react from '@vitejs/plugin-react';
|
|
294
|
+
import vitePluginSingleSpa from 'vite-plugin-single-spa';
|
|
295
|
+
import { federation } from '@module-federation/vite';
|
|
296
|
+
|
|
297
|
+
export default defineConfig({
|
|
298
|
+
plugins: [
|
|
299
|
+
react(),
|
|
300
|
+
vitePluginSingleSpa({
|
|
301
|
+
serverPort: 3001,
|
|
302
|
+
spaEntryPoints: 'src/spa.tsx',
|
|
303
|
+
cssStrategy: 'singleMife',
|
|
304
|
+
projectId: 'finance-module',
|
|
305
|
+
}),
|
|
306
|
+
// Solo agregar federation si necesita consumir módulos compartidos
|
|
307
|
+
federation({
|
|
308
|
+
name: 'finance',
|
|
309
|
+
remotes: {
|
|
310
|
+
sharedComponents: {
|
|
311
|
+
type: 'module',
|
|
312
|
+
name: 'sharedComponents',
|
|
313
|
+
entry: 'http://localhost:3010/remoteEntry.js',
|
|
314
|
+
entryGlobalName: 'sharedComponents',
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
shared: {
|
|
318
|
+
react: { singleton: true, requiredVersion: '^18.3.1' },
|
|
319
|
+
'react-dom': { singleton: true, requiredVersion: '^18.3.1' },
|
|
320
|
+
},
|
|
321
|
+
}),
|
|
322
|
+
],
|
|
323
|
+
server: {
|
|
324
|
+
port: 3001,
|
|
325
|
+
cors: true,
|
|
326
|
+
},
|
|
327
|
+
base: '/finance/',
|
|
328
|
+
});
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### 2.3 Tipos para Módulos Federables
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
// types/remotes.d.ts
|
|
335
|
+
declare module 'sharedComponents/Button' {
|
|
336
|
+
const Button: React.ComponentType<ButtonProps>;
|
|
337
|
+
export default Button;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
declare module 'sharedComponents/Modal' {
|
|
341
|
+
const Modal: React.ComponentType<ModalProps>;
|
|
342
|
+
export default Modal;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
declare module 'sharedComponents/DataTable' {
|
|
346
|
+
const DataTable: React.ComponentType<DataTableProps>;
|
|
347
|
+
export default DataTable;
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## 3. Convención de Puertos
|
|
354
|
+
|
|
355
|
+
| Módulo | Puerto | Tipo | Descripción |
|
|
356
|
+
|--------|--------|------|-------------|
|
|
357
|
+
| app-shell | 3000 | Host | Orquestador Single-SPA |
|
|
358
|
+
| finance | 3001 | Single-SPA | Módulo Finanzas |
|
|
359
|
+
| inventory | 3002 | Single-SPA | Módulo Inventario |
|
|
360
|
+
| hr | 3003 | Single-SPA | Módulo RRHH |
|
|
361
|
+
| crm | 3004 | Single-SPA | Módulo CRM |
|
|
362
|
+
| pos | 3005 | Single-SPA | Módulo POS |
|
|
363
|
+
| shared-components | 3010 | Federation | Componentes compartidos (federable) |
|
|
364
|
+
| shared-utils | 3011 | Federation | Utilidades compartidas (federable) |
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## 4. Routing con TanStack Router
|
|
369
|
+
|
|
370
|
+
### 4.1 Router del MFE (Single-SPA)
|
|
371
|
+
|
|
372
|
+
> ⚠️ **IMPORTANTE:** Todas las rutas deben tener prefijo único que coincida con `base` en vite.config.ts
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
// modules/finance/src/router.tsx
|
|
376
|
+
import {
|
|
377
|
+
createRouter,
|
|
378
|
+
createRootRoute,
|
|
379
|
+
createRoute,
|
|
380
|
+
redirect,
|
|
381
|
+
} from '@tanstack/react-router';
|
|
382
|
+
import { MainLayout } from './components/layout/MainLayout';
|
|
383
|
+
import Dashboard from './routes/dashboard';
|
|
384
|
+
import AccountsIndex from './routes/accounts.index';
|
|
385
|
+
import AccountDetail from './routes/accounts.$id';
|
|
386
|
+
|
|
387
|
+
// Root route con layout
|
|
388
|
+
const rootRoute = createRootRoute({
|
|
389
|
+
component: MainLayout,
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
// Ruta índice - redirige al dashboard
|
|
393
|
+
const indexRoute = createRoute({
|
|
394
|
+
getParentRoute: () => rootRoute,
|
|
395
|
+
path: '/',
|
|
396
|
+
beforeLoad: () => {
|
|
397
|
+
throw redirect({ to: '/finance/dashboard' });
|
|
398
|
+
},
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
// Dashboard
|
|
402
|
+
const dashboardRoute = createRoute({
|
|
403
|
+
getParentRoute: () => rootRoute,
|
|
404
|
+
path: '/finance/dashboard',
|
|
405
|
+
component: Dashboard,
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
// Cuentas - listado
|
|
409
|
+
const accountsRoute = createRoute({
|
|
410
|
+
getParentRoute: () => rootRoute,
|
|
411
|
+
path: '/finance/accounts',
|
|
412
|
+
component: AccountsIndex,
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
// Cuentas - detalle
|
|
416
|
+
const accountDetailRoute = createRoute({
|
|
417
|
+
getParentRoute: () => rootRoute,
|
|
418
|
+
path: '/finance/accounts/$id',
|
|
419
|
+
component: AccountDetail,
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
const routeTree = rootRoute.addChildren([
|
|
423
|
+
indexRoute,
|
|
424
|
+
dashboardRoute,
|
|
425
|
+
accountsRoute,
|
|
426
|
+
accountDetailRoute,
|
|
427
|
+
]);
|
|
428
|
+
|
|
429
|
+
export const router = createRouter({ routeTree });
|
|
430
|
+
|
|
431
|
+
declare module '@tanstack/react-router' {
|
|
432
|
+
interface Register {
|
|
433
|
+
router: typeof router;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### 4.2 Convención de Prefijos de Rutas
|
|
439
|
+
|
|
440
|
+
| Módulo | Puerto | Base (vite.config) | Prefijo Rutas |
|
|
441
|
+
|--------|--------|---------------------|---------------|
|
|
442
|
+
| app-shell | 3000 | `/` | `/` |
|
|
443
|
+
| finance | 3001 | `/finance/` | `/finance/*` |
|
|
444
|
+
| inventory | 3002 | `/inventory/` | `/inventory/*` |
|
|
445
|
+
| hr | 3003 | `/hr/` | `/hr/*` |
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
## 5. Shared Dependencies (para ambos)
|
|
450
|
+
|
|
451
|
+
```typescript
|
|
452
|
+
shared: {
|
|
453
|
+
// SIEMPRE singleton para React
|
|
454
|
+
react: { singleton: true, requiredVersion: '^18.3.1' },
|
|
455
|
+
'react-dom': { singleton: true, requiredVersion: '^18.3.1' },
|
|
456
|
+
|
|
457
|
+
// UI Kit compartido
|
|
458
|
+
'siesa-ui-kit': { singleton: true },
|
|
459
|
+
|
|
460
|
+
// Router y Query
|
|
461
|
+
'@tanstack/react-router': { singleton: true },
|
|
462
|
+
'@tanstack/react-query': { singleton: true },
|
|
463
|
+
|
|
464
|
+
// State management
|
|
465
|
+
'zustand': { singleton: true },
|
|
466
|
+
|
|
467
|
+
// i18n
|
|
468
|
+
'react-i18next': { singleton: true },
|
|
469
|
+
'i18next': { singleton: true },
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
## 6. Checklist de Configuración
|
|
476
|
+
|
|
477
|
+
### MFE Single-SPA (DEFAULT)
|
|
478
|
+
|
|
479
|
+
- [ ] `vite-plugin-single-spa` instalado y configurado
|
|
480
|
+
- [ ] `single-spa-react` instalado
|
|
481
|
+
- [ ] `src/spa.tsx` con lifecycles exportados
|
|
482
|
+
- [ ] `cssLifecycleFactory` configurado para CSS isolation
|
|
483
|
+
- [ ] `errorBoundary` implementado
|
|
484
|
+
- [ ] **`domElementGetter` apuntando a `#single-spa-application`** ⚠️ CRÍTICO
|
|
485
|
+
- [ ] Puerto único configurado
|
|
486
|
+
- [ ] `base` configurado con prefijo (ej: `/finance/`)
|
|
487
|
+
- [ ] Todas las rutas usan el prefijo
|
|
488
|
+
- [ ] `cors: true` en server
|
|
489
|
+
- [ ] `src/main.tsx` para desarrollo standalone
|
|
490
|
+
|
|
491
|
+
### Módulo Federable (SOLO si explícitamente requerido)
|
|
492
|
+
|
|
493
|
+
- [ ] `@module-federation/vite` instalado
|
|
494
|
+
- [ ] `name` único en federation config
|
|
495
|
+
- [ ] `filename: 'remoteEntry.js'`
|
|
496
|
+
- [ ] `exposes` con componentes/utilidades a compartir
|
|
497
|
+
- [ ] `shared` con React y dependencias como singleton
|
|
498
|
+
- [ ] Puerto único (rango 3010+)
|
|
499
|
+
- [ ] `cors: true` en server
|
|
500
|
+
- [ ] `modulePreload: false` en build
|
|
501
|
+
- [ ] `cssCodeSplit: false` en build
|
|
502
|
+
- [ ] Tipos declarados en consumidores
|
|
503
|
+
|
|
504
|
+
### App Shell
|
|
505
|
+
|
|
506
|
+
- [ ] `single-spa` instalado
|
|
507
|
+
- [ ] Import map con React y dependencias compartidas
|
|
508
|
+
- [ ] `registerApplication` para cada MFE
|
|
509
|
+
- [ ] `start()` llamado después de registrar
|
|
510
|
+
- [ ] `customProps` con contexto compartido (i18n, auth, eventBus)
|
|
511
|
+
- [ ] **Contenedor `<div id="single-spa-application">` en el layout** ⚠️ CRÍTICO para MFEs
|
|
512
|
+
|
|
513
|
+
---
|
|
514
|
+
|
|
515
|
+
## 7. Beneficios de Single-SPA como Default
|
|
516
|
+
|
|
517
|
+
| Aspecto | Single-SPA | Module Federation |
|
|
518
|
+
|---------|------------|-------------------|
|
|
519
|
+
| **Aislamiento** | ✅ Completo (CSS, JS, lifecycle) | ⚠️ Parcial |
|
|
520
|
+
| **Hot Reload** | ✅ Funciona bien | ⚠️ Problemas conocidos |
|
|
521
|
+
| **CSS Isolation** | ✅ `cssLifecycleFactory` automático | ⚠️ Manual |
|
|
522
|
+
| **Error Boundaries** | ✅ Built-in | ⚠️ Manual |
|
|
523
|
+
| **Mount/Unmount** | ✅ Lifecycle completo | ⚠️ Solo lazy load |
|
|
524
|
+
| **Complejidad** | ✅ Baja | ⚠️ Alta |
|
|
525
|
+
| **Sharing código** | ⚠️ Via import maps | ✅ Nativo |
|
|
526
|
+
|
|
527
|
+
---
|
|
528
|
+
|
|
529
|
+
## 8. Referencias
|
|
530
|
+
|
|
531
|
+
- [Single-SPA Documentation](https://single-spa.js.org/)
|
|
532
|
+
- [single-spa-react](https://single-spa.js.org/docs/ecosystem-react/)
|
|
533
|
+
- [vite-plugin-single-spa](https://github.com/nickt/vite-plugin-single-spa)
|
|
534
|
+
- [Module Federation](https://module-federation.io/)
|
|
535
|
+
- [Vite Documentation](https://vitejs.dev/)
|
package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md
CHANGED
|
@@ -115,7 +115,32 @@ For each proposed epic:
|
|
|
115
115
|
1. **Epic Title**: User-centric, value-focused
|
|
116
116
|
2. **User Outcome**: What users can accomplish after this epic
|
|
117
117
|
3. **FR Coverage**: Which FR numbers this epic addresses
|
|
118
|
-
4. **
|
|
118
|
+
4. **High-Level Acceptance Criteria (QA Validation)**: 3-5 criteria that QA can use to validate the complete epic
|
|
119
|
+
5. **Implementation Notes**: Any technical or UX considerations
|
|
120
|
+
|
|
121
|
+
**🎯 EPIC ACCEPTANCE CRITERIA GUIDELINES:**
|
|
122
|
+
|
|
123
|
+
The Epic AC are HIGH-LEVEL criteria oriented to QA and end-users, NOT technical criteria:
|
|
124
|
+
|
|
125
|
+
**✅ DO (Correct Examples):**
|
|
126
|
+
- "A new user can complete registration and receive confirmation email"
|
|
127
|
+
- "Users can search for products and see relevant results"
|
|
128
|
+
- "The shopping cart persists across browser sessions"
|
|
129
|
+
- "Users receive notification when their order status changes"
|
|
130
|
+
|
|
131
|
+
**❌ DON'T (Wrong Examples - Too Technical):**
|
|
132
|
+
- "API returns 200 status code with JWT token" (technical)
|
|
133
|
+
- "Database query executes in less than 100ms" (technical)
|
|
134
|
+
- "Redis cache invalidates on entity update" (technical)
|
|
135
|
+
- "WebSocket connection established with heartbeat" (technical)
|
|
136
|
+
|
|
137
|
+
**Writing Rules for Epic AC:**
|
|
138
|
+
- Write from end-user perspective
|
|
139
|
+
- Use business language, not technical jargon
|
|
140
|
+
- Describe complete user flows, not implementation details
|
|
141
|
+
- Make them verifiable by QA without code knowledge
|
|
142
|
+
- Cover both success scenarios and key error scenarios
|
|
143
|
+
- Each AC should map to one or more stories within the epic
|
|
119
144
|
|
|
120
145
|
**Step C: Create the epics_list**
|
|
121
146
|
|
|
@@ -126,10 +151,22 @@ Format the epics_list as:
|
|
|
126
151
|
|
|
127
152
|
### Epic 1: [Epic Title]
|
|
128
153
|
[Epic goal statement - what users can accomplish]
|
|
154
|
+
|
|
155
|
+
#### Acceptance Criteria (QA Validation)
|
|
156
|
+
- [ ] **AC-E1.1:** [High-level criterion from user perspective]
|
|
157
|
+
- [ ] **AC-E1.2:** [High-level criterion from user perspective]
|
|
158
|
+
- [ ] **AC-E1.3:** [High-level criterion from user perspective]
|
|
159
|
+
|
|
129
160
|
**FRs covered:** FR1, FR2, FR3, etc.
|
|
130
161
|
|
|
131
162
|
### Epic 2: [Epic Title]
|
|
132
163
|
[Epic goal statement - what users can accomplish]
|
|
164
|
+
|
|
165
|
+
#### Acceptance Criteria (QA Validation)
|
|
166
|
+
- [ ] **AC-E2.1:** [High-level criterion from user perspective]
|
|
167
|
+
- [ ] **AC-E2.2:** [High-level criterion from user perspective]
|
|
168
|
+
- [ ] **AC-E2.3:** [High-level criterion from user perspective]
|
|
169
|
+
|
|
133
170
|
**FRs covered:** FR4, FR5, FR6, etc.
|
|
134
171
|
|
|
135
172
|
[Continue for all epics]
|
|
@@ -219,6 +256,8 @@ ONLY WHEN C is selected and the approved epics_list is saved to document, will y
|
|
|
219
256
|
- Epics designed around user value
|
|
220
257
|
- All FRs mapped to specific epics
|
|
221
258
|
- epics_list created and formatted correctly
|
|
259
|
+
- **Each epic has 3-5 high-level Acceptance Criteria (QA Validation)**
|
|
260
|
+
- **Epic AC written from end-user perspective, not technical**
|
|
222
261
|
- Requirements coverage map completed
|
|
223
262
|
- User gives explicit approval for epic structure
|
|
224
263
|
- Document updated with approved epics
|
|
@@ -227,6 +266,8 @@ ONLY WHEN C is selected and the approved epics_list is saved to document, will y
|
|
|
227
266
|
|
|
228
267
|
- Epics organized by technical layers
|
|
229
268
|
- Missing FRs in coverage map
|
|
269
|
+
- **Missing or technical Epic Acceptance Criteria**
|
|
270
|
+
- **Epic AC using technical jargon instead of business language**
|
|
230
271
|
- No user approval obtained
|
|
231
272
|
- epics_list not saved to document
|
|
232
273
|
|