@atlashub/smartstack-cli 4.23.0 → 4.25.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/package.json +1 -1
- package/templates/skills/ba-generate-html/html/ba-interactive.html +950 -1055
- package/templates/skills/ba-generate-html/html/src/scripts/01-data-init.js +1 -2
- package/templates/skills/ba-generate-html/html/src/scripts/02-navigation.js +0 -1
- package/templates/skills/ba-generate-html/html/src/scripts/03-render-cadrage.js +0 -39
- package/templates/skills/ba-generate-html/html/src/scripts/05-render-specs.js +0 -1
- package/templates/skills/ba-generate-html/html/src/scripts/07-render-handoff.js +0 -1
- package/templates/skills/ba-generate-html/html/src/scripts/08-editing.js +133 -135
- package/templates/skills/ba-generate-html/html/src/scripts/10-comments.js +199 -199
- package/templates/skills/ba-generate-html/html/src/scripts/11-review-panel.js +165 -166
- package/templates/skills/ba-generate-html/html/src/styles/05-modules.css +444 -454
- package/templates/skills/ba-generate-html/html/src/template.html +0 -49
- package/templates/skills/ba-generate-html/references/data-build.md +176 -182
- package/templates/skills/ba-generate-html/references/data-mapping.md +295 -301
- package/templates/skills/ba-generate-html/steps/step-01-collect.md +1 -1
- package/templates/skills/ba-generate-html/steps/step-02-build-data.md +0 -9
- package/templates/skills/derive-prd/SKILL.md +9 -9
- package/templates/skills/derive-prd/references/acceptance-criteria.md +166 -116
- package/templates/skills/derive-prd/references/entity-domain-mapping.md +5 -5
- package/templates/skills/derive-prd/references/handoff-file-templates.md +12 -12
- package/templates/skills/derive-prd/references/handoff-mappings.md +13 -14
- package/templates/skills/derive-prd/references/handoff-seeddata-generation.md +1 -1
- package/templates/skills/derive-prd/references/readiness-scoring.md +41 -50
- package/templates/skills/derive-prd/schemas/handoff-schema.json +2 -2
- package/templates/skills/derive-prd/steps/step-00-validate.md +73 -52
- package/templates/skills/derive-prd/steps/step-01-transform.md +86 -43
- package/templates/skills/ba-generate-html/html/src/partials/cadrage-risks.html +0 -48
|
@@ -1,301 +1,295 @@
|
|
|
1
|
-
# HTML Data Mapping Reference
|
|
2
|
-
|
|
3
|
-
> **Used by:** `/ba-generate-html` skill (step-02-build-data)
|
|
4
|
-
> **Purpose:** Exact mapping from module JSON files to HTML FEATURE_DATA and EMBEDDED_ARTIFACTS objects
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## FEATURE_DATA Mapping
|
|
9
|
-
|
|
10
|
-
Build a JSON object following this **exact mapping** from index.json to the HTML data model:
|
|
11
|
-
|
|
12
|
-
```javascript
|
|
13
|
-
{
|
|
14
|
-
metadata: {
|
|
15
|
-
applicationName: master.metadata.application, // e.g. "RH"
|
|
16
|
-
applicationId: master.id, // e.g. "FEAT-001"
|
|
17
|
-
version: master.version, // e.g. "1.0"
|
|
18
|
-
createdAt: master.metadata.createdAt,
|
|
19
|
-
lastModified: master.metadata.updatedAt,
|
|
20
|
-
analysisMode: master.metadata.analysisMode || "interactive" // always "interactive" in JSON format
|
|
21
|
-
},
|
|
22
|
-
cadrage: {
|
|
23
|
-
// CONTEXT SECTION — lean format (merged from problem/asIs/toBe)
|
|
24
|
-
// NOTE: 01-data-init.js has backward compat for old problem/current/vision format
|
|
25
|
-
context: {
|
|
26
|
-
problem: master.cadrage.problem || "", // flat string from index.json
|
|
27
|
-
trigger: master.cadrage.trigger || "", // flat string from index.json
|
|
28
|
-
currentSituation: master.cadrage.asIs || "", // flat string from index.json
|
|
29
|
-
desiredSituation: master.cadrage.toBe || "", // flat string from index.json
|
|
30
|
-
painPoints: (master.cadrage.stakeholders || [])
|
|
31
|
-
.flatMap(s => s.painPoints || []).join("\n"), // aggregate all painPoints
|
|
32
|
-
acceptanceCriteria: (master.cadrage.acceptanceCriteria || [])
|
|
33
|
-
.map(ac => ac.criterion).join("\n") // AC → newline-separated string
|
|
34
|
-
},
|
|
35
|
-
stakeholders: master.cadrage.stakeholders.map(s => ({
|
|
36
|
-
role: s.role,
|
|
37
|
-
function: s.function || "",
|
|
38
|
-
tasks: s.tasks || [],
|
|
39
|
-
frequency: mapFrequency(s.frequency), // "Quotidien"→"daily", etc.
|
|
40
|
-
access: mapAccess(s.involvement), // "decision-maker"→"admin", "end-user"→"contributor"
|
|
41
|
-
frustrations: (s.painPoints || []).join("\n")
|
|
42
|
-
})),
|
|
43
|
-
scope: {
|
|
44
|
-
vital: (master.cadrage.globalScope.mustHave || [])
|
|
45
|
-
.map(item => ({ name: item, description: "" })), // string[] → {name,description}[]
|
|
46
|
-
important: (master.cadrage.globalScope.shouldHave || [])
|
|
47
|
-
.map(item => ({ name: item, description: "" })),
|
|
48
|
-
optional: (master.cadrage.globalScope.couldHave || [])
|
|
49
|
-
.map(item => ({ name: item, description: "" })),
|
|
50
|
-
excluded: (master.cadrage.globalScope.outOfScope || [])
|
|
51
|
-
.map(item => ({ name: item, description: "" }))
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
})),
|
|
118
|
-
|
|
119
|
-
name:
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
//
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
3. Replace `{{FEATURE_DATA}}` with the serialized FEATURE_DATA JSON
|
|
297
|
-
4. Replace `{{EMBEDDED_ARTIFACTS}}` with the serialized EMBEDDED_ARTIFACTS JSON
|
|
298
|
-
5. Replace `{{APPLICATION_NAME}}` → `{application_name}` (still used in `<title>` and header)
|
|
299
|
-
6. Replace `{{APPLICATION_ID}}` → `{feature_id}` (still used in `APP_KEY`)
|
|
300
|
-
7. Replace `{{VERSION}}` → `{version}`
|
|
301
|
-
8. Replace `{{CREATED_AT}}` → `{ISO timestamp}`
|
|
1
|
+
# HTML Data Mapping Reference
|
|
2
|
+
|
|
3
|
+
> **Used by:** `/ba-generate-html` skill (step-02-build-data)
|
|
4
|
+
> **Purpose:** Exact mapping from module JSON files to HTML FEATURE_DATA and EMBEDDED_ARTIFACTS objects
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## FEATURE_DATA Mapping
|
|
9
|
+
|
|
10
|
+
Build a JSON object following this **exact mapping** from index.json to the HTML data model:
|
|
11
|
+
|
|
12
|
+
```javascript
|
|
13
|
+
{
|
|
14
|
+
metadata: {
|
|
15
|
+
applicationName: master.metadata.application, // e.g. "RH"
|
|
16
|
+
applicationId: master.id, // e.g. "FEAT-001"
|
|
17
|
+
version: master.version, // e.g. "1.0"
|
|
18
|
+
createdAt: master.metadata.createdAt,
|
|
19
|
+
lastModified: master.metadata.updatedAt,
|
|
20
|
+
analysisMode: master.metadata.analysisMode || "interactive" // always "interactive" in JSON format
|
|
21
|
+
},
|
|
22
|
+
cadrage: {
|
|
23
|
+
// CONTEXT SECTION — lean format (merged from problem/asIs/toBe)
|
|
24
|
+
// NOTE: 01-data-init.js has backward compat for old problem/current/vision format
|
|
25
|
+
context: {
|
|
26
|
+
problem: master.cadrage.problem || "", // flat string from index.json
|
|
27
|
+
trigger: master.cadrage.trigger || "", // flat string from index.json
|
|
28
|
+
currentSituation: master.cadrage.asIs || "", // flat string from index.json
|
|
29
|
+
desiredSituation: master.cadrage.toBe || "", // flat string from index.json
|
|
30
|
+
painPoints: (master.cadrage.stakeholders || [])
|
|
31
|
+
.flatMap(s => s.painPoints || []).join("\n"), // aggregate all painPoints
|
|
32
|
+
acceptanceCriteria: (master.cadrage.acceptanceCriteria || [])
|
|
33
|
+
.map(ac => ac.criterion).join("\n") // AC → newline-separated string
|
|
34
|
+
},
|
|
35
|
+
stakeholders: master.cadrage.stakeholders.map(s => ({
|
|
36
|
+
role: s.role,
|
|
37
|
+
function: s.function || "",
|
|
38
|
+
tasks: s.tasks || [],
|
|
39
|
+
frequency: mapFrequency(s.frequency), // "Quotidien"→"daily", etc.
|
|
40
|
+
access: mapAccess(s.involvement), // "decision-maker"→"admin", "end-user"→"contributor"
|
|
41
|
+
frustrations: (s.painPoints || []).join("\n")
|
|
42
|
+
})),
|
|
43
|
+
scope: {
|
|
44
|
+
vital: (master.cadrage.globalScope.mustHave || [])
|
|
45
|
+
.map(item => ({ name: item, description: "" })), // string[] → {name,description}[]
|
|
46
|
+
important: (master.cadrage.globalScope.shouldHave || [])
|
|
47
|
+
.map(item => ({ name: item, description: "" })),
|
|
48
|
+
optional: (master.cadrage.globalScope.couldHave || [])
|
|
49
|
+
.map(item => ({ name: item, description: "" })),
|
|
50
|
+
excluded: (master.cadrage.globalScope.outOfScope || [])
|
|
51
|
+
.map(item => ({ name: item, description: "" }))
|
|
52
|
+
},
|
|
53
|
+
criteria: (master.cadrage.acceptanceCriteria || []).map(ac => ({
|
|
54
|
+
text: ac.criterion,
|
|
55
|
+
validated: ac.validated || false
|
|
56
|
+
}))
|
|
57
|
+
},
|
|
58
|
+
modules: master.modules.map(m => ({
|
|
59
|
+
code: m.code,
|
|
60
|
+
name: m.name || m.code, // display name (MANDATORY, separate from code)
|
|
61
|
+
description: m.description || "",
|
|
62
|
+
featureType: m.featureType || "data-centric",
|
|
63
|
+
priority: m.priority || "must",
|
|
64
|
+
entities: m.entities || [],
|
|
65
|
+
anticipatedSections: m.anticipatedSections || [], // [{code, description, resources[]}]
|
|
66
|
+
dependencies: m.dependencies || [],
|
|
67
|
+
dependents: m.dependents || [],
|
|
68
|
+
estimatedComplexity: m.estimatedComplexity || "medium",
|
|
69
|
+
status: m.status || "handed-off"
|
|
70
|
+
})),
|
|
71
|
+
dependencies: (master.dependencyGraph?.edges || []).map(e => ({
|
|
72
|
+
from: e.from,
|
|
73
|
+
to: e.to,
|
|
74
|
+
description: e.description || ""
|
|
75
|
+
})),
|
|
76
|
+
moduleSpecs: {
|
|
77
|
+
// FOR EACH module: read module index.json, then map:
|
|
78
|
+
// [moduleCode]: { useCases, businessRules, entities, permissions, notes, mockupNotes }
|
|
79
|
+
},
|
|
80
|
+
consolidation: {
|
|
81
|
+
interactions: (master.consolidation?.crossModuleInteractions || []).map(i => ({
|
|
82
|
+
from: i.fromModule,
|
|
83
|
+
to: i.toModule,
|
|
84
|
+
description: i.description || ""
|
|
85
|
+
})),
|
|
86
|
+
e2eFlows: (master.consolidation?.e2eFlows || []).map(f => ({
|
|
87
|
+
name: f.name,
|
|
88
|
+
steps: (f.steps || []).map(s => ({ module: s.module, action: s.action })),
|
|
89
|
+
actors: (f.steps || []).map(s => s.permission).join(", ")
|
|
90
|
+
}))
|
|
91
|
+
},
|
|
92
|
+
handoff: master.handoff || {}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Module Specs Mapping
|
|
97
|
+
|
|
98
|
+
For EACH module in `master.modules[]`:
|
|
99
|
+
|
|
100
|
+
1. Read the module index.json at `master.modules[i].featureJsonPath`
|
|
101
|
+
2. Map to `moduleSpecs[moduleCode]`:
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
moduleSpecs[moduleCode] = {
|
|
105
|
+
useCases: (moduleFeature.specification?.useCases || []).map(uc => ({
|
|
106
|
+
name: uc.name,
|
|
107
|
+
actor: uc.primaryActor,
|
|
108
|
+
steps: (uc.mainScenario || []).join("\n"), // array → newline-separated string
|
|
109
|
+
alternative: (uc.alternativeScenarios || [])
|
|
110
|
+
.map(a => a.name + ": " + (a.steps || []).join(", ")).join("\n")
|
|
111
|
+
})),
|
|
112
|
+
businessRules: (moduleFeature.analysis?.businessRules || []).map(br => ({
|
|
113
|
+
name: br.name,
|
|
114
|
+
category: br.category, // "validation"|"calculation"|"workflow"|"security"|"data"
|
|
115
|
+
statement: br.statement,
|
|
116
|
+
example: (br.examples || []).map(e => e.input + " → " + e.expected).join("; ")
|
|
117
|
+
})),
|
|
118
|
+
entities: (moduleFeature.analysis?.entities || []).map(ent => ({
|
|
119
|
+
name: ent.name,
|
|
120
|
+
description: ent.description || "",
|
|
121
|
+
attributes: (ent.attributes || []).map(a => ({
|
|
122
|
+
name: a.name,
|
|
123
|
+
type: a.type || "string", // string, int, decimal, date, datetime, bool, enum, guid, text
|
|
124
|
+
required: a.required || false,
|
|
125
|
+
description: a.description || ""
|
|
126
|
+
})),
|
|
127
|
+
relationships: (ent.relationships || []).map(r =>
|
|
128
|
+
r.target + " (" + r.type + ") - " + (r.description || "")
|
|
129
|
+
)
|
|
130
|
+
})),
|
|
131
|
+
permissions: buildPermissionKeys(moduleFeature), // see below
|
|
132
|
+
notes: "",
|
|
133
|
+
mockupNotes: "" // Deprecated: wireframes now embedded separately in EMBEDDED_ARTIFACTS
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Permission Keys Function
|
|
138
|
+
|
|
139
|
+
The HTML uses `"Role|Action"` format (e.g. `"RH Admin|Consulter"`):
|
|
140
|
+
|
|
141
|
+
```javascript
|
|
142
|
+
function buildPermissionKeys(moduleFeature) {
|
|
143
|
+
const keys = [];
|
|
144
|
+
const matrix = moduleFeature.specification?.permissionMatrix;
|
|
145
|
+
if (!matrix) return keys;
|
|
146
|
+
const actionMap = { read: "Consulter", create: "Creer", update: "Modifier",
|
|
147
|
+
delete: "Supprimer", validate: "Valider", export: "Exporter",
|
|
148
|
+
submit: "Valider", import: "Creer" };
|
|
149
|
+
(matrix.roleAssignments || []).forEach(ra => {
|
|
150
|
+
(ra.permissions || []).forEach(permPath => {
|
|
151
|
+
const action = permPath.split(".").pop(); // last segment = action
|
|
152
|
+
if (action === "*") {
|
|
153
|
+
// Wildcard: expand to all standard actions
|
|
154
|
+
Object.values(actionMap).forEach(uiAction => {
|
|
155
|
+
const key = ra.role + "|" + uiAction;
|
|
156
|
+
if (!keys.includes(key)) keys.push(key);
|
|
157
|
+
});
|
|
158
|
+
} else {
|
|
159
|
+
const uiAction = actionMap[action] || action;
|
|
160
|
+
keys.push(ra.role + "|" + uiAction);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
return keys;
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Frequency Mapping
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
"Quotidien" → "daily", "Hebdomadaire" → "weekly", "Mensuel" → "monthly"
|
|
172
|
+
Default: "daily"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Access Mapping (involvement → access)
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
"decision-maker" → "admin", "end-user" with manager-like tasks → "manager"
|
|
179
|
+
"end-user" → "contributor", "observer" → "viewer"
|
|
180
|
+
Default: "contributor"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## EMBEDDED_ARTIFACTS Mapping
|
|
186
|
+
|
|
187
|
+
> **FIELD RENAME WARNING:** Module JSON files store wireframes with `mockupFormat` and `mockup` fields.
|
|
188
|
+
> The HTML renderer reads `format` and `content`. You MUST rename: `mockupFormat` → `format`, `mockup` → `content`.
|
|
189
|
+
> Failure to rename = empty mockup display in the browser.
|
|
190
|
+
|
|
191
|
+
Build a JSON object containing ALL visual artifacts from module JSON files (index.json):
|
|
192
|
+
|
|
193
|
+
```javascript
|
|
194
|
+
{
|
|
195
|
+
wireframes: {
|
|
196
|
+
// FOR EACH module: extract all wireframes from module index.json
|
|
197
|
+
// [moduleCode]: [ {screen, format, content, elements, componentMapping, layout, description} ]
|
|
198
|
+
},
|
|
199
|
+
e2eFlows: [
|
|
200
|
+
// Extract from master consolidation.e2eFlows[]
|
|
201
|
+
// { name, diagram, steps, actors }
|
|
202
|
+
],
|
|
203
|
+
dependencyGraph: {
|
|
204
|
+
// Extract from master dependencyGraph
|
|
205
|
+
// nodes: [ {id, label, type} ], edges: [ {from, to, description} ]
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Wireframes Mapping
|
|
211
|
+
|
|
212
|
+
For EACH module in `master.modules[]`:
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
// Read the module index.json file
|
|
216
|
+
const moduleFeature = readModuleFeature(moduleCode);
|
|
217
|
+
const wireframes = (moduleFeature.specification?.uiWireframes || []).map(wf => ({
|
|
218
|
+
screen: wf.screen, // e.g. "UM-list", "UM-form"
|
|
219
|
+
section: wf.section, // e.g. "list", "form"
|
|
220
|
+
format: wf.mockupFormat || "ascii", // "ascii" | "svg"
|
|
221
|
+
content: wf.mockup, // ASCII art or SVG markup
|
|
222
|
+
description: wf.description || "",
|
|
223
|
+
elements: wf.elements || [], // ["DataGrid", "FilterBar", ...]
|
|
224
|
+
actions: wf.actions || [], // ["filter", "sort", "create", ...]
|
|
225
|
+
componentMapping: wf.componentMapping || [], // [{ wireframeElement, reactComponent }]
|
|
226
|
+
layout: wf.layout || null, // { type, regions: [...] }
|
|
227
|
+
permissionsRequired: wf.permissionsRequired || []
|
|
228
|
+
}));
|
|
229
|
+
|
|
230
|
+
// Store in artifacts object
|
|
231
|
+
EMBEDDED_ARTIFACTS.wireframes[moduleCode] = wireframes;
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### E2E Flows Mapping
|
|
235
|
+
|
|
236
|
+
From master consolidation:
|
|
237
|
+
|
|
238
|
+
```javascript
|
|
239
|
+
EMBEDDED_ARTIFACTS.e2eFlows = (master.consolidation?.e2eFlows || []).map(flow => ({
|
|
240
|
+
name: flow.name,
|
|
241
|
+
diagram: generateE2EDiagram(flow), // ASCII diagram from flow.steps[]
|
|
242
|
+
steps: flow.steps || [], // [{ module, action, permission }]
|
|
243
|
+
actors: Array.from(new Set((flow.steps || [])
|
|
244
|
+
.map(s => s.permission?.split(".")[0]) // Extract role from permission path
|
|
245
|
+
.filter(Boolean))).join(", "),
|
|
246
|
+
modules: Array.from(new Set((flow.steps || [])
|
|
247
|
+
.map(s => s.module))).join(" → ")
|
|
248
|
+
}));
|
|
249
|
+
|
|
250
|
+
function generateE2EDiagram(flow) {
|
|
251
|
+
// Generate ASCII diagram from flow.steps[]
|
|
252
|
+
// Example output:
|
|
253
|
+
// "Customer ──[read]──→ Order ──[create]──→ Invoice ──[send]──→"
|
|
254
|
+
// " (Orders) (Orders) (Invoices)"
|
|
255
|
+
// " Contributor Manager System"
|
|
256
|
+
|
|
257
|
+
const stepDiagrams = (flow.steps || []).map(s =>
|
|
258
|
+
`${s.action}(${s.module})`
|
|
259
|
+
).join(" ──→ ");
|
|
260
|
+
|
|
261
|
+
return stepDiagrams;
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Dependency Graph Mapping
|
|
266
|
+
|
|
267
|
+
From master dependencyGraph:
|
|
268
|
+
|
|
269
|
+
```javascript
|
|
270
|
+
EMBEDDED_ARTIFACTS.dependencyGraph = {
|
|
271
|
+
nodes: (master.modules || []).map(m => ({
|
|
272
|
+
id: m.code,
|
|
273
|
+
label: m.code,
|
|
274
|
+
type: m.featureType || "data-centric"
|
|
275
|
+
})),
|
|
276
|
+
edges: (master.dependencyGraph?.edges || []).map(e => ({
|
|
277
|
+
from: e.from,
|
|
278
|
+
to: e.to,
|
|
279
|
+
description: e.description || ""
|
|
280
|
+
}))
|
|
281
|
+
};
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Usage in step-05-deploy
|
|
287
|
+
|
|
288
|
+
1. Serialize the FEATURE_DATA object as JSON (with 2-space indentation for readability)
|
|
289
|
+
2. Serialize the EMBEDDED_ARTIFACTS object as JSON (with 2-space indentation)
|
|
290
|
+
3. Replace `{{FEATURE_DATA}}` with the serialized FEATURE_DATA JSON
|
|
291
|
+
4. Replace `{{EMBEDDED_ARTIFACTS}}` with the serialized EMBEDDED_ARTIFACTS JSON
|
|
292
|
+
5. Replace `{{APPLICATION_NAME}}` → `{application_name}` (still used in `<title>` and header)
|
|
293
|
+
6. Replace `{{APPLICATION_ID}}` → `{feature_id}` (still used in `APP_KEY`)
|
|
294
|
+
7. Replace `{{VERSION}}` → `{version}`
|
|
295
|
+
8. Replace `{{CREATED_AT}}` → `{ISO timestamp}`
|
|
@@ -57,7 +57,7 @@ ELSE:
|
|
|
57
57
|
collected_data = {
|
|
58
58
|
master: {
|
|
59
59
|
index: READ(index.json), // metadata, modules[], consolidation, handoff
|
|
60
|
-
cadrage: READ(cadrage.json) // context, stakeholders, scope
|
|
60
|
+
cadrage: READ(cadrage.json) // context, stakeholders, scope
|
|
61
61
|
},
|
|
62
62
|
modules: {}
|
|
63
63
|
}
|
|
@@ -69,15 +69,6 @@ scope: {
|
|
|
69
69
|
|
|
70
70
|
> Safety net: also check `master.cadrage.coverageMatrix` as alternative source for scope items.
|
|
71
71
|
|
|
72
|
-
**cadrage.risks:**
|
|
73
|
-
```javascript
|
|
74
|
-
risks: (master.cadrage.risks || []).map(r => ({
|
|
75
|
-
description: r.description,
|
|
76
|
-
probability: r.probability,
|
|
77
|
-
impact: r.impact,
|
|
78
|
-
mitigation: r.mitigation || ""
|
|
79
|
-
}))
|
|
80
|
-
```
|
|
81
72
|
|
|
82
73
|
**modules[]:**
|
|
83
74
|
```javascript
|