@atlashub/smartstack-cli 3.1.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/.documentation/prd-json-v2.0.0.md +396 -0
- package/.documentation/testing-ba-e2e.md +462 -0
- package/dist/index.js +605 -25
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
- package/templates/agents/ba-reader.md +1 -1
- package/templates/agents/ba-writer.md +8 -1
- package/templates/skills/business-analyse/SKILL.md +46 -31
- 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/html/ba-interactive.html +146 -57
- package/templates/skills/business-analyse/questionnaire/06-security.md +1 -1
- package/templates/skills/business-analyse/questionnaire.md +22 -17
- 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 +85 -59
- 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 +134 -4
- 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/ralph-loop/SKILL.md +138 -20
- package/templates/skills/ralph-loop/steps/step-01-task.md +75 -18
- package/templates/skills/ralph-loop/steps/step-04-check.md +72 -5
- package/templates/skills/business-analyse/steps/step-05-handoff.md +0 -1414
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Business Analysis - Suggestions & Context7 (_suggestions.md)
|
|
2
|
+
|
|
3
|
+
> **Loaded by:** step-01-cadrage, step-04-consolidation
|
|
4
|
+
> **Purpose:** Proactive suggestion patterns and Context7 library references
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Proactive Suggestions
|
|
9
|
+
|
|
10
|
+
After scope definition in step-01, the skill suggests complementary modules/sections:
|
|
11
|
+
|
|
12
|
+
1. Analyze feature type and scope from questionnaire answers
|
|
13
|
+
2. Load `patterns/suggestion-catalog.md`
|
|
14
|
+
3. Match against catalog patterns
|
|
15
|
+
4. Present suggestions via AskUserQuestion (accept/reject per suggestion)
|
|
16
|
+
5. Store in feature.json.suggestions[]
|
|
17
|
+
|
|
18
|
+
Accepted suggestions become candidates for future /business-analyse runs.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Context7 (Step 04)
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
Prompt pattern:
|
|
26
|
+
"use context7 with /facebook/react and /i18next/react-i18next
|
|
27
|
+
to generate {component} following SmartStack patterns"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Libraries:
|
|
31
|
+
- `/facebook/react` - React 19 patterns
|
|
32
|
+
- `/i18next/react-i18next` - Internationalization
|
|
33
|
+
- `/remix-run/react-router` - React Router v7
|
|
34
|
+
- `/lucide-icons/lucide-react` - Icons
|
|
@@ -374,6 +374,95 @@
|
|
|
374
374
|
min-height: 200px;
|
|
375
375
|
}
|
|
376
376
|
|
|
377
|
+
/* Wireframe rendering */
|
|
378
|
+
.ascii-wireframe {
|
|
379
|
+
font-family: 'Courier New', 'Consolas', monospace;
|
|
380
|
+
font-size: 0.7rem;
|
|
381
|
+
line-height: 1.3;
|
|
382
|
+
color: var(--primary-light);
|
|
383
|
+
background: var(--bg-dark);
|
|
384
|
+
padding: 1rem;
|
|
385
|
+
border-radius: 6px;
|
|
386
|
+
overflow-x: auto;
|
|
387
|
+
white-space: pre;
|
|
388
|
+
margin: 0;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.svg-wireframe {
|
|
392
|
+
background: var(--bg-dark);
|
|
393
|
+
padding: 1rem;
|
|
394
|
+
border-radius: 6px;
|
|
395
|
+
overflow-x: auto;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.svg-wireframe svg {
|
|
399
|
+
max-width: 100%;
|
|
400
|
+
height: auto;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
.wireframe-description {
|
|
404
|
+
padding: 0.75rem 1rem;
|
|
405
|
+
font-size: 0.85rem;
|
|
406
|
+
color: var(--text);
|
|
407
|
+
border-top: 1px solid var(--border);
|
|
408
|
+
background: var(--bg-input);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
.wireframe-metadata {
|
|
412
|
+
padding: 0.75rem 1rem;
|
|
413
|
+
font-size: 0.8rem;
|
|
414
|
+
color: var(--text-muted);
|
|
415
|
+
border-top: 1px solid var(--border);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.wireframe-details {
|
|
419
|
+
padding: 0.75rem 1rem;
|
|
420
|
+
border-top: 1px solid var(--border);
|
|
421
|
+
background: var(--bg-input);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.wireframe-details summary {
|
|
425
|
+
cursor: pointer;
|
|
426
|
+
font-size: 0.85rem;
|
|
427
|
+
color: var(--primary-light);
|
|
428
|
+
font-weight: 500;
|
|
429
|
+
user-select: none;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
.wireframe-details summary:hover {
|
|
433
|
+
color: var(--primary);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.mapping-table {
|
|
437
|
+
width: 100%;
|
|
438
|
+
margin-top: 0.75rem;
|
|
439
|
+
border-collapse: collapse;
|
|
440
|
+
font-size: 0.8rem;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.mapping-table th {
|
|
444
|
+
background: var(--bg-hover);
|
|
445
|
+
padding: 0.5rem;
|
|
446
|
+
text-align: left;
|
|
447
|
+
font-weight: 500;
|
|
448
|
+
color: var(--text-bright);
|
|
449
|
+
border: 1px solid var(--border);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
.mapping-table td {
|
|
453
|
+
padding: 0.5rem;
|
|
454
|
+
border: 1px solid var(--border);
|
|
455
|
+
color: var(--text);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
.mapping-table code {
|
|
459
|
+
background: var(--bg-dark);
|
|
460
|
+
padding: 0.2rem 0.4rem;
|
|
461
|
+
border-radius: 3px;
|
|
462
|
+
font-size: 0.75rem;
|
|
463
|
+
color: var(--accent);
|
|
464
|
+
}
|
|
465
|
+
|
|
377
466
|
/* Mockup components */
|
|
378
467
|
.mock-header {
|
|
379
468
|
display: flex;
|
|
@@ -1407,6 +1496,7 @@
|
|
|
1407
1496
|
============================================ */
|
|
1408
1497
|
const APP_KEY = 'ba-{{APPLICATION_ID}}';
|
|
1409
1498
|
let data = {{FEATURE_DATA}};
|
|
1499
|
+
const EMBEDDED_ARTIFACTS = {{EMBEDDED_ARTIFACTS}};
|
|
1410
1500
|
|
|
1411
1501
|
/* ============================================
|
|
1412
1502
|
INITIALIZATION
|
|
@@ -1682,7 +1772,8 @@
|
|
|
1682
1772
|
modules: data.modules,
|
|
1683
1773
|
dependencies: data.dependencies,
|
|
1684
1774
|
moduleSpecifications: {},
|
|
1685
|
-
consolidation: data.consolidation
|
|
1775
|
+
consolidation: data.consolidation,
|
|
1776
|
+
artifacts: EMBEDDED_ARTIFACTS // NEW: Include visual artifacts
|
|
1686
1777
|
};
|
|
1687
1778
|
|
|
1688
1779
|
// Structure module specs for export
|
|
@@ -1700,8 +1791,8 @@
|
|
|
1700
1791
|
})),
|
|
1701
1792
|
entities: spec.entities || [],
|
|
1702
1793
|
permissions: spec.permissions || [],
|
|
1703
|
-
notes: spec.notes || ''
|
|
1704
|
-
mockupNotes:
|
|
1794
|
+
notes: spec.notes || ''
|
|
1795
|
+
// mockupNotes removed: wireframes now in artifacts
|
|
1705
1796
|
};
|
|
1706
1797
|
});
|
|
1707
1798
|
|
|
@@ -2132,60 +2223,9 @@
|
|
|
2132
2223
|
|
|
2133
2224
|
<!-- TAB: Maquettes -->
|
|
2134
2225
|
<div class="tab-panel" id="tab-${code}-mock">
|
|
2135
|
-
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
<div class="mockup-toolbar">
|
|
2139
|
-
<div class="mockup-dot mockup-dot-red"></div>
|
|
2140
|
-
<div class="mockup-dot mockup-dot-yellow"></div>
|
|
2141
|
-
<div class="mockup-dot mockup-dot-green"></div>
|
|
2142
|
-
<span class="mockup-title">${mod.name} - Liste</span>
|
|
2143
|
-
</div>
|
|
2144
|
-
<div class="mockup-content">
|
|
2145
|
-
<div class="mock-header">
|
|
2146
|
-
<div class="mock-title">${mod.name}</div>
|
|
2147
|
-
<div class="mock-btn">+ Nouveau</div>
|
|
2148
|
-
</div>
|
|
2149
|
-
<div class="mock-search">Rechercher...</div>
|
|
2150
|
-
<table class="mock-table">
|
|
2151
|
-
<thead><tr>
|
|
2152
|
-
${(mod.entities || []).slice(0, 1).length > 0 ? '<th>Identifiant</th><th>Nom</th><th>Statut</th><th>Date</th><th>Actions</th>' : '<th>Colonne 1</th><th>Colonne 2</th><th>Statut</th><th>Actions</th>'}
|
|
2153
|
-
</tr></thead>
|
|
2154
|
-
<tbody>
|
|
2155
|
-
<tr><td style="color:var(--primary-light);">001</td><td>Exemple 1</td><td><span class="mock-status mock-status-active">Actif</span></td><td>Aujourd'hui</td><td style="color:var(--text-muted);">Voir | Modifier</td></tr>
|
|
2156
|
-
<tr><td style="color:var(--primary-light);">002</td><td>Exemple 2</td><td><span class="mock-status mock-status-pending">En attente</span></td><td>Hier</td><td style="color:var(--text-muted);">Voir | Modifier</td></tr>
|
|
2157
|
-
<tr><td style="color:var(--primary-light);">003</td><td>Exemple 3</td><td><span class="mock-status mock-status-draft">Brouillon</span></td><td>Il y a 3 jours</td><td style="color:var(--text-muted);">Voir | Modifier</td></tr>
|
|
2158
|
-
</tbody>
|
|
2159
|
-
</table>
|
|
2160
|
-
</div>
|
|
2161
|
-
</div>
|
|
2162
|
-
|
|
2163
|
-
<div class="mockup-frame" style="margin-top:1rem;">
|
|
2164
|
-
<div class="mockup-toolbar">
|
|
2165
|
-
<div class="mockup-dot mockup-dot-red"></div>
|
|
2166
|
-
<div class="mockup-dot mockup-dot-yellow"></div>
|
|
2167
|
-
<div class="mockup-dot mockup-dot-green"></div>
|
|
2168
|
-
<span class="mockup-title">${mod.name} - Formulaire de creation</span>
|
|
2169
|
-
</div>
|
|
2170
|
-
<div class="mockup-content">
|
|
2171
|
-
<div class="mock-header">
|
|
2172
|
-
<div class="mock-title">Nouveau ${(mod.entities || [])[0] || 'enregistrement'}</div>
|
|
2173
|
-
</div>
|
|
2174
|
-
<div class="mock-form-row">
|
|
2175
|
-
<div class="mock-form-group"><div class="mock-label">Identifiant</div><div class="mock-input" style="color:var(--text-muted);">Genere automatiquement</div></div>
|
|
2176
|
-
<div class="mock-form-group"><div class="mock-label">Nom</div><div class="mock-input"></div></div>
|
|
2177
|
-
</div>
|
|
2178
|
-
<div class="mock-form-group"><div class="mock-label">Description</div><div class="mock-input" style="height:60px;"></div></div>
|
|
2179
|
-
<div class="mock-form-actions">
|
|
2180
|
-
<div class="mock-btn" style="background:var(--bg-hover);color:var(--text);">Annuler</div>
|
|
2181
|
-
<div class="mock-btn">Enregistrer</div>
|
|
2182
|
-
</div>
|
|
2183
|
-
</div>
|
|
2184
|
-
</div>
|
|
2185
|
-
|
|
2186
|
-
<div class="card" style="margin-top:1rem;">
|
|
2187
|
-
<div class="card-label">Notes sur les maquettes</div>
|
|
2188
|
-
<div class="editable" contenteditable="true" data-module-code="${code}" data-module-field="mockupNotes" data-placeholder="Ajoutez vos remarques sur les maquettes : elements manquants, disposition souhaitee, comportements particuliers...">${spec.mockupNotes || ''}</div>
|
|
2226
|
+
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">Maquettes validees lors de l'analyse. Ces wireframes montrent la structure exacte des ecrans de ce domaine.</p>
|
|
2227
|
+
<div id="mockupContainer-${code}">
|
|
2228
|
+
${renderModuleMockups(code)}
|
|
2189
2229
|
</div>
|
|
2190
2230
|
</div>
|
|
2191
2231
|
|
|
@@ -2328,6 +2368,55 @@
|
|
|
2328
2368
|
autoSave();
|
|
2329
2369
|
}
|
|
2330
2370
|
|
|
2371
|
+
function renderModuleMockups(code) {
|
|
2372
|
+
// Get embedded wireframes for this module
|
|
2373
|
+
const wireframes = EMBEDDED_ARTIFACTS?.wireframes?.[code] || [];
|
|
2374
|
+
|
|
2375
|
+
if (wireframes.length === 0) {
|
|
2376
|
+
return `
|
|
2377
|
+
<div class="card" style="text-align:center;padding:2rem;color:var(--text-muted);">
|
|
2378
|
+
<p>Aucune maquette disponible pour ce module.</p>
|
|
2379
|
+
<p style="font-size:0.85rem;margin-top:0.5rem;">Les maquettes seront generees lors de la specification detaillee.</p>
|
|
2380
|
+
</div>`;
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
return wireframes.map((wf, i) => `
|
|
2384
|
+
<div class="mockup-frame" style="${i > 0 ? 'margin-top:1.5rem;' : ''}">
|
|
2385
|
+
<div class="mockup-toolbar">
|
|
2386
|
+
<div class="mockup-dot mockup-dot-red"></div>
|
|
2387
|
+
<div class="mockup-dot mockup-dot-yellow"></div>
|
|
2388
|
+
<div class="mockup-dot mockup-dot-green"></div>
|
|
2389
|
+
<span class="mockup-title">${wf.screen || wf.section}</span>
|
|
2390
|
+
</div>
|
|
2391
|
+
<div class="mockup-content">
|
|
2392
|
+
${wf.format === 'ascii'
|
|
2393
|
+
? `<pre class="ascii-wireframe">${wf.content || ''}</pre>`
|
|
2394
|
+
: `<div class="svg-wireframe">${wf.content || ''}</div>`}
|
|
2395
|
+
</div>
|
|
2396
|
+
${wf.description ? `
|
|
2397
|
+
<div class="wireframe-description">
|
|
2398
|
+
<strong>Description:</strong> ${wf.description}
|
|
2399
|
+
</div>` : ''}
|
|
2400
|
+
${(wf.elements || []).length > 0 ? `
|
|
2401
|
+
<div class="wireframe-metadata">
|
|
2402
|
+
<div><strong>Elements:</strong> ${wf.elements.join(', ')}</div>
|
|
2403
|
+
</div>` : ''}
|
|
2404
|
+
${(wf.componentMapping || []).length > 0 ? `
|
|
2405
|
+
<details class="wireframe-details">
|
|
2406
|
+
<summary>Mapping composants SmartStack</summary>
|
|
2407
|
+
<table class="mapping-table">
|
|
2408
|
+
<thead><tr><th>Element maquette</th><th>Composant React</th></tr></thead>
|
|
2409
|
+
<tbody>
|
|
2410
|
+
${wf.componentMapping.map(m =>
|
|
2411
|
+
`<tr><td>${m.wireframeElement}</td><td><code>${m.reactComponent}</code></td></tr>`
|
|
2412
|
+
).join('')}
|
|
2413
|
+
</tbody>
|
|
2414
|
+
</table>
|
|
2415
|
+
</details>` : ''}
|
|
2416
|
+
</div>
|
|
2417
|
+
`).join('');
|
|
2418
|
+
}
|
|
2419
|
+
|
|
2331
2420
|
function renderPermissionGrid(code) {
|
|
2332
2421
|
const roles = data.cadrage.stakeholders.length > 0
|
|
2333
2422
|
? data.cadrage.stakeholders.map(s => s.role)
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
> - Les rôles identifiés en Q6.1-Q6.4 sont des **ensembles de permissions**, pas des données métier
|
|
45
45
|
> - L'accès est contrôlé par des permissions attribuées aux rôles, pas par des propriétés d'entité
|
|
46
46
|
> - Ne jamais proposer de créer une entité `Role`, `UserRole`, ou un attribut `User.Role`
|
|
47
|
-
> - Le mapping rôle → permissions se fait dans la **Permission Matrix** (step-
|
|
47
|
+
> - Le mapping rôle → permissions se fait dans la **Permission Matrix** (step-03a-specify)
|
|
48
48
|
|
|
49
49
|
## Elicitation Guide
|
|
50
50
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Elicitation Questionnaire - Business Analysis
|
|
2
2
|
|
|
3
|
-
> **Usage:** Structured questions for step-01-cadrage and step-
|
|
3
|
+
> **Usage:** Structured questions for step-01-cadrage and step-03a-specify
|
|
4
4
|
> **Standard:** BABOK v3 - Elicitation Techniques (VibeCoding-focused)
|
|
5
5
|
> **Model:** OPUS with ULTRATHINK
|
|
6
6
|
> **Total:** ~68 targeted questions (dev-relevant only)
|
|
@@ -284,7 +284,7 @@
|
|
|
284
284
|
| Phase | Categories utilisees |
|
|
285
285
|
|-------|---------------------|
|
|
286
286
|
| step-01-cadrage | 00 (si mode application), 01, 02, 03, 14, 15 + conditionnelles (05, 06, 08, 09, 10) |
|
|
287
|
-
| step-
|
|
287
|
+
| step-03a-specify (par module) | 04, 07, 11, 12, 13 (chargees par module) |
|
|
288
288
|
|
|
289
289
|
### Phase de cadrage
|
|
290
290
|
|
|
@@ -315,18 +315,23 @@ Chaque question conservee passe ce test :
|
|
|
315
315
|
|
|
316
316
|
| Categorie | Questions | Phase | Focus |
|
|
317
317
|
|-----------|-----------|-------|-------|
|
|
318
|
-
| 0. Identite de l'application |
|
|
319
|
-
| 1. Contexte metier |
|
|
320
|
-
| 2. Parties prenantes |
|
|
321
|
-
| 3. Perimetre fonctionnel |
|
|
322
|
-
| 4. Donnees |
|
|
323
|
-
| 5. Integrations |
|
|
324
|
-
| 6. Securite et acces |
|
|
325
|
-
| 7. Interface utilisateur |
|
|
326
|
-
| 8. Performance et qualite |
|
|
327
|
-
| 9. Contraintes |
|
|
328
|
-
| 10. Documentation |
|
|
329
|
-
|
|
|
330
|
-
|
|
|
331
|
-
|
|
|
332
|
-
|
|
|
318
|
+
| 0. Identite de l'application | 18 | step-01 (mode application) | Nom, domaines, profils |
|
|
319
|
+
| 1. Contexte metier | 32 | step-01 | Probleme, situation actuelle, vision, declencheur |
|
|
320
|
+
| 2. Parties prenantes | 33 | step-01 | Utilisateurs, taches, acces, changement |
|
|
321
|
+
| 3. Perimetre fonctionnel | 32 | step-01 | Priorites, parcours, besoins transversaux |
|
|
322
|
+
| 4. Donnees | 15 | step-03 (par module) | Entites et regles |
|
|
323
|
+
| 5. Integrations | 14 | step-01 (conditionnel) | Systemes et flux |
|
|
324
|
+
| 6. Securite et acces | 13 | step-01 (conditionnel) | Permissions et restrictions |
|
|
325
|
+
| 7. Interface utilisateur | 19 | step-03 (par module) | Ecrans et experience |
|
|
326
|
+
| 8. Performance et qualite | 8 | step-01 (conditionnel) | Temps de reponse et tests |
|
|
327
|
+
| 9. Contraintes | 6 | step-01 (conditionnel) | Technologies et dependances |
|
|
328
|
+
| 10. Documentation | 7 | step-01 (conditionnel) | Guides et formation |
|
|
329
|
+
| 11. Cycle de vie donnees | 14 | step-03 (conditionnel) | Retention, archivage, RGPD |
|
|
330
|
+
| 12. Migration et transition | 14 | step-03 (conditionnel) | Donnees existantes, cutover |
|
|
331
|
+
| 13. Impact inter-modules | 14 | step-03 (conditionnel) | Dependances, evenements |
|
|
332
|
+
| 14. Risques et hypotheses | 16 | step-01 | Risques, hypotheses, lecons du passe |
|
|
333
|
+
| 15. Criteres de reussite | 17 | step-01 | Indicateurs de succes, conditions d'acceptation |
|
|
334
|
+
| **Total noyau (01-03, 14-15)** | **130** | | **Toujours charges** |
|
|
335
|
+
| **Total avec app (00)** | **148** | | **Si mode application** |
|
|
336
|
+
| **Total conditionnel (04-13)** | **124** | | **Selon contexte** |
|
|
337
|
+
| **Total maximum possible** | **272** | | **Noyau + app + tous conditionnels** |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# React Components - Business Analyse Viewer
|
|
2
2
|
|
|
3
3
|
> **Usage:** React component that renders feature.json directly
|
|
4
|
-
> **Loaded in:** step-
|
|
4
|
+
> **Loaded in:** step-05b-deploy.md
|
|
5
5
|
> **Data source (module):** `docs/business/{app}/{module}/business-analyse/v{X.Y}/feature.json`
|
|
6
6
|
> **Data source (application):** `docs/business/{app}/business-analyse/v{X.Y}/feature.json`
|
|
7
7
|
> **Related:** `react/application-viewer.md` for application-level view
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# TypeScript Schema - Feature JSON Types
|
|
2
2
|
|
|
3
3
|
> **Usage:** TypeScript interfaces aligned with feature-schema.json and application-schema.json
|
|
4
|
-
> **Loaded in:** step-
|
|
4
|
+
> **Loaded in:** step-05b-deploy.md (for web app rendering)
|
|
5
5
|
> **Source (module):** `docs/business/{app}/{module}/business-analyse/v{X.Y}/feature.json`
|
|
6
6
|
> **Source (application):** `docs/business/{app}/business-analyse/v{X.Y}/feature.json`
|
|
7
7
|
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# HTML Data Mapping Reference (references/html-data-mapping.md)
|
|
2
|
+
|
|
3
|
+
> **Used by:** step-05b-deploy (section 3: Deploy Interactive HTML Document)
|
|
4
|
+
> **Purpose:** Exact mapping from feature.json 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 feature.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
|
+
},
|
|
21
|
+
cadrage: {
|
|
22
|
+
problem: {
|
|
23
|
+
description: master.cadrage.problem, // string → problem.description
|
|
24
|
+
trigger: master.cadrage.trigger, // string → problem.trigger
|
|
25
|
+
impactedPeople: "", // not in feature.json, client fills
|
|
26
|
+
history: "",
|
|
27
|
+
consequences: ""
|
|
28
|
+
},
|
|
29
|
+
current: {
|
|
30
|
+
tools: master.cadrage.asIs, // string → current.tools
|
|
31
|
+
steps: [], // client can add process steps
|
|
32
|
+
painPoints: master.cadrage.stakeholders
|
|
33
|
+
.flatMap(s => s.painPoints || []).join("\n"), // aggregate all painPoints
|
|
34
|
+
errors: ""
|
|
35
|
+
},
|
|
36
|
+
vision: {
|
|
37
|
+
changes: master.cadrage.toBe, // string → vision.changes
|
|
38
|
+
results: master.cadrage.acceptanceCriteria
|
|
39
|
+
.map(ac => ac.criterion).join("\n"), // AC → results (one per line)
|
|
40
|
+
successSign: ""
|
|
41
|
+
},
|
|
42
|
+
stakeholders: master.cadrage.stakeholders.map(s => ({
|
|
43
|
+
role: s.role,
|
|
44
|
+
function: s.function || "",
|
|
45
|
+
tasks: s.tasks || [],
|
|
46
|
+
frequency: mapFrequency(s.frequency), // "Quotidien"→"daily", etc.
|
|
47
|
+
access: mapAccess(s.involvement), // "decision-maker"→"admin", "end-user"→"contributor"
|
|
48
|
+
frustrations: (s.painPoints || []).join("\n")
|
|
49
|
+
})),
|
|
50
|
+
scope: {
|
|
51
|
+
vital: (master.cadrage.globalScope.mustHave || [])
|
|
52
|
+
.map(item => ({ name: item, description: "" })), // string[] → {name,description}[]
|
|
53
|
+
important: (master.cadrage.globalScope.shouldHave || [])
|
|
54
|
+
.map(item => ({ name: item, description: "" })),
|
|
55
|
+
optional: (master.cadrage.globalScope.couldHave || [])
|
|
56
|
+
.map(item => ({ name: item, description: "" })),
|
|
57
|
+
excluded: (master.cadrage.globalScope.outOfScope || [])
|
|
58
|
+
.map(item => ({ name: item, description: "" }))
|
|
59
|
+
},
|
|
60
|
+
risks: (master.cadrage.risks || []).map(r => ({
|
|
61
|
+
description: r.description,
|
|
62
|
+
probability: r.probability, // "high" | "medium" | "low"
|
|
63
|
+
impact: r.impact,
|
|
64
|
+
mitigation: r.mitigation || ""
|
|
65
|
+
})),
|
|
66
|
+
assumptions: "",
|
|
67
|
+
success: {
|
|
68
|
+
definition: (master.cadrage.acceptanceCriteria || [])
|
|
69
|
+
.map(ac => ac.criterion).join("\n"),
|
|
70
|
+
metrics: "",
|
|
71
|
+
timeline: "",
|
|
72
|
+
minimumConditions: ""
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
modules: master.modules.map(m => ({
|
|
76
|
+
code: m.code,
|
|
77
|
+
name: m.code, // module code as name
|
|
78
|
+
description: m.description || "",
|
|
79
|
+
featureType: m.featureType || "data-centric",
|
|
80
|
+
priority: m.priority || "must",
|
|
81
|
+
entities: m.entities || [],
|
|
82
|
+
status: m.status || "handed-off"
|
|
83
|
+
})),
|
|
84
|
+
dependencies: (master.dependencyGraph?.edges || []).map(e => ({
|
|
85
|
+
from: e.from,
|
|
86
|
+
to: e.to,
|
|
87
|
+
description: e.description || ""
|
|
88
|
+
})),
|
|
89
|
+
moduleSpecs: {
|
|
90
|
+
// FOR EACH module: read module feature.json, then map:
|
|
91
|
+
// [moduleCode]: { useCases, businessRules, entities, permissions, notes, mockupNotes }
|
|
92
|
+
},
|
|
93
|
+
consolidation: {
|
|
94
|
+
interactions: (master.consolidation?.crossModuleInteractions || []).map(i => ({
|
|
95
|
+
from: i.fromModule,
|
|
96
|
+
to: i.toModule,
|
|
97
|
+
description: i.description || ""
|
|
98
|
+
})),
|
|
99
|
+
e2eFlows: (master.consolidation?.e2eFlows || []).map(f => ({
|
|
100
|
+
name: f.name,
|
|
101
|
+
steps: (f.steps || []).map(s => ({ module: s.module, action: s.action })),
|
|
102
|
+
actors: (f.steps || []).map(s => s.permission).join(", ")
|
|
103
|
+
}))
|
|
104
|
+
},
|
|
105
|
+
handoff: master.handoff || {}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Module Specs Mapping
|
|
110
|
+
|
|
111
|
+
For EACH module in `master.modules[]`:
|
|
112
|
+
|
|
113
|
+
1. Read the module feature.json at `master.modules[i].featureJsonPath`
|
|
114
|
+
2. Map to `moduleSpecs[moduleCode]`:
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
moduleSpecs[moduleCode] = {
|
|
118
|
+
useCases: (moduleFeature.specification?.useCases || []).map(uc => ({
|
|
119
|
+
name: uc.name,
|
|
120
|
+
actor: uc.primaryActor,
|
|
121
|
+
steps: (uc.mainScenario || []).join("\n"), // array → newline-separated string
|
|
122
|
+
alternative: (uc.alternativeScenarios || [])
|
|
123
|
+
.map(a => a.name + ": " + (a.steps || []).join(", ")).join("\n")
|
|
124
|
+
})),
|
|
125
|
+
businessRules: (moduleFeature.analysis?.businessRules || []).map(br => ({
|
|
126
|
+
name: br.name,
|
|
127
|
+
category: br.category, // "validation"|"calculation"|"workflow"|"security"|"data"
|
|
128
|
+
statement: br.statement,
|
|
129
|
+
example: (br.examples || []).map(e => e.input + " → " + e.expected).join("; ")
|
|
130
|
+
})),
|
|
131
|
+
entities: (moduleFeature.analysis?.entities || []).map(ent => ({
|
|
132
|
+
name: ent.name,
|
|
133
|
+
description: ent.description || "",
|
|
134
|
+
attributes: (ent.attributes || []).map(a => ({
|
|
135
|
+
name: a.name,
|
|
136
|
+
description: a.description || ""
|
|
137
|
+
})),
|
|
138
|
+
relationships: (ent.relationships || []).map(r =>
|
|
139
|
+
r.target + " (" + r.type + ") - " + (r.description || "")
|
|
140
|
+
)
|
|
141
|
+
})),
|
|
142
|
+
permissions: buildPermissionKeys(moduleFeature), // see below
|
|
143
|
+
notes: "",
|
|
144
|
+
mockupNotes: "" // Deprecated: wireframes now embedded separately in EMBEDDED_ARTIFACTS
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Permission Keys Function
|
|
149
|
+
|
|
150
|
+
The HTML uses `"Role|Action"` format (e.g. `"RH Admin|Consulter"`):
|
|
151
|
+
|
|
152
|
+
```javascript
|
|
153
|
+
function buildPermissionKeys(moduleFeature) {
|
|
154
|
+
const keys = [];
|
|
155
|
+
const matrix = moduleFeature.specification?.permissionMatrix;
|
|
156
|
+
if (!matrix) return keys;
|
|
157
|
+
const actionMap = { read: "Consulter", create: "Creer", update: "Modifier",
|
|
158
|
+
delete: "Supprimer", validate: "Valider", export: "Exporter",
|
|
159
|
+
submit: "Valider", import: "Creer" };
|
|
160
|
+
(matrix.roleAssignments || []).forEach(ra => {
|
|
161
|
+
(ra.permissions || []).forEach(permPath => {
|
|
162
|
+
const action = permPath.split(".").pop(); // last segment = action
|
|
163
|
+
const uiAction = actionMap[action] || action;
|
|
164
|
+
keys.push(ra.role + "|" + uiAction);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
return keys;
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Frequency Mapping
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
"Quotidien" → "daily", "Hebdomadaire" → "weekly", "Mensuel" → "monthly"
|
|
175
|
+
Default: "daily"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Access Mapping (involvement → access)
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
"decision-maker" → "admin", "end-user" with manager-like tasks → "manager"
|
|
182
|
+
"end-user" → "contributor", "observer" → "viewer"
|
|
183
|
+
Default: "contributor"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## EMBEDDED_ARTIFACTS Mapping
|
|
189
|
+
|
|
190
|
+
Build a JSON object containing ALL visual artifacts from feature.json:
|
|
191
|
+
|
|
192
|
+
```javascript
|
|
193
|
+
{
|
|
194
|
+
wireframes: {
|
|
195
|
+
// FOR EACH module: extract all wireframes from module feature.json
|
|
196
|
+
// [moduleCode]: [ {screen, format, content, elements, componentMapping, layout, description} ]
|
|
197
|
+
},
|
|
198
|
+
e2eFlows: [
|
|
199
|
+
// Extract from master consolidation.e2eFlows[]
|
|
200
|
+
// { name, diagram, steps, actors }
|
|
201
|
+
],
|
|
202
|
+
dependencyGraph: {
|
|
203
|
+
// Extract from master dependencyGraph
|
|
204
|
+
// nodes: [ {id, label, type} ], edges: [ {from, to, description} ]
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Wireframes Mapping
|
|
210
|
+
|
|
211
|
+
For EACH module in `master.modules[]`:
|
|
212
|
+
|
|
213
|
+
```javascript
|
|
214
|
+
// Read the module feature.json
|
|
215
|
+
const moduleFeature = readModuleFeature(moduleCode);
|
|
216
|
+
const wireframes = (moduleFeature.specification?.uiWireframes || []).map(wf => ({
|
|
217
|
+
screen: wf.screen, // e.g. "UM-list", "UM-form"
|
|
218
|
+
section: wf.section, // e.g. "list", "form"
|
|
219
|
+
format: wf.mockupFormat || "ascii", // "ascii" | "svg"
|
|
220
|
+
content: wf.mockup, // ASCII art or SVG markup
|
|
221
|
+
description: wf.description || "",
|
|
222
|
+
elements: wf.elements || [], // ["DataGrid", "FilterBar", ...]
|
|
223
|
+
actions: wf.actions || [], // ["filter", "sort", "create", ...]
|
|
224
|
+
componentMapping: wf.componentMapping || [], // [{ wireframeElement, reactComponent }]
|
|
225
|
+
layout: wf.layout || null, // { type, regions: [...] }
|
|
226
|
+
permissionsRequired: wf.permissionsRequired || []
|
|
227
|
+
}));
|
|
228
|
+
|
|
229
|
+
// Store in artifacts object
|
|
230
|
+
EMBEDDED_ARTIFACTS.wireframes[moduleCode] = wireframes;
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### E2E Flows Mapping
|
|
234
|
+
|
|
235
|
+
From master consolidation:
|
|
236
|
+
|
|
237
|
+
```javascript
|
|
238
|
+
EMBEDDED_ARTIFACTS.e2eFlows = (master.consolidation?.e2eFlows || []).map(flow => ({
|
|
239
|
+
name: flow.name,
|
|
240
|
+
diagram: generateE2EDiagram(flow), // ASCII diagram from flow.steps[]
|
|
241
|
+
steps: flow.steps || [], // [{ module, action, permission }]
|
|
242
|
+
actors: Array.from(new Set((flow.steps || [])
|
|
243
|
+
.map(s => s.permission?.split(".")[0]) // Extract role from permission path
|
|
244
|
+
.filter(Boolean))).join(", "),
|
|
245
|
+
modules: Array.from(new Set((flow.steps || [])
|
|
246
|
+
.map(s => s.module))).join(" → ")
|
|
247
|
+
}));
|
|
248
|
+
|
|
249
|
+
function generateE2EDiagram(flow) {
|
|
250
|
+
// Generate ASCII diagram from flow.steps[]
|
|
251
|
+
// Example output:
|
|
252
|
+
// "Customer ──[read]──→ Order ──[create]──→ Invoice ──[send]──→"
|
|
253
|
+
// " (Orders) (Orders) (Invoices)"
|
|
254
|
+
// " Contributor Manager System"
|
|
255
|
+
|
|
256
|
+
const stepDiagrams = (flow.steps || []).map(s =>
|
|
257
|
+
`${s.action}(${s.module})`
|
|
258
|
+
).join(" ──→ ");
|
|
259
|
+
|
|
260
|
+
return stepDiagrams;
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Dependency Graph Mapping
|
|
265
|
+
|
|
266
|
+
From master dependencyGraph:
|
|
267
|
+
|
|
268
|
+
```javascript
|
|
269
|
+
EMBEDDED_ARTIFACTS.dependencyGraph = {
|
|
270
|
+
nodes: (master.modules || []).map(m => ({
|
|
271
|
+
id: m.code,
|
|
272
|
+
label: m.code,
|
|
273
|
+
type: m.featureType || "data-centric"
|
|
274
|
+
})),
|
|
275
|
+
edges: (master.dependencyGraph?.edges || []).map(e => ({
|
|
276
|
+
from: e.from,
|
|
277
|
+
to: e.to,
|
|
278
|
+
description: e.description || ""
|
|
279
|
+
}))
|
|
280
|
+
};
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Usage in step-05b-deploy
|
|
286
|
+
|
|
287
|
+
1. Serialize the FEATURE_DATA object as JSON (with 2-space indentation for readability)
|
|
288
|
+
2. Serialize the EMBEDDED_ARTIFACTS object as JSON (with 2-space indentation)
|
|
289
|
+
3. Replace `{{FEATURE_DATA}}` with the serialized FEATURE_DATA JSON
|
|
290
|
+
4. Replace `{{EMBEDDED_ARTIFACTS}}` with the serialized EMBEDDED_ARTIFACTS JSON
|
|
291
|
+
5. Replace `{{APPLICATION_NAME}}` → `{application_name}` (still used in `<title>` and header)
|
|
292
|
+
6. Replace `{{APPLICATION_ID}}` → `{feature_id}` (still used in `APP_KEY`)
|
|
293
|
+
7. Replace `{{VERSION}}` → `{version}`
|
|
294
|
+
8. Replace `{{CREATED_AT}}` → `{ISO timestamp}`
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
|
|
46
|
-
"$comment": "Sub-schema loading guide per BA step: step-00-init → metadata-schema.json | step-01-cadrage → discovery-schema.json (module) OR application-schema.json (master) | step-02-decomposition → application-schema.json (modules[], dependencyGraph) | step-
|
|
46
|
+
"$comment": "Sub-schema loading guide per BA step: step-00-init → metadata-schema.json | step-01-cadrage → discovery-schema.json (module) OR application-schema.json (master) | step-02-decomposition → application-schema.json (modules[], dependencyGraph) | step-03a-specify → analysis-schema.json | step-03b-compile → specification-schema.json | step-04-consolidation → validation-schema.json + application-schema.json (consolidation) | step-05a-handoff → handoff-schema.json | step-05b-deploy → (artifacts only)",
|
|
47
47
|
|
|
48
48
|
"$defs": {
|
|
49
49
|
"stepStatus": { "$ref": "shared/common-defs.json#/$defs/stepStatus" },
|