@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.
Files changed (39) hide show
  1. package/.documentation/prd-json-v2.0.0.md +396 -0
  2. package/.documentation/testing-ba-e2e.md +462 -0
  3. package/dist/index.js +605 -25
  4. package/dist/index.js.map +1 -1
  5. package/package.json +6 -2
  6. package/templates/agents/ba-reader.md +1 -1
  7. package/templates/agents/ba-writer.md +8 -1
  8. package/templates/skills/business-analyse/SKILL.md +46 -31
  9. package/templates/skills/business-analyse/_architecture.md +123 -0
  10. package/templates/skills/business-analyse/_elicitation.md +206 -0
  11. package/templates/skills/business-analyse/_module-loop.md +56 -0
  12. package/templates/skills/business-analyse/_shared.md +75 -531
  13. package/templates/skills/business-analyse/_suggestions.md +34 -0
  14. package/templates/skills/business-analyse/html/ba-interactive.html +146 -57
  15. package/templates/skills/business-analyse/questionnaire/06-security.md +1 -1
  16. package/templates/skills/business-analyse/questionnaire.md +22 -17
  17. package/templates/skills/business-analyse/react/components.md +1 -1
  18. package/templates/skills/business-analyse/react/schema.md +1 -1
  19. package/templates/skills/business-analyse/references/html-data-mapping.md +294 -0
  20. package/templates/skills/business-analyse/schemas/feature-schema.json +1 -1
  21. package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +1 -1
  22. package/templates/skills/business-analyse/schemas/sections/handoff-schema.json +1 -1
  23. package/templates/skills/business-analyse/schemas/sections/specification-schema.json +1 -1
  24. package/templates/skills/business-analyse/steps/step-00-init.md +85 -59
  25. package/templates/skills/business-analyse/steps/step-01-cadrage.md +2 -0
  26. package/templates/skills/business-analyse/steps/step-02-decomposition.md +5 -3
  27. package/templates/skills/business-analyse/steps/{step-03-specify.md → step-03a-specify.md} +16 -606
  28. package/templates/skills/business-analyse/steps/step-03b-compile.md +670 -0
  29. package/templates/skills/business-analyse/steps/step-04-consolidation.md +7 -5
  30. package/templates/skills/business-analyse/steps/step-05a-handoff.md +727 -0
  31. package/templates/skills/business-analyse/steps/step-05b-deploy.md +479 -0
  32. package/templates/skills/business-analyse/steps/step-06-extract.md +134 -4
  33. package/templates/skills/business-analyse/templates/tpl-frd.md +1 -1
  34. package/templates/skills/business-analyse/templates/tpl-launch-displays.md +161 -0
  35. package/templates/skills/business-analyse/templates/tpl-progress.md +171 -0
  36. package/templates/skills/ralph-loop/SKILL.md +138 -20
  37. package/templates/skills/ralph-loop/steps/step-01-task.md +75 -18
  38. package/templates/skills/ralph-loop/steps/step-04-check.md +72 -5
  39. 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: spec.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;">Exemples visuels des ecrans principaux de ce domaine. Ces maquettes montrent la disposition generale, pas le design final.</p>
2136
-
2137
- <div class="mockup-frame">
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-03-specify)
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-03-specify
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-03-specify (par module) | 04, 07, 11, 12, 13 (chargees par module) |
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 | 8 | step-01 (mode application) | Nom, domaines, profils |
319
- | 1. Contexte metier | 12 | step-01 | Probleme, situation actuelle, vision, declencheur |
320
- | 2. Parties prenantes | 14 | step-01 | Utilisateurs, taches, acces, changement |
321
- | 3. Perimetre fonctionnel | 12 | step-01 | Priorites, parcours, besoins transversaux |
322
- | 4. Donnees | 8 | step-03 (par module) | Entites et regles |
323
- | 5. Integrations | 8 | step-01 (conditionnel) | Systemes et flux |
324
- | 6. Securite et acces | 8 | step-01 (conditionnel) | Permissions et restrictions |
325
- | 7. Interface utilisateur | 8 | step-03 (par module) | Ecrans et experience |
326
- | 8. Performance et qualite | 4 | step-01 (conditionnel) | Temps de reponse et tests |
327
- | 9. Contraintes | 4 | step-01 (conditionnel) | Technologies et dependances |
328
- | 10. Documentation | 4 | step-01 (conditionnel) | Guides et formation |
329
- | 14. Risques et hypotheses | 8 | step-01 | Risques, hypotheses, lecons du passe |
330
- | 15. Criteres de reussite | 8 | step-01 | Indicateurs de succes, conditions d'acceptation |
331
- | **Total noyau** | **~86** | | |
332
- | 11-13 (conditionnel) | ~24 | step-03 (par module) | Cycle de vie, migration, impact inter-modules |
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-05-handoff.md
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-05-handoff.md (for web app rendering)
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-03-specify → analysis-schema.json + specification-schema.json | step-04-consolidation → validation-schema.json + application-schema.json (consolidation) | step-05-handoff → handoff-schema.json",
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" },