@atlashub/smartstack-cli 3.4.0 → 3.4.1

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.
@@ -1,648 +0,0 @@
1
- ---
2
- name: step-06-extract
3
- description: Extract interactive HTML document data into feature.json - zero information loss
4
- model: sonnet
5
- next_step: null
6
- ---
7
-
8
- > **Context files:** `_shared.md`
9
-
10
- # Step 6: Extraction depuis le document interactif
11
-
12
- ## REGLES D'EXECUTION
13
-
14
- - TOUJOURS lire le fichier JSON exporte avant toute operation
15
- - TOUJOURS mapper CHAQUE element sans exception (zero perte d'information)
16
- - TOUJOURS utiliser ba-writer pour ecrire dans feature.json
17
- - TOUJOURS afficher un resume comparatif avant/apres extraction
18
- - TOUJOURS demander confirmation avant d'ecraser un feature.json existant
19
- - COMMUNICATION en `{language}` (depuis metadata ou config)
20
-
21
- ## VOTRE TACHE
22
-
23
- Lire le fichier JSON exporte depuis le document HTML interactif et transformer toutes les donnees client en feature.json conforme au schema. Chaque element saisi par le client doit se retrouver dans le feature.json sans perte ni alteration.
24
-
25
- ---
26
-
27
- ## SEQUENCE D'EXECUTION
28
-
29
- ### 1. Lire le fichier JSON exporte
30
-
31
- ```
32
- Lire le fichier passe en argument : {extract_path}
33
- → Parser le JSON
34
- → Valider la structure minimale : metadata, cadrage, modules
35
- ```
36
-
37
- **Structure attendue du JSON exporte :**
38
- ```json
39
- {
40
- "metadata": {
41
- "applicationName": "...",
42
- "applicationId": "...",
43
- "version": "...",
44
- "createdAt": "...",
45
- "lastModified": "...",
46
- "exportedAt": "..."
47
- },
48
- "cadrage": {
49
- "problem": { "description": "", "impactedPeople": "", "history": "", "trigger": "", "consequences": "" },
50
- "current": { "tools": "", "painPoints": "", "errors": "", "steps": [] },
51
- "vision": { "changes": "", "results": "", "successSign": "" },
52
- "stakeholders": [{ "role": "", "function": "", "tasks": [], "frequency": "", "access": "", "frustrations": "" }],
53
- "scope": {
54
- "vital": [{ "name": "", "description": "" }],
55
- "important": [],
56
- "optional": [],
57
- "excluded": []
58
- },
59
- "risks": [{ "description": "", "probability": "", "impact": "", "mitigation": "" }],
60
- "assumptions": "",
61
- "success": { "definition": "", "metrics": "", "timeline": "", "minimumConditions": "" }
62
- },
63
- "modules": [{ "code": "", "name": "", "description": "", "featureType": "", "priority": "", "entities": [], "status": "" }],
64
- "dependencies": [{ "from": "", "to": "", "description": "" }],
65
- "moduleSpecifications": {
66
- "{code}": {
67
- "module": {},
68
- "useCases": [{ "id": "", "name": "", "actor": "", "steps": "", "alternative": "" }],
69
- "businessRules": [{ "id": "", "name": "", "category": "", "statement": "", "example": "" }],
70
- "entities": [{ "name": "", "description": "", "attributes": [{ "name": "", "description": "" }], "relationships": [] }],
71
- "permissions": [],
72
- "notes": ""
73
- }
74
- },
75
- "consolidation": {
76
- "interactions": [],
77
- "e2eFlows": [{ "name": "", "steps": [{ "module": "", "action": "" }], "actors": "", "diagram": "" }]
78
- },
79
- "artifacts": {
80
- "wireframes": {
81
- "{moduleCode}": [
82
- { "screen": "", "section": "", "format": "ascii|svg", "content": "", "description": "",
83
- "elements": [], "actions": [], "componentMapping": [], "layout": {}, "permissionsRequired": [] }
84
- ]
85
- },
86
- "e2eFlows": [
87
- { "name": "", "diagram": "", "steps": [], "actors": "", "modules": "" }
88
- ],
89
- "dependencyGraph": {
90
- "nodes": [{ "id": "", "label": "", "type": "" }],
91
- "edges": [{ "from": "", "to": "", "description": "" }]
92
- }
93
- }
94
- }
95
- ```
96
-
97
- SI le fichier est invalide ou manquant → STOP avec message d'erreur.
98
-
99
- ### 2. Determiner l'application et le contexte
100
-
101
- ```
102
- application_name = metadata.applicationName OU metadata.applicationId
103
- version = metadata.version OU "1.0"
104
- language = "fr" (par defaut, le document HTML est en francais)
105
- ```
106
-
107
- Verifier si un feature.json existe deja :
108
- ```
109
- ba-reader.findFeature(application_name)
110
- ```
111
-
112
- SI feature.json existe :
113
- → Demander via AskUserQuestion :
114
- ```
115
- question: "Un feature.json existe deja pour cette application. Que souhaitez-vous faire ?"
116
- header: "Conflit"
117
- options:
118
- - label: "Remplacer"
119
- description: "Ecraser le feature.json existant avec les donnees du document interactif"
120
- - label: "Fusionner"
121
- description: "Fusionner les nouvelles donnees avec l'existant (priorite au document interactif)"
122
- - label: "Nouvelle version"
123
- description: "Creer une nouvelle version (v1.1) en conservant l'ancien"
124
- ```
125
-
126
- ### 3. Mapper le cadrage
127
-
128
- **Transformation : HTML export → feature.json cadrage**
129
-
130
- | Source (export JSON) | Destination (feature.json) |
131
- |---------------------|---------------------------|
132
- | `cadrage.problem.description` | `cadrage.problem` |
133
- | `cadrage.problem.impactedPeople` | `cadrage.problem` (append) |
134
- | `cadrage.problem.history` | `cadrage.problem` (append) |
135
- | `cadrage.problem.trigger` | `cadrage.trigger` |
136
- | `cadrage.problem.consequences` | `cadrage.problem` (append) |
137
- | `cadrage.current.tools` | `cadrage.asIs` |
138
- | `cadrage.current.steps[]` | `cadrage.asIs` (append process steps) |
139
- | `cadrage.current.painPoints` | `cadrage.asIs` (append) |
140
- | `cadrage.current.errors` | `cadrage.asIs` (append) |
141
- | `cadrage.vision.changes` | `cadrage.toBe` |
142
- | `cadrage.vision.results` | `cadrage.toBe` (append) |
143
- | `cadrage.vision.successSign` | `cadrage.toBe` (append) |
144
- | `cadrage.stakeholders[]` | `cadrage.stakeholders[]` (voir mapping detaille) |
145
- | `cadrage.scope.vital[]` | `cadrage.globalScope.mustHave[]` |
146
- | `cadrage.scope.important[]` | `cadrage.globalScope.shouldHave[]` |
147
- | `cadrage.scope.optional[]` | `cadrage.globalScope.couldHave[]` |
148
- | `cadrage.scope.excluded[]` | `cadrage.globalScope.outOfScope[]` |
149
- | `cadrage.risks[]` | `cadrage.risks[]` (voir mapping detaille) |
150
- | `cadrage.assumptions` | `cadrage.risks[]` (type: "assumption") |
151
- | `cadrage.success.definition` | `cadrage.acceptanceCriteria[]` |
152
- | `cadrage.success.metrics` | `cadrage.acceptanceCriteria[]` |
153
- | `cadrage.success.timeline` | `cadrage.acceptanceCriteria[]` |
154
- | `cadrage.success.minimumConditions` | `cadrage.acceptanceCriteria[]` |
155
-
156
- **Mapping detaille des parties prenantes :**
157
-
158
- Pour chaque `cadrage.stakeholders[i]` :
159
- ```json
160
- {
161
- "role": stakeholders[i].role,
162
- "function": stakeholders[i].function,
163
- "involvement": mapAccessToInvolvement(stakeholders[i].access),
164
- "tasks": stakeholders[i].tasks,
165
- "frequency": stakeholders[i].frequency,
166
- "painPoints": [stakeholders[i].frustrations]
167
- }
168
- ```
169
-
170
- Mapping `access` → `involvement` :
171
- | access (HTML) | involvement (feature.json) |
172
- |--------------|---------------------------|
173
- | admin | decision-maker |
174
- | manager | approver |
175
- | contributor | end-user |
176
- | viewer | informed |
177
-
178
- **Mapping detaille des risques :**
179
-
180
- Pour chaque `cadrage.risks[i]` :
181
- ```json
182
- {
183
- "id": "RISK-" + String(i + 1).padStart(3, '0'),
184
- "type": "business",
185
- "description": risks[i].description,
186
- "probability": risks[i].probability,
187
- "impact": risks[i].impact,
188
- "priority": computePriority(risks[i].probability, risks[i].impact),
189
- "mitigation": risks[i].mitigation
190
- }
191
- ```
192
-
193
- Pour les hypotheses (texte libre `cadrage.assumptions`) :
194
- ```
195
- Decouper le texte par lignes
196
- Pour chaque ligne non vide, creer un risque :
197
- {
198
- "id": "RISK-ASM-" + index,
199
- "type": "assumption",
200
- "description": ligne,
201
- "probability": "medium",
202
- "impact": "medium",
203
- "priority": "medium",
204
- "mitigation": "A verifier avant le demarrage du projet"
205
- }
206
- ```
207
-
208
- **Mapping de la couverture :**
209
-
210
- Construire `cadrage.coverageMatrix[]` a partir du scope :
211
- ```
212
- Pour chaque item dans scope.vital :
213
- { "item": item.name, "category": "mustHave", "module": assignModule(item), "notes": item.description }
214
- Pour chaque item dans scope.important :
215
- { "item": item.name, "category": "shouldHave", "module": assignModule(item), "notes": item.description }
216
- Pour chaque item dans scope.optional :
217
- { "item": item.name, "category": "couldHave", "module": assignModule(item), "notes": item.description }
218
- Pour chaque item dans scope.excluded :
219
- { "item": item.name, "category": "outOfScope", "module": null, "notes": item.description }
220
- ```
221
-
222
- `assignModule(item)` : Si un seul module, assigner ce module. Si plusieurs modules, chercher le module dont le nom ou les entites correspondent le mieux a l'item.
223
-
224
- **Mapping des roles applicatifs :**
225
-
226
- Deriver `cadrage.applicationRoles[]` a partir des profils stakeholders :
227
- ```
228
- Pour chaque stakeholder unique par niveau d'acces :
229
- {
230
- "role": "{App} " + formatRole(access),
231
- "description": stakeholder.function,
232
- "level": access,
233
- "permissionPattern": "business.{app}." + (access === "admin" ? "*" : "...")
234
- }
235
- ```
236
-
237
- **Ecriture :**
238
- ```
239
- ba-writer.enrichSection({
240
- featureId: {feature_id},
241
- section: "cadrage",
242
- data: { problem, asIs, toBe, trigger, stakeholders, globalScope, applicationRoles, risks, acceptanceCriteria, coverageMatrix, codebaseContext }
243
- })
244
- ba-writer.updateStatus({feature_id}, "framed")
245
- ```
246
-
247
- ### 4. Mapper les modules
248
-
249
- Pour chaque `modules[i]` du JSON exporte :
250
- ```json
251
- {
252
- "code": modules[i].code,
253
- "description": modules[i].description,
254
- "featureType": modules[i].featureType,
255
- "dependencies": deriveDependencies(modules[i].code),
256
- "dependents": deriveDependents(modules[i].code),
257
- "status": "pending",
258
- "featureJsonPath": null,
259
- "priority": modules[i].priority,
260
- "sortOrder": computeSortOrder(modules[i].code),
261
- "entities": modules[i].entities,
262
- "estimatedComplexity": estimateComplexity(modules[i].code)
263
- }
264
- ```
265
-
266
- `deriveDependencies(code)` : filtrer `dependencies[]` ou `from === code`, retourner les `to`
267
- `deriveDependents(code)` : filtrer `dependencies[]` ou `to === code`, retourner les `from`
268
- `computeSortOrder(code)` : depuis le tri topologique
269
- `estimateComplexity(code)` : basee sur le nombre d'entites et de cas d'utilisation du module
270
-
271
- **Construire le graphe de dependances :**
272
- ```json
273
- {
274
- "edges": dependencies.map(d => ({ "from": d.from, "to": d.to, "type": "FK", "description": d.description })),
275
- "topologicalOrder": computeTopologicalOrder(),
276
- "layers": computeLayers()
277
- }
278
- ```
279
-
280
- **Ecriture :**
281
- ```
282
- ba-writer.enrichModuleRegistry({
283
- featureId: {feature_id},
284
- modules: [mapped modules],
285
- dependencyGraph: { edges, topologicalOrder, layers }
286
- })
287
- ba-writer.updateStatus({feature_id}, "decomposed")
288
- ```
289
-
290
- ### 5. Mapper les specifications par module
291
-
292
- Pour chaque module dans l'ordre topologique :
293
-
294
- #### 5a. Creer le feature.json du module
295
-
296
- ```
297
- ba-writer.create({
298
- scope: "module",
299
- applicationRef: {feature_id},
300
- moduleCode: {module.code},
301
- path: "docs/business/{app}/{module_code}/business-analyse/v1.0/feature.json"
302
- })
303
- ```
304
-
305
- #### 5b. Mapper la section discovery
306
-
307
- Deriver de la cadrage, filtree pour ce module (meme logique que step-03 section 2-ter).
308
-
309
- #### 5c. Mapper les cas d'utilisation
310
-
311
- Pour chaque `moduleSpecifications[code].useCases[i]` :
312
- ```json
313
- {
314
- "id": "UC-{PREFIX}-" + String(i + 1).padStart(3, '0'),
315
- "name": uc.name,
316
- "primaryActor": uc.actor,
317
- "permission": "business.{app}.{module}.{inferAction(uc.name)}",
318
- "preconditions": [],
319
- "postconditions": [],
320
- "mainScenario": parseSteps(uc.steps),
321
- "alternativeScenarios": uc.alternative ? [{ "name": "Cas alternatif", "steps": [uc.alternative] }] : [],
322
- "errorScenarios": [],
323
- "linkedRules": linkToBusinessRules(uc, moduleSpec.businessRules)
324
- }
325
- ```
326
-
327
- `parseSteps(text)` : Decouper par lignes, retourner en tableau.
328
- `inferAction(name)` : Extraire le verbe (Creer→create, Modifier→update, Supprimer→delete, Consulter→read, Valider→approve, Exporter→export).
329
- `linkToBusinessRules(uc, rules)` : Chercher les regles dont le statement mentionne des concepts similaires au nom du UC.
330
-
331
- #### 5d. Mapper les regles metier
332
-
333
- Pour chaque `moduleSpecifications[code].businessRules[i]` :
334
- ```json
335
- {
336
- "id": "BR-{CAT}-{PREFIX}-" + String(i + 1).padStart(3, '0'),
337
- "name": br.name,
338
- "category": br.category,
339
- "statement": br.statement,
340
- "priority": "must",
341
- "conditions": extractConditions(br.statement),
342
- "examples": br.example ? [{ "input": br.example, "expected": "Selon la regle" }] : [],
343
- "testability": "Via test unitaire"
344
- }
345
- ```
346
-
347
- `{CAT}` derive de `category` : validation→VAL, calculation→CALC, workflow→WF, security→SEC, data→DATA
348
- `extractConditions(statement)` : Extraire les conditions depuis le texte "Si..." en tableau.
349
-
350
- #### 5e. Mapper les entites
351
-
352
- Pour chaque `moduleSpecifications[code].entities[i]` :
353
- ```json
354
- {
355
- "name": toPascalCase(ent.name),
356
- "description": ent.description,
357
- "attributes": ent.attributes.map(a => ({
358
- "name": toCamelCase(a.name),
359
- "description": a.description,
360
- "required": true,
361
- "unique": false,
362
- "validation": ""
363
- })),
364
- "relationships": parseRelationships(ent.relationships)
365
- }
366
- ```
367
-
368
- `parseRelationships(rels)` : Pour chaque relation texte "Nom - Description", extraire :
369
- ```json
370
- { "target": toPascalCase(nom), "type": "1:N", "description": description }
371
- ```
372
-
373
- #### 5f. Mapper les permissions
374
-
375
- Transformer le format `permissions: ["Role|Action"]` en matrice structuree :
376
- ```json
377
- {
378
- "permissions": derivePermissionPaths(code, actions),
379
- "roleAssignments": deriveRoleAssignments(code, permissions)
380
- }
381
- ```
382
-
383
- #### 5g. Generer les sections, wireframes et seedDataCore
384
-
385
- Inferer automatiquement a partir des entites et du type de module (meme logique que step-03 section 3a-infer).
386
-
387
- #### 5h. Ecrire le feature.json du module
388
-
389
- ```
390
- ba-writer.enrichSection({ featureId: moduleFeatureId, section: "analysis", data: { objectives, entities, businessRules, processFlow, dataLifecycle } })
391
- ba-writer.enrichSection({ featureId: moduleFeatureId, section: "specification", data: { actors, useCases, functionalRequirements, permissionMatrix, navigation, seedDataCore, sections, uiWireframes } })
392
- ba-writer.updateModuleStatus({feature_id}, {module.code}, "specified")
393
- ```
394
-
395
- ### 6. Mapper la consolidation
396
-
397
- Si plusieurs modules :
398
- ```
399
- ba-writer.enrichSection({
400
- featureId: {feature_id},
401
- section: "consolidation",
402
- data: {
403
- crossModuleInteractions: dependencies.map(d => ({
404
- "fromModule": d.from, "toModule": d.to,
405
- "interactionType": "FK-reference",
406
- "description": d.description,
407
- "entities": []
408
- })),
409
- e2eFlows: consolidation.e2eFlows.map(flow => ({
410
- "name": flow.name,
411
- "modules": [...new Set(flow.steps.map(s => s.module))],
412
- "steps": flow.steps.map(s => ({
413
- "module": s.module,
414
- "action": s.action,
415
- "permission": "",
416
- "dataFlow": ""
417
- }))
418
- })),
419
- permissionCoherence: { rolesConsistent: true, pathFormatConsistent: true, hierarchyRespected: true, conflicts: [], warnings: [] },
420
- decision: { approved: true, reason: "Extracted from interactive document", approvedBy: "Client", approvedAt: new Date().toISOString() }
421
- }
422
- })
423
- ba-writer.updateStatus({feature_id}, "consolidated")
424
- ```
425
-
426
- ### 6-bis. Extraire et reconstituer les artefacts visuels (NEW)
427
-
428
- > Visual artifacts (wireframes, E2E diagrams, dependency graph) are extracted from the exported JSON and reconstituted into feature.json.
429
-
430
- **IF** `artifacts` exists in exported JSON:
431
-
432
- #### Extract wireframes per module
433
-
434
- Pour chaque module dans `artifacts.wireframes`:
435
-
436
- ```
437
- FOR EACH moduleCode IN artifacts.wireframes:
438
- moduleWireframes = artifacts.wireframes[moduleCode]
439
-
440
- // Locate the module feature.json
441
- moduleFeature = ba-reader.findModuleFeature({feature_id}, moduleCode)
442
-
443
- // Map wireframes to specification.uiWireframes[]
444
- uiWireframes = moduleWireframes.map(wf => ({
445
- "screen": wf.screen,
446
- "section": wf.section,
447
- "mockupFormat": wf.format,
448
- "mockup": wf.content,
449
- "description": wf.description || "",
450
- "elements": wf.elements || [],
451
- "actions": wf.actions || [],
452
- "permissionsRequired": wf.permissionsRequired || [],
453
- "componentMapping": wf.componentMapping || [],
454
- "layout": wf.layout || null
455
- }))
456
-
457
- // Write to module feature.json (enriching specification section)
458
- ba-writer.enrichSection({
459
- featureId: moduleFeature.id,
460
- section: "specification",
461
- data: { uiWireframes: uiWireframes }
462
- })
463
- ```
464
-
465
- **Validation:** For each wireframe:
466
- - `screen` must be unique within module
467
- - `mockupFormat` must be "ascii" or "svg"
468
- - `mockup` content must not be empty
469
- - `componentMapping` array must have at least one entry
470
- - `layout` object must have `type` and `regions` if present
471
-
472
- #### Extract E2E flow diagrams
473
-
474
- IF `artifacts.e2eFlows` exists:
475
-
476
- ```
477
- e2eFlows = artifacts.e2eFlows.map(flow => ({
478
- "name": flow.name,
479
- "modules": flow.modules.split(" → ").map(m => m.trim()), // "OrderManagement → Invoicing" → ["OrderManagement", "Invoicing"]
480
- "steps": flow.steps || [],
481
- "diagram": flow.diagram, // NEW: ASCII diagram preserved
482
- "actors": flow.actors.split(", ").map(a => a.trim())
483
- }))
484
-
485
- // Merge with existing e2eFlows from consolidation.e2eFlows
486
- ba-writer.enrichSection({
487
- featureId: {feature_id},
488
- section: "consolidation",
489
- data: { e2eFlows: e2eFlows }
490
- })
491
- ```
492
-
493
- **Validation:** For each E2E flow:
494
- - `diagram` must not be empty if present
495
- - `modules` array must match modules defined in master feature.json
496
- - `steps` must have at least 2 entries (cross-module flow)
497
-
498
- #### Extract dependency graph (optional)
499
-
500
- IF `artifacts.dependencyGraph` exists:
501
-
502
- ```
503
- dependencyGraph = {
504
- "nodes": artifacts.dependencyGraph.nodes.map(n => ({
505
- "id": n.id,
506
- "label": n.label || n.id,
507
- "type": n.type || "data-centric"
508
- })),
509
- "edges": artifacts.dependencyGraph.edges.map(e => ({
510
- "from": e.from,
511
- "to": e.to,
512
- "description": e.description || ""
513
- }))
514
- }
515
-
516
- // Write to master feature.json
517
- ba-writer.enrichSection({
518
- featureId: {feature_id},
519
- section: "decomposition",
520
- data: { dependencyGraph: dependencyGraph }
521
- })
522
- ```
523
-
524
- **Post-extraction summary:**
525
-
526
- ```
527
- ✓ Artefacts visuels extraits:
528
- - Wireframes: {total_wireframe_count} across {module_count} modules
529
- - E2E diagrams: {e2e_flow_count}
530
- - Dependency graph: {node_count} nodes, {edge_count} edges
531
- ```
532
-
533
- ### 7. Resume de l'extraction
534
-
535
- Afficher un resume comparatif :
536
- ```
537
- ═══════════════════════════════════════════════════════════════
538
- EXTRACTION TERMINEE - {application_name}
539
- ═══════════════════════════════════════════════════════════════
540
-
541
- | Element | Document client | Feature.json |
542
- |------------------------|----------------|--------------|
543
- | Probleme | {oui/non} | cadrage.problem |
544
- | Situation actuelle | {oui/non} | cadrage.asIs |
545
- | Vision | {oui/non} | cadrage.toBe |
546
- | Parties prenantes | {count} | cadrage.stakeholders |
547
- | Perimetre (vital) | {count} | globalScope.mustHave |
548
- | Perimetre (important) | {count} | globalScope.shouldHave |
549
- | Perimetre (optionnel) | {count} | globalScope.couldHave |
550
- | Risques | {count} | cadrage.risks |
551
- | Criteres de reussite | {count} | acceptanceCriteria |
552
- | Domaines fonctionnels | {count} | modules |
553
- | Dependances | {count} | dependencyGraph.edges |
554
- | Cas d'utilisation | {total} | specification.useCases |
555
- | Regles metier | {total} | analysis.businessRules |
556
- | Entites | {total} | analysis.entities |
557
- | Parcours E2E | {count} | consolidation.e2eFlows |
558
- | Maquettes (wireframes) | {total} | specification.uiWireframes[] |
559
- | Diagrammes E2E | {count} | consolidation.e2eFlows[].diagram |
560
-
561
- Fichiers generes :
562
- - docs/business/{app}/business-analyse/v1.0/feature.json (master)
563
- - docs/business/{app}/{module}/business-analyse/v1.0/feature.json (par module)
564
-
565
- Artefacts visuels preserves :
566
- - Toutes les maquettes ASCII/SVG validees lors de la specification
567
- - Tous les diagrammes E2E pour les flux cross-module
568
- - Graphe de dependances entre modules
569
-
570
- ═══════════════════════════════════════════════════════════════
571
- ```
572
-
573
- ### 8. Choix de la suite
574
-
575
- ```
576
- question: "L'extraction est terminee. Que souhaitez-vous faire ?"
577
- header: "Suite"
578
- options:
579
- - label: "Enrichir avec le questionnaire"
580
- description: "Lancer le cadrage approfondi (step-01) pour completer l'analyse avec des questions detaillees"
581
- - label: "Passer au handoff"
582
- description: "Generer directement le plan de developpement (step-05)"
583
- - label: "Terminer"
584
- description: "L'extraction suffit, je reprendrai manuellement"
585
- ```
586
-
587
- SI "Enrichir" → charger step-01-cadrage.md (les donnees existantes seront preservees)
588
- SI "Handoff" → charger step-05a-handoff.md
589
- SI "Terminer" → EXIT
590
-
591
- ---
592
-
593
- ## FONCTIONS UTILITAIRES
594
-
595
- ### toPascalCase(text)
596
- "gestion des commandes" → "GestionDesCommandes"
597
- "commande" → "Commande"
598
-
599
- ### toCamelCase(text)
600
- "Numero de commande" → "numeroDeCommande"
601
- "Date" → "date"
602
-
603
- ### computePriority(probability, impact)
604
- | probability | impact | priority |
605
- |------------|--------|----------|
606
- | high | high | critical |
607
- | high | medium | critical |
608
- | high | low | medium |
609
- | medium | high | critical |
610
- | medium | medium | medium |
611
- | medium | low | low |
612
- | low | high | medium |
613
- | low | medium | low |
614
- | low | low | low |
615
-
616
- ### inferAction(ucName)
617
- Mots cles → action :
618
- - creer, ajouter, nouveau → create
619
- - modifier, editer, mettre a jour → update
620
- - supprimer, retirer, annuler → delete
621
- - consulter, voir, afficher, lister → read
622
- - valider, approuver, confirmer → approve
623
- - exporter, telecharger → export
624
- - importer, charger → import
625
- - defaut → read
626
-
627
- ---
628
-
629
- ## VALIDATION
630
-
631
- Avant d'ecrire dans feature.json, verifier :
632
- - Chaque stakeholder a au minimum : role, function
633
- - Chaque use case a au minimum : name, actor
634
- - Chaque business rule a au minimum : name, statement
635
- - Chaque entite a au minimum : name
636
- - Les IDs sont uniques (pas de doublons UC, BR, RISK)
637
- - Les modules references dans les dependances existent
638
-
639
- SI une validation echoue → afficher l'erreur et demander correction.
640
-
641
- ---
642
-
643
- ## GARANTIES
644
-
645
- - **Zero perte** : chaque champ saisi dans le document HTML se retrouve dans le feature.json
646
- - **Enrichissement** : les IDs, permissions et liens sont generes automatiquement
647
- - **Conformite** : le feature.json resultant est conforme au schema
648
- - **Reversibilite** : le JSON exporte original est conserve dans `metadata.sourceExport`