@atlashub/smartstack-cli 3.2.0 → 3.3.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/dist/index.js +605 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/agents/ba-reader.md +1 -1
- package/templates/agents/ba-writer.md +8 -1
- package/templates/skills/business-analyse/SKILL.md +21 -23
- package/templates/skills/business-analyse/_architecture.md +123 -0
- package/templates/skills/business-analyse/_elicitation.md +206 -0
- package/templates/skills/business-analyse/_module-loop.md +56 -0
- package/templates/skills/business-analyse/_shared.md +75 -531
- package/templates/skills/business-analyse/_suggestions.md +34 -0
- package/templates/skills/business-analyse/questionnaire/06-security.md +1 -1
- package/templates/skills/business-analyse/questionnaire.md +2 -2
- package/templates/skills/business-analyse/react/components.md +1 -1
- package/templates/skills/business-analyse/react/schema.md +1 -1
- package/templates/skills/business-analyse/references/html-data-mapping.md +294 -0
- package/templates/skills/business-analyse/schemas/feature-schema.json +1 -1
- package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +1 -1
- package/templates/skills/business-analyse/schemas/sections/handoff-schema.json +1 -1
- package/templates/skills/business-analyse/schemas/sections/specification-schema.json +1 -1
- package/templates/skills/business-analyse/steps/step-00-init.md +13 -10
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +2 -0
- package/templates/skills/business-analyse/steps/step-02-decomposition.md +5 -3
- package/templates/skills/business-analyse/steps/{step-03-specify.md → step-03a-specify.md} +16 -606
- package/templates/skills/business-analyse/steps/step-03b-compile.md +670 -0
- package/templates/skills/business-analyse/steps/step-04-consolidation.md +7 -5
- package/templates/skills/business-analyse/steps/step-05a-handoff.md +727 -0
- package/templates/skills/business-analyse/steps/step-05b-deploy.md +479 -0
- package/templates/skills/business-analyse/steps/step-06-extract.md +4 -2
- package/templates/skills/business-analyse/templates/tpl-frd.md +1 -1
- package/templates/skills/business-analyse/templates/tpl-launch-displays.md +161 -0
- package/templates/skills/business-analyse/templates/tpl-progress.md +171 -0
- package/templates/skills/business-analyse/steps/step-05-handoff.md +0 -1682
|
@@ -1,1682 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: step-05-handoff
|
|
3
|
-
description: Development handoff - file mapping, BR-to-code, API endpoints, prd.json, progress tracker
|
|
4
|
-
model: sonnet
|
|
5
|
-
next_step: null
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Step 5: Handoff
|
|
9
|
-
|
|
10
|
-
## MANDATORY EXECUTION RULES
|
|
11
|
-
|
|
12
|
-
- **ALWAYS** verify status = "consolidated" before proceeding
|
|
13
|
-
- **ALWAYS** ask user for implementation strategy preference (multi-module only)
|
|
14
|
-
- **ALWAYS** derive prd.json from feature.json (NEVER independently)
|
|
15
|
-
- **NEVER** invent entities/FRs/BRs not in feature.json
|
|
16
|
-
- **ALL** API routes from specification.apiEndpoints (exact copy)
|
|
17
|
-
- **Permission** paths from specification.permissionMatrix (full format)
|
|
18
|
-
- **ALWAYS** generate 5 CORE SeedData task entries per module
|
|
19
|
-
|
|
20
|
-
## YOUR TASK
|
|
21
|
-
|
|
22
|
-
Generate the development handoff package: file mapping, BR-to-code mapping, API endpoint summary, prd.json, and progress tracker. For multi-module applications, support both per-module and consolidated handoff approaches.
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## EXECUTION SEQUENCE
|
|
27
|
-
|
|
28
|
-
### 1. Verify Consolidation Passed
|
|
29
|
-
|
|
30
|
-
Use ba-reader to locate the feature and verify consolidation status:
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
ba-reader.findFeature({feature_id})
|
|
34
|
-
→ Check status = "consolidated"
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
**IF** status ≠ "consolidated" → **STOP**. Return to step-04-consolidation.md.
|
|
38
|
-
|
|
39
|
-
Display validation summary:
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
✓ Consolidation: APPROVED
|
|
43
|
-
✓ Modules: {count} specified and validated
|
|
44
|
-
✓ Cross-module: interactions mapped
|
|
45
|
-
✓ Permissions: coherent
|
|
46
|
-
→ Proceeding to handoff...
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Include:
|
|
50
|
-
- Number of modules
|
|
51
|
-
- Number of entities across all modules
|
|
52
|
-
- Number of use cases across all modules
|
|
53
|
-
- Number of business rules across all modules
|
|
54
|
-
- Cross-module interaction count
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
### 2. Implementation Strategy Choice (Multi-Module)
|
|
59
|
-
|
|
60
|
-
**IF** more than 1 module defined in feature.json:
|
|
61
|
-
|
|
62
|
-
Ask via AskUserQuestion:
|
|
63
|
-
|
|
64
|
-
```
|
|
65
|
-
question: "Quelle stratégie d'implémentation préférez-vous ?"
|
|
66
|
-
header: "Stratégie d'implémentation"
|
|
67
|
-
options:
|
|
68
|
-
- label: "Module par module (Recommandé)"
|
|
69
|
-
description: "Implémenter chaque module complètement avant de passer au suivant. Suit l'ordre topologique des dépendances."
|
|
70
|
-
- label: "Couche par couche"
|
|
71
|
-
description: "Implémenter toutes les entités, puis tous les services, puis tous les contrôleurs, etc. Plus de parallélisation possible mais plus complexe."
|
|
72
|
-
- label: "Hybride"
|
|
73
|
-
description: "Modules fondation en premier (couche par couche), puis modules dépendants (module par module)"
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Store the chosen strategy in `handoff.implementationStrategy`.
|
|
77
|
-
|
|
78
|
-
**IF** only 1 module → default to "Module par module" (no choice needed).
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
### 3. Calculate Complexity
|
|
83
|
-
|
|
84
|
-
For each module in feature.json.modules[], calculate:
|
|
85
|
-
|
|
86
|
-
```json
|
|
87
|
-
{
|
|
88
|
-
"complexity": "simple|medium|complex",
|
|
89
|
-
"complexityDetails": {
|
|
90
|
-
"entities": {count},
|
|
91
|
-
"useCases": {count},
|
|
92
|
-
"businessRules": {count},
|
|
93
|
-
"calculated": "{level} (≤X entities, ≤Y UCs, ≤Z BRs)"
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
| Criteria | Simple | Medium | Complex |
|
|
99
|
-
|----------|--------|--------|---------|
|
|
100
|
-
| Entities | ≤3 | ≤6 | >6 |
|
|
101
|
-
| Use Cases | ≤5 | ≤12 | >12 |
|
|
102
|
-
| Business Rules | ≤10 | ≤20 | >20 |
|
|
103
|
-
|
|
104
|
-
**Global complexity** = highest complexity across all modules.
|
|
105
|
-
|
|
106
|
-
Example:
|
|
107
|
-
- Module A: 4 entities, 6 use cases, 8 BRs → **simple**
|
|
108
|
-
- Module B: 8 entities, 15 use cases, 25 BRs → **complex**
|
|
109
|
-
- Overall: **complex**
|
|
110
|
-
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
### 4. Map Specification to Files
|
|
114
|
-
|
|
115
|
-
> **IMPORTANT:** Generate `handoff.filesToCreate` as structured object with 7 categories.
|
|
116
|
-
> Each file entry is `{path, type, linkedFRs, linkedUCs, module}`. NO free text.
|
|
117
|
-
> Read `.smartstack/config.json` to extract baseNamespace for project namespace.
|
|
118
|
-
|
|
119
|
-
**Order by topological dependency** (modules with no deps first, then dependents).
|
|
120
|
-
|
|
121
|
-
For **EACH module** in topological order:
|
|
122
|
-
|
|
123
|
-
#### 4.1 Domain Files
|
|
124
|
-
|
|
125
|
-
From `analysis.entities[]` of the module:
|
|
126
|
-
|
|
127
|
-
```json
|
|
128
|
-
"domain": [
|
|
129
|
-
{
|
|
130
|
-
"path": "src/Domain/Entities/{ModuleName}/{EntityName}.cs",
|
|
131
|
-
"type": "Entity",
|
|
132
|
-
"linkedFRs": ["FR-001", "FR-002"],
|
|
133
|
-
"linkedUCs": ["UC-001"],
|
|
134
|
-
"module": "{moduleCode}"
|
|
135
|
-
}
|
|
136
|
-
]
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
Include:
|
|
140
|
-
- Value objects referenced by entities
|
|
141
|
-
- Enums used in domain
|
|
142
|
-
- Domain exceptions specific to module
|
|
143
|
-
|
|
144
|
-
#### 4.2 Application Files
|
|
145
|
-
|
|
146
|
-
From `analysis.useCases[]` of the module:
|
|
147
|
-
|
|
148
|
-
```json
|
|
149
|
-
"application": [
|
|
150
|
-
{
|
|
151
|
-
"path": "src/Application/Services/{ModuleName}/{ServiceName}Service.cs",
|
|
152
|
-
"type": "Service",
|
|
153
|
-
"linkedFRs": ["FR-001"],
|
|
154
|
-
"linkedUCs": ["UC-001", "UC-002"],
|
|
155
|
-
"module": "{moduleCode}"
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
"path": "src/Application/DTOs/{ModuleName}/{DtoName}Dto.cs",
|
|
159
|
-
"type": "Dto",
|
|
160
|
-
"linkedUCs": ["UC-001"],
|
|
161
|
-
"module": "{moduleCode}"
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
"path": "src/Application/Validators/{ModuleName}/{ValidatorName}Validator.cs",
|
|
165
|
-
"type": "Validator",
|
|
166
|
-
"linkedFRs": ["FR-001"],
|
|
167
|
-
"module": "{moduleCode}"
|
|
168
|
-
}
|
|
169
|
-
]
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
Include:
|
|
173
|
-
- Service per use case cluster (or per domain entity if applicable)
|
|
174
|
-
- DTOs for API contracts
|
|
175
|
-
- Validators for FluentValidation
|
|
176
|
-
- Query handlers
|
|
177
|
-
|
|
178
|
-
#### 4.3 Infrastructure Files
|
|
179
|
-
|
|
180
|
-
From `analysis.entities[]` of the module:
|
|
181
|
-
|
|
182
|
-
```json
|
|
183
|
-
"infrastructure": [
|
|
184
|
-
{
|
|
185
|
-
"path": "src/Infrastructure/Repositories/{ModuleName}/{EntityName}Repository.cs",
|
|
186
|
-
"type": "Repository",
|
|
187
|
-
"linkedFRs": ["FR-001"],
|
|
188
|
-
"module": "{moduleCode}"
|
|
189
|
-
},
|
|
190
|
-
{
|
|
191
|
-
"path": "src/Infrastructure/Persistence/{ModuleName}DbContext.cs",
|
|
192
|
-
"type": "DbContext",
|
|
193
|
-
"linkedFRs": ["FR-001", "FR-002"],
|
|
194
|
-
"module": "{moduleCode}"
|
|
195
|
-
}
|
|
196
|
-
]
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
Include:
|
|
200
|
-
- Repository per entity
|
|
201
|
-
- DbContext configuration (if module-specific)
|
|
202
|
-
- Unit of Work pattern if applicable
|
|
203
|
-
- Specifications if complex queries
|
|
204
|
-
|
|
205
|
-
#### 4.4 API Files
|
|
206
|
-
|
|
207
|
-
From `specification.apiEndpoints[]` of the module:
|
|
208
|
-
|
|
209
|
-
```json
|
|
210
|
-
"api": [
|
|
211
|
-
{
|
|
212
|
-
"path": "src/API/Controllers/{ModuleName}Controller.cs",
|
|
213
|
-
"type": "ApiController",
|
|
214
|
-
"linkedUCs": ["UC-001", "UC-002"],
|
|
215
|
-
"linkedFRs": ["FR-001"],
|
|
216
|
-
"module": "{moduleCode}"
|
|
217
|
-
}
|
|
218
|
-
]
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
Include:
|
|
222
|
-
- One controller per domain aggregate root (or logical grouping)
|
|
223
|
-
- Include all HTTP methods (GET, POST, PUT, DELETE, PATCH)
|
|
224
|
-
- Error handling and validation responses
|
|
225
|
-
|
|
226
|
-
#### 4.5 Frontend Files
|
|
227
|
-
|
|
228
|
-
From `specification.uiWireframes[]`, `specification.dashboards[]` and `analysis.useCases[]` of the module:
|
|
229
|
-
|
|
230
|
-
> **WIREFRAME TRACEABILITY RULE:** Every frontend file (Page, DashboardPage, Component) MUST include `linkedWireframes[]` referencing the wireframe `screen` identifiers from `specification.uiWireframes[]`. This ensures the BA mockups validated by the client are respected during implementation.
|
|
231
|
-
|
|
232
|
-
```json
|
|
233
|
-
"frontend": [
|
|
234
|
-
{
|
|
235
|
-
"path": "src/pages/{ModuleName}/{PageName}Page.tsx",
|
|
236
|
-
"type": "Page",
|
|
237
|
-
"linkedUCs": ["UC-001", "UC-002"],
|
|
238
|
-
"linkedWireframes": ["{module}-list"],
|
|
239
|
-
"module": "{moduleCode}",
|
|
240
|
-
"wireframeAcceptanceCriteria": "Layout MUST match wireframe '{module}-list': elements [{elements}], actions [{actions}]. See specification.uiWireframes[] for exact mockup."
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
"path": "src/pages/{ModuleName}/{PageName}DetailPage.tsx",
|
|
244
|
-
"type": "Page",
|
|
245
|
-
"linkedUCs": ["UC-003"],
|
|
246
|
-
"linkedWireframes": ["{module}-detail"],
|
|
247
|
-
"module": "{moduleCode}",
|
|
248
|
-
"wireframeAcceptanceCriteria": "Layout MUST match wireframe '{module}-detail': elements [{elements}], actions [{actions}]. See specification.uiWireframes[] for exact mockup."
|
|
249
|
-
},
|
|
250
|
-
{
|
|
251
|
-
"path": "src/pages/{ModuleName}/{DashboardName}DashboardPage.tsx",
|
|
252
|
-
"type": "DashboardPage",
|
|
253
|
-
"linkedUCs": ["UC-060"],
|
|
254
|
-
"linkedWireframes": ["{module}-dashboard"],
|
|
255
|
-
"module": "{moduleCode}",
|
|
256
|
-
"dashboardRef": "{module}-dashboard",
|
|
257
|
-
"instructions": "Use Recharts library. See specification.dashboards[] for KPI definitions, chart types, filters, and data sources.",
|
|
258
|
-
"wireframeAcceptanceCriteria": "Layout MUST match wireframe '{module}-dashboard': KPI card positions, chart placement, filter bar location. See specification.uiWireframes[] AND specification.dashboards[] for exact mockup and KPI specs."
|
|
259
|
-
},
|
|
260
|
-
{
|
|
261
|
-
"path": "src/components/{ModuleName}/{ComponentName}.tsx",
|
|
262
|
-
"type": "Component",
|
|
263
|
-
"linkedUCs": ["UC-001"],
|
|
264
|
-
"linkedWireframes": ["{module}-{section}"],
|
|
265
|
-
"module": "{moduleCode}"
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
"path": "src/hooks/use{ModuleName}{Hook}.ts",
|
|
269
|
-
"type": "Hook",
|
|
270
|
-
"linkedUCs": ["UC-001", "UC-002"],
|
|
271
|
-
"module": "{moduleCode}"
|
|
272
|
-
}
|
|
273
|
-
]
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
**Wireframe Acceptance Criteria (ALL frontend pages):**
|
|
277
|
-
> **MANDATORY** for every Page and DashboardPage task. These criteria ensure the BA mockups are respected.
|
|
278
|
-
- Layout structure matches the validated ASCII/SVG wireframe from `specification.uiWireframes[]`
|
|
279
|
-
- All `elements` listed in the wireframe are present in the generated component
|
|
280
|
-
- All `actions` listed in the wireframe are implemented with correct permissions
|
|
281
|
-
- Component mapping follows the wireframe-to-component table (see step-03 section 3b-bis)
|
|
282
|
-
- If wireframe shows a DataGrid → implement with `SmartTable` or `EntityCard` grid
|
|
283
|
-
- If wireframe shows FilterBar → implement with `SmartFilter`
|
|
284
|
-
- If wireframe shows ActionButton → wrap in `RequirePermission`
|
|
285
|
-
|
|
286
|
-
**Dashboard pages (type: DashboardPage):**
|
|
287
|
-
- Generated from `specification.dashboards[]` entries
|
|
288
|
-
- `dashboardRef` links to the dashboard code in specification.dashboards[]
|
|
289
|
-
- `linkedWireframes` links to the dashboard wireframe in specification.uiWireframes[]
|
|
290
|
-
- `instructions` MUST reference chart types, KPI definitions, and data sources
|
|
291
|
-
- Acceptance criteria for DashboardPage tasks MUST include:
|
|
292
|
-
- Chart library (Recharts) installed in package.json
|
|
293
|
-
- Chart types matching specification.dashboards[].kpis[].visualization
|
|
294
|
-
- KPI cards for kpi-card type visualizations
|
|
295
|
-
- Filters functional (dateRange, select, etc.)
|
|
296
|
-
- CSS variables used (no hardcoded colors) - see ui-components/patterns/dashboard-chart.md
|
|
297
|
-
- Responsive layout (1-col mobile, 2-col tablet, 3-col desktop)
|
|
298
|
-
- **KPI card positions match wireframe layout** (e.g., 4 cards in a row if wireframe shows 4)
|
|
299
|
-
- **Chart placement matches wireframe** (e.g., 2-column grid if wireframe shows side-by-side)
|
|
300
|
-
|
|
301
|
-
**Standard pages (type: Page):**
|
|
302
|
-
- Pages for major use cases
|
|
303
|
-
- Components for reusable UI elements
|
|
304
|
-
- Custom hooks for business logic
|
|
305
|
-
- Forms for data entry
|
|
306
|
-
- List/Detail views
|
|
307
|
-
- **ALL pages MUST reference their wireframe via `linkedWireframes`**
|
|
308
|
-
|
|
309
|
-
#### 4.6 SeedData Files
|
|
310
|
-
|
|
311
|
-
**OBLIGATORY:** 5 CORE SeedData entries per module + business seed data:
|
|
312
|
-
|
|
313
|
-
```json
|
|
314
|
-
"seedData": [
|
|
315
|
-
{
|
|
316
|
-
"path": "src/Infrastructure/Persistence/Seeding/Data/{ModuleName}/NavigationModuleSeedData.cs",
|
|
317
|
-
"type": "SeedData",
|
|
318
|
-
"category": "core",
|
|
319
|
-
"source": "specification.seedDataCore.navigationModules",
|
|
320
|
-
"module": "{moduleCode}"
|
|
321
|
-
},
|
|
322
|
-
{
|
|
323
|
-
"path": "src/Infrastructure/Persistence/Seeding/Data/{ModuleName}/PermissionsSeedData.cs",
|
|
324
|
-
"type": "SeedData",
|
|
325
|
-
"category": "core",
|
|
326
|
-
"source": "specification.seedDataCore.permissions",
|
|
327
|
-
"module": "{moduleCode}"
|
|
328
|
-
},
|
|
329
|
-
{
|
|
330
|
-
"path": "src/Infrastructure/Persistence/Seeding/Data/{ModuleName}/RolesSeedData.cs",
|
|
331
|
-
"type": "SeedData",
|
|
332
|
-
"category": "core",
|
|
333
|
-
"source": "specification.seedDataCore.roles",
|
|
334
|
-
"module": "{moduleCode}"
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
"path": "src/Infrastructure/Persistence/Seeding/Data/{ModuleName}/TenantSeedData.cs",
|
|
338
|
-
"type": "SeedData",
|
|
339
|
-
"category": "core",
|
|
340
|
-
"source": "specification.seedDataCore.tenants",
|
|
341
|
-
"module": "{moduleCode}"
|
|
342
|
-
},
|
|
343
|
-
{
|
|
344
|
-
"path": "src/Infrastructure/Persistence/Seeding/Data/{ModuleName}/UserSeedData.cs",
|
|
345
|
-
"type": "SeedData",
|
|
346
|
-
"category": "core",
|
|
347
|
-
"source": "specification.seedDataCore.users",
|
|
348
|
-
"module": "{moduleCode}"
|
|
349
|
-
},
|
|
350
|
-
{
|
|
351
|
-
"path": "src/Infrastructure/Persistence/Seeding/Data/{ModuleName}/{Entity}SeedData.cs",
|
|
352
|
-
"type": "SeedData",
|
|
353
|
-
"category": "business",
|
|
354
|
-
"source": "specification.seedDataBusiness.{module}",
|
|
355
|
-
"module": "{moduleCode}"
|
|
356
|
-
}
|
|
357
|
-
]
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
**For client projects (ExtensionsDbContext), add these MANDATORY infrastructure files:**
|
|
361
|
-
|
|
362
|
-
```json
|
|
363
|
-
"seedData": [
|
|
364
|
-
// ... 5 core + business entries above ...
|
|
365
|
-
{
|
|
366
|
-
"path": "src/Infrastructure/Persistence/Seeding/{AppPascalName}SeedDataProvider.cs",
|
|
367
|
-
"type": "IClientSeedDataProvider",
|
|
368
|
-
"category": "infrastructure",
|
|
369
|
-
"description": "Runtime provider that injects core seed data (navigation, permissions, roles) into Core schema",
|
|
370
|
-
"source": "specification.seedDataCore",
|
|
371
|
-
"module": "{moduleCode}"
|
|
372
|
-
},
|
|
373
|
-
{
|
|
374
|
-
"path": "src/Infrastructure/Persistence/Seeding/DevDataSeeder.cs",
|
|
375
|
-
"type": "DevDataSeeder",
|
|
376
|
-
"category": "infrastructure",
|
|
377
|
-
"description": "Seeds development/demo data for domain entities at startup",
|
|
378
|
-
"module": "{moduleCode}"
|
|
379
|
-
},
|
|
380
|
-
{
|
|
381
|
-
"path": "src/Infrastructure/Persistence/Seeding/Data/SeedConstants.cs",
|
|
382
|
-
"type": "SeedConstants",
|
|
383
|
-
"category": "infrastructure",
|
|
384
|
-
"description": "Shared constants for deterministic seed data",
|
|
385
|
-
"module": "{moduleCode}"
|
|
386
|
-
}
|
|
387
|
-
]
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
**Path convention:** All seed data files MUST be under `Persistence/Seeding/Data/` (matching SmartStack.app architecture).
|
|
391
|
-
NEVER use `Data/SeedData/` or `Infrastructure/Data/SeedData/`.
|
|
392
|
-
|
|
393
|
-
**IClientSeedDataProvider (MANDATORY for client projects):** This provider injects core seed data
|
|
394
|
-
(navigation, permissions, roles) into the Core schema at runtime. Generated at
|
|
395
|
-
`src/Infrastructure/Persistence/Seeding/{AppPascalName}SeedDataProvider.cs`.
|
|
396
|
-
See `/application` skill step-03b-provider for the full pattern.
|
|
397
|
-
Without this provider, the 5 core SeedData files are DEAD CODE and will have no effect.
|
|
398
|
-
|
|
399
|
-
Core categories (ALWAYS 5):
|
|
400
|
-
1. NavigationModuleSeedData (navigation items for module)
|
|
401
|
-
2. PermissionsSeedData (RBAC permissions)
|
|
402
|
-
3. RolesSeedData (roles using permissions)
|
|
403
|
-
4. TenantSeedData (test tenants)
|
|
404
|
-
5. UserSeedData (test users)
|
|
405
|
-
|
|
406
|
-
Business categories (from specification.seedDataBusiness):
|
|
407
|
-
- Domain-specific reference data
|
|
408
|
-
- Test data fixtures
|
|
409
|
-
- Lookup tables (statuses, categories, etc.)
|
|
410
|
-
|
|
411
|
-
#### 4.7 Test Files
|
|
412
|
-
|
|
413
|
-
```json
|
|
414
|
-
"tests": [
|
|
415
|
-
{
|
|
416
|
-
"path": "src/Tests/Unit/Domain/{ModuleName}/{Entity}Tests.cs",
|
|
417
|
-
"type": "UnitTests",
|
|
418
|
-
"linkedFRs": ["FR-001"],
|
|
419
|
-
"module": "{moduleCode}"
|
|
420
|
-
},
|
|
421
|
-
{
|
|
422
|
-
"path": "src/Tests/Unit/Application/{ModuleName}/{ServiceName}ServiceTests.cs",
|
|
423
|
-
"type": "UnitTests",
|
|
424
|
-
"linkedFRs": ["FR-001"],
|
|
425
|
-
"linkedUCs": ["UC-001"],
|
|
426
|
-
"module": "{moduleCode}"
|
|
427
|
-
},
|
|
428
|
-
{
|
|
429
|
-
"path": "src/Tests/Integration/{ModuleName}/{ApiControllerName}ControllerTests.cs",
|
|
430
|
-
"type": "IntegrationTests",
|
|
431
|
-
"linkedUCs": ["UC-001"],
|
|
432
|
-
"module": "{moduleCode}"
|
|
433
|
-
},
|
|
434
|
-
{
|
|
435
|
-
"path": "src/Tests/Security/{ModuleName}/{ModuleName}SecurityTests.cs",
|
|
436
|
-
"type": "SecurityTests",
|
|
437
|
-
"linkedFRs": ["FR-001"],
|
|
438
|
-
"module": "{moduleCode}"
|
|
439
|
-
}
|
|
440
|
-
]
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
Test files:
|
|
444
|
-
- Unit tests for domain entities and value objects
|
|
445
|
-
- Unit tests for services and validators
|
|
446
|
-
- Integration tests for API endpoints
|
|
447
|
-
- Security tests for authorization and tenant isolation
|
|
448
|
-
- E2E tests for critical user flows
|
|
449
|
-
|
|
450
|
-
---
|
|
451
|
-
|
|
452
|
-
### 5. Map Business Rules to Code
|
|
453
|
-
|
|
454
|
-
Derive from `analysis.businessRules[]` of **EACH module**.
|
|
455
|
-
|
|
456
|
-
Generate complete mapping for each BR:
|
|
457
|
-
|
|
458
|
-
```json
|
|
459
|
-
{
|
|
460
|
-
"brToCodeMapping": [
|
|
461
|
-
{
|
|
462
|
-
"ruleId": "BR-VAL-001",
|
|
463
|
-
"title": "Order total must equal sum of item prices",
|
|
464
|
-
"module": "{moduleCode}",
|
|
465
|
-
"severity": "critical",
|
|
466
|
-
"implementationPoints": [
|
|
467
|
-
{
|
|
468
|
-
"layer": "Domain",
|
|
469
|
-
"component": "Order.cs",
|
|
470
|
-
"method": "CalculateTotal()",
|
|
471
|
-
"implementation": "Validate sum equals sum of OrderItems.Price"
|
|
472
|
-
},
|
|
473
|
-
{
|
|
474
|
-
"layer": "Application",
|
|
475
|
-
"component": "CreateOrderService.cs",
|
|
476
|
-
"method": "Handle()",
|
|
477
|
-
"implementation": "Calculate total before persisting"
|
|
478
|
-
},
|
|
479
|
-
{
|
|
480
|
-
"layer": "API",
|
|
481
|
-
"component": "OrdersController.cs",
|
|
482
|
-
"method": "CreateOrder()",
|
|
483
|
-
"implementation": "Return validation error if total mismatch"
|
|
484
|
-
},
|
|
485
|
-
{
|
|
486
|
-
"layer": "Frontend",
|
|
487
|
-
"component": "OrderForm.tsx",
|
|
488
|
-
"method": "calculateTotal()",
|
|
489
|
-
"implementation": "Real-time calculation on item change"
|
|
490
|
-
}
|
|
491
|
-
]
|
|
492
|
-
},
|
|
493
|
-
{
|
|
494
|
-
"ruleId": "BR-SEC-002",
|
|
495
|
-
"title": "User can only view orders from their tenant",
|
|
496
|
-
"module": "{moduleCode}",
|
|
497
|
-
"severity": "critical",
|
|
498
|
-
"implementationPoints": [
|
|
499
|
-
{
|
|
500
|
-
"layer": "Domain",
|
|
501
|
-
"component": "Order.cs",
|
|
502
|
-
"method": "Validate()",
|
|
503
|
-
"implementation": "Check TenantId matches user context"
|
|
504
|
-
},
|
|
505
|
-
{
|
|
506
|
-
"layer": "Infrastructure",
|
|
507
|
-
"component": "OrderRepository.cs",
|
|
508
|
-
"method": "GetUserOrders()",
|
|
509
|
-
"implementation": "Filter by TenantId in WHERE clause"
|
|
510
|
-
},
|
|
511
|
-
{
|
|
512
|
-
"layer": "API",
|
|
513
|
-
"component": "OrdersController.cs",
|
|
514
|
-
"method": "GetOrders()",
|
|
515
|
-
"implementation": "Enforce permission check + tenant filter"
|
|
516
|
-
}
|
|
517
|
-
]
|
|
518
|
-
}
|
|
519
|
-
]
|
|
520
|
-
}
|
|
521
|
-
```
|
|
522
|
-
|
|
523
|
-
For each BR include:
|
|
524
|
-
- **ruleId**: Reference to analysis.businessRules[].id
|
|
525
|
-
- **title**: The rule statement
|
|
526
|
-
- **module**: Which module it belongs to
|
|
527
|
-
- **severity**: "critical", "high", "medium", "low"
|
|
528
|
-
- **implementationPoints**: Array of {layer, component, method, implementation}
|
|
529
|
-
|
|
530
|
-
Layers: Domain, Application, Infrastructure, API, Frontend
|
|
531
|
-
|
|
532
|
-
---
|
|
533
|
-
|
|
534
|
-
### 6. API Endpoint Summary
|
|
535
|
-
|
|
536
|
-
> **ABSOLUTE RULE:** Copy **EXACTLY** from `specification.apiEndpoints[]`. **NEVER** reinvent routes.
|
|
537
|
-
|
|
538
|
-
Generate summary with full details:
|
|
539
|
-
|
|
540
|
-
```json
|
|
541
|
-
{
|
|
542
|
-
"apiEndpointSummary": [
|
|
543
|
-
{
|
|
544
|
-
"operation": "ListOrders",
|
|
545
|
-
"method": "GET",
|
|
546
|
-
"route": "/api/business/orders",
|
|
547
|
-
"linkedUC": "UC-001",
|
|
548
|
-
"linkedFR": "FR-001",
|
|
549
|
-
"permissions": ["business.orders.read"],
|
|
550
|
-
"requestSchema": { "type": "query", "params": ["pageNumber", "pageSize", "status"] },
|
|
551
|
-
"responseSchema": { "type": "PaginatedOrderDto[]" },
|
|
552
|
-
"errorCodes": [401, 403, 400, 500],
|
|
553
|
-
"module": "{moduleCode}"
|
|
554
|
-
},
|
|
555
|
-
{
|
|
556
|
-
"operation": "CreateOrder",
|
|
557
|
-
"method": "POST",
|
|
558
|
-
"route": "/api/business/orders",
|
|
559
|
-
"linkedUC": "UC-002",
|
|
560
|
-
"linkedFR": "FR-002",
|
|
561
|
-
"permissions": ["business.orders.create"],
|
|
562
|
-
"requestSchema": { "type": "body", "schema": "CreateOrderDto" },
|
|
563
|
-
"responseSchema": { "type": "OrderDto" },
|
|
564
|
-
"errorCodes": [400, 401, 403, 422, 500],
|
|
565
|
-
"module": "{moduleCode}"
|
|
566
|
-
}
|
|
567
|
-
]
|
|
568
|
-
}
|
|
569
|
-
```
|
|
570
|
-
|
|
571
|
-
For each endpoint:
|
|
572
|
-
- **operation**: Use case name or operation name
|
|
573
|
-
- **method**: HTTP method (GET, POST, PUT, DELETE, PATCH)
|
|
574
|
-
- **route**: Full API path from specification
|
|
575
|
-
- **linkedUC**: Use case ID(s) this endpoint implements
|
|
576
|
-
- **linkedFR**: Feature requirement ID(s)
|
|
577
|
-
- **permissions**: Array of exact permission paths
|
|
578
|
-
- **requestSchema**: Input contract (query params or body)
|
|
579
|
-
- **responseSchema**: Output contract
|
|
580
|
-
- **errorCodes**: Expected HTTP error codes
|
|
581
|
-
- **module**: Which module
|
|
582
|
-
|
|
583
|
-
Total endpoints = count of specification.apiEndpoints[] across all modules.
|
|
584
|
-
|
|
585
|
-
---
|
|
586
|
-
|
|
587
|
-
### 7. Generate prd.json (PROGRAMMATIC)
|
|
588
|
-
|
|
589
|
-
> **RULE:** prd.json is extracted by CLI code, **NEVER** generated by LLM.
|
|
590
|
-
> The `ss derive-prd` command performs a deterministic data transformation from feature.json.
|
|
591
|
-
|
|
592
|
-
**For each module:**
|
|
593
|
-
|
|
594
|
-
```
|
|
595
|
-
Execute: ss derive-prd --feature {moduleFeaturePath} --output .ralph/prd-{moduleCode}.json
|
|
596
|
-
```
|
|
597
|
-
|
|
598
|
-
**For consolidated view (multi-module, optional):**
|
|
599
|
-
|
|
600
|
-
```
|
|
601
|
-
Execute: ss derive-prd --application {masterFeaturePath}
|
|
602
|
-
→ Generates .ralph/prd-{moduleCode}.json for each module
|
|
603
|
-
```
|
|
604
|
-
|
|
605
|
-
**Verification:** After execution, read the generated prd.json and display summary:
|
|
606
|
-
|
|
607
|
-
```
|
|
608
|
-
prd.json generated for module {moduleCode}:
|
|
609
|
-
- Use cases: {count}
|
|
610
|
-
- Functional requirements: {count}
|
|
611
|
-
- Business rules: {count}
|
|
612
|
-
- API endpoints: {count}
|
|
613
|
-
- Sections: {count}
|
|
614
|
-
- Files to create: {count}
|
|
615
|
-
- BR-to-code mappings: {count}
|
|
616
|
-
```
|
|
617
|
-
|
|
618
|
-
**Key guarantees:**
|
|
619
|
-
- Source MUST reference feature.json path (traceability)
|
|
620
|
-
- All data is EXACT COPY from feature.json (no transformation, no invention)
|
|
621
|
-
- prd.json version: "2.0.0"
|
|
622
|
-
- source.type: "ba-handoff-programmatic"
|
|
623
|
-
|
|
624
|
-
---
|
|
625
|
-
|
|
626
|
-
### 8. Initialize Progress Tracker
|
|
627
|
-
|
|
628
|
-
Generate `.ralph/progress.txt` as main task tracker:
|
|
629
|
-
|
|
630
|
-
```
|
|
631
|
-
═════════════════════════════════════════════════════════════════
|
|
632
|
-
SMARTSTACK RALPH LOOP - PROGRESS TRACKER
|
|
633
|
-
Project: {project_name} | Application: {app_name}
|
|
634
|
-
Modules: {count} ({moduleOrder.join(', ')})
|
|
635
|
-
Strategy: {implementation_strategy}
|
|
636
|
-
Created: {timestamp}
|
|
637
|
-
Status: HANDED-OFF
|
|
638
|
-
═════════════════════════════════════════════════════════════════
|
|
639
|
-
|
|
640
|
-
{For each module in topological order:}
|
|
641
|
-
[MODULE: {module_name}] ({complexity})
|
|
642
|
-
Status: NOT STARTED
|
|
643
|
-
Dependencies: {list of module dependencies or "FOUNDATION"}
|
|
644
|
-
|
|
645
|
-
[DOMAIN] Entity & Value Object Definitions
|
|
646
|
-
□ Define {Entity1} entity with properties and validation
|
|
647
|
-
□ Define {Entity2} entity with relationships
|
|
648
|
-
□ Define {ValueObject1} value object
|
|
649
|
-
□ Define domain exceptions
|
|
650
|
-
□ Total: X tasks
|
|
651
|
-
|
|
652
|
-
[SEEDDATA-CORE] Core Configuration (MANDATORY)
|
|
653
|
-
□ NavigationModuleConfiguration - Module navigation structure
|
|
654
|
-
□ PermissionsConfiguration - RBAC permissions setup
|
|
655
|
-
□ RolesConfiguration - Predefined roles
|
|
656
|
-
□ TenantConfiguration - Test tenants
|
|
657
|
-
□ UserConfiguration - Test users
|
|
658
|
-
Total: 5 CORE tasks
|
|
659
|
-
|
|
660
|
-
[SEEDDATA] Business Reference Data
|
|
661
|
-
□ Seed {Entity1} reference data
|
|
662
|
-
□ Seed {Entity2} lookup values
|
|
663
|
-
□ Total: Y business seed tasks
|
|
664
|
-
|
|
665
|
-
[APPLICATION] Services & Business Logic
|
|
666
|
-
□ Create {ServiceName}Service for {UC1}
|
|
667
|
-
□ Create {DtoName}Dto for API contracts
|
|
668
|
-
□ Create {ValidatorName}Validator for input validation
|
|
669
|
-
□ Implement query handlers
|
|
670
|
-
Total: Z tasks
|
|
671
|
-
|
|
672
|
-
[INFRASTRUCTURE] Repositories & Persistence
|
|
673
|
-
□ Create {Entity1}Repository with CRUD + custom queries
|
|
674
|
-
□ Create {Entity2}Repository
|
|
675
|
-
□ Configure DbContext for module
|
|
676
|
-
□ Setup specifications for complex queries
|
|
677
|
-
□ Create IClientSeedDataProvider (client projects ONLY - injects core seeds at runtime)
|
|
678
|
-
□ Create DevDataSeeder + SeedConstants (if first module)
|
|
679
|
-
Total: A tasks
|
|
680
|
-
|
|
681
|
-
[API] REST Endpoints & Controllers
|
|
682
|
-
□ Create {ModuleNameController} GET endpoints (List, GetById)
|
|
683
|
-
□ Create {ModuleNameController} POST endpoint (Create)
|
|
684
|
-
□ Create {ModuleNameController} PUT endpoint (Update)
|
|
685
|
-
□ Create {ModuleNameController} DELETE endpoint (Delete)
|
|
686
|
-
□ Implement error handling and validation responses
|
|
687
|
-
Total: B tasks
|
|
688
|
-
|
|
689
|
-
[FRONTEND] UI Components & Pages (wireframe-driven)
|
|
690
|
-
□ Create {ModuleName}Page for listing [wireframe: {module}-list]
|
|
691
|
-
□ Create {ModuleName}DetailPage for viewing [wireframe: {module}-detail]
|
|
692
|
-
□ Create {ModuleName}Form component for creation/edit [wireframe: {module}-create]
|
|
693
|
-
□ Create custom hook use{ModuleName}
|
|
694
|
-
□ Implement pagination, filtering, sorting
|
|
695
|
-
□ Validate all pages match their wireframe layout
|
|
696
|
-
□ ⚠️ Routes MUST be INSIDE Layout wrapper (AdminLayout/BusinessLayout/UserLayout)
|
|
697
|
-
Total: C tasks
|
|
698
|
-
|
|
699
|
-
[I18N] Internationalization Keys
|
|
700
|
-
□ Define i18n keys for {Module} UI labels
|
|
701
|
-
□ Setup translations for locales: fr, en, it, de
|
|
702
|
-
Total: D keys
|
|
703
|
-
|
|
704
|
-
[TESTS] Unit & Integration Tests
|
|
705
|
-
□ Unit tests for {Entity} domain logic
|
|
706
|
-
□ Unit tests for {ServiceName}Service
|
|
707
|
-
□ Integration tests for {ModuleNameController}
|
|
708
|
-
□ Security tests for authorization & tenant isolation
|
|
709
|
-
□ E2E tests for critical user flows
|
|
710
|
-
Total: E unit + F integration + G security = H tests
|
|
711
|
-
|
|
712
|
-
[QA] Quality Assurance
|
|
713
|
-
□ Code review against SmartStack conventions
|
|
714
|
-
□ Test coverage minimum 80%
|
|
715
|
-
□ Security scan for OWASP vulnerabilities
|
|
716
|
-
□ Performance testing under load
|
|
717
|
-
Total: 4 QA tasks
|
|
718
|
-
|
|
719
|
-
Module Total: X + 5 + Y + Z + A + B + C + D + H + 4 = {module_total} tasks
|
|
720
|
-
Estimated Effort: {simple/medium/complex} - {1-3/3-8/8-15} days
|
|
721
|
-
|
|
722
|
-
{If multi-module:}
|
|
723
|
-
[CROSS-MODULE] Integration Tasks
|
|
724
|
-
Status: NOT STARTED
|
|
725
|
-
Dependencies: All modules COMPLETED
|
|
726
|
-
|
|
727
|
-
□ Verify cross-module entity relationships
|
|
728
|
-
□ Test cross-module API dependencies
|
|
729
|
-
□ Validate permission matrix across modules
|
|
730
|
-
□ E2E flow tests spanning multiple modules
|
|
731
|
-
□ Cross-module data consistency checks
|
|
732
|
-
□ Integration test suite for module interactions
|
|
733
|
-
Total: 6 CROSS-MODULE tasks
|
|
734
|
-
|
|
735
|
-
═════════════════════════════════════════════════════════════════
|
|
736
|
-
SUMMARY
|
|
737
|
-
═════════════════════════════════════════════════════════════════
|
|
738
|
-
Total Modules: {count}
|
|
739
|
-
Total Tasks: {total_count}
|
|
740
|
-
- CORE SeedData: {count} × 5 = {total_core}
|
|
741
|
-
- Business Tasks: {total_biz}
|
|
742
|
-
- Development: {total_dev}
|
|
743
|
-
- Tests: {total_tests}
|
|
744
|
-
- QA: {total_qa}
|
|
745
|
-
- Cross-Module: {cross_module_count or 0}
|
|
746
|
-
|
|
747
|
-
Strategy: {strategy}
|
|
748
|
-
Module Order: {topological order with dependencies noted}
|
|
749
|
-
|
|
750
|
-
Complexity Distribution:
|
|
751
|
-
Simple: {count} modules ({estimate} days each)
|
|
752
|
-
Medium: {count} modules ({estimate} days each)
|
|
753
|
-
Complex: {count} modules ({estimate} days each)
|
|
754
|
-
|
|
755
|
-
Total Effort Estimate: {total_days} days ({total_hours} hours)
|
|
756
|
-
Per Developer (2): {total_days / 2} days
|
|
757
|
-
Parallel Potential: {strategy_efficiency_percent}%
|
|
758
|
-
|
|
759
|
-
═════════════════════════════════════════════════════════════════
|
|
760
|
-
LEGEND
|
|
761
|
-
═════════════════════════════════════════════════════════════════
|
|
762
|
-
□ = Task not started
|
|
763
|
-
✓ = Task completed
|
|
764
|
-
⚠ = Task in progress
|
|
765
|
-
✗ = Task failed / blocked
|
|
766
|
-
|
|
767
|
-
COLORS:
|
|
768
|
-
[DOMAIN] = Domain Model & Business Logic
|
|
769
|
-
[SEEDDATA-CORE] = MANDATORY core configuration (5 entries)
|
|
770
|
-
[SEEDDATA] = Business reference & lookup data
|
|
771
|
-
[APPLICATION] = Services, DTOs, Validators
|
|
772
|
-
[INFRASTRUCTURE] = Repositories, DbContext, ORM
|
|
773
|
-
[API] = REST controllers & endpoints
|
|
774
|
-
[FRONTEND] = React pages, components, hooks
|
|
775
|
-
[I18N] = Internationalization
|
|
776
|
-
[TESTS] = Unit, Integration, Security, E2E
|
|
777
|
-
[QA] = Code quality, coverage, security
|
|
778
|
-
[CROSS-MODULE] = Multi-module integration (if applicable)
|
|
779
|
-
|
|
780
|
-
═════════════════════════════════════════════════════════════════
|
|
781
|
-
```
|
|
782
|
-
|
|
783
|
-
**Progress Tracker Rules:**
|
|
784
|
-
- One section per module, in topological order (dependencies first)
|
|
785
|
-
- CORE SeedData ALWAYS 5 entries (mandatory)
|
|
786
|
-
- Business SeedData varies by module
|
|
787
|
-
- Hierarchical task structure (module → layer → tasks)
|
|
788
|
-
- Each task is independent, assignable checkbox
|
|
789
|
-
- Effort estimate per module (simple/medium/complex)
|
|
790
|
-
- Summary with totals across all modules
|
|
791
|
-
- Identified dependencies for parallel execution
|
|
792
|
-
- Cross-module tasks only if multi-module
|
|
793
|
-
|
|
794
|
-
---
|
|
795
|
-
|
|
796
|
-
### 9. Write Handoff to Feature.json
|
|
797
|
-
|
|
798
|
-
> **BLOCKING RULE: The handoff MUST be written in EACH module feature.json.**
|
|
799
|
-
> A handoff at master level alone is INSUFFICIENT. Ralph-loop consumes module-level handoffs.
|
|
800
|
-
> An empty module handoff (`"handoff": {}`) is a CRITICAL BUG that blocks all downstream generation.
|
|
801
|
-
|
|
802
|
-
#### 9a. Module Handoff Loop (MANDATORY)
|
|
803
|
-
|
|
804
|
-
> **STRUCTURE CARD: handoff** — Field names are EXACT. Include ALL fields below.
|
|
805
|
-
> ```json
|
|
806
|
-
> {
|
|
807
|
-
> "complexity": "simple|medium|complex",
|
|
808
|
-
> "filesToCreate": {
|
|
809
|
-
> "domain": [{"path": "...", "type": "Entity|ValueObject|Enum", "linkedFRs": [], "linkedUCs": [], "module": "..."}],
|
|
810
|
-
> "application": [{"path": "...", "type": "Service|Dto|Validator", "linkedFRs": [], "linkedUCs": [], "module": "..."}],
|
|
811
|
-
> "infrastructure": [{"path": "...", "type": "Repository|DbContext", "linkedFRs": [], "module": "..."}],
|
|
812
|
-
> "api": [{"path": "...", "type": "ApiController", "linkedUCs": [], "linkedFRs": [], "module": "..."}],
|
|
813
|
-
> "frontend": [{"path": "...", "type": "Page|Component|Hook|DashboardPage", "linkedUCs": [], "linkedWireframes": [], "module": "..."}],
|
|
814
|
-
> "seedData": [{"path": "...", "type": "HasData", "category": "core|business", "source": "...", "module": "..."}],
|
|
815
|
-
> "tests": [{"path": "...", "type": "UnitTests|IntegrationTests|SecurityTests", "linkedFRs": [], "linkedUCs": [], "module": "..."}]
|
|
816
|
-
> },
|
|
817
|
-
> "brToCodeMapping": [{"ruleId": "BR-...", "files": ["path1", "path2"], "implementation": "description"}],
|
|
818
|
-
> "apiEndpointSummary": [{"method": "GET|POST|PUT|DELETE", "path": "/api/...", "permission": "business.{app}.{module}.{action}", "linkedUC": "UC-..."}],
|
|
819
|
-
> "prdFile": ".ralph/prd-{module}.json",
|
|
820
|
-
> "totalFiles": 0,
|
|
821
|
-
> "totalTasks": 0,
|
|
822
|
-
> "handedOffAt": "{ISO timestamp}"
|
|
823
|
-
> }
|
|
824
|
-
> ```
|
|
825
|
-
> **MANDATORY fields:** ALL of the above. `filesToCreate` MUST have all 7 categories (even if empty arrays).
|
|
826
|
-
> **FORBIDDEN:** `handoff: {}` (empty object is a CRITICAL BUG). Missing `brToCodeMapping` or `apiEndpointSummary`.
|
|
827
|
-
|
|
828
|
-
**For i = 0; i < modules.length; i++:**
|
|
829
|
-
|
|
830
|
-
```
|
|
831
|
-
1. moduleCode = modules[i].code
|
|
832
|
-
2. moduleFeatureId = modules[i].featureJsonPath or find via ba-reader.findFeature()
|
|
833
|
-
3. Read the module feature.json via ba-reader.findFeature(moduleFeatureId)
|
|
834
|
-
4. Build the handoff payload for THIS module:
|
|
835
|
-
- complexity (from step 3 calculation)
|
|
836
|
-
- filesToCreate (full 7-category structure from step 4, filtered for this module)
|
|
837
|
-
- brToCodeMapping (from step 5, filtered for this module)
|
|
838
|
-
- apiEndpointSummary (from step 6, filtered for this module)
|
|
839
|
-
- prdFile path
|
|
840
|
-
- totalFiles count
|
|
841
|
-
- totalTasks count
|
|
842
|
-
- handedOffAt timestamp
|
|
843
|
-
|
|
844
|
-
5. Write via ba-writer:
|
|
845
|
-
ba-writer.enrichModuleHandoff({
|
|
846
|
-
moduleFeatureId: {moduleFeatureId},
|
|
847
|
-
handoffData: {
|
|
848
|
-
complexity: "{simple|medium|complex}",
|
|
849
|
-
filesToCreate: {...},
|
|
850
|
-
brToCodeMapping: [...],
|
|
851
|
-
apiEndpointSummary: [...],
|
|
852
|
-
prdFile: ".ralph/prd-{moduleCode}.json",
|
|
853
|
-
totalFiles: {count},
|
|
854
|
-
totalTasks: {count},
|
|
855
|
-
handedOffAt: "{ISO timestamp}"
|
|
856
|
-
}
|
|
857
|
-
})
|
|
858
|
-
|
|
859
|
-
6. VERIFICATION (MANDATORY - done automatically by enrichModuleHandoff):
|
|
860
|
-
- handoff !== {}
|
|
861
|
-
- handoff.filesToCreate has 7 categories
|
|
862
|
-
- handoff.brToCodeMapping.length > 0
|
|
863
|
-
IF verification fails → STOP, report error, do NOT continue
|
|
864
|
-
|
|
865
|
-
7. Display progress:
|
|
866
|
-
"✓ Handoff module {i+1}/{N} : {moduleCode} ({fileCount} fichiers, {brCount} BRs mappées)"
|
|
867
|
-
```
|
|
868
|
-
|
|
869
|
-
#### 9b. Master Handoff (after ALL modules written successfully)
|
|
870
|
-
|
|
871
|
-
```
|
|
872
|
-
ba-writer.enrichSection({
|
|
873
|
-
featureId: {feature_id},
|
|
874
|
-
section: "handoff",
|
|
875
|
-
data: {
|
|
876
|
-
status: "handed-off",
|
|
877
|
-
complexity: "{simple|medium|complex}",
|
|
878
|
-
implementationStrategy: "{strategy}",
|
|
879
|
-
moduleCount: {count},
|
|
880
|
-
moduleOrder: [...],
|
|
881
|
-
totalFilesToCreate: {sum across all modules},
|
|
882
|
-
totalTasks: {sum across all modules},
|
|
883
|
-
prdStructure: "per-module | consolidated",
|
|
884
|
-
prdFiles: [
|
|
885
|
-
{ module: "{module1}", path: ".ralph/prd-{module1}.json" },
|
|
886
|
-
{ module: "{module2}", path: ".ralph/prd-{module2}.json" }
|
|
887
|
-
],
|
|
888
|
-
progressTrackerPath: ".ralph/progress.txt",
|
|
889
|
-
handedOffAt: "{ISO timestamp}"
|
|
890
|
-
}
|
|
891
|
-
})
|
|
892
|
-
```
|
|
893
|
-
|
|
894
|
-
#### 9c. Final Verification (BLOCKING)
|
|
895
|
-
|
|
896
|
-
```
|
|
897
|
-
count = 0
|
|
898
|
-
FOR each module in modules[]:
|
|
899
|
-
Read module feature.json
|
|
900
|
-
IF module.handoff !== {} AND module.status === "handed-off":
|
|
901
|
-
count++
|
|
902
|
-
|
|
903
|
-
IF count < modules.length:
|
|
904
|
-
→ BLOCKING ERROR: {modules.length - count} modules missing handoff
|
|
905
|
-
→ List the missing modules by name
|
|
906
|
-
→ DO NOT proceed to step 10
|
|
907
|
-
→ Return to 9a for missing modules only
|
|
908
|
-
|
|
909
|
-
IF count === modules.length:
|
|
910
|
-
ba-writer.updateStatus({feature_id}, "handed-off")
|
|
911
|
-
Display: "✓ Handoff complet: {count}/{modules.length} modules avec handoff valide"
|
|
912
|
-
```
|
|
913
|
-
|
|
914
|
-
Status journey: analyze → consolidate → **handed-off**
|
|
915
|
-
|
|
916
|
-
---
|
|
917
|
-
|
|
918
|
-
### 9d. Deploy Interactive HTML Document (MANDATORY)
|
|
919
|
-
|
|
920
|
-
> **The interactive HTML document is deployed to the project PRE-POPULATED with ALL analysis data.**
|
|
921
|
-
> The client opens it in a browser and sees the complete analysis (cadrage, modules, entities, UCs, BRs, wireframes, permissions, consolidation).
|
|
922
|
-
> The client can then review, edit, enrich, and export modifications as JSON.
|
|
923
|
-
> That JSON can be re-imported via `/business-analyse -x` to update the feature.json.
|
|
924
|
-
|
|
925
|
-
**Source:** `html/ba-interactive.html` (relative to skill root = `~/.claude/skills/business-analyse/html/`)
|
|
926
|
-
|
|
927
|
-
**Destination:** `docs/business/{app}/business-analyse/v{version}/ba-interactive.html`
|
|
928
|
-
|
|
929
|
-
**Deployment steps:**
|
|
930
|
-
|
|
931
|
-
#### Step 1: Read source data
|
|
932
|
-
|
|
933
|
-
1. Read the HTML template from skill directory
|
|
934
|
-
2. Read the master feature.json (application level)
|
|
935
|
-
3. Read EACH module feature.json (module level)
|
|
936
|
-
|
|
937
|
-
#### Step 2: Build FEATURE_DATA object
|
|
938
|
-
|
|
939
|
-
> **CRITICAL:** The HTML `data` object MUST be pre-populated with ALL analysis data.
|
|
940
|
-
> An empty data object is a **BUG** — the client would see a blank page.
|
|
941
|
-
|
|
942
|
-
Build a JSON object following this **exact mapping** from feature.json to the HTML data model:
|
|
943
|
-
|
|
944
|
-
```javascript
|
|
945
|
-
{
|
|
946
|
-
metadata: {
|
|
947
|
-
applicationName: master.metadata.application, // e.g. "RH"
|
|
948
|
-
applicationId: master.id, // e.g. "FEAT-001"
|
|
949
|
-
version: master.version, // e.g. "1.0"
|
|
950
|
-
createdAt: master.metadata.createdAt,
|
|
951
|
-
lastModified: master.metadata.updatedAt
|
|
952
|
-
},
|
|
953
|
-
cadrage: {
|
|
954
|
-
problem: {
|
|
955
|
-
description: master.cadrage.problem, // string → problem.description
|
|
956
|
-
trigger: master.cadrage.trigger, // string → problem.trigger
|
|
957
|
-
impactedPeople: "", // not in feature.json, client fills
|
|
958
|
-
history: "",
|
|
959
|
-
consequences: ""
|
|
960
|
-
},
|
|
961
|
-
current: {
|
|
962
|
-
tools: master.cadrage.asIs, // string → current.tools
|
|
963
|
-
steps: [], // client can add process steps
|
|
964
|
-
painPoints: master.cadrage.stakeholders
|
|
965
|
-
.flatMap(s => s.painPoints || []).join("\n"), // aggregate all painPoints
|
|
966
|
-
errors: ""
|
|
967
|
-
},
|
|
968
|
-
vision: {
|
|
969
|
-
changes: master.cadrage.toBe, // string → vision.changes
|
|
970
|
-
results: master.cadrage.acceptanceCriteria
|
|
971
|
-
.map(ac => ac.criterion).join("\n"), // AC → results (one per line)
|
|
972
|
-
successSign: ""
|
|
973
|
-
},
|
|
974
|
-
stakeholders: master.cadrage.stakeholders.map(s => ({
|
|
975
|
-
role: s.role,
|
|
976
|
-
function: s.function || "",
|
|
977
|
-
tasks: s.tasks || [],
|
|
978
|
-
frequency: mapFrequency(s.frequency), // "Quotidien"→"daily", etc.
|
|
979
|
-
access: mapAccess(s.involvement), // "decision-maker"→"admin", "end-user"→"contributor"
|
|
980
|
-
frustrations: (s.painPoints || []).join("\n")
|
|
981
|
-
})),
|
|
982
|
-
scope: {
|
|
983
|
-
vital: (master.cadrage.globalScope.mustHave || [])
|
|
984
|
-
.map(item => ({ name: item, description: "" })), // string[] → {name,description}[]
|
|
985
|
-
important: (master.cadrage.globalScope.shouldHave || [])
|
|
986
|
-
.map(item => ({ name: item, description: "" })),
|
|
987
|
-
optional: (master.cadrage.globalScope.couldHave || [])
|
|
988
|
-
.map(item => ({ name: item, description: "" })),
|
|
989
|
-
excluded: (master.cadrage.globalScope.outOfScope || [])
|
|
990
|
-
.map(item => ({ name: item, description: "" }))
|
|
991
|
-
},
|
|
992
|
-
risks: (master.cadrage.risks || []).map(r => ({
|
|
993
|
-
description: r.description,
|
|
994
|
-
probability: r.probability, // "high" | "medium" | "low"
|
|
995
|
-
impact: r.impact,
|
|
996
|
-
mitigation: r.mitigation || ""
|
|
997
|
-
})),
|
|
998
|
-
assumptions: "",
|
|
999
|
-
success: {
|
|
1000
|
-
definition: (master.cadrage.acceptanceCriteria || [])
|
|
1001
|
-
.map(ac => ac.criterion).join("\n"),
|
|
1002
|
-
metrics: "",
|
|
1003
|
-
timeline: "",
|
|
1004
|
-
minimumConditions: ""
|
|
1005
|
-
}
|
|
1006
|
-
},
|
|
1007
|
-
modules: master.modules.map(m => ({
|
|
1008
|
-
code: m.code,
|
|
1009
|
-
name: m.code, // module code as name
|
|
1010
|
-
description: m.description || "",
|
|
1011
|
-
featureType: m.featureType || "data-centric",
|
|
1012
|
-
priority: m.priority || "must",
|
|
1013
|
-
entities: m.entities || [],
|
|
1014
|
-
status: m.status || "handed-off"
|
|
1015
|
-
})),
|
|
1016
|
-
dependencies: (master.dependencyGraph?.edges || []).map(e => ({
|
|
1017
|
-
from: e.from,
|
|
1018
|
-
to: e.to,
|
|
1019
|
-
description: e.description || ""
|
|
1020
|
-
})),
|
|
1021
|
-
moduleSpecs: {
|
|
1022
|
-
// FOR EACH module: read module feature.json, then map:
|
|
1023
|
-
// [moduleCode]: { useCases, businessRules, entities, permissions, notes, mockupNotes }
|
|
1024
|
-
},
|
|
1025
|
-
consolidation: {
|
|
1026
|
-
interactions: (master.consolidation?.crossModuleInteractions || []).map(i => ({
|
|
1027
|
-
from: i.fromModule,
|
|
1028
|
-
to: i.toModule,
|
|
1029
|
-
description: i.description || ""
|
|
1030
|
-
})),
|
|
1031
|
-
e2eFlows: (master.consolidation?.e2eFlows || []).map(f => ({
|
|
1032
|
-
name: f.name,
|
|
1033
|
-
steps: (f.steps || []).map(s => ({ module: s.module, action: s.action })),
|
|
1034
|
-
actors: (f.steps || []).map(s => s.permission).join(", ")
|
|
1035
|
-
}))
|
|
1036
|
-
},
|
|
1037
|
-
handoff: master.handoff || {}
|
|
1038
|
-
}
|
|
1039
|
-
```
|
|
1040
|
-
|
|
1041
|
-
**Module specs mapping** — for EACH module in `master.modules[]`:
|
|
1042
|
-
|
|
1043
|
-
1. Read the module feature.json at `master.modules[i].featureJsonPath`
|
|
1044
|
-
2. Map to `moduleSpecs[moduleCode]`:
|
|
1045
|
-
|
|
1046
|
-
```javascript
|
|
1047
|
-
moduleSpecs[moduleCode] = {
|
|
1048
|
-
useCases: (moduleFeature.specification?.useCases || []).map(uc => ({
|
|
1049
|
-
name: uc.name,
|
|
1050
|
-
actor: uc.primaryActor,
|
|
1051
|
-
steps: (uc.mainScenario || []).join("\n"), // array → newline-separated string
|
|
1052
|
-
alternative: (uc.alternativeScenarios || [])
|
|
1053
|
-
.map(a => a.name + ": " + (a.steps || []).join(", ")).join("\n")
|
|
1054
|
-
})),
|
|
1055
|
-
businessRules: (moduleFeature.analysis?.businessRules || []).map(br => ({
|
|
1056
|
-
name: br.name,
|
|
1057
|
-
category: br.category, // "validation"|"calculation"|"workflow"|"security"|"data"
|
|
1058
|
-
statement: br.statement,
|
|
1059
|
-
example: (br.examples || []).map(e => e.input + " → " + e.expected).join("; ")
|
|
1060
|
-
})),
|
|
1061
|
-
entities: (moduleFeature.analysis?.entities || []).map(ent => ({
|
|
1062
|
-
name: ent.name,
|
|
1063
|
-
description: ent.description || "",
|
|
1064
|
-
attributes: (ent.attributes || []).map(a => ({
|
|
1065
|
-
name: a.name,
|
|
1066
|
-
description: a.description || ""
|
|
1067
|
-
})),
|
|
1068
|
-
relationships: (ent.relationships || []).map(r =>
|
|
1069
|
-
r.target + " (" + r.type + ") - " + (r.description || "")
|
|
1070
|
-
)
|
|
1071
|
-
})),
|
|
1072
|
-
permissions: buildPermissionKeys(moduleFeature), // see below
|
|
1073
|
-
notes: "",
|
|
1074
|
-
mockupNotes: "" // Deprecated: wireframes now embedded separately in EMBEDDED_ARTIFACTS
|
|
1075
|
-
}
|
|
1076
|
-
```
|
|
1077
|
-
|
|
1078
|
-
**Permission keys** — the HTML uses `"Role|Action"` format (e.g. `"RH Admin|Consulter"`):
|
|
1079
|
-
|
|
1080
|
-
```javascript
|
|
1081
|
-
function buildPermissionKeys(moduleFeature) {
|
|
1082
|
-
const keys = [];
|
|
1083
|
-
const matrix = moduleFeature.specification?.permissionMatrix;
|
|
1084
|
-
if (!matrix) return keys;
|
|
1085
|
-
const actionMap = { read: "Consulter", create: "Creer", update: "Modifier",
|
|
1086
|
-
delete: "Supprimer", validate: "Valider", export: "Exporter",
|
|
1087
|
-
submit: "Valider", import: "Creer" };
|
|
1088
|
-
(matrix.roleAssignments || []).forEach(ra => {
|
|
1089
|
-
(ra.permissions || []).forEach(permPath => {
|
|
1090
|
-
const action = permPath.split(".").pop(); // last segment = action
|
|
1091
|
-
const uiAction = actionMap[action] || action;
|
|
1092
|
-
keys.push(ra.role + "|" + uiAction);
|
|
1093
|
-
});
|
|
1094
|
-
});
|
|
1095
|
-
return keys;
|
|
1096
|
-
}
|
|
1097
|
-
```
|
|
1098
|
-
|
|
1099
|
-
**Frequency mapping:**
|
|
1100
|
-
```
|
|
1101
|
-
"Quotidien" → "daily", "Hebdomadaire" → "weekly", "Mensuel" → "monthly"
|
|
1102
|
-
Default: "daily"
|
|
1103
|
-
```
|
|
1104
|
-
|
|
1105
|
-
**Access mapping (involvement → access):**
|
|
1106
|
-
```
|
|
1107
|
-
"decision-maker" → "admin", "end-user" with manager-like tasks → "manager"
|
|
1108
|
-
"end-user" → "contributor", "observer" → "viewer"
|
|
1109
|
-
Default: "contributor"
|
|
1110
|
-
```
|
|
1111
|
-
|
|
1112
|
-
#### Step 2-bis: Build EMBEDDED_ARTIFACTS object (NEW)
|
|
1113
|
-
|
|
1114
|
-
> **NEW in v6.2:** Visual artifacts (wireframes, E2E diagrams) are now embedded as a separate JavaScript object in the HTML for client-side rendering and export.
|
|
1115
|
-
|
|
1116
|
-
Build a JSON object containing ALL visual artifacts from feature.json:
|
|
1117
|
-
|
|
1118
|
-
```javascript
|
|
1119
|
-
{
|
|
1120
|
-
wireframes: {
|
|
1121
|
-
// FOR EACH module: extract all wireframes from module feature.json
|
|
1122
|
-
// [moduleCode]: [ {screen, format, content, elements, componentMapping, layout, description} ]
|
|
1123
|
-
},
|
|
1124
|
-
e2eFlows: [
|
|
1125
|
-
// Extract from master consolidation.e2eFlows[]
|
|
1126
|
-
// { name, diagram, steps, actors }
|
|
1127
|
-
],
|
|
1128
|
-
dependencyGraph: {
|
|
1129
|
-
// Extract from master dependencyGraph
|
|
1130
|
-
// nodes: [ {id, label, type} ], edges: [ {from, to, description} ]
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
```
|
|
1134
|
-
|
|
1135
|
-
**Wireframes mapping** — for EACH module in `master.modules[]`:
|
|
1136
|
-
|
|
1137
|
-
```javascript
|
|
1138
|
-
// Read the module feature.json
|
|
1139
|
-
const moduleFeature = readModuleFeature(moduleCode);
|
|
1140
|
-
const wireframes = (moduleFeature.specification?.uiWireframes || []).map(wf => ({
|
|
1141
|
-
screen: wf.screen, // e.g. "UM-list", "UM-form"
|
|
1142
|
-
section: wf.section, // e.g. "list", "form"
|
|
1143
|
-
format: wf.mockupFormat || "ascii", // "ascii" | "svg"
|
|
1144
|
-
content: wf.mockup, // ASCII art or SVG markup
|
|
1145
|
-
description: wf.description || "",
|
|
1146
|
-
elements: wf.elements || [], // ["DataGrid", "FilterBar", ...]
|
|
1147
|
-
actions: wf.actions || [], // ["filter", "sort", "create", ...]
|
|
1148
|
-
componentMapping: wf.componentMapping || [], // [{ wireframeElement, reactComponent }]
|
|
1149
|
-
layout: wf.layout || null, // { type, regions: [...] }
|
|
1150
|
-
permissionsRequired: wf.permissionsRequired || []
|
|
1151
|
-
}));
|
|
1152
|
-
|
|
1153
|
-
// Store in artifacts object
|
|
1154
|
-
EMBEDDED_ARTIFACTS.wireframes[moduleCode] = wireframes;
|
|
1155
|
-
```
|
|
1156
|
-
|
|
1157
|
-
**E2E flows mapping** — from master consolidation:
|
|
1158
|
-
|
|
1159
|
-
```javascript
|
|
1160
|
-
EMBEDDED_ARTIFACTS.e2eFlows = (master.consolidation?.e2eFlows || []).map(flow => ({
|
|
1161
|
-
name: flow.name,
|
|
1162
|
-
diagram: generateE2EDiagram(flow), // ASCII diagram from flow.steps[]
|
|
1163
|
-
steps: flow.steps || [], // [{ module, action, permission }]
|
|
1164
|
-
actors: Array.from(new Set((flow.steps || [])
|
|
1165
|
-
.map(s => s.permission?.split(".")[0]) // Extract role from permission path
|
|
1166
|
-
.filter(Boolean))).join(", "),
|
|
1167
|
-
modules: Array.from(new Set((flow.steps || [])
|
|
1168
|
-
.map(s => s.module))).join(" → ")
|
|
1169
|
-
}));
|
|
1170
|
-
|
|
1171
|
-
function generateE2EDiagram(flow) {
|
|
1172
|
-
// Generate ASCII diagram from flow.steps[]
|
|
1173
|
-
// Example output:
|
|
1174
|
-
// "Customer ──[read]──→ Order ──[create]──→ Invoice ──[send]──→"
|
|
1175
|
-
// " (Orders) (Orders) (Invoices)"
|
|
1176
|
-
// " Contributor Manager System"
|
|
1177
|
-
|
|
1178
|
-
const stepDiagrams = (flow.steps || []).map(s =>
|
|
1179
|
-
`${s.action}(${s.module})`
|
|
1180
|
-
).join(" ──→ ");
|
|
1181
|
-
|
|
1182
|
-
return stepDiagrams;
|
|
1183
|
-
}
|
|
1184
|
-
```
|
|
1185
|
-
|
|
1186
|
-
**Dependency graph mapping** — from master dependencyGraph:
|
|
1187
|
-
|
|
1188
|
-
```javascript
|
|
1189
|
-
EMBEDDED_ARTIFACTS.dependencyGraph = {
|
|
1190
|
-
nodes: (master.modules || []).map(m => ({
|
|
1191
|
-
id: m.code,
|
|
1192
|
-
label: m.code,
|
|
1193
|
-
type: m.featureType || "data-centric"
|
|
1194
|
-
})),
|
|
1195
|
-
edges: (master.dependencyGraph?.edges || []).map(e => ({
|
|
1196
|
-
from: e.from,
|
|
1197
|
-
to: e.to,
|
|
1198
|
-
description: e.description || ""
|
|
1199
|
-
}))
|
|
1200
|
-
};
|
|
1201
|
-
```
|
|
1202
|
-
|
|
1203
|
-
#### Step 3: Replace placeholders in template
|
|
1204
|
-
|
|
1205
|
-
1. Serialize the FEATURE_DATA object as JSON (with 2-space indentation for readability)
|
|
1206
|
-
2. Serialize the EMBEDDED_ARTIFACTS object as JSON (with 2-space indentation)
|
|
1207
|
-
3. Replace `{{FEATURE_DATA}}` with the serialized FEATURE_DATA JSON
|
|
1208
|
-
4. Replace `{{EMBEDDED_ARTIFACTS}}` with the serialized EMBEDDED_ARTIFACTS JSON
|
|
1209
|
-
5. Replace `{{APPLICATION_NAME}}` → `{application_name}` (still used in `<title>` and header)
|
|
1210
|
-
6. Replace `{{APPLICATION_ID}}` → `{feature_id}` (still used in `APP_KEY`)
|
|
1211
|
-
7. Replace `{{VERSION}}` → `{version}`
|
|
1212
|
-
8. Replace `{{CREATED_AT}}` → `{ISO timestamp}`
|
|
1213
|
-
|
|
1214
|
-
> **NOTE:** `{{APPLICATION_NAME}}`, `{{APPLICATION_ID}}`, `{{VERSION}}`, `{{CREATED_AT}}` still appear
|
|
1215
|
-
> in the HTML body (`<title>`, header, `APP_KEY`). They MUST be replaced separately from FEATURE_DATA.
|
|
1216
|
-
|
|
1217
|
-
> **NEW:** `{{EMBEDDED_ARTIFACTS}}` is a separate JavaScript variable in the HTML that stores all visual artifacts (wireframes, E2E diagrams, dependency graph) for client-side rendering and export.
|
|
1218
|
-
|
|
1219
|
-
#### Step 4: Write and confirm
|
|
1220
|
-
|
|
1221
|
-
1. Write the populated HTML to the output directory
|
|
1222
|
-
2. Display deployment confirmation:
|
|
1223
|
-
|
|
1224
|
-
```
|
|
1225
|
-
✓ Interactive HTML deployed:
|
|
1226
|
-
Path: docs/business/{app}/business-analyse/v{version}/ba-interactive.html
|
|
1227
|
-
Pre-populated with: {stakeholder_count} stakeholders, {module_count} modules,
|
|
1228
|
-
{total_uc} use cases, {total_br} business rules, {total_entity} entities
|
|
1229
|
-
Visual artifacts: {total_wireframes} wireframes, {e2e_flow_count} E2E diagrams
|
|
1230
|
-
Open in browser to review and edit the business analysis.
|
|
1231
|
-
Export JSON and re-import with: /business-analyse -x <exported-json-path>
|
|
1232
|
-
```
|
|
1233
|
-
|
|
1234
|
-
**Why a FINAL deployment at handoff?**
|
|
1235
|
-
- Step 03 already deploys the HTML incrementally after each module (partial data)
|
|
1236
|
-
- This final deployment adds the COMPLETE data: all modules + consolidation + handoff info
|
|
1237
|
-
- The client sees the FULL analysis pre-populated — including cross-module interactions and E2E flows
|
|
1238
|
-
- The client can review, edit, and enrich directly in the browser
|
|
1239
|
-
- Any client modifications can be re-imported via `-x` extraction mode
|
|
1240
|
-
- The HTML is standalone (no server required) with localStorage persistence
|
|
1241
|
-
- On first open: pre-populated data displays. After client edits: localStorage overrides
|
|
1242
|
-
- **NOTE:** This overwrites the incremental HTML from step-03 with the complete version
|
|
1243
|
-
|
|
1244
|
-
---
|
|
1245
|
-
|
|
1246
|
-
### 9e. Update BA Manifest (MANDATORY)
|
|
1247
|
-
|
|
1248
|
-
> **The BA manifest enables the SmartStack web app to discover and display all available business analyses.**
|
|
1249
|
-
> It is a JSON index file at `docs/business/index.json` that lists all feature.json files.
|
|
1250
|
-
|
|
1251
|
-
**Path:** `docs/business/index.json` (project root relative)
|
|
1252
|
-
|
|
1253
|
-
**Schema:**
|
|
1254
|
-
```json
|
|
1255
|
-
{
|
|
1256
|
-
"version": "1.0",
|
|
1257
|
-
"updatedAt": "{ISO timestamp}",
|
|
1258
|
-
"analyses": [
|
|
1259
|
-
{
|
|
1260
|
-
"appCode": "{app_code}",
|
|
1261
|
-
"appName": "{application_name}",
|
|
1262
|
-
"moduleCode": null | "{module_code}",
|
|
1263
|
-
"moduleName": "{module_name}",
|
|
1264
|
-
"version": "{version}",
|
|
1265
|
-
"status": "handed-off",
|
|
1266
|
-
"featureDescription": "{feature_description}",
|
|
1267
|
-
"path": "{app_code}/business-analyse/v{version}/feature.json",
|
|
1268
|
-
"updatedAt": "{ISO timestamp}"
|
|
1269
|
-
}
|
|
1270
|
-
]
|
|
1271
|
-
}
|
|
1272
|
-
```
|
|
1273
|
-
|
|
1274
|
-
**Update logic:**
|
|
1275
|
-
|
|
1276
|
-
1. Read existing manifest at `docs/business/index.json` (or create empty `{ "version": "1.0", "updatedAt": "", "analyses": [] }`)
|
|
1277
|
-
2. For the APPLICATION-level feature.json:
|
|
1278
|
-
- Find existing entry where `appCode == {app_code}` AND `moduleCode == null` AND `version == {version}`
|
|
1279
|
-
- If found: update `status`, `updatedAt`, `featureDescription`
|
|
1280
|
-
- If not found: append new entry with `moduleCode: null` and `path: "{app_code}/business-analyse/v{version}/feature.json"`
|
|
1281
|
-
3. For EACH MODULE-level feature.json:
|
|
1282
|
-
- Find existing entry where `appCode == {app_code}` AND `moduleCode == {module_code}` AND `version == {version}`
|
|
1283
|
-
- If found: update `status`, `updatedAt`, `featureDescription`
|
|
1284
|
-
- If not found: append new entry with `moduleCode: "{module_code}"` and `path: "{app_code}/{module_code}/business-analyse/v{version}/feature.json"`
|
|
1285
|
-
4. Update root `updatedAt` to current timestamp
|
|
1286
|
-
5. Write manifest back to `docs/business/index.json`
|
|
1287
|
-
|
|
1288
|
-
**Display confirmation:**
|
|
1289
|
-
```
|
|
1290
|
-
✓ BA manifest updated: docs/business/index.json
|
|
1291
|
-
Entries: {total_count} ({app_count} applications, {module_count} modules)
|
|
1292
|
-
Web viewer: /system/docs/ba
|
|
1293
|
-
```
|
|
1294
|
-
|
|
1295
|
-
**Why a manifest?**
|
|
1296
|
-
- The web app needs to discover available BAs without scanning the filesystem
|
|
1297
|
-
- Static file serving (no backend API needed)
|
|
1298
|
-
- Incremental updates: each handoff adds/updates only its entries
|
|
1299
|
-
- Consumed by the SmartStack web app BA viewer at `/system/docs/ba`
|
|
1300
|
-
|
|
1301
|
-
---
|
|
1302
|
-
|
|
1303
|
-
### 10. User Choice: Next Agent
|
|
1304
|
-
|
|
1305
|
-
Present development options after successful handoff:
|
|
1306
|
-
|
|
1307
|
-
```
|
|
1308
|
-
═══════════════════════════════════════════════════════════════
|
|
1309
|
-
✓ HANDOFF COMPLETE - {application_name}
|
|
1310
|
-
═══════════════════════════════════════════════════════════════
|
|
1311
|
-
|
|
1312
|
-
Modules: {count} ({names})
|
|
1313
|
-
Strategy: {strategy}
|
|
1314
|
-
Files: {total files across all modules}
|
|
1315
|
-
Tasks: {total tasks} ({core_count} CORE + {biz_count} business + {dev_count} development)
|
|
1316
|
-
Complexity: {complexity}
|
|
1317
|
-
Effort: {total_days} days ({total_hours} hours)
|
|
1318
|
-
|
|
1319
|
-
Generated Artifacts:
|
|
1320
|
-
✓ feature.json (master + per-module) - enhanced with handoff section
|
|
1321
|
-
✓ .ralph/prd.json or .ralph/prd-{module}.json - derived from feature.json
|
|
1322
|
-
✓ .ralph/progress.txt - comprehensive task tracker
|
|
1323
|
-
✓ ba-interactive.html - client-facing interactive review document
|
|
1324
|
-
✓ Implementation strategy selected: {strategy}
|
|
1325
|
-
|
|
1326
|
-
Next: Choose development approach
|
|
1327
|
-
═══════════════════════════════════════════════════════════════
|
|
1328
|
-
```
|
|
1329
|
-
|
|
1330
|
-
Ask via AskUserQuestion:
|
|
1331
|
-
|
|
1332
|
-
```
|
|
1333
|
-
question: "Quelle approche de développement souhaitez-vous utiliser ?"
|
|
1334
|
-
header: "Approche de développement"
|
|
1335
|
-
options:
|
|
1336
|
-
- label: "Feature Full (Recommandé)"
|
|
1337
|
-
description: "Génération parallèle rapide (code + tests). Couverture 70-80%. ~{hours/3} heures."
|
|
1338
|
-
- label: "Ralph Loop"
|
|
1339
|
-
description: "Développement itératif task-par-task avec cycle : Analyse → Dev (backend + tests unitaires + tests non-régression + frontend + tests + documentation) → Validation → Correction → Test ... jusqu'à 100% tests pass. Couverture 95-100%. ~{hours} heures."
|
|
1340
|
-
- label: "Terminer le BA"
|
|
1341
|
-
description: "Finir l'analyse, développement manuel par l'équipe."
|
|
1342
|
-
```
|
|
1343
|
-
|
|
1344
|
-
**Recommendations by complexity:**
|
|
1345
|
-
- **Simple:** Feature Full (1-3 days) or Ralph Loop (2-4 days)
|
|
1346
|
-
- **Medium:** Ralph Loop recommended (5-10 days), Feature Full possible (3-6 days)
|
|
1347
|
-
- **Complex:** Ralph Loop strongly recommended (10-20 days), Feature Full (8-12 days)
|
|
1348
|
-
|
|
1349
|
-
---
|
|
1350
|
-
|
|
1351
|
-
### 10-bis. Execute User Choice (Automatic Skill Launch)
|
|
1352
|
-
|
|
1353
|
-
> **NEW in v6.1:** Automatically launch the chosen development approach for seamless transition.
|
|
1354
|
-
|
|
1355
|
-
**After receiving AskUserQuestion response:**
|
|
1356
|
-
|
|
1357
|
-
```javascript
|
|
1358
|
-
const choice = userAnswer; // "Feature Full (Recommandé)" | "Ralph Loop" | "Terminer le BA"
|
|
1359
|
-
|
|
1360
|
-
// Extract choice label (remove "(Recommandé)" suffix)
|
|
1361
|
-
const choiceLabel = choice.replace(/\s*\(.*?\)\s*$/g, '').trim();
|
|
1362
|
-
|
|
1363
|
-
if (choiceLabel === "Ralph Loop") {
|
|
1364
|
-
// Launch ralph-loop skill automatically
|
|
1365
|
-
display("");
|
|
1366
|
-
display("🚀 Lancement de Ralph Loop - Développement itératif automatique");
|
|
1367
|
-
display("");
|
|
1368
|
-
display("╔══════════════════════════════════════════════════════════════╗");
|
|
1369
|
-
display("║ CYCLE RALPH LOOP - Comment ça fonctionne ? ║");
|
|
1370
|
-
display("╠══════════════════════════════════════════════════════════════╣");
|
|
1371
|
-
display("║ ║");
|
|
1372
|
-
display("║ Ralph Loop exécute un cycle itératif jusqu'à 100% tests: ║");
|
|
1373
|
-
display("║ ║");
|
|
1374
|
-
display("║ 1️⃣ ANALYSE → Charger task suivante du prd.json ║");
|
|
1375
|
-
display("║ 2️⃣ DÉVELOPPEMENT → Générer le code demandé ║");
|
|
1376
|
-
display("║ • Backend (Entities, Services, Controllers, Repos) ║");
|
|
1377
|
-
display("║ • Tests unitaires (xUnit) + non-régression ║");
|
|
1378
|
-
display("║ • Frontend (Pages, Components, Hooks) ║");
|
|
1379
|
-
display("║ • Tests frontend (React Testing Library) ║");
|
|
1380
|
-
display("║ • SeedData (Core RBAC + business data) ║");
|
|
1381
|
-
display("║ • Documentation utilisateur (inline + tooltips) ║");
|
|
1382
|
-
display("║ 3️⃣ VALIDATION → Commit + MCP conventions check ║");
|
|
1383
|
-
display("║ 4️⃣ TEST → Exécuter dotnet test + npm test ║");
|
|
1384
|
-
display("║ 5️⃣ CORRECTION → Si échec, analyser et corriger ║");
|
|
1385
|
-
display("║ 6️⃣ BOUCLE → Répéter 4-5 jusqu'à 100% tests pass ║");
|
|
1386
|
-
display("║ 7️⃣ NEXT TASK → Passer à la task suivante (retour à 1) ║");
|
|
1387
|
-
display("║ ║");
|
|
1388
|
-
display("║ 🎯 Objectif: ZÉRO ERREUR avant de passer à la task suivante║");
|
|
1389
|
-
display("║ 📊 Couverture: 95-100% (tests générés automatiquement) ║");
|
|
1390
|
-
display("║ ║");
|
|
1391
|
-
display("╚══════════════════════════════════════════════════════════════╝");
|
|
1392
|
-
display("");
|
|
1393
|
-
display(" Configuration du projet:");
|
|
1394
|
-
display(" ┌────────────────────────────────────────────────────────────┐");
|
|
1395
|
-
display(" │ Modules: " + modules.map(m => m.code).join(", "));
|
|
1396
|
-
display(" │ Stratégie: " + implementationStrategy);
|
|
1397
|
-
display(" │ PRD: " + (modules.length > 1 ? ".ralph/prd-{module}.json (per module)" : ".ralph/prd.json"));
|
|
1398
|
-
display(" │ Progress: .ralph/progress.txt");
|
|
1399
|
-
display(" │ Ordre: " + (modules.length > 1 ? "topologique (dépendances d'abord)" : "module unique"));
|
|
1400
|
-
display(" └────────────────────────────────────────────────────────────┘");
|
|
1401
|
-
display("");
|
|
1402
|
-
display(" Modules à traiter (dans l'ordre):");
|
|
1403
|
-
for (let i = 0; i < modules.length; i++) {
|
|
1404
|
-
display(" " + (i+1) + ". " + modules[i].code + " (" + modules[i].complexity + ") - " + modules[i].tasksCount + " tasks");
|
|
1405
|
-
}
|
|
1406
|
-
display("");
|
|
1407
|
-
display(" 📂 Fichiers générés par le BA (inputs pour Ralph):");
|
|
1408
|
-
display(" ├─ feature.json (master + modules) → Spécification source");
|
|
1409
|
-
display(" ├─ prd.json (ou prd-{module}.json) → Task breakdown avec UC/FR/BR");
|
|
1410
|
-
display(" ├─ progress.txt → Tracker hiérarchique (module → layer → tasks)");
|
|
1411
|
-
display(" └─ ba-interactive.html → Revue client (mockups, wireframes)");
|
|
1412
|
-
display("");
|
|
1413
|
-
display(" 🔄 Ralph Loop va maintenant:");
|
|
1414
|
-
display(" 1. Détecter les prd-*.json par module (si multi-module)");
|
|
1415
|
-
display(" 2. Créer modules-queue.json avec l'ordre de traitement");
|
|
1416
|
-
display(" 3. Traiter module par module dans l'ordre topologique");
|
|
1417
|
-
display(" 4. Pour chaque module: parcourir les tasks (domain → seeddata → application → infrastructure → api → frontend → i18n → tests)");
|
|
1418
|
-
display(" 5. Pour chaque task: générer code → commit → tests → correction si échec → re-test → next task");
|
|
1419
|
-
display(" 6. Passer au module suivant quand 100% tasks du module actuel = completed");
|
|
1420
|
-
display(" 7. Générer rapport final avec métriques de couverture");
|
|
1421
|
-
display("");
|
|
1422
|
-
display("═══════════════════════════════════════════════════════════════");
|
|
1423
|
-
display("");
|
|
1424
|
-
display("➡️ Transition vers Ralph Loop...");
|
|
1425
|
-
display("");
|
|
1426
|
-
|
|
1427
|
-
// Call the ralph-loop skill (no arguments needed - prd.json exists)
|
|
1428
|
-
Skill({ skill: "ralph-loop" });
|
|
1429
|
-
|
|
1430
|
-
// EXIT - ralph-loop takes over
|
|
1431
|
-
// The skill does NOT return here - ralph-loop continues in a new context
|
|
1432
|
-
|
|
1433
|
-
} else if (choiceLabel === "Feature Full") {
|
|
1434
|
-
// Launch feature-full skill automatically
|
|
1435
|
-
display("");
|
|
1436
|
-
display("🚀 Lancement de Feature Full...");
|
|
1437
|
-
display("");
|
|
1438
|
-
display(" Configuration:");
|
|
1439
|
-
display(" - Mode: Parallel generation");
|
|
1440
|
-
display(" - Couverture: 70-80%");
|
|
1441
|
-
display(" - Durée estimée: ~" + Math.round(totalHours / 3) + " heures");
|
|
1442
|
-
display("");
|
|
1443
|
-
display("═══════════════════════════════════════════════════════════════");
|
|
1444
|
-
display("");
|
|
1445
|
-
|
|
1446
|
-
Skill({ skill: "feature-full" });
|
|
1447
|
-
|
|
1448
|
-
// EXIT
|
|
1449
|
-
|
|
1450
|
-
} else {
|
|
1451
|
-
// "Terminer le BA" - no skill launch, end gracefully
|
|
1452
|
-
display("");
|
|
1453
|
-
display("✅ Business Analysis terminée.");
|
|
1454
|
-
display("");
|
|
1455
|
-
display(" Les équipes peuvent commencer le développement manuel.");
|
|
1456
|
-
display(" Tous les artefacts sont prêts pour l'implémentation.");
|
|
1457
|
-
display("");
|
|
1458
|
-
display("📂 Fichiers générés:");
|
|
1459
|
-
display(" - feature.json (master + modules) - Spécification complète");
|
|
1460
|
-
display(" - .ralph/prd.json (ou prd-{module}.json) - Task breakdown");
|
|
1461
|
-
display(" - .ralph/progress.txt - Tracker de progression");
|
|
1462
|
-
display(" - ba-interactive.html - Document de revue client");
|
|
1463
|
-
display("");
|
|
1464
|
-
display("📊 Métriques:");
|
|
1465
|
-
display(" - Modules: " + modules.length);
|
|
1466
|
-
display(" - Entités: " + totalEntities);
|
|
1467
|
-
display(" - Use cases: " + totalUseCases);
|
|
1468
|
-
display(" - Business rules: " + totalBusinessRules);
|
|
1469
|
-
display(" - Fichiers à créer: " + totalFiles);
|
|
1470
|
-
display("");
|
|
1471
|
-
display("🎯 Prochaines étapes recommandées:");
|
|
1472
|
-
display(" 1. Ouvrir ba-interactive.html dans le navigateur");
|
|
1473
|
-
display(" 2. Partager avec les stakeholders pour validation finale");
|
|
1474
|
-
display(" 3. Utiliser progress.txt comme guide de développement");
|
|
1475
|
-
display(" 4. Implémenter module par module selon l'ordre topologique");
|
|
1476
|
-
display("");
|
|
1477
|
-
display("💡 Pour lancer le développement assisté plus tard:");
|
|
1478
|
-
display(" - Ralph Loop: /ralph-loop (détecte automatiquement .ralph/prd.json)");
|
|
1479
|
-
display(" - Feature Full: /feature-full");
|
|
1480
|
-
display("");
|
|
1481
|
-
display("═══════════════════════════════════════════════════════════════");
|
|
1482
|
-
|
|
1483
|
-
// EXIT gracefully - BA workflow complete
|
|
1484
|
-
}
|
|
1485
|
-
```
|
|
1486
|
-
|
|
1487
|
-
**Key behaviors:**
|
|
1488
|
-
|
|
1489
|
-
1. **Ralph Loop launch:**
|
|
1490
|
-
- No arguments needed (prd.json already exists)
|
|
1491
|
-
- Ralph automatically detects single vs multi-module
|
|
1492
|
-
- Ralph reads modules-queue.json if multi-module
|
|
1493
|
-
- Seamless transition - user sees continuous flow
|
|
1494
|
-
|
|
1495
|
-
2. **Feature Full launch:**
|
|
1496
|
-
- Passes application context
|
|
1497
|
-
- Parallel generation starts immediately
|
|
1498
|
-
|
|
1499
|
-
3. **Manual development:**
|
|
1500
|
-
- Clear summary of generated artifacts
|
|
1501
|
-
- Actionable next steps
|
|
1502
|
-
- Instructions for later skill launch
|
|
1503
|
-
|
|
1504
|
-
**Error handling:**
|
|
1505
|
-
|
|
1506
|
-
```javascript
|
|
1507
|
-
try {
|
|
1508
|
-
Skill({ skill: "ralph-loop" });
|
|
1509
|
-
} catch (error) {
|
|
1510
|
-
display("⚠️ Échec du lancement automatique de Ralph Loop");
|
|
1511
|
-
display("");
|
|
1512
|
-
display(" Veuillez lancer manuellement:");
|
|
1513
|
-
display(" /ralph-loop");
|
|
1514
|
-
display("");
|
|
1515
|
-
display(" Si le problème persiste:");
|
|
1516
|
-
display(" 1. Vérifier que la skill ralph-loop est installée");
|
|
1517
|
-
display(" 2. Vérifier les permissions Claude Code");
|
|
1518
|
-
display(" 3. Consulter les logs: .ralph/logs/");
|
|
1519
|
-
}
|
|
1520
|
-
```
|
|
1521
|
-
|
|
1522
|
-
---
|
|
1523
|
-
|
|
1524
|
-
## MODE SUPPORT
|
|
1525
|
-
|
|
1526
|
-
### Standard Mode
|
|
1527
|
-
|
|
1528
|
-
Full handoff with all implementation details:
|
|
1529
|
-
- All 7 file categories
|
|
1530
|
-
- Complete BR-to-code mapping
|
|
1531
|
-
- Full API endpoint summary
|
|
1532
|
-
- Detailed prd.json
|
|
1533
|
-
- Comprehensive progress tracker
|
|
1534
|
-
|
|
1535
|
-
### Micro Mode (use_case = micro)
|
|
1536
|
-
|
|
1537
|
-
Simplified handoff with minimal scope:
|
|
1538
|
-
- Only essential CRUD entity + controller
|
|
1539
|
-
- 3 core SeedData entries (omit some optional ones)
|
|
1540
|
-
- Basic prd.json with simplified sections
|
|
1541
|
-
- Lightweight progress.txt
|
|
1542
|
-
- Auto-suggest Feature Full for rapid development
|
|
1543
|
-
|
|
1544
|
-
### Delta Mode (use_case = refactoring)
|
|
1545
|
-
|
|
1546
|
-
Focused handoff for changes:
|
|
1547
|
-
- Only affected modules listed
|
|
1548
|
-
- Reuse existing implementation patterns
|
|
1549
|
-
- Highlight what changed vs baseline
|
|
1550
|
-
- Update only affected prd.json sections
|
|
1551
|
-
- Progress tracker shows only delta tasks
|
|
1552
|
-
|
|
1553
|
-
---
|
|
1554
|
-
|
|
1555
|
-
## OUTPUT
|
|
1556
|
-
|
|
1557
|
-
> **FORBIDDEN:** Do NOT generate separate JSON files (specification.json, analysis.json, etc.).
|
|
1558
|
-
> **ONLY:** feature.json is the mandatory JSON deliverable.
|
|
1559
|
-
> **PLUS:** prd.json and progress.txt are additional working files.
|
|
1560
|
-
|
|
1561
|
-
This step enriches **feature.json** (master + per-module) with:
|
|
1562
|
-
- **handoff** section: complexity, implementationStrategy, moduleOrder, filesToCreate (7 categories), brToCodeMapping, apiEndpointSummary, prdFiles
|
|
1563
|
-
- **status:** "handed-off"
|
|
1564
|
-
|
|
1565
|
-
Also generates working files and updates the manifest:
|
|
1566
|
-
|
|
1567
|
-
- **ba-interactive.html** (deployed to docs/business/{app}/business-analyse/v{version}/)
|
|
1568
|
-
- Standalone interactive HTML document for client review
|
|
1569
|
-
- Pre-populated with application name, ID, version
|
|
1570
|
-
- Client can edit, add use cases, modify scope, and export JSON
|
|
1571
|
-
- Re-importable via `/business-analyse -x <exported-json-path>`
|
|
1572
|
-
|
|
1573
|
-
- **.ralph/prd.json** (or .ralph/prd-{module}.json per module structure)
|
|
1574
|
-
- Derived entirely from feature.json
|
|
1575
|
-
- Single source of truth for development team
|
|
1576
|
-
- Includes all entities, use cases, business rules, API endpoints
|
|
1577
|
-
- Task breakdown and implementation sequence
|
|
1578
|
-
|
|
1579
|
-
- **.ralph/progress.txt**
|
|
1580
|
-
- Main development task tracker
|
|
1581
|
-
- Hierarchical structure (module → layer → tasks)
|
|
1582
|
-
- Checkboxes for progress tracking
|
|
1583
|
-
- Effort estimates per module
|
|
1584
|
-
- Cross-module integration tasks (if multi-module)
|
|
1585
|
-
|
|
1586
|
-
Next agent selection via user question:
|
|
1587
|
-
1. **Feature Full** - Parallel rapid code generation (70-80% coverage)
|
|
1588
|
-
2. **Ralph Loop** - Sequential task-driven development (95-100% coverage)
|
|
1589
|
-
3. **End BA** - Manual development by team
|
|
1590
|
-
|
|
1591
|
-
---
|
|
1592
|
-
|
|
1593
|
-
## EXAMPLES & TEMPLATES
|
|
1594
|
-
|
|
1595
|
-
### Example: Simple Single Module (Orders)
|
|
1596
|
-
|
|
1597
|
-
**Feature:** Order Management
|
|
1598
|
-
**Module:** Orders (1 entity, 2 use cases, 3 BRs)
|
|
1599
|
-
|
|
1600
|
-
**Output:**
|
|
1601
|
-
- feature.json with handoff section
|
|
1602
|
-
- .ralph/prd.json (single consolidated file)
|
|
1603
|
-
- .ralph/progress.txt (~150 lines, 20-30 tasks)
|
|
1604
|
-
|
|
1605
|
-
Strategy: Module by module (only 1 module)
|
|
1606
|
-
|
|
1607
|
-
### Example: Medium Multi-Module (E-Commerce)
|
|
1608
|
-
|
|
1609
|
-
**Feature:** E-Commerce Platform
|
|
1610
|
-
**Modules:** Customers (4 entities), Products (6 entities), Orders (8 entities), Invoices (3 entities)
|
|
1611
|
-
|
|
1612
|
-
**Dependencies:**
|
|
1613
|
-
- Customers: Foundation (no deps)
|
|
1614
|
-
- Products: Foundation (no deps)
|
|
1615
|
-
- Orders: Depends on Customers + Products
|
|
1616
|
-
- Invoices: Depends on Orders
|
|
1617
|
-
|
|
1618
|
-
**Output:**
|
|
1619
|
-
- feature.json (master + 4 module features) with handoff sections
|
|
1620
|
-
- User chooses: per-module prd (.ralph/prd-customers.json, .ralph/prd-products.json, etc.) or consolidated (.ralph/prd.json)
|
|
1621
|
-
- .ralph/progress.txt (~400 lines, 100+ tasks)
|
|
1622
|
-
- Module order: Customers, Products → Orders → Invoices (topological)
|
|
1623
|
-
|
|
1624
|
-
Strategy options: Module by module (recommended), Layer by layer, Hybrid
|
|
1625
|
-
|
|
1626
|
-
### Example: Complex Multi-Module (ERP)
|
|
1627
|
-
|
|
1628
|
-
**Feature:** Enterprise Resource Planning
|
|
1629
|
-
**Modules:** Accounting, Sales, Purchasing, Inventory, HR, Finance (20+ entities total, 50+ use cases, 100+ BRs)
|
|
1630
|
-
|
|
1631
|
-
**Output:**
|
|
1632
|
-
- feature.json (master + 6 module features) with handoff sections
|
|
1633
|
-
- Per-module prd.json (recommended for complexity management)
|
|
1634
|
-
- .ralph/progress.txt (~800+ lines, 200+ tasks)
|
|
1635
|
-
|
|
1636
|
-
Complexity: Complex (highest across all modules)
|
|
1637
|
-
Strategy: Hybrid recommended (Foundation modules layer-by-layer, then dependent modules module-by-module)
|
|
1638
|
-
|
|
1639
|
-
---
|
|
1640
|
-
|
|
1641
|
-
## VALIDATION CHECKLIST
|
|
1642
|
-
|
|
1643
|
-
Before presenting handoff to user:
|
|
1644
|
-
|
|
1645
|
-
- [ ] Status verified: "consolidated"
|
|
1646
|
-
- [ ] Implementation strategy selected or defaulted
|
|
1647
|
-
- [ ] Complexity calculated for each module and overall
|
|
1648
|
-
- [ ] filesToCreate: 7 categories complete, no free text
|
|
1649
|
-
- [ ] **WIREFRAME TRACEABILITY:** Every frontend Page/DashboardPage has `linkedWireframes[]` referencing specification.uiWireframes[].screen
|
|
1650
|
-
- [ ] **WIREFRAME ACCEPTANCE:** Every frontend Page/DashboardPage has `wireframeAcceptanceCriteria` describing expected layout
|
|
1651
|
-
- [ ] brToCodeMapping: All business rules from analysis.businessRules[] mapped
|
|
1652
|
-
- [ ] apiEndpointSummary: Exact copy from specification.apiEndpoints[]
|
|
1653
|
-
- [ ] prd.json: Derived from feature.json, not independently generated
|
|
1654
|
-
- [ ] prd.json: Includes all UCs, FRs, BRs, entities, API endpoints from source
|
|
1655
|
-
- [ ] progress.txt: Hierarchical, all modules in topological order, 5 CORE SeedData per module
|
|
1656
|
-
- [ ] progress.txt: Frontend tasks reference wireframe identifiers [wireframe: {screen}]
|
|
1657
|
-
- [ ] Module order: Follows topological dependency graph
|
|
1658
|
-
- [ ] feature.json updated: handoff section + status "handed-off"
|
|
1659
|
-
- [ ] All paths use project namespace from .smartstack/config.json
|
|
1660
|
-
- [ ] No invented requirements (everything traced to feature.json)
|
|
1661
|
-
- [ ] ba-interactive.html deployed PRE-POPULATED with all analysis data (not empty)
|
|
1662
|
-
- [ ] BA manifest (docs/business/index.json) updated with current analysis entries
|
|
1663
|
-
- [ ] User ready for next agent selection
|
|
1664
|
-
|
|
1665
|
-
---
|
|
1666
|
-
|
|
1667
|
-
## TROUBLESHOOTING
|
|
1668
|
-
|
|
1669
|
-
| Issue | Resolution |
|
|
1670
|
-
|-------|-----------|
|
|
1671
|
-
| Status ≠ "consolidated" | Stop. Return to step-04-consolidation.md. |
|
|
1672
|
-
| No specification section | Cannot generate handoff without specification. Return to step-02-specify.md. |
|
|
1673
|
-
| Missing apiEndpoints | Copy exact routes from specification.apiEndpoints[] (absolute rule). |
|
|
1674
|
-
| BR not in analysis | Do not invent. Update feature.json analysis section. |
|
|
1675
|
-
| Circular dependencies | Reorder modules or break circular dependency. Notify user. |
|
|
1676
|
-
| prd.json too large | Use per-module structure instead of consolidated (multi-module). |
|
|
1677
|
-
| Progress.txt tasks unclear | Ensure each task is atomic and independently assignable. |
|
|
1678
|
-
| Module complexity unclear | Recalculate using entity count, UC count, BR count against thresholds. |
|
|
1679
|
-
|
|
1680
|
-
---
|
|
1681
|
-
|
|
1682
|
-
END OF STEP 5: HANDOFF
|