@atlashub/smartstack-cli 3.1.0 → 3.2.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/package.json +6 -2
- package/templates/skills/business-analyse/SKILL.md +34 -17
- package/templates/skills/business-analyse/html/ba-interactive.html +146 -57
- package/templates/skills/business-analyse/questionnaire.md +20 -15
- package/templates/skills/business-analyse/steps/step-00-init.md +80 -57
- package/templates/skills/business-analyse/steps/step-05-handoff.md +276 -8
- package/templates/skills/business-analyse/steps/step-06-extract.md +131 -3
- 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
|
@@ -1071,8 +1071,7 @@ moduleSpecs[moduleCode] = {
|
|
|
1071
1071
|
})),
|
|
1072
1072
|
permissions: buildPermissionKeys(moduleFeature), // see below
|
|
1073
1073
|
notes: "",
|
|
1074
|
-
mockupNotes:
|
|
1075
|
-
.map(w => "[" + w.screen + "]\n" + w.mockup).join("\n\n")
|
|
1074
|
+
mockupNotes: "" // Deprecated: wireframes now embedded separately in EMBEDDED_ARTIFACTS
|
|
1076
1075
|
}
|
|
1077
1076
|
```
|
|
1078
1077
|
|
|
@@ -1110,18 +1109,113 @@ Default: "daily"
|
|
|
1110
1109
|
Default: "contributor"
|
|
1111
1110
|
```
|
|
1112
1111
|
|
|
1112
|
+
#### Step 2-bis: Build EMBEDDED_ARTIFACTS object (NEW)
|
|
1113
|
+
|
|
1114
|
+
> **NEW in v6.2:** Visual artifacts (wireframes, E2E diagrams) are now embedded as a separate JavaScript object in the HTML for client-side rendering and export.
|
|
1115
|
+
|
|
1116
|
+
Build a JSON object containing ALL visual artifacts from feature.json:
|
|
1117
|
+
|
|
1118
|
+
```javascript
|
|
1119
|
+
{
|
|
1120
|
+
wireframes: {
|
|
1121
|
+
// FOR EACH module: extract all wireframes from module feature.json
|
|
1122
|
+
// [moduleCode]: [ {screen, format, content, elements, componentMapping, layout, description} ]
|
|
1123
|
+
},
|
|
1124
|
+
e2eFlows: [
|
|
1125
|
+
// Extract from master consolidation.e2eFlows[]
|
|
1126
|
+
// { name, diagram, steps, actors }
|
|
1127
|
+
],
|
|
1128
|
+
dependencyGraph: {
|
|
1129
|
+
// Extract from master dependencyGraph
|
|
1130
|
+
// nodes: [ {id, label, type} ], edges: [ {from, to, description} ]
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
```
|
|
1134
|
+
|
|
1135
|
+
**Wireframes mapping** — for EACH module in `master.modules[]`:
|
|
1136
|
+
|
|
1137
|
+
```javascript
|
|
1138
|
+
// Read the module feature.json
|
|
1139
|
+
const moduleFeature = readModuleFeature(moduleCode);
|
|
1140
|
+
const wireframes = (moduleFeature.specification?.uiWireframes || []).map(wf => ({
|
|
1141
|
+
screen: wf.screen, // e.g. "UM-list", "UM-form"
|
|
1142
|
+
section: wf.section, // e.g. "list", "form"
|
|
1143
|
+
format: wf.mockupFormat || "ascii", // "ascii" | "svg"
|
|
1144
|
+
content: wf.mockup, // ASCII art or SVG markup
|
|
1145
|
+
description: wf.description || "",
|
|
1146
|
+
elements: wf.elements || [], // ["DataGrid", "FilterBar", ...]
|
|
1147
|
+
actions: wf.actions || [], // ["filter", "sort", "create", ...]
|
|
1148
|
+
componentMapping: wf.componentMapping || [], // [{ wireframeElement, reactComponent }]
|
|
1149
|
+
layout: wf.layout || null, // { type, regions: [...] }
|
|
1150
|
+
permissionsRequired: wf.permissionsRequired || []
|
|
1151
|
+
}));
|
|
1152
|
+
|
|
1153
|
+
// Store in artifacts object
|
|
1154
|
+
EMBEDDED_ARTIFACTS.wireframes[moduleCode] = wireframes;
|
|
1155
|
+
```
|
|
1156
|
+
|
|
1157
|
+
**E2E flows mapping** — from master consolidation:
|
|
1158
|
+
|
|
1159
|
+
```javascript
|
|
1160
|
+
EMBEDDED_ARTIFACTS.e2eFlows = (master.consolidation?.e2eFlows || []).map(flow => ({
|
|
1161
|
+
name: flow.name,
|
|
1162
|
+
diagram: generateE2EDiagram(flow), // ASCII diagram from flow.steps[]
|
|
1163
|
+
steps: flow.steps || [], // [{ module, action, permission }]
|
|
1164
|
+
actors: Array.from(new Set((flow.steps || [])
|
|
1165
|
+
.map(s => s.permission?.split(".")[0]) // Extract role from permission path
|
|
1166
|
+
.filter(Boolean))).join(", "),
|
|
1167
|
+
modules: Array.from(new Set((flow.steps || [])
|
|
1168
|
+
.map(s => s.module))).join(" → ")
|
|
1169
|
+
}));
|
|
1170
|
+
|
|
1171
|
+
function generateE2EDiagram(flow) {
|
|
1172
|
+
// Generate ASCII diagram from flow.steps[]
|
|
1173
|
+
// Example output:
|
|
1174
|
+
// "Customer ──[read]──→ Order ──[create]──→ Invoice ──[send]──→"
|
|
1175
|
+
// " (Orders) (Orders) (Invoices)"
|
|
1176
|
+
// " Contributor Manager System"
|
|
1177
|
+
|
|
1178
|
+
const stepDiagrams = (flow.steps || []).map(s =>
|
|
1179
|
+
`${s.action}(${s.module})`
|
|
1180
|
+
).join(" ──→ ");
|
|
1181
|
+
|
|
1182
|
+
return stepDiagrams;
|
|
1183
|
+
}
|
|
1184
|
+
```
|
|
1185
|
+
|
|
1186
|
+
**Dependency graph mapping** — from master dependencyGraph:
|
|
1187
|
+
|
|
1188
|
+
```javascript
|
|
1189
|
+
EMBEDDED_ARTIFACTS.dependencyGraph = {
|
|
1190
|
+
nodes: (master.modules || []).map(m => ({
|
|
1191
|
+
id: m.code,
|
|
1192
|
+
label: m.code,
|
|
1193
|
+
type: m.featureType || "data-centric"
|
|
1194
|
+
})),
|
|
1195
|
+
edges: (master.dependencyGraph?.edges || []).map(e => ({
|
|
1196
|
+
from: e.from,
|
|
1197
|
+
to: e.to,
|
|
1198
|
+
description: e.description || ""
|
|
1199
|
+
}))
|
|
1200
|
+
};
|
|
1201
|
+
```
|
|
1202
|
+
|
|
1113
1203
|
#### Step 3: Replace placeholders in template
|
|
1114
1204
|
|
|
1115
1205
|
1. Serialize the FEATURE_DATA object as JSON (with 2-space indentation for readability)
|
|
1116
|
-
2.
|
|
1117
|
-
3. Replace `{{
|
|
1118
|
-
4. Replace `{{
|
|
1119
|
-
5. Replace `{{
|
|
1120
|
-
6. Replace `{{
|
|
1206
|
+
2. Serialize the EMBEDDED_ARTIFACTS object as JSON (with 2-space indentation)
|
|
1207
|
+
3. Replace `{{FEATURE_DATA}}` with the serialized FEATURE_DATA JSON
|
|
1208
|
+
4. Replace `{{EMBEDDED_ARTIFACTS}}` with the serialized EMBEDDED_ARTIFACTS JSON
|
|
1209
|
+
5. Replace `{{APPLICATION_NAME}}` → `{application_name}` (still used in `<title>` and header)
|
|
1210
|
+
6. Replace `{{APPLICATION_ID}}` → `{feature_id}` (still used in `APP_KEY`)
|
|
1211
|
+
7. Replace `{{VERSION}}` → `{version}`
|
|
1212
|
+
8. Replace `{{CREATED_AT}}` → `{ISO timestamp}`
|
|
1121
1213
|
|
|
1122
1214
|
> **NOTE:** `{{APPLICATION_NAME}}`, `{{APPLICATION_ID}}`, `{{VERSION}}`, `{{CREATED_AT}}` still appear
|
|
1123
1215
|
> in the HTML body (`<title>`, header, `APP_KEY`). They MUST be replaced separately from FEATURE_DATA.
|
|
1124
1216
|
|
|
1217
|
+
> **NEW:** `{{EMBEDDED_ARTIFACTS}}` is a separate JavaScript variable in the HTML that stores all visual artifacts (wireframes, E2E diagrams, dependency graph) for client-side rendering and export.
|
|
1218
|
+
|
|
1125
1219
|
#### Step 4: Write and confirm
|
|
1126
1220
|
|
|
1127
1221
|
1. Write the populated HTML to the output directory
|
|
@@ -1132,6 +1226,7 @@ Default: "contributor"
|
|
|
1132
1226
|
Path: docs/business/{app}/business-analyse/v{version}/ba-interactive.html
|
|
1133
1227
|
Pre-populated with: {stakeholder_count} stakeholders, {module_count} modules,
|
|
1134
1228
|
{total_uc} use cases, {total_br} business rules, {total_entity} entities
|
|
1229
|
+
Visual artifacts: {total_wireframes} wireframes, {e2e_flow_count} E2E diagrams
|
|
1135
1230
|
Open in browser to review and edit the business analysis.
|
|
1136
1231
|
Export JSON and re-import with: /business-analyse -x <exported-json-path>
|
|
1137
1232
|
```
|
|
@@ -1241,7 +1336,7 @@ options:
|
|
|
1241
1336
|
- label: "Feature Full (Recommandé)"
|
|
1242
1337
|
description: "Génération parallèle rapide (code + tests). Couverture 70-80%. ~{hours/3} heures."
|
|
1243
1338
|
- label: "Ralph Loop"
|
|
1244
|
-
description: "Développement task-
|
|
1339
|
+
description: "Développement itératif task-par-task avec cycle : Analyse → Dev (backend + tests unitaires + tests non-régression + frontend + tests + documentation) → Validation → Correction → Test ... jusqu'à 100% tests pass. Couverture 95-100%. ~{hours} heures."
|
|
1245
1340
|
- label: "Terminer le BA"
|
|
1246
1341
|
description: "Finir l'analyse, développement manuel par l'équipe."
|
|
1247
1342
|
```
|
|
@@ -1253,6 +1348,179 @@ options:
|
|
|
1253
1348
|
|
|
1254
1349
|
---
|
|
1255
1350
|
|
|
1351
|
+
### 10-bis. Execute User Choice (Automatic Skill Launch)
|
|
1352
|
+
|
|
1353
|
+
> **NEW in v6.1:** Automatically launch the chosen development approach for seamless transition.
|
|
1354
|
+
|
|
1355
|
+
**After receiving AskUserQuestion response:**
|
|
1356
|
+
|
|
1357
|
+
```javascript
|
|
1358
|
+
const choice = userAnswer; // "Feature Full (Recommandé)" | "Ralph Loop" | "Terminer le BA"
|
|
1359
|
+
|
|
1360
|
+
// Extract choice label (remove "(Recommandé)" suffix)
|
|
1361
|
+
const choiceLabel = choice.replace(/\s*\(.*?\)\s*$/g, '').trim();
|
|
1362
|
+
|
|
1363
|
+
if (choiceLabel === "Ralph Loop") {
|
|
1364
|
+
// Launch ralph-loop skill automatically
|
|
1365
|
+
display("");
|
|
1366
|
+
display("🚀 Lancement de Ralph Loop - Développement itératif automatique");
|
|
1367
|
+
display("");
|
|
1368
|
+
display("╔══════════════════════════════════════════════════════════════╗");
|
|
1369
|
+
display("║ CYCLE RALPH LOOP - Comment ça fonctionne ? ║");
|
|
1370
|
+
display("╠══════════════════════════════════════════════════════════════╣");
|
|
1371
|
+
display("║ ║");
|
|
1372
|
+
display("║ Ralph Loop exécute un cycle itératif jusqu'à 100% tests: ║");
|
|
1373
|
+
display("║ ║");
|
|
1374
|
+
display("║ 1️⃣ ANALYSE → Charger task suivante du prd.json ║");
|
|
1375
|
+
display("║ 2️⃣ DÉVELOPPEMENT → Générer le code demandé ║");
|
|
1376
|
+
display("║ • Backend (Entities, Services, Controllers, Repos) ║");
|
|
1377
|
+
display("║ • Tests unitaires (xUnit) + non-régression ║");
|
|
1378
|
+
display("║ • Frontend (Pages, Components, Hooks) ║");
|
|
1379
|
+
display("║ • Tests frontend (React Testing Library) ║");
|
|
1380
|
+
display("║ • SeedData (Core RBAC + business data) ║");
|
|
1381
|
+
display("║ • Documentation utilisateur (inline + tooltips) ║");
|
|
1382
|
+
display("║ 3️⃣ VALIDATION → Commit + MCP conventions check ║");
|
|
1383
|
+
display("║ 4️⃣ TEST → Exécuter dotnet test + npm test ║");
|
|
1384
|
+
display("║ 5️⃣ CORRECTION → Si échec, analyser et corriger ║");
|
|
1385
|
+
display("║ 6️⃣ BOUCLE → Répéter 4-5 jusqu'à 100% tests pass ║");
|
|
1386
|
+
display("║ 7️⃣ NEXT TASK → Passer à la task suivante (retour à 1) ║");
|
|
1387
|
+
display("║ ║");
|
|
1388
|
+
display("║ 🎯 Objectif: ZÉRO ERREUR avant de passer à la task suivante║");
|
|
1389
|
+
display("║ 📊 Couverture: 95-100% (tests générés automatiquement) ║");
|
|
1390
|
+
display("║ ║");
|
|
1391
|
+
display("╚══════════════════════════════════════════════════════════════╝");
|
|
1392
|
+
display("");
|
|
1393
|
+
display(" Configuration du projet:");
|
|
1394
|
+
display(" ┌────────────────────────────────────────────────────────────┐");
|
|
1395
|
+
display(" │ Modules: " + modules.map(m => m.code).join(", "));
|
|
1396
|
+
display(" │ Stratégie: " + implementationStrategy);
|
|
1397
|
+
display(" │ PRD: " + (modules.length > 1 ? ".ralph/prd-{module}.json (per module)" : ".ralph/prd.json"));
|
|
1398
|
+
display(" │ Progress: .ralph/progress.txt");
|
|
1399
|
+
display(" │ Ordre: " + (modules.length > 1 ? "topologique (dépendances d'abord)" : "module unique"));
|
|
1400
|
+
display(" └────────────────────────────────────────────────────────────┘");
|
|
1401
|
+
display("");
|
|
1402
|
+
display(" Modules à traiter (dans l'ordre):");
|
|
1403
|
+
for (let i = 0; i < modules.length; i++) {
|
|
1404
|
+
display(" " + (i+1) + ". " + modules[i].code + " (" + modules[i].complexity + ") - " + modules[i].tasksCount + " tasks");
|
|
1405
|
+
}
|
|
1406
|
+
display("");
|
|
1407
|
+
display(" 📂 Fichiers générés par le BA (inputs pour Ralph):");
|
|
1408
|
+
display(" ├─ feature.json (master + modules) → Spécification source");
|
|
1409
|
+
display(" ├─ prd.json (ou prd-{module}.json) → Task breakdown avec UC/FR/BR");
|
|
1410
|
+
display(" ├─ progress.txt → Tracker hiérarchique (module → layer → tasks)");
|
|
1411
|
+
display(" └─ ba-interactive.html → Revue client (mockups, wireframes)");
|
|
1412
|
+
display("");
|
|
1413
|
+
display(" 🔄 Ralph Loop va maintenant:");
|
|
1414
|
+
display(" 1. Détecter les prd-*.json par module (si multi-module)");
|
|
1415
|
+
display(" 2. Créer modules-queue.json avec l'ordre de traitement");
|
|
1416
|
+
display(" 3. Traiter module par module dans l'ordre topologique");
|
|
1417
|
+
display(" 4. Pour chaque module: parcourir les tasks (domain → seeddata → application → infrastructure → api → frontend → i18n → tests)");
|
|
1418
|
+
display(" 5. Pour chaque task: générer code → commit → tests → correction si échec → re-test → next task");
|
|
1419
|
+
display(" 6. Passer au module suivant quand 100% tasks du module actuel = completed");
|
|
1420
|
+
display(" 7. Générer rapport final avec métriques de couverture");
|
|
1421
|
+
display("");
|
|
1422
|
+
display("═══════════════════════════════════════════════════════════════");
|
|
1423
|
+
display("");
|
|
1424
|
+
display("➡️ Transition vers Ralph Loop...");
|
|
1425
|
+
display("");
|
|
1426
|
+
|
|
1427
|
+
// Call the ralph-loop skill (no arguments needed - prd.json exists)
|
|
1428
|
+
Skill({ skill: "ralph-loop" });
|
|
1429
|
+
|
|
1430
|
+
// EXIT - ralph-loop takes over
|
|
1431
|
+
// The skill does NOT return here - ralph-loop continues in a new context
|
|
1432
|
+
|
|
1433
|
+
} else if (choiceLabel === "Feature Full") {
|
|
1434
|
+
// Launch feature-full skill automatically
|
|
1435
|
+
display("");
|
|
1436
|
+
display("🚀 Lancement de Feature Full...");
|
|
1437
|
+
display("");
|
|
1438
|
+
display(" Configuration:");
|
|
1439
|
+
display(" - Mode: Parallel generation");
|
|
1440
|
+
display(" - Couverture: 70-80%");
|
|
1441
|
+
display(" - Durée estimée: ~" + Math.round(totalHours / 3) + " heures");
|
|
1442
|
+
display("");
|
|
1443
|
+
display("═══════════════════════════════════════════════════════════════");
|
|
1444
|
+
display("");
|
|
1445
|
+
|
|
1446
|
+
Skill({ skill: "feature-full" });
|
|
1447
|
+
|
|
1448
|
+
// EXIT
|
|
1449
|
+
|
|
1450
|
+
} else {
|
|
1451
|
+
// "Terminer le BA" - no skill launch, end gracefully
|
|
1452
|
+
display("");
|
|
1453
|
+
display("✅ Business Analysis terminée.");
|
|
1454
|
+
display("");
|
|
1455
|
+
display(" Les équipes peuvent commencer le développement manuel.");
|
|
1456
|
+
display(" Tous les artefacts sont prêts pour l'implémentation.");
|
|
1457
|
+
display("");
|
|
1458
|
+
display("📂 Fichiers générés:");
|
|
1459
|
+
display(" - feature.json (master + modules) - Spécification complète");
|
|
1460
|
+
display(" - .ralph/prd.json (ou prd-{module}.json) - Task breakdown");
|
|
1461
|
+
display(" - .ralph/progress.txt - Tracker de progression");
|
|
1462
|
+
display(" - ba-interactive.html - Document de revue client");
|
|
1463
|
+
display("");
|
|
1464
|
+
display("📊 Métriques:");
|
|
1465
|
+
display(" - Modules: " + modules.length);
|
|
1466
|
+
display(" - Entités: " + totalEntities);
|
|
1467
|
+
display(" - Use cases: " + totalUseCases);
|
|
1468
|
+
display(" - Business rules: " + totalBusinessRules);
|
|
1469
|
+
display(" - Fichiers à créer: " + totalFiles);
|
|
1470
|
+
display("");
|
|
1471
|
+
display("🎯 Prochaines étapes recommandées:");
|
|
1472
|
+
display(" 1. Ouvrir ba-interactive.html dans le navigateur");
|
|
1473
|
+
display(" 2. Partager avec les stakeholders pour validation finale");
|
|
1474
|
+
display(" 3. Utiliser progress.txt comme guide de développement");
|
|
1475
|
+
display(" 4. Implémenter module par module selon l'ordre topologique");
|
|
1476
|
+
display("");
|
|
1477
|
+
display("💡 Pour lancer le développement assisté plus tard:");
|
|
1478
|
+
display(" - Ralph Loop: /ralph-loop (détecte automatiquement .ralph/prd.json)");
|
|
1479
|
+
display(" - Feature Full: /feature-full");
|
|
1480
|
+
display("");
|
|
1481
|
+
display("═══════════════════════════════════════════════════════════════");
|
|
1482
|
+
|
|
1483
|
+
// EXIT gracefully - BA workflow complete
|
|
1484
|
+
}
|
|
1485
|
+
```
|
|
1486
|
+
|
|
1487
|
+
**Key behaviors:**
|
|
1488
|
+
|
|
1489
|
+
1. **Ralph Loop launch:**
|
|
1490
|
+
- No arguments needed (prd.json already exists)
|
|
1491
|
+
- Ralph automatically detects single vs multi-module
|
|
1492
|
+
- Ralph reads modules-queue.json if multi-module
|
|
1493
|
+
- Seamless transition - user sees continuous flow
|
|
1494
|
+
|
|
1495
|
+
2. **Feature Full launch:**
|
|
1496
|
+
- Passes application context
|
|
1497
|
+
- Parallel generation starts immediately
|
|
1498
|
+
|
|
1499
|
+
3. **Manual development:**
|
|
1500
|
+
- Clear summary of generated artifacts
|
|
1501
|
+
- Actionable next steps
|
|
1502
|
+
- Instructions for later skill launch
|
|
1503
|
+
|
|
1504
|
+
**Error handling:**
|
|
1505
|
+
|
|
1506
|
+
```javascript
|
|
1507
|
+
try {
|
|
1508
|
+
Skill({ skill: "ralph-loop" });
|
|
1509
|
+
} catch (error) {
|
|
1510
|
+
display("⚠️ Échec du lancement automatique de Ralph Loop");
|
|
1511
|
+
display("");
|
|
1512
|
+
display(" Veuillez lancer manuellement:");
|
|
1513
|
+
display(" /ralph-loop");
|
|
1514
|
+
display("");
|
|
1515
|
+
display(" Si le problème persiste:");
|
|
1516
|
+
display(" 1. Vérifier que la skill ralph-loop est installée");
|
|
1517
|
+
display(" 2. Vérifier les permissions Claude Code");
|
|
1518
|
+
display(" 3. Consulter les logs: .ralph/logs/");
|
|
1519
|
+
}
|
|
1520
|
+
```
|
|
1521
|
+
|
|
1522
|
+
---
|
|
1523
|
+
|
|
1256
1524
|
## MODE SUPPORT
|
|
1257
1525
|
|
|
1258
1526
|
### Standard Mode
|
|
@@ -67,13 +67,27 @@ Lire le fichier passe en argument : {extract_path}
|
|
|
67
67
|
"businessRules": [{ "id": "", "name": "", "category": "", "statement": "", "example": "" }],
|
|
68
68
|
"entities": [{ "name": "", "description": "", "attributes": [{ "name": "", "description": "" }], "relationships": [] }],
|
|
69
69
|
"permissions": [],
|
|
70
|
-
"notes": ""
|
|
71
|
-
"mockupNotes": ""
|
|
70
|
+
"notes": ""
|
|
72
71
|
}
|
|
73
72
|
},
|
|
74
73
|
"consolidation": {
|
|
75
74
|
"interactions": [],
|
|
76
|
-
"e2eFlows": [{ "name": "", "steps": [{ "module": "", "action": "" }], "actors": "" }]
|
|
75
|
+
"e2eFlows": [{ "name": "", "steps": [{ "module": "", "action": "" }], "actors": "", "diagram": "" }]
|
|
76
|
+
},
|
|
77
|
+
"artifacts": {
|
|
78
|
+
"wireframes": {
|
|
79
|
+
"{moduleCode}": [
|
|
80
|
+
{ "screen": "", "section": "", "format": "ascii|svg", "content": "", "description": "",
|
|
81
|
+
"elements": [], "actions": [], "componentMapping": [], "layout": {}, "permissionsRequired": [] }
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
"e2eFlows": [
|
|
85
|
+
{ "name": "", "diagram": "", "steps": [], "actors": "", "modules": "" }
|
|
86
|
+
],
|
|
87
|
+
"dependencyGraph": {
|
|
88
|
+
"nodes": [{ "id": "", "label": "", "type": "" }],
|
|
89
|
+
"edges": [{ "from": "", "to": "", "description": "" }]
|
|
90
|
+
}
|
|
77
91
|
}
|
|
78
92
|
}
|
|
79
93
|
```
|
|
@@ -407,6 +421,113 @@ ba-writer.enrichSection({
|
|
|
407
421
|
ba-writer.updateStatus({feature_id}, "consolidated")
|
|
408
422
|
```
|
|
409
423
|
|
|
424
|
+
### 6-bis. Extraire et reconstituer les artefacts visuels (NEW)
|
|
425
|
+
|
|
426
|
+
> **NEW in v6.2:** Visual artifacts (wireframes, E2E diagrams, dependency graph) are now extracted from the exported JSON and reconstituted into feature.json.
|
|
427
|
+
|
|
428
|
+
**IF** `artifacts` exists in exported JSON:
|
|
429
|
+
|
|
430
|
+
#### Extract wireframes per module
|
|
431
|
+
|
|
432
|
+
Pour chaque module dans `artifacts.wireframes`:
|
|
433
|
+
|
|
434
|
+
```
|
|
435
|
+
FOR EACH moduleCode IN artifacts.wireframes:
|
|
436
|
+
moduleWireframes = artifacts.wireframes[moduleCode]
|
|
437
|
+
|
|
438
|
+
// Locate the module feature.json
|
|
439
|
+
moduleFeature = ba-reader.findModuleFeature({feature_id}, moduleCode)
|
|
440
|
+
|
|
441
|
+
// Map wireframes to specification.uiWireframes[]
|
|
442
|
+
uiWireframes = moduleWireframes.map(wf => ({
|
|
443
|
+
"screen": wf.screen,
|
|
444
|
+
"section": wf.section,
|
|
445
|
+
"mockupFormat": wf.format,
|
|
446
|
+
"mockup": wf.content,
|
|
447
|
+
"description": wf.description || "",
|
|
448
|
+
"elements": wf.elements || [],
|
|
449
|
+
"actions": wf.actions || [],
|
|
450
|
+
"permissionsRequired": wf.permissionsRequired || [],
|
|
451
|
+
"componentMapping": wf.componentMapping || [],
|
|
452
|
+
"layout": wf.layout || null
|
|
453
|
+
}))
|
|
454
|
+
|
|
455
|
+
// Write to module feature.json (enriching specification section)
|
|
456
|
+
ba-writer.enrichSection({
|
|
457
|
+
featureId: moduleFeature.id,
|
|
458
|
+
section: "specification",
|
|
459
|
+
data: { uiWireframes: uiWireframes }
|
|
460
|
+
})
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
**Validation:** For each wireframe:
|
|
464
|
+
- `screen` must be unique within module
|
|
465
|
+
- `mockupFormat` must be "ascii" or "svg"
|
|
466
|
+
- `mockup` content must not be empty
|
|
467
|
+
- `componentMapping` array must have at least one entry
|
|
468
|
+
- `layout` object must have `type` and `regions` if present
|
|
469
|
+
|
|
470
|
+
#### Extract E2E flow diagrams
|
|
471
|
+
|
|
472
|
+
IF `artifacts.e2eFlows` exists:
|
|
473
|
+
|
|
474
|
+
```
|
|
475
|
+
e2eFlows = artifacts.e2eFlows.map(flow => ({
|
|
476
|
+
"name": flow.name,
|
|
477
|
+
"modules": flow.modules.split(" → ").map(m => m.trim()), // "OrderManagement → Invoicing" → ["OrderManagement", "Invoicing"]
|
|
478
|
+
"steps": flow.steps || [],
|
|
479
|
+
"diagram": flow.diagram, // NEW: ASCII diagram preserved
|
|
480
|
+
"actors": flow.actors.split(", ").map(a => a.trim())
|
|
481
|
+
}))
|
|
482
|
+
|
|
483
|
+
// Merge with existing e2eFlows from consolidation.e2eFlows
|
|
484
|
+
ba-writer.enrichSection({
|
|
485
|
+
featureId: {feature_id},
|
|
486
|
+
section: "consolidation",
|
|
487
|
+
data: { e2eFlows: e2eFlows }
|
|
488
|
+
})
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
**Validation:** For each E2E flow:
|
|
492
|
+
- `diagram` must not be empty if present
|
|
493
|
+
- `modules` array must match modules defined in master feature.json
|
|
494
|
+
- `steps` must have at least 2 entries (cross-module flow)
|
|
495
|
+
|
|
496
|
+
#### Extract dependency graph (optional)
|
|
497
|
+
|
|
498
|
+
IF `artifacts.dependencyGraph` exists:
|
|
499
|
+
|
|
500
|
+
```
|
|
501
|
+
dependencyGraph = {
|
|
502
|
+
"nodes": artifacts.dependencyGraph.nodes.map(n => ({
|
|
503
|
+
"id": n.id,
|
|
504
|
+
"label": n.label || n.id,
|
|
505
|
+
"type": n.type || "data-centric"
|
|
506
|
+
})),
|
|
507
|
+
"edges": artifacts.dependencyGraph.edges.map(e => ({
|
|
508
|
+
"from": e.from,
|
|
509
|
+
"to": e.to,
|
|
510
|
+
"description": e.description || ""
|
|
511
|
+
}))
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Write to master feature.json
|
|
515
|
+
ba-writer.enrichSection({
|
|
516
|
+
featureId: {feature_id},
|
|
517
|
+
section: "decomposition",
|
|
518
|
+
data: { dependencyGraph: dependencyGraph }
|
|
519
|
+
})
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
**Post-extraction summary:**
|
|
523
|
+
|
|
524
|
+
```
|
|
525
|
+
✓ Artefacts visuels extraits:
|
|
526
|
+
- Wireframes: {total_wireframe_count} across {module_count} modules
|
|
527
|
+
- E2E diagrams: {e2e_flow_count}
|
|
528
|
+
- Dependency graph: {node_count} nodes, {edge_count} edges
|
|
529
|
+
```
|
|
530
|
+
|
|
410
531
|
### 7. Resume de l'extraction
|
|
411
532
|
|
|
412
533
|
Afficher un resume comparatif :
|
|
@@ -432,11 +553,18 @@ Afficher un resume comparatif :
|
|
|
432
553
|
| Regles metier | {total} | analysis.businessRules |
|
|
433
554
|
| Entites | {total} | analysis.entities |
|
|
434
555
|
| Parcours E2E | {count} | consolidation.e2eFlows |
|
|
556
|
+
| Maquettes (wireframes) | {total} | specification.uiWireframes[] |
|
|
557
|
+
| Diagrammes E2E | {count} | consolidation.e2eFlows[].diagram |
|
|
435
558
|
|
|
436
559
|
Fichiers generes :
|
|
437
560
|
- docs/business/{app}/business-analyse/v1.0/feature.json (master)
|
|
438
561
|
- docs/business/{app}/{module}/business-analyse/v1.0/feature.json (par module)
|
|
439
562
|
|
|
563
|
+
Artefacts visuels preserves :
|
|
564
|
+
- Toutes les maquettes ASCII/SVG validees lors de la specification
|
|
565
|
+
- Tous les diagrammes E2E pour les flux cross-module
|
|
566
|
+
- Graphe de dependances entre modules
|
|
567
|
+
|
|
440
568
|
═══════════════════════════════════════════════════════════════
|
|
441
569
|
```
|
|
442
570
|
|