@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.
- package/dist/index.js +152 -31
- package/dist/index.js.map +1 -1
- package/dist/mcp-entry.mjs +14 -3
- package/dist/mcp-entry.mjs.map +1 -1
- package/package.json +1 -1
- package/templates/agents/ba-reader.md +17 -15
- package/templates/agents/ba-writer.md +49 -51
- package/templates/skills/apex/SKILL.md +2 -2
- package/templates/skills/apex/_shared.md +1 -1
- package/templates/skills/apex/references/checks/backend-checks.sh +21 -7
- package/templates/skills/apex/references/checks/frontend-checks.sh +26 -0
- package/templates/skills/apex/references/checks/infrastructure-checks.sh +47 -10
- package/templates/skills/apex/references/checks/seed-checks.sh +47 -7
- package/templates/skills/apex/references/core-seed-data.md +20 -18
- package/templates/skills/apex/references/frontend-route-wiring-app-tsx.md +3 -0
- package/templates/skills/apex/references/post-checks.md +23 -3
- package/templates/skills/apex/references/smartstack-api.md +4 -4
- package/templates/skills/apex/references/smartstack-frontend.md +54 -8
- package/templates/skills/apex/references/smartstack-layers.md +6 -6
- package/templates/skills/apex/steps/step-00-init.md +75 -1
- package/templates/skills/apex/steps/step-03-execute.md +16 -4
- package/templates/skills/apex/steps/step-03b-layer1-seed.md +65 -6
- package/templates/skills/apex/steps/step-03c-layer2-backend.md +50 -5
- package/templates/skills/apex/steps/step-03d-layer3-frontend.md +226 -4
- package/templates/skills/apex/steps/step-04-examine.md +163 -0
- package/templates/skills/apex-verify/SKILL.md +110 -0
- package/templates/skills/apex-verify/references/audit-rules.md +50 -0
- package/templates/skills/apex-verify/steps/step-00-init.md +119 -0
- package/templates/skills/apex-verify/steps/step-01-nav-audit.md +92 -0
- package/templates/skills/apex-verify/steps/step-02-crud-audit.md +127 -0
- package/templates/skills/apex-verify/steps/step-03-perm-audit.md +119 -0
- package/templates/skills/apex-verify/steps/step-04-route-audit.md +98 -0
- package/templates/skills/apex-verify/steps/step-05-report.md +110 -0
- package/templates/skills/application/references/frontend-route-wiring-app-tsx.md +3 -0
- package/templates/skills/application/templates-frontend.md +2 -2
- package/templates/skills/business-analyse/SKILL.md +17 -3
- package/templates/skills/business-analyse/_shared.md +64 -0
- package/templates/skills/business-analyse/patterns/suggestion-catalog.md +34 -26
- package/templates/skills/business-analyse/questionnaire/01-context.md +13 -9
- package/templates/skills/business-analyse/questionnaire/02-stakeholders-scope.md +20 -27
- package/templates/skills/business-analyse/questionnaire.md +86 -9
- package/templates/skills/business-analyse/references/03-json-schemas.md +221 -0
- package/templates/skills/business-analyse/references/03-post-check-validation.md +208 -0
- package/templates/skills/business-analyse/references/03-smartstack-entity-guards.md +32 -0
- package/templates/skills/business-analyse/references/04-cross-module-validation.md +95 -0
- package/templates/skills/business-analyse/references/04-file-allocation.md +162 -0
- package/templates/skills/business-analyse/references/04-naming-audit-checks.md +174 -0
- package/templates/skills/business-analyse/references/04-semantic-validation-matrix.md +118 -0
- package/templates/skills/business-analyse/references/canonical-json-formats.md +7 -3
- package/templates/skills/business-analyse/references/domain-research-playbook.md +234 -0
- package/templates/skills/business-analyse/references/entity-sourcing-presentation.md +166 -0
- package/templates/skills/business-analyse/references/init-resume-logic.md +70 -0
- package/templates/skills/business-analyse/references/module-completeness-challenge.md +174 -0
- package/templates/skills/business-analyse/references/multi-app-detection.md +149 -0
- package/templates/skills/business-analyse/references/portal-classification.md +52 -0
- package/templates/skills/business-analyse/references/robustness-checks.md +1 -1
- package/templates/skills/business-analyse/references/validation-checklist.md +35 -6
- package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +50 -6
- package/templates/skills/business-analyse/steps/step-00-init.md +22 -190
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +365 -269
- package/templates/skills/business-analyse/steps/step-02-structure.md +98 -20
- package/templates/skills/business-analyse/steps/step-03-specify.md +810 -229
- package/templates/skills/business-analyse/steps/step-04-consolidate.md +509 -278
- package/templates/skills/business-analyse-design/SKILL.md +10 -0
- package/templates/skills/business-analyse-design/references/screens-post-check.md +221 -0
- package/templates/skills/business-analyse-design/references/screens-type-mapping.md +138 -0
- package/templates/skills/business-analyse-design/references/smartcomponents-templates.md +225 -0
- package/templates/skills/{business-analyse → business-analyse-design}/references/spec-auto-inference.md +117 -117
- package/templates/skills/business-analyse-design/steps/step-01-screens.md +36 -162
- package/templates/skills/business-analyse-design/steps/step-02-wireframes.md +8 -7
- package/templates/skills/business-analyse-design/steps/step-03-navigation.md +89 -42
- package/templates/skills/business-analyse-develop/references/compact-loop.md +9 -0
- package/templates/skills/business-analyse-develop/references/handoff-quality-gate.md +132 -0
- package/templates/skills/business-analyse-develop/references/prd-v3-transformation.md +326 -0
- package/templates/skills/business-analyse-develop/references/report-reconciliation.md +140 -0
- package/templates/skills/business-analyse-develop/references/report-template.md +142 -0
- package/templates/skills/business-analyse-develop/steps/step-01-task.md +5 -177
- package/templates/skills/business-analyse-develop/steps/step-02-execute.md +17 -4
- package/templates/skills/business-analyse-develop/steps/step-03-commit.md +6 -2
- package/templates/skills/business-analyse-develop/steps/step-04-check.md +6 -0
- package/templates/skills/business-analyse-develop/steps/step-05-report.md +3 -269
- package/templates/skills/business-analyse-handoff/SKILL.md +10 -0
- package/templates/skills/business-analyse-handoff/references/agent-handoff-transform-prompt.md +211 -0
- package/templates/skills/business-analyse-handoff/references/context-isolation-pattern.md +47 -0
- package/templates/skills/business-analyse-handoff/references/handoff-file-inventory.md +49 -0
- package/templates/skills/business-analyse-handoff/references/handoff-global-validation.md +142 -0
- package/templates/skills/business-analyse-handoff/references/prd-validation-checks.md +125 -0
- package/templates/skills/business-analyse-handoff/references/project-index-update.md +98 -0
- package/templates/skills/business-analyse-handoff/steps/step-01-transform.md +9 -160
- package/templates/skills/business-analyse-handoff/steps/step-02-export.md +10 -99
- package/templates/skills/business-analyse-html/SKILL.md +10 -0
- package/templates/skills/business-analyse-html/html/ba-interactive.html +504 -97
- package/templates/skills/business-analyse-html/html/src/scripts/01-data-init.js +79 -2
- package/templates/skills/business-analyse-html/html/src/scripts/02-navigation.js +6 -46
- package/templates/skills/business-analyse-html/html/src/scripts/05-render-specs.js +80 -11
- package/templates/skills/business-analyse-html/html/src/scripts/06-render-consolidation.js +2 -2
- package/templates/skills/business-analyse-html/html/src/scripts/06-render-mockups.js +94 -36
- package/templates/skills/business-analyse-html/html/src/scripts/12-render-diagrams.js +162 -0
- package/templates/skills/business-analyse-html/html/src/styles/10-diagrams.css +73 -0
- package/templates/skills/business-analyse-html/html/src/template.html +2 -0
- package/templates/skills/business-analyse-html/references/02-embedded-artifacts-building.md +144 -0
- package/templates/skills/business-analyse-html/references/02-feature-data-building.md +143 -0
- package/templates/skills/business-analyse-html/references/02-mapping-tables.md +442 -0
- package/templates/skills/business-analyse-html/references/02-normalization-helpers.md +139 -0
- package/templates/skills/business-analyse-html/references/02-screen-format-detection.md +283 -0
- package/templates/skills/business-analyse-html/references/02-self-check-validation.md +199 -0
- package/templates/skills/business-analyse-html/references/data-build.md +24 -1
- package/templates/skills/business-analyse-html/references/data-mapping.md +119 -17
- package/templates/skills/business-analyse-html/steps/step-02-build-data.md +18 -555
- package/templates/skills/business-analyse-html/steps/step-04-verify.md +92 -3
- package/templates/skills/business-analyse-quick/SKILL.md +807 -0
- package/templates/skills/{sketch → business-analyse-quick}/references/domain-heuristics.md +59 -3
- package/templates/skills/business-analyse-quick/references/prd-schema.md +268 -0
- package/templates/skills/business-analyse-review/SKILL.md +10 -0
- package/templates/skills/business-analyse-review/references/review-data-mapping.md +6 -0
- package/templates/skills/business-analyse-status/SKILL.md +8 -0
- package/templates/skills/dev-start/SKILL.md +143 -307
- package/templates/skills/efcore/SKILL.md +13 -0
- package/templates/skills/sketch/SKILL.md +15 -153
- package/templates/skills/ui-components/SKILL.md +1 -1
- package/templates/skills/ui-components/patterns/data-table.md +1 -1
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/* ==========================================
|
|
2
|
+
MERMAID DIAGRAM RENDERING
|
|
3
|
+
Renders ERD, state machines, and sequence diagrams
|
|
4
|
+
from consolidation.mermaidDiagrams data.
|
|
5
|
+
========================================== */
|
|
6
|
+
|
|
7
|
+
function renderMermaidDiagrams() {
|
|
8
|
+
const data = window.FEATURE_DATA;
|
|
9
|
+
if (!data) return;
|
|
10
|
+
|
|
11
|
+
const diagrams = data.consolidation?.mermaidDiagrams;
|
|
12
|
+
if (!diagrams) return;
|
|
13
|
+
|
|
14
|
+
// 1. ERD in consol-datamodel (prepend before entity cards)
|
|
15
|
+
if (diagrams.erd) {
|
|
16
|
+
const erdContainer = document.getElementById('dataModelContainer');
|
|
17
|
+
if (erdContainer) {
|
|
18
|
+
const erdDiv = document.createElement('div');
|
|
19
|
+
erdDiv.className = 'diagram-container diagram-erd';
|
|
20
|
+
erdDiv.innerHTML =
|
|
21
|
+
'<div class="diagram-section-header">Diagramme Entit\u00e9-Relation (ERD)</div>' +
|
|
22
|
+
'<div class="mermaid">' + escapeHtml(diagrams.erd) + '</div>';
|
|
23
|
+
erdContainer.insertBefore(erdDiv, erdContainer.firstChild);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 1b. MCD (Modèle Conceptuel de Données) — after ERD
|
|
28
|
+
if (diagrams.mcd) {
|
|
29
|
+
var erdContainer = document.getElementById('dataModelContainer');
|
|
30
|
+
if (erdContainer) {
|
|
31
|
+
var mcdDiv = document.createElement('div');
|
|
32
|
+
mcdDiv.className = 'diagram-container diagram-mcd';
|
|
33
|
+
mcdDiv.innerHTML =
|
|
34
|
+
'<div class="diagram-section-header" style="font-size:0.95rem;font-weight:600;color:var(--text-bright);margin-bottom:0.75rem;">Mod\u00e8le Conceptuel de Donn\u00e9es (MCD)</div>' +
|
|
35
|
+
'<div class="mermaid">' + escapeHtml(diagrams.mcd) + '</div>';
|
|
36
|
+
var erdDiv = erdContainer.querySelector('.diagram-erd');
|
|
37
|
+
if (erdDiv && erdDiv.nextSibling) {
|
|
38
|
+
erdContainer.insertBefore(mcdDiv, erdDiv.nextSibling);
|
|
39
|
+
} else {
|
|
40
|
+
erdContainer.appendChild(mcdDiv);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 2. State machine diagrams — inject in module spec sections or consol-datamodel
|
|
46
|
+
if (diagrams.stateMachines && Object.keys(diagrams.stateMachines).length > 0) {
|
|
47
|
+
const smContainer = document.getElementById('dataModelContainer');
|
|
48
|
+
if (smContainer) {
|
|
49
|
+
const smSection = document.createElement('div');
|
|
50
|
+
smSection.innerHTML = '<div class="diagram-section-header">Cycles de vie (State Machines)</div>';
|
|
51
|
+
|
|
52
|
+
Object.entries(diagrams.stateMachines).forEach(function(entry) {
|
|
53
|
+
var entity = entry[0];
|
|
54
|
+
var def = entry[1];
|
|
55
|
+
var smDiv = document.createElement('div');
|
|
56
|
+
smDiv.className = 'diagram-container diagram-state-machine';
|
|
57
|
+
smDiv.innerHTML =
|
|
58
|
+
'<h4>' + escapeHtml(entity) + '</h4>' +
|
|
59
|
+
'<div class="mermaid">' + escapeHtml(def) + '</div>';
|
|
60
|
+
smSection.appendChild(smDiv);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
smContainer.appendChild(smSection);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 2b. Use Case diagrams — inject in each module's UC tab
|
|
68
|
+
if (diagrams.useCases && Object.keys(diagrams.useCases).length > 0) {
|
|
69
|
+
Object.entries(diagrams.useCases).forEach(function(entry) {
|
|
70
|
+
var moduleCode = entry[0];
|
|
71
|
+
var def = entry[1];
|
|
72
|
+
var ucTab = document.getElementById('tab-' + moduleCode + '-uc');
|
|
73
|
+
if (!ucTab) {
|
|
74
|
+
// Try kebab-case version
|
|
75
|
+
var kebab = moduleCode.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
76
|
+
ucTab = document.getElementById('tab-' + kebab + '-uc');
|
|
77
|
+
}
|
|
78
|
+
if (ucTab) {
|
|
79
|
+
var ucDiagramDiv = document.createElement('div');
|
|
80
|
+
ucDiagramDiv.className = 'diagram-container diagram-usecase';
|
|
81
|
+
ucDiagramDiv.innerHTML =
|
|
82
|
+
'<div class="diagram-section-header" style="font-size:0.95rem;font-weight:600;color:var(--text-bright);margin-bottom:0.75rem;">Diagramme de cas d\'utilisation</div>' +
|
|
83
|
+
'<div class="mermaid">' + escapeHtml(def) + '</div>';
|
|
84
|
+
// Insert after the first paragraph (description text)
|
|
85
|
+
var firstP = ucTab.querySelector('p');
|
|
86
|
+
if (firstP && firstP.nextSibling) {
|
|
87
|
+
ucTab.insertBefore(ucDiagramDiv, firstP.nextSibling);
|
|
88
|
+
} else {
|
|
89
|
+
ucTab.insertBefore(ucDiagramDiv, ucTab.firstChild);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 3. Sequence diagrams in consol-flows
|
|
96
|
+
if (diagrams.sequences && Object.keys(diagrams.sequences).length > 0) {
|
|
97
|
+
var flowsContainer = document.getElementById('consolFlowsContainer');
|
|
98
|
+
// Fallback: try the consol-flows section
|
|
99
|
+
if (!flowsContainer) {
|
|
100
|
+
var consolFlows = document.getElementById('consol-flows');
|
|
101
|
+
if (consolFlows) {
|
|
102
|
+
flowsContainer = consolFlows.querySelector('.section-body') || consolFlows;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (flowsContainer) {
|
|
107
|
+
var seqSection = document.createElement('div');
|
|
108
|
+
seqSection.innerHTML = '<div class="diagram-section-header">Diagrammes de s\u00e9quence</div>';
|
|
109
|
+
|
|
110
|
+
Object.entries(diagrams.sequences).forEach(function(entry) {
|
|
111
|
+
var flowName = entry[0];
|
|
112
|
+
var def = entry[1];
|
|
113
|
+
var seqDiv = document.createElement('div');
|
|
114
|
+
seqDiv.className = 'diagram-container diagram-sequence';
|
|
115
|
+
seqDiv.innerHTML =
|
|
116
|
+
'<h4>' + escapeHtml(flowName) + '</h4>' +
|
|
117
|
+
'<div class="mermaid">' + escapeHtml(def) + '</div>';
|
|
118
|
+
seqSection.appendChild(seqDiv);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
flowsContainer.appendChild(seqSection);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 4. Render all mermaid elements
|
|
126
|
+
try {
|
|
127
|
+
if (typeof mermaid !== 'undefined' && mermaid.run) {
|
|
128
|
+
mermaid.run({ querySelector: '.mermaid' });
|
|
129
|
+
}
|
|
130
|
+
} catch (e) {
|
|
131
|
+
console.warn('Mermaid rendering failed:', e);
|
|
132
|
+
// Fallback: show raw text
|
|
133
|
+
document.querySelectorAll('.mermaid').forEach(function(el) {
|
|
134
|
+
if (!el.querySelector('svg')) {
|
|
135
|
+
el.style.whiteSpace = 'pre-wrap';
|
|
136
|
+
el.style.fontFamily = 'monospace';
|
|
137
|
+
el.style.fontSize = '0.85rem';
|
|
138
|
+
el.style.color = 'var(--text-muted)';
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Escape HTML for safe injection
|
|
145
|
+
function escapeHtml(text) {
|
|
146
|
+
if (!text) return '';
|
|
147
|
+
// For mermaid content, we need to preserve the syntax
|
|
148
|
+
// Only escape actual HTML tags, not mermaid arrows
|
|
149
|
+
return text.replace(/</g, '<').replace(/>/g, '>');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Auto-run after consolidation rendering
|
|
153
|
+
(function() {
|
|
154
|
+
// Wait for DOM and other render functions to complete
|
|
155
|
+
if (document.readyState === 'loading') {
|
|
156
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
157
|
+
setTimeout(renderMermaidDiagrams, 500);
|
|
158
|
+
});
|
|
159
|
+
} else {
|
|
160
|
+
setTimeout(renderMermaidDiagrams, 500);
|
|
161
|
+
}
|
|
162
|
+
})();
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/* ==========================================
|
|
2
|
+
MERMAID DIAGRAMS
|
|
3
|
+
========================================== */
|
|
4
|
+
|
|
5
|
+
.diagram-container {
|
|
6
|
+
margin: 1.5rem 0;
|
|
7
|
+
padding: 1rem;
|
|
8
|
+
background: var(--bg-card);
|
|
9
|
+
border-radius: 8px;
|
|
10
|
+
border: 1px solid var(--border);
|
|
11
|
+
overflow-x: auto;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.diagram-container h3,
|
|
15
|
+
.diagram-container h4 {
|
|
16
|
+
color: var(--text-bright);
|
|
17
|
+
margin-bottom: 1rem;
|
|
18
|
+
font-size: 1.1rem;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.diagram-container .mermaid {
|
|
22
|
+
display: flex;
|
|
23
|
+
justify-content: center;
|
|
24
|
+
min-height: 200px;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.diagram-container .mermaid svg {
|
|
28
|
+
max-width: 100%;
|
|
29
|
+
height: auto;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* ERD specific */
|
|
33
|
+
.diagram-erd {
|
|
34
|
+
margin-bottom: 2rem;
|
|
35
|
+
border-left: 3px solid var(--primary);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* State machine specific */
|
|
39
|
+
.diagram-state-machine {
|
|
40
|
+
border-left: 3px solid var(--accent);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Sequence diagram specific */
|
|
44
|
+
.diagram-sequence {
|
|
45
|
+
border-left: 3px solid var(--success);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Diagram section header */
|
|
49
|
+
.diagram-section-header {
|
|
50
|
+
display: flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
gap: 0.5rem;
|
|
53
|
+
margin-bottom: 1rem;
|
|
54
|
+
color: var(--text-bright);
|
|
55
|
+
font-size: 1.2rem;
|
|
56
|
+
font-weight: 600;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.diagram-section-header::before {
|
|
60
|
+
content: '';
|
|
61
|
+
width: 4px;
|
|
62
|
+
height: 1.2em;
|
|
63
|
+
background: var(--primary);
|
|
64
|
+
border-radius: 2px;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* No diagrams fallback */
|
|
68
|
+
.diagram-empty {
|
|
69
|
+
color: var(--text-muted);
|
|
70
|
+
font-style: italic;
|
|
71
|
+
padding: 1rem;
|
|
72
|
+
text-align: center;
|
|
73
|
+
}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>{{APPLICATION_NAME}} - Analyse métier</title>
|
|
7
|
+
<script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"></script>
|
|
8
|
+
<script>mermaid.initialize({ startOnLoad: false, theme: 'dark', securityLevel: 'loose' });</script>
|
|
7
9
|
<style>
|
|
8
10
|
<!-- CSS_PLACEHOLDER -->
|
|
9
11
|
</style>
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Reference: EMBEDDED_ARTIFACTS Building Details
|
|
2
|
+
|
|
3
|
+
## wireframes{} — per moduleCode
|
|
4
|
+
|
|
5
|
+
### Architecture: Flat File + Nested Structures
|
|
6
|
+
|
|
7
|
+
**FLAT-FILE:** Wireframes come from `screens.json` in each module directory (collected in step-01),
|
|
8
|
+
NOT from `moduleFeature.specification.uiWireframes`.
|
|
9
|
+
|
|
10
|
+
### STEP 1: Collect wireframe sources from BOTH flat and nested structures
|
|
11
|
+
|
|
12
|
+
```javascript
|
|
13
|
+
const mod = collected_data.modules[moduleCode];
|
|
14
|
+
|
|
15
|
+
// Flat: mod.screens.screens[] with mockupFormat/mockup at top level
|
|
16
|
+
// Nested: mod.screens.sections[].resources[].wireframe (design step output)
|
|
17
|
+
let rawWireframes = [];
|
|
18
|
+
|
|
19
|
+
// Source A: flat screens[] array (original BA output or manually enriched)
|
|
20
|
+
const flatScreens = mod.screens?.screens || [];
|
|
21
|
+
rawWireframes.push(...flatScreens.filter(s => s.mockup || s.mockupFormat));
|
|
22
|
+
|
|
23
|
+
// Source B: nested sections[].resources[].wireframe (design step output)
|
|
24
|
+
const sections = mod.screens?.sections || [];
|
|
25
|
+
for (const section of sections) {
|
|
26
|
+
// B1: wireframe directly on section (ba-004 style: sections[].wireframe)
|
|
27
|
+
if (section.wireframe) {
|
|
28
|
+
rawWireframes.push({
|
|
29
|
+
...section.wireframe,
|
|
30
|
+
section: section.wireframe.section || section.id || section.code || section.sectionCode || "",
|
|
31
|
+
screen: section.wireframe.screen || section.id || section.code || section.sectionCode || ""
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
// B2: wireframe on resources (nested: sections[].resources[].wireframe)
|
|
35
|
+
for (const resource of (section.resources || [])) {
|
|
36
|
+
if (resource.wireframe) {
|
|
37
|
+
rawWireframes.push({
|
|
38
|
+
...resource.wireframe,
|
|
39
|
+
section: resource.wireframe.section || section.sectionCode || section.id || "",
|
|
40
|
+
screen: resource.wireframe.screen || `${section.sectionCode || section.id}-${resource.code}` || ""
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Source C: screens/sections without mockup → auto-generate text description as wireframe fallback
|
|
47
|
+
// C1: from flat screens[]
|
|
48
|
+
const screensWithoutMockup = flatScreens.filter(s => !s.mockup && !s.mockupFormat);
|
|
49
|
+
// C2: from sections[] (ba-004 style) — sections without wireframe property
|
|
50
|
+
const sectionsWithoutWireframe = sections.filter(s => !s.wireframe);
|
|
51
|
+
const allNoMockup = [
|
|
52
|
+
...screensWithoutMockup.map(s => ({
|
|
53
|
+
type: s.componentType || "", columns: s.columns || [], tabs: s.tabs || [],
|
|
54
|
+
kpis: s.kpis || [], screen: s.screen || "", section: s.section || "",
|
|
55
|
+
description: s.sectionDescription || ""
|
|
56
|
+
})),
|
|
57
|
+
...sectionsWithoutWireframe.map(s => ({
|
|
58
|
+
type: s.layout || s.componentType || "", columns: s.columns || [], tabs: s.tabs || [],
|
|
59
|
+
kpis: s.kpis || [], screen: s.id || s.code || "", section: s.id || s.code || "",
|
|
60
|
+
description: s.description || ""
|
|
61
|
+
}))
|
|
62
|
+
];
|
|
63
|
+
for (const screen of allNoMockup) {
|
|
64
|
+
const type = screen.type;
|
|
65
|
+
let desc = "";
|
|
66
|
+
if (type.includes("Table") || type.includes("Grid")) {
|
|
67
|
+
const cols = screen.columns;
|
|
68
|
+
desc = "Tableau avec " + cols.length + " colonnes : " + cols.map(c => c.label || c.displayName || c.code || c.name).join(", ");
|
|
69
|
+
} else if (type.includes("Form")) {
|
|
70
|
+
const tabs = screen.tabs;
|
|
71
|
+
desc = "Formulaire " + (tabs.length > 0 ? "avec " + tabs.length + " onglet(s)" : "");
|
|
72
|
+
} else if (type.includes("Dashboard")) {
|
|
73
|
+
desc = "Tableau de bord avec " + (screen.kpis.length || "") + " KPIs";
|
|
74
|
+
} else if (type.includes("Kanban")) {
|
|
75
|
+
desc = "Vue Kanban";
|
|
76
|
+
}
|
|
77
|
+
if (desc) {
|
|
78
|
+
rawWireframes.push({
|
|
79
|
+
screen: screen.screen, section: screen.section,
|
|
80
|
+
mockupFormat: "text", mockup: desc,
|
|
81
|
+
description: screen.description, elements: [], componentMapping: []
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### STEP 2: Map to HTML format (RENAME: mockupFormat → format, mockup → content)
|
|
88
|
+
|
|
89
|
+
**FIELD RENAME WARNING:** Module JSON uses `mockupFormat`/`mockup`. HTML reads `format`/`content`. You MUST rename.
|
|
90
|
+
|
|
91
|
+
```javascript
|
|
92
|
+
wireframes: {
|
|
93
|
+
[moduleCode]: rawWireframes.map(wf => ({
|
|
94
|
+
screen: wf.screen || wf.name || wf.title || wf.id || "",
|
|
95
|
+
section: wf.section || "",
|
|
96
|
+
format: wf.mockupFormat || "ascii", // RENAME: mockupFormat → format
|
|
97
|
+
content: wf.mockup || wf.ascii || wf.content || "", // RENAME: mockup → content
|
|
98
|
+
svgContent: null,
|
|
99
|
+
description: wf.description || "",
|
|
100
|
+
elements: wf.elements || [],
|
|
101
|
+
actions: wf.actions || [],
|
|
102
|
+
componentMapping: Array.isArray(wf.componentMapping)
|
|
103
|
+
? wf.componentMapping.map(function(entry) {
|
|
104
|
+
if (entry.wireframeElement && entry.reactComponent) return entry; // canonical
|
|
105
|
+
// Shorthand: [{key: value}] → {wireframeElement, reactComponent}
|
|
106
|
+
var keys = Object.keys(entry);
|
|
107
|
+
if (keys.length === 1 && !entry.wireframeElement) {
|
|
108
|
+
return { wireframeElement: keys[0], reactComponent: entry[keys[0]] };
|
|
109
|
+
}
|
|
110
|
+
return entry;
|
|
111
|
+
})
|
|
112
|
+
: typeof wf.componentMapping === 'object' && wf.componentMapping !== null
|
|
113
|
+
? Object.entries(wf.componentMapping).map(([k, v]) => ({ wireframeElement: k, reactComponent: v }))
|
|
114
|
+
: [],
|
|
115
|
+
layout: typeof wf.layout === 'object' ? wf.layout : null,
|
|
116
|
+
permissionsRequired: wf.permissionsRequired || []
|
|
117
|
+
}))
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## e2eFlows[]
|
|
122
|
+
|
|
123
|
+
```javascript
|
|
124
|
+
e2eFlows: (master.consolidation?.e2eFlows || []).map(flow => ({
|
|
125
|
+
name: flow.name,
|
|
126
|
+
diagram: flow.steps.map(s => s.action + "(" + s.module + ")").join(" ──→ "),
|
|
127
|
+
steps: flow.steps || [],
|
|
128
|
+
actors: [...new Set(flow.steps.map(s => s.permission?.split(".")[0]).filter(Boolean))].join(", "),
|
|
129
|
+
modules: [...new Set(flow.steps.map(s => s.module))].join(" → ")
|
|
130
|
+
}))
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## dependencyGraph
|
|
134
|
+
|
|
135
|
+
```javascript
|
|
136
|
+
dependencyGraph: {
|
|
137
|
+
nodes: (master.modules || []).map(m => ({
|
|
138
|
+
id: m.code, label: m.code, type: m.featureType || "data-centric"
|
|
139
|
+
})),
|
|
140
|
+
edges: (master.dependencyGraph?.edges || []).map(e => ({
|
|
141
|
+
from: e.from, to: e.to, description: e.description || ""
|
|
142
|
+
}))
|
|
143
|
+
}
|
|
144
|
+
```
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Reference: FEATURE_DATA Building Details
|
|
2
|
+
|
|
3
|
+
## moduleSpecs{} — ONE entry per module (CRITICAL)
|
|
4
|
+
|
|
5
|
+
### Architecture: Flat File Data Collection
|
|
6
|
+
|
|
7
|
+
**FLAT-FILE ARCHITECTURE:** Module data comes from separate JSON files collected in step-01,
|
|
8
|
+
NOT from index.json fields. Use `collected_data.modules[moduleCode].entities`, `.usecases`, etc.
|
|
9
|
+
|
|
10
|
+
For EACH module, use the flat file data from `collected_data.modules[moduleCode]`:
|
|
11
|
+
|
|
12
|
+
```javascript
|
|
13
|
+
const mod = collected_data.modules[moduleCode];
|
|
14
|
+
|
|
15
|
+
// NORMALIZE: usecases.json may use "useCases" (camelCase) or "usecases" (lowercase)
|
|
16
|
+
const rawUCs = mod.usecases?.useCases || mod.usecases?.usecases || [];
|
|
17
|
+
// NORMALIZE: rules.json may use "rules" or "businessRules"
|
|
18
|
+
const rawBRs = mod.rules?.rules || mod.rules?.businessRules || [];
|
|
19
|
+
|
|
20
|
+
moduleSpecs[moduleCode] = {
|
|
21
|
+
useCases: rawUCs.map(uc => ({
|
|
22
|
+
name: uc.name || uc.title || uc.id || "",
|
|
23
|
+
sectionCode: uc.sectionCode || "",
|
|
24
|
+
actor: uc.primaryActor || uc.actor || "",
|
|
25
|
+
// SAFETY NET: steps may be strings[] (mainScenario) or objects[] ({step, action})
|
|
26
|
+
steps: (uc.mainScenario || uc.steps || []).map(s =>
|
|
27
|
+
typeof s === 'string' ? s : (s.action || s.description || "")
|
|
28
|
+
).join("\n"),
|
|
29
|
+
alternative: (uc.alternativeScenarios || uc.alternativeFlows || []).map(a =>
|
|
30
|
+
(a.name || a.trigger || "") + ": " + (a.steps || a.actions || []).map(s =>
|
|
31
|
+
typeof s === 'string' ? s : (s.action || s.description || "")
|
|
32
|
+
).join(", ")
|
|
33
|
+
).join("\n")
|
|
34
|
+
})),
|
|
35
|
+
businessRules: rawBRs.map(br => ({
|
|
36
|
+
name: br.name || br.id || "",
|
|
37
|
+
sectionCode: br.sectionCode || "",
|
|
38
|
+
category: br.category || "",
|
|
39
|
+
severity: br.severity || "",
|
|
40
|
+
statement: br.statement || br.description || "",
|
|
41
|
+
example: (br.examples || (br.example ? [br.example] : [])).map(e =>
|
|
42
|
+
typeof e === 'string' ? e : ((e.input || "") + " → " + (e.expected || ""))
|
|
43
|
+
).join("; "),
|
|
44
|
+
domainSpecific: br.domainSpecific || false
|
|
45
|
+
})),
|
|
46
|
+
// ENTITY SAFETY NET: map fields[] → attributes[] if agent deviated
|
|
47
|
+
entities: (mod.entities?.entities || []).map(ent => ({
|
|
48
|
+
name: ent.name,
|
|
49
|
+
description: ent.description || "",
|
|
50
|
+
attributes: (ent.attributes || []).length > 0
|
|
51
|
+
? ent.attributes.map(a => ({ name: a.name, type: a.type || "string", required: a.required || false, description: a.description || "" }))
|
|
52
|
+
: (ent.fields || []).map(f => ({ name: f.name, type: f.type || "string", required: f.required || false, description: f.description || "" })),
|
|
53
|
+
relationships: (ent.relationships || []).map(r =>
|
|
54
|
+
typeof r === 'string' ? r : r.target + " (" + r.type + ") - " + (r.description || ""))
|
|
55
|
+
})),
|
|
56
|
+
permissions: buildPermissionKeys(mod.permissions),
|
|
57
|
+
apiEndpoints: mod.usecases?.apiEndpoints || []
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Building screens[] for HTML Interactive Mockups
|
|
62
|
+
|
|
63
|
+
```javascript
|
|
64
|
+
// BUILD screens[] for HTML interactive mockups — use helpers and format detection from references
|
|
65
|
+
const flatScr = mod.screens?.screens || [];
|
|
66
|
+
const sectionScr = mod.screens?.sections || [];
|
|
67
|
+
let screens = [];
|
|
68
|
+
|
|
69
|
+
// Apply normalization helpers from references/02-normalization-helpers.md
|
|
70
|
+
// Apply format detection from references/02-screen-format-detection.md
|
|
71
|
+
|
|
72
|
+
moduleSpecs[moduleCode].screens = screens;
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Enrich anticipatedSections with section-level UC/BR
|
|
76
|
+
|
|
77
|
+
**CRITICAL for HTML viewer to display UC/BR grouped by section.**
|
|
78
|
+
|
|
79
|
+
Execute AFTER moduleSpecs is built:
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
// Post-processing: populate each section's useCases[] and businessRules[]
|
|
83
|
+
// using the sectionCode field from moduleSpecs
|
|
84
|
+
FEATURE_DATA.modules.forEach(m => {
|
|
85
|
+
const spec = FEATURE_DATA.moduleSpecs[m.code];
|
|
86
|
+
if (!spec) return;
|
|
87
|
+
(m.anticipatedSections || []).forEach(section => {
|
|
88
|
+
section.useCases = (spec.useCases || []).filter(uc => uc.sectionCode === section.code);
|
|
89
|
+
section.businessRules = (spec.businessRules || []).filter(br => br.sectionCode === section.code);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Top-Level Fields: dependencies, consolidation, handoff
|
|
95
|
+
|
|
96
|
+
### dependencies[] (TOP-LEVEL — CRITICAL for HTML navigation)
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
dependencies: (master.consolidation?.crossModuleInteractions || master.dependencyGraph?.edges || []).map(i => ({
|
|
100
|
+
from: i.fromModule || i.from || "",
|
|
101
|
+
to: i.toModule || i.to || "",
|
|
102
|
+
description: i.description || ""
|
|
103
|
+
}))
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**WARNING:** `data.dependencies` is used by the sidebar (navigation), module rendering, consolidation views,
|
|
107
|
+
handoff summary, and export. If this array is missing, the entire HTML page crashes with a TypeError.
|
|
108
|
+
ALWAYS include it, even if empty (`dependencies: []`).
|
|
109
|
+
|
|
110
|
+
### consolidation
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
consolidation: {
|
|
114
|
+
interactions: (master.consolidation?.crossModuleInteractions || []).map(i => ({
|
|
115
|
+
from: i.fromModule,
|
|
116
|
+
to: i.toModule,
|
|
117
|
+
description: i.description || ""
|
|
118
|
+
})),
|
|
119
|
+
sharedEntities: master.consolidation?.sharedEntities || [],
|
|
120
|
+
e2eFlows: (master.consolidation?.e2eFlows || []).map(f => ({
|
|
121
|
+
name: f.name,
|
|
122
|
+
steps: (f.steps || []).map(s => ({ module: s.module, action: s.action })),
|
|
123
|
+
actors: (f.steps || []).map(s => s.permission).join(", ")
|
|
124
|
+
}))
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### handoff
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
handoff: {
|
|
132
|
+
complexity: master.handoff?.complexity,
|
|
133
|
+
implementationStrategy: master.handoff?.implementationStrategy,
|
|
134
|
+
moduleOrder: master.handoff?.moduleOrder,
|
|
135
|
+
filesToCreate: master.handoff?.filesToCreate,
|
|
136
|
+
brToCodeMapping: master.handoff?.brToCodeMapping,
|
|
137
|
+
apiEndpointSummary: master.handoff?.apiEndpointSummary
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Helper Function: buildPermissionKeys()
|
|
142
|
+
|
|
143
|
+
See `references/data-mapping.md` for `buildPermissionKeys()` implementation.
|