@atlashub/smartstack-cli 4.74.0 → 4.76.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.
Files changed (121) hide show
  1. package/dist/index.js +152 -31
  2. package/dist/index.js.map +1 -1
  3. package/dist/mcp-entry.mjs +14 -3
  4. package/dist/mcp-entry.mjs.map +1 -1
  5. package/package.json +1 -1
  6. package/templates/agents/ba-reader.md +17 -15
  7. package/templates/agents/ba-writer.md +49 -51
  8. package/templates/skills/apex/SKILL.md +2 -2
  9. package/templates/skills/apex/_shared.md +1 -1
  10. package/templates/skills/apex/references/checks/backend-checks.sh +21 -7
  11. package/templates/skills/apex/references/checks/frontend-checks.sh +26 -0
  12. package/templates/skills/apex/references/checks/infrastructure-checks.sh +47 -10
  13. package/templates/skills/apex/references/checks/seed-checks.sh +47 -7
  14. package/templates/skills/apex/references/core-seed-data.md +20 -18
  15. package/templates/skills/apex/references/frontend-route-wiring-app-tsx.md +3 -0
  16. package/templates/skills/apex/references/post-checks.md +23 -3
  17. package/templates/skills/apex/references/smartstack-api.md +4 -4
  18. package/templates/skills/apex/references/smartstack-frontend.md +54 -8
  19. package/templates/skills/apex/references/smartstack-layers.md +6 -6
  20. package/templates/skills/apex/steps/step-00-init.md +75 -1
  21. package/templates/skills/apex/steps/step-03-execute.md +16 -4
  22. package/templates/skills/apex/steps/step-03b-layer1-seed.md +65 -6
  23. package/templates/skills/apex/steps/step-03c-layer2-backend.md +50 -5
  24. package/templates/skills/apex/steps/step-03d-layer3-frontend.md +226 -4
  25. package/templates/skills/apex/steps/step-04-examine.md +163 -0
  26. package/templates/skills/apex-verify/SKILL.md +110 -0
  27. package/templates/skills/apex-verify/references/audit-rules.md +50 -0
  28. package/templates/skills/apex-verify/steps/step-00-init.md +119 -0
  29. package/templates/skills/apex-verify/steps/step-01-nav-audit.md +92 -0
  30. package/templates/skills/apex-verify/steps/step-02-crud-audit.md +127 -0
  31. package/templates/skills/apex-verify/steps/step-03-perm-audit.md +119 -0
  32. package/templates/skills/apex-verify/steps/step-04-route-audit.md +98 -0
  33. package/templates/skills/apex-verify/steps/step-05-report.md +110 -0
  34. package/templates/skills/application/references/frontend-route-wiring-app-tsx.md +3 -0
  35. package/templates/skills/application/templates-frontend.md +2 -2
  36. package/templates/skills/business-analyse/SKILL.md +17 -3
  37. package/templates/skills/business-analyse/_shared.md +64 -0
  38. package/templates/skills/business-analyse/patterns/suggestion-catalog.md +34 -26
  39. package/templates/skills/business-analyse/questionnaire/01-context.md +13 -9
  40. package/templates/skills/business-analyse/questionnaire/02-stakeholders-scope.md +20 -27
  41. package/templates/skills/business-analyse/questionnaire.md +86 -9
  42. package/templates/skills/business-analyse/references/03-json-schemas.md +221 -0
  43. package/templates/skills/business-analyse/references/03-post-check-validation.md +208 -0
  44. package/templates/skills/business-analyse/references/03-smartstack-entity-guards.md +32 -0
  45. package/templates/skills/business-analyse/references/04-cross-module-validation.md +95 -0
  46. package/templates/skills/business-analyse/references/04-file-allocation.md +162 -0
  47. package/templates/skills/business-analyse/references/04-naming-audit-checks.md +174 -0
  48. package/templates/skills/business-analyse/references/04-semantic-validation-matrix.md +118 -0
  49. package/templates/skills/business-analyse/references/canonical-json-formats.md +7 -3
  50. package/templates/skills/business-analyse/references/domain-research-playbook.md +234 -0
  51. package/templates/skills/business-analyse/references/entity-sourcing-presentation.md +166 -0
  52. package/templates/skills/business-analyse/references/init-resume-logic.md +70 -0
  53. package/templates/skills/business-analyse/references/module-completeness-challenge.md +174 -0
  54. package/templates/skills/business-analyse/references/multi-app-detection.md +149 -0
  55. package/templates/skills/business-analyse/references/portal-classification.md +52 -0
  56. package/templates/skills/business-analyse/references/robustness-checks.md +1 -1
  57. package/templates/skills/business-analyse/references/validation-checklist.md +35 -6
  58. package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +50 -6
  59. package/templates/skills/business-analyse/steps/step-00-init.md +22 -190
  60. package/templates/skills/business-analyse/steps/step-01-cadrage.md +365 -269
  61. package/templates/skills/business-analyse/steps/step-02-structure.md +98 -20
  62. package/templates/skills/business-analyse/steps/step-03-specify.md +810 -229
  63. package/templates/skills/business-analyse/steps/step-04-consolidate.md +509 -278
  64. package/templates/skills/business-analyse-design/SKILL.md +10 -0
  65. package/templates/skills/business-analyse-design/references/screens-post-check.md +221 -0
  66. package/templates/skills/business-analyse-design/references/screens-type-mapping.md +138 -0
  67. package/templates/skills/business-analyse-design/references/smartcomponents-templates.md +225 -0
  68. package/templates/skills/{business-analyse → business-analyse-design}/references/spec-auto-inference.md +117 -117
  69. package/templates/skills/business-analyse-design/steps/step-01-screens.md +36 -162
  70. package/templates/skills/business-analyse-design/steps/step-02-wireframes.md +8 -7
  71. package/templates/skills/business-analyse-design/steps/step-03-navigation.md +89 -42
  72. package/templates/skills/business-analyse-develop/references/compact-loop.md +9 -0
  73. package/templates/skills/business-analyse-develop/references/handoff-quality-gate.md +132 -0
  74. package/templates/skills/business-analyse-develop/references/prd-v3-transformation.md +326 -0
  75. package/templates/skills/business-analyse-develop/references/report-reconciliation.md +140 -0
  76. package/templates/skills/business-analyse-develop/references/report-template.md +142 -0
  77. package/templates/skills/business-analyse-develop/steps/step-01-task.md +5 -177
  78. package/templates/skills/business-analyse-develop/steps/step-02-execute.md +17 -4
  79. package/templates/skills/business-analyse-develop/steps/step-03-commit.md +6 -2
  80. package/templates/skills/business-analyse-develop/steps/step-04-check.md +6 -0
  81. package/templates/skills/business-analyse-develop/steps/step-05-report.md +3 -269
  82. package/templates/skills/business-analyse-handoff/SKILL.md +10 -0
  83. package/templates/skills/business-analyse-handoff/references/agent-handoff-transform-prompt.md +211 -0
  84. package/templates/skills/business-analyse-handoff/references/context-isolation-pattern.md +47 -0
  85. package/templates/skills/business-analyse-handoff/references/handoff-file-inventory.md +49 -0
  86. package/templates/skills/business-analyse-handoff/references/handoff-global-validation.md +142 -0
  87. package/templates/skills/business-analyse-handoff/references/prd-validation-checks.md +125 -0
  88. package/templates/skills/business-analyse-handoff/references/project-index-update.md +98 -0
  89. package/templates/skills/business-analyse-handoff/steps/step-01-transform.md +9 -160
  90. package/templates/skills/business-analyse-handoff/steps/step-02-export.md +10 -99
  91. package/templates/skills/business-analyse-html/SKILL.md +10 -0
  92. package/templates/skills/business-analyse-html/html/ba-interactive.html +504 -97
  93. package/templates/skills/business-analyse-html/html/src/scripts/01-data-init.js +79 -2
  94. package/templates/skills/business-analyse-html/html/src/scripts/02-navigation.js +6 -46
  95. package/templates/skills/business-analyse-html/html/src/scripts/05-render-specs.js +80 -11
  96. package/templates/skills/business-analyse-html/html/src/scripts/06-render-consolidation.js +2 -2
  97. package/templates/skills/business-analyse-html/html/src/scripts/06-render-mockups.js +94 -36
  98. package/templates/skills/business-analyse-html/html/src/scripts/12-render-diagrams.js +162 -0
  99. package/templates/skills/business-analyse-html/html/src/styles/10-diagrams.css +73 -0
  100. package/templates/skills/business-analyse-html/html/src/template.html +2 -0
  101. package/templates/skills/business-analyse-html/references/02-embedded-artifacts-building.md +144 -0
  102. package/templates/skills/business-analyse-html/references/02-feature-data-building.md +143 -0
  103. package/templates/skills/business-analyse-html/references/02-mapping-tables.md +442 -0
  104. package/templates/skills/business-analyse-html/references/02-normalization-helpers.md +139 -0
  105. package/templates/skills/business-analyse-html/references/02-screen-format-detection.md +283 -0
  106. package/templates/skills/business-analyse-html/references/02-self-check-validation.md +199 -0
  107. package/templates/skills/business-analyse-html/references/data-build.md +24 -1
  108. package/templates/skills/business-analyse-html/references/data-mapping.md +119 -17
  109. package/templates/skills/business-analyse-html/steps/step-02-build-data.md +18 -555
  110. package/templates/skills/business-analyse-html/steps/step-04-verify.md +92 -3
  111. package/templates/skills/business-analyse-quick/SKILL.md +807 -0
  112. package/templates/skills/{sketch → business-analyse-quick}/references/domain-heuristics.md +59 -3
  113. package/templates/skills/business-analyse-quick/references/prd-schema.md +268 -0
  114. package/templates/skills/business-analyse-review/SKILL.md +10 -0
  115. package/templates/skills/business-analyse-review/references/review-data-mapping.md +6 -0
  116. package/templates/skills/business-analyse-status/SKILL.md +8 -0
  117. package/templates/skills/dev-start/SKILL.md +143 -307
  118. package/templates/skills/efcore/SKILL.md +13 -0
  119. package/templates/skills/sketch/SKILL.md +15 -153
  120. package/templates/skills/ui-components/SKILL.md +1 -1
  121. package/templates/skills/ui-components/patterns/data-table.md +1 -1
@@ -0,0 +1,442 @@
1
+ ---
2
+ name: 02-mapping-tables
3
+ description: Complete mapping tables for FEATURE_DATA object fields from master and collected_data sources
4
+ ---
5
+
6
+ # Mapping Tables
7
+
8
+ This reference documents all field mappings used when constructing the FEATURE_DATA object from collected BA data sources.
9
+
10
+ ---
11
+
12
+ ## Metadata Mapping
13
+
14
+ **Source:** `master.metadata` and root `master` fields
15
+
16
+ **Mapping:**
17
+ ```javascript
18
+ metadata: {
19
+ applicationName: master.metadata.application, // application name
20
+ applicationId: master.id, // application unique ID
21
+ version: master.version, // version string
22
+ createdAt: master.metadata.createdAt, // ISO timestamp
23
+ lastModified: master.metadata.updatedAt, // ISO timestamp
24
+ analysisMode: master.metadata.analysisMode || "interactive" // default: interactive
25
+ }
26
+ ```
27
+
28
+ ---
29
+
30
+ ## Cadrage Context Mapping
31
+
32
+ **Source:** `master.cadrage` object
33
+
34
+ **Mapping:**
35
+ ```javascript
36
+ cadrage.context: {
37
+ problem: master.cadrage.problem || "", // problem statement
38
+ trigger: master.cadrage.trigger || "", // what triggered the project
39
+ currentSituation: master.cadrage.asIs || "", // current state (AS-IS)
40
+ desiredSituation: master.cadrage.toBe || "", // desired state (TO-BE)
41
+ painPoints: (master.cadrage.stakeholders || []) // extracted from stakeholders
42
+ .flatMap(s => s.painPoints || [])
43
+ .join("\n"),
44
+ acceptanceCriteria: (master.cadrage.acceptanceCriteria || []) // AC list
45
+ .map(ac => ac.criterion)
46
+ .join("\n")
47
+ }
48
+ ```
49
+
50
+ **Validation:** Warn if `problem` or `currentSituation/desiredSituation` are empty — these are MANDATORY for the HTML viewer.
51
+
52
+ ---
53
+
54
+ ## Cadrage Stakeholders Mapping
55
+
56
+ **Source:** `master.cadrage.stakeholders[]`
57
+
58
+ **Mapping:**
59
+ ```javascript
60
+ cadrage.stakeholders: master.cadrage.stakeholders.map(s => ({
61
+ role: s.role, // role name
62
+ function: s.function || "", // job function
63
+ tasks: Array.isArray(s.tasks)
64
+ ? s.tasks // already an array
65
+ : typeof s.tasks === 'string'
66
+ ? s.tasks.split(',').map(t => t.trim()).filter(Boolean) // parse CSV string
67
+ : [],
68
+ frequency: mapFrequency(s.frequency), // frequency conversion
69
+ access: mapAccess(s.involvement), // involvement → access level conversion
70
+ frustrations: (s.painPoints || []).join("\n") // stakeholder pain points
71
+ }))
72
+ ```
73
+
74
+ **Helper: `mapFrequency(freq)`**
75
+
76
+ Maps user frequency to standardized values:
77
+ ```
78
+ "Quotidien" | "Journalière" | "daily" → "daily"
79
+ "Hebdomadaire" | "weekly" → "weekly"
80
+ "Mensuel" | "monthly" → "monthly"
81
+ "Trimestriel" | "quarterly" → "quarterly"
82
+ "Annuel" | "yearly" → "yearly"
83
+ default → freq (as-is)
84
+ ```
85
+
86
+ **Helper: `mapAccess(involvement)`**
87
+
88
+ Maps user involvement/role to access level:
89
+ ```
90
+ "decision-maker" | "approver" | "responsable" → "admin"
91
+ "end-user" | "user" | "utilisateur" → "contributor"
92
+ "observer" | "lecteur" | "stakeholder" → "viewer"
93
+ default → "viewer"
94
+ ```
95
+
96
+ ---
97
+
98
+ ## Cadrage Scope Mapping
99
+
100
+ **Source:** `master.cadrage.globalScope` and fallback `master.cadrage.coverageMatrix`
101
+
102
+ **Key Challenge:** Scope items can be strings, simple objects `{name, description}`, or complex objects `{feature, priority, module, app}`.
103
+
104
+ **Normalization Helper:**
105
+ ```javascript
106
+ function normalizeScopeItem(item) {
107
+ // Case 1: string value
108
+ if (typeof item === 'string') return { name: item, description: "" };
109
+
110
+ // Case 2: already in {name, description} format
111
+ if (item.name) return { name: item.name, description: item.description || "" };
112
+
113
+ // Case 3: {feature, priority, module, app} format (from globalScope)
114
+ var name = item.feature || item.label || item.title || JSON.stringify(item);
115
+ var parts = [];
116
+ if (item.priority) parts.push(item.priority.toUpperCase()); // priority → upper
117
+ if (item.module) parts.push("Module: " + item.module); // module reference
118
+ if (item.app) parts.push("App: " + item.app); // app reference
119
+ return { name: name, description: parts.join(" — ") }; // parts → description
120
+ }
121
+ ```
122
+
123
+ **Mapping:**
124
+ ```javascript
125
+ cadrage.scope: {
126
+ inscope: (master.cadrage.globalScope?.inScope || [])
127
+ .map(normalizeScopeItem),
128
+ outofscope: (master.cadrage.globalScope?.outOfScope || [])
129
+ .map(normalizeScopeItem)
130
+ }
131
+ ```
132
+
133
+ **Fallback:** If `globalScope` is missing/empty but `coverageMatrix` exists, build `inscope` from coverageMatrix entries.
134
+
135
+ ---
136
+
137
+ ## Cadrage Criteria Mapping
138
+
139
+ **Source:** `master.cadrage.acceptanceCriteria[]` with fallback to `collected_data.master.validation.acceptanceCriteria[]`
140
+
141
+ **Primary Mapping:**
142
+ ```javascript
143
+ let criteria = (master.cadrage.acceptanceCriteria || []).map(ac => ({
144
+ text: ac.criterion || ac.text || "",
145
+ validated: false
146
+ }));
147
+ ```
148
+
149
+ **Fallback (if criteria is empty):**
150
+ ```javascript
151
+ if (criteria.length === 0 && collected_data.master.validation) {
152
+ const valAC = collected_data.master.validation.acceptanceCriteria || [];
153
+ criteria = valAC.map(ac => ({
154
+ text: (ac.module ? '[' + ac.module + '] ' : '') + (ac.criteria || ac.criterion || ac.text || ""),
155
+ validated: false,
156
+ module: ac.module || null,
157
+ type: ac.type || null
158
+ }));
159
+ }
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Modules and Applications Mapping
165
+
166
+ **Source:** `master.modules[]` and `master.applications[]` (with fallback to `collected_data.navigation?.applications`)
167
+
168
+ **Applications Mapping:**
169
+ ```javascript
170
+ applications: (collected_data.navigation?.applications || master.applications || []).map(app => ({
171
+ code: app.code, // unique application code
172
+ name: app.name || app.code, // display name (fallback to code)
173
+ icon: app.icon || "" // icon reference
174
+ }))
175
+ ```
176
+
177
+ **Modules Mapping:**
178
+ ```javascript
179
+ modules: master.modules.map(m => ({
180
+ code: m.code, // unique module code
181
+ name: m.name || m.code, // display name (MANDATORY)
182
+ applicationCode: m.applicationCode || "", // multi-app grouping
183
+ description: m.description || "",
184
+ featureType: m.featureType || "data-centric", // component type
185
+ entities: m.entities || [], // entity references
186
+ anticipatedSections: (m.anticipatedSections || []).map(s =>
187
+ typeof s === 'string'
188
+ ? { code: s, name: s, description: "", resources: [] }
189
+ : {
190
+ code: s.code || s.name || "",
191
+ name: s.label || s.name || s.code || "",
192
+ description: s.description || "",
193
+ resources: s.resources || [],
194
+ route: s.route || "",
195
+ permission: s.permission || ""
196
+ }
197
+ ),
198
+ dependencies: m.dependencies || [], // module dependencies
199
+ dependents: m.dependents || [], // dependent modules
200
+ estimatedComplexity: m.estimatedComplexity || "medium",
201
+ status: m.status || "handed-off" // handoff status
202
+ }))
203
+ ```
204
+
205
+ ---
206
+
207
+ ## Dependencies Mapping (Top-Level)
208
+
209
+ **Source:** `master.consolidation?.crossModuleInteractions` or `master.dependencyGraph?.edges`
210
+
211
+ **CRITICAL:** This array is used by HTML sidebar navigation, module rendering, consolidation views, handoff summary, and export. If missing, the HTML page crashes with a TypeError.
212
+
213
+ **Mapping:**
214
+ ```javascript
215
+ dependencies: (master.consolidation?.crossModuleInteractions || master.dependencyGraph?.edges || []).map(i => ({
216
+ from: i.fromModule || i.from || "",
217
+ to: i.toModule || i.to || "",
218
+ description: i.description || ""
219
+ }))
220
+ ```
221
+
222
+ **Always include**, even if empty: `dependencies: []`
223
+
224
+ ---
225
+
226
+ ## Consolidation Mapping
227
+
228
+ **Source:** `master.consolidation` object
229
+
230
+ **Mapping:**
231
+ ```javascript
232
+ consolidation: {
233
+ interactions: (master.consolidation?.crossModuleInteractions || []).map(i => ({
234
+ from: i.fromModule,
235
+ to: i.toModule,
236
+ description: i.description || ""
237
+ })),
238
+ sharedEntities: master.consolidation?.sharedEntities || [],
239
+ e2eFlows: (master.consolidation?.e2eFlows || []).map(f => ({
240
+ name: f.name,
241
+ steps: (f.steps || []).map(s => ({ module: s.module, action: s.action })),
242
+ actors: (f.steps || []).map(s => s.permission).join(", ")
243
+ }))
244
+ }
245
+ ```
246
+
247
+ ---
248
+
249
+ ## Handoff Mapping
250
+
251
+ **Source:** `master.handoff` object
252
+
253
+ **Mapping:**
254
+ ```javascript
255
+ handoff: {
256
+ complexity: master.handoff?.complexity,
257
+ implementationStrategy: master.handoff?.implementationStrategy,
258
+ moduleOrder: master.handoff?.moduleOrder,
259
+ filesToCreate: master.handoff?.filesToCreate,
260
+ brToCodeMapping: master.handoff?.brToCodeMapping,
261
+ apiEndpointSummary: master.handoff?.apiEndpointSummary
262
+ }
263
+ ```
264
+
265
+ ---
266
+
267
+ ## Module Specifications: useCases Mapping
268
+
269
+ **Source:** `collected_data.modules[moduleCode].usecases`
270
+
271
+ **Normalization Notes:**
272
+ - Field may be `useCases` (camelCase) or `usecases` (lowercase)
273
+ - Steps may be strings[] or objects[] with `{step, action}` structure
274
+ - Alternative flows may be `alternativeScenarios` or `alternativeFlows`
275
+
276
+ **Mapping:**
277
+ ```javascript
278
+ const rawUCs = mod.usecases?.useCases || mod.usecases?.usecases || [];
279
+
280
+ useCases: rawUCs.map(uc => ({
281
+ name: uc.name || uc.title || uc.id || "",
282
+ sectionCode: uc.sectionCode || "",
283
+ actor: uc.primaryActor || uc.actor || "",
284
+ steps: (uc.mainScenario || uc.steps || []).map(s =>
285
+ typeof s === 'string' ? s : (s.action || s.description || "")
286
+ ).join("\n"),
287
+ alternative: (uc.alternativeScenarios || uc.alternativeFlows || []).map(a =>
288
+ (a.name || a.trigger || "") + ": " + (a.steps || a.actions || []).map(s =>
289
+ typeof s === 'string' ? s : (s.action || s.description || "")
290
+ ).join(", ")
291
+ ).join("\n")
292
+ }))
293
+ ```
294
+
295
+ ---
296
+
297
+ ## Module Specifications: businessRules Mapping
298
+
299
+ **Source:** `collected_data.modules[moduleCode].rules`
300
+
301
+ **Normalization Notes:**
302
+ - Field may be `rules` or `businessRules`
303
+
304
+ **Mapping:**
305
+ ```javascript
306
+ const rawBRs = mod.rules?.rules || mod.rules?.businessRules || [];
307
+
308
+ businessRules: rawBRs.map(br => ({
309
+ name: br.name || br.id || "",
310
+ sectionCode: br.sectionCode || "",
311
+ category: br.category || "",
312
+ statement: br.statement || br.description || "",
313
+ example: (br.examples || []).map(e =>
314
+ typeof e === 'string' ? e : ((e.input || "") + " → " + (e.expected || ""))
315
+ ).join("; ")
316
+ }))
317
+ ```
318
+
319
+ ---
320
+
321
+ ## Module Specifications: Entities Mapping
322
+
323
+ **Source:** `collected_data.modules[moduleCode].entities`
324
+
325
+ **Normalization Notes:**
326
+ - Attributes may be `attributes[]` or `fields[]` (fallback if attributes missing)
327
+
328
+ **Mapping:**
329
+ ```javascript
330
+ entities: (mod.entities?.entities || []).map(ent => ({
331
+ name: ent.name,
332
+ description: ent.description || "",
333
+ attributes: (ent.attributes || []).length > 0
334
+ ? ent.attributes.map(a => ({
335
+ name: a.name,
336
+ type: a.type || "string",
337
+ required: a.required || false,
338
+ description: a.description || ""
339
+ }))
340
+ : (ent.fields || []).map(f => ({ // fallback to fields[]
341
+ name: f.name,
342
+ type: f.type || "string",
343
+ required: f.required || false,
344
+ description: f.description || ""
345
+ })),
346
+ relationships: (ent.relationships || []).map(r =>
347
+ typeof r === 'string' ? r : r.target + " (" + r.type + ") - " + (r.description || "")
348
+ )
349
+ }))
350
+ ```
351
+
352
+ ---
353
+
354
+ ## Wireframes Mapping
355
+
356
+ **Source:** `collected_data.modules[moduleCode].screens` with wireframe data
357
+
358
+ **Field Rename CRITICAL:** Module JSON uses `mockupFormat`/`mockup`. HTML reads `format`/`content`.
359
+
360
+ **Mapping:**
361
+ ```javascript
362
+ wireframes: {
363
+ [moduleCode]: rawWireframes.map(wf => ({
364
+ screen: wf.screen || wf.name || wf.title || wf.id || "",
365
+ section: wf.section || "",
366
+ format: wf.mockupFormat || "ascii", // RENAME: mockupFormat → format
367
+ content: wf.mockup || wf.ascii || wf.content || "", // RENAME: mockup → content
368
+ svgContent: null, // populated later if SVG generated
369
+ description: wf.description || "",
370
+ elements: wf.elements || [],
371
+ actions: wf.actions || [],
372
+ componentMapping: Array.isArray(wf.componentMapping)
373
+ ? wf.componentMapping.map(entry => ...) // see below
374
+ : typeof wf.componentMapping === 'object' && wf.componentMapping !== null
375
+ ? Object.entries(wf.componentMapping).map(([k, v]) => ({ wireframeElement: k, reactComponent: v }))
376
+ : [],
377
+ layout: typeof wf.layout === 'object' ? wf.layout : null,
378
+ permissionsRequired: wf.permissionsRequired || []
379
+ }))
380
+ }
381
+ ```
382
+
383
+ **componentMapping Normalization:**
384
+
385
+ Handles three formats:
386
+ ```javascript
387
+ // Format 1: Array of canonical entries {wireframeElement, reactComponent}
388
+ [{wireframeElement: "Button1", reactComponent: "Button"}]
389
+
390
+ // Format 2: Shorthand [{key: value}]
391
+ [{"Button1": "Button"}] → {wireframeElement: "Button1", reactComponent: "Button"}
392
+
393
+ // Format 3: Object {key: value}
394
+ {"Button1": "Button"} → [{wireframeElement: "Button1", reactComponent: "Button"}]
395
+ ```
396
+
397
+ ---
398
+
399
+ ## E2E Flows Mapping
400
+
401
+ **Source:** `master.consolidation?.e2eFlows`
402
+
403
+ **Mapping:**
404
+ ```javascript
405
+ e2eFlows: (master.consolidation?.e2eFlows || []).map(flow => ({
406
+ name: flow.name,
407
+ diagram: flow.steps.map(s => s.action + "(" + s.module + ")").join(" ──→ "),
408
+ steps: flow.steps || [],
409
+ actors: [...new Set(flow.steps.map(s => s.permission?.split(".")[0]).filter(Boolean))].join(", "),
410
+ modules: [...new Set(flow.steps.map(s => s.module))].join(" → ")
411
+ }))
412
+ ```
413
+
414
+ ---
415
+
416
+ ## Dependency Graph Mapping
417
+
418
+ **Source:** `master.modules[]` and `master.dependencyGraph?.edges`
419
+
420
+ **Mapping:**
421
+ ```javascript
422
+ dependencyGraph: {
423
+ nodes: (master.modules || []).map(m => ({
424
+ id: m.code,
425
+ label: m.code,
426
+ type: m.featureType || "data-centric"
427
+ })),
428
+ edges: (master.dependencyGraph?.edges || []).map(e => ({
429
+ from: e.from,
430
+ to: e.to,
431
+ description: e.description || ""
432
+ }))
433
+ }
434
+ ```
435
+
436
+ ---
437
+
438
+ ## Permission Keys Helper
439
+
440
+ **Source:** `collected_data.modules[moduleCode].permissions`
441
+
442
+ **Implementation:** See `references/data-mapping.md` for `buildPermissionKeys()` function implementation.
@@ -0,0 +1,139 @@
1
+ ---
2
+ name: 02-normalization-helpers
3
+ description: Helper functions for normalizing field definitions, columns, filters, actions, charts, and KPIs across various JSON schema formats
4
+ ---
5
+
6
+ # Normalization Helpers
7
+
8
+ These helper functions normalize field definitions, columns, filters, actions, charts, and KPIs from various JSON schema conventions into a standard format used by the HTML renderer.
9
+
10
+ ## Column Normalization
11
+
12
+ ```javascript
13
+ // Helper: normalize a column definition regardless of field naming convention
14
+ function normalizeColumn(c) {
15
+ return {
16
+ field: c.code || c.name || c.id || c.field || c.fieldCode || "",
17
+ label: c.label || c.displayName || c.code || c.name || "",
18
+ type: c.renderAs === "badge" ? "badge" : (c.type || c.dataType || "text"),
19
+ sortable: !!c.sortable
20
+ };
21
+ }
22
+ ```
23
+
24
+ **Handles:** `code`, `name`, `id`, `field`, `fieldCode` for field reference; `label`, `displayName` for display; `renderAs`, `type`, `dataType` for type detection; `sortable` flag.
25
+
26
+ ## Form Field Normalization
27
+
28
+ ```javascript
29
+ // Helper: normalize a form field
30
+ function normalizeField(f) {
31
+ return {
32
+ field: f.code || f.name || f.id || f.fieldCode || f.field || "",
33
+ label: f.label || f.displayName || f.code || f.name || "",
34
+ type: f.type || f.fieldType || f.dataType || "text",
35
+ required: !!f.required
36
+ };
37
+ }
38
+ ```
39
+
40
+ **Handles:** Field reference via `code`, `name`, `id`, `fieldCode`, `field`; display via `label`, `displayName`; type via `type`, `fieldType`, `dataType`; required flag.
41
+
42
+ ## Filter Normalization (Simple)
43
+
44
+ ```javascript
45
+ // Helper: normalize a filter (for SmartTable inline filters — label only)
46
+ function normalizeFilter(f) {
47
+ if (typeof f === 'string') return f;
48
+ return f.label || f.displayName || f.filterLabel || f.name || f.code || f.filterCode || "";
49
+ }
50
+ ```
51
+
52
+ **Handles:** String filters (direct label) or objects with `label`, `displayName`, `filterLabel`, `name`, `code`, or `filterCode`.
53
+
54
+ ## SmartFilter Field Normalization
55
+
56
+ ```javascript
57
+ // Helper: normalize a SmartFilter field (preserves type/options/entity for rich rendering)
58
+ function normalizeSmartFilterField(f) {
59
+ if (typeof f === 'string') return { label: f, type: 'text', field: '' };
60
+ return {
61
+ field: f.field || f.code || f.name || "",
62
+ label: f.label || f.displayName || f.field || "",
63
+ type: f.type || "text",
64
+ options: f.options || [],
65
+ entity: f.entity || ""
66
+ };
67
+ }
68
+ ```
69
+
70
+ **Handles:** String filters or rich objects with field reference, label, type, options array, and entity linkage for dropdown/select filters.
71
+
72
+ ## Action Normalization
73
+
74
+ ```javascript
75
+ // Helper: normalize an action
76
+ function normalizeAction(a) {
77
+ if (typeof a === 'string') return a;
78
+ return a.code || a.id || a.label || a.actionCode || "";
79
+ }
80
+ ```
81
+
82
+ **Handles:** String actions (direct code/label) or objects with `code`, `id`, `label`, or `actionCode`.
83
+
84
+ ## Chart Normalization
85
+
86
+ ```javascript
87
+ // Helper: normalize a chart definition
88
+ function normalizeChart(c) {
89
+ if (typeof c === 'string') return { type: 'bar', label: c };
90
+ return {
91
+ type: c.type || c.chartType || 'bar',
92
+ label: c.label || c.displayName || c.title || 'Graphique'
93
+ };
94
+ }
95
+ ```
96
+
97
+ **Handles:** String charts (default to bar type with label) or objects with `type`/`chartType` and `label`/`displayName`/`title`.
98
+
99
+ ## KPI Normalization
100
+
101
+ ```javascript
102
+ // Helper: normalize a KPI — replace formula values with sample display values
103
+ function normalizeKpi(k) {
104
+ if (typeof k !== 'object') return { label: String(k), value: "0" };
105
+ const label = k.label || k.displayName || "";
106
+ const rawValue = k.value || k.metric || "0";
107
+ let displayValue = rawValue;
108
+ // Detect formula patterns (e.g., count(...), sum(...), ratio(...), avg(...))
109
+ if (typeof rawValue === 'string' && rawValue.includes('(')) {
110
+ const lbl = label.toLowerCase();
111
+ if (rawValue.includes('ratio') || rawValue.includes('%') || lbl.includes('taux') || lbl.includes('rate'))
112
+ displayValue = "87.5%";
113
+ else if (rawValue.includes('avg') || lbl.includes('moyen') || lbl.includes('average'))
114
+ displayValue = "12.4";
115
+ else if (rawValue.includes('sum'))
116
+ displayValue = (lbl.includes('jour') || lbl.includes('day') || lbl.includes('heure') || lbl.includes('hour')) ? "156" : "45,678";
117
+ else
118
+ displayValue = "1,234";
119
+ }
120
+ // Also handle format hint from the KPI definition
121
+ if (k.format === 'percentage' && displayValue === rawValue) displayValue = "80%";
122
+ return { label: label, value: displayValue };
123
+ }
124
+ ```
125
+
126
+ **Handles:** Non-object KPIs (converted to `{label, value}`); label via `label` or `displayName`; value via `value` or `metric`; formula pattern detection (ratio/avg/sum) to generate representative display values; percentage format hints.
127
+
128
+ ---
129
+
130
+ ## Usage Pattern
131
+
132
+ All helpers follow this pattern:
133
+
134
+ 1. **Handle multiple naming conventions** for the same field (e.g., `code`, `name`, `id`)
135
+ 2. **Preserve data** when already in canonical form
136
+ 3. **Generate reasonable defaults** for optional fields
137
+ 4. **Convert internal formats** to HTML-renderable values (e.g., formula → sample number)
138
+
139
+ Use these helpers when building `moduleSpecs[moduleCode].screens` arrays to normalize columns, fields, filters, actions, charts, and KPIs from heterogeneous BA JSON outputs.