@atlashub/smartstack-cli 2.9.0 → 3.0.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 (70) hide show
  1. package/.documentation/business-analyse.html +81 -17
  2. package/dist/mcp-entry.mjs +1302 -223
  3. package/dist/mcp-entry.mjs.map +1 -1
  4. package/package.json +1 -1
  5. package/templates/agents/efcore/db-deploy.md +1 -1
  6. package/templates/agents/efcore/migration.md +26 -10
  7. package/templates/agents/efcore/rebase-snapshot.md +24 -7
  8. package/templates/agents/efcore/squash.md +73 -57
  9. package/templates/agents/gitflow/commit.md +138 -18
  10. package/templates/agents/gitflow/exec.md +1 -1
  11. package/templates/agents/gitflow/finish.md +79 -62
  12. package/templates/agents/gitflow/init-clone.md +186 -0
  13. package/templates/agents/gitflow/init-detect.md +137 -0
  14. package/templates/agents/gitflow/init-validate.md +210 -0
  15. package/templates/agents/gitflow/init.md +231 -74
  16. package/templates/agents/gitflow/merge.md +65 -33
  17. package/templates/agents/gitflow/pr.md +93 -49
  18. package/templates/agents/gitflow/start.md +76 -33
  19. package/templates/agents/gitflow/status.md +41 -71
  20. package/templates/hooks/appsettings-guard.sh +76 -0
  21. package/templates/hooks/ef-migration-check.md +1 -1
  22. package/templates/hooks/hooks.json +9 -0
  23. package/templates/project/test-frontend/msw/handlers.ts +58 -0
  24. package/templates/project/test-frontend/msw/server.ts +25 -0
  25. package/templates/project/test-frontend/setup.ts +16 -0
  26. package/templates/project/test-frontend/test-utils.tsx +59 -0
  27. package/templates/project/test-frontend/vitest.config.ts +31 -0
  28. package/templates/skills/_resources/config-safety.md +61 -0
  29. package/templates/skills/_resources/formatting-guide.md +2 -2
  30. package/templates/skills/application/SKILL.md +12 -3
  31. package/templates/skills/application/steps/step-04-backend.md +21 -0
  32. package/templates/skills/application/steps/step-07-tests.md +259 -120
  33. package/templates/skills/business-analyse/SKILL.md +57 -28
  34. package/templates/skills/business-analyse/_shared.md +70 -39
  35. package/templates/skills/business-analyse/html/ba-interactive.html +2622 -0
  36. package/templates/skills/business-analyse/questionnaire/00-application.md +123 -131
  37. package/templates/skills/business-analyse/questionnaire/01-context.md +173 -24
  38. package/templates/skills/business-analyse/questionnaire/02-stakeholders.md +170 -50
  39. package/templates/skills/business-analyse/questionnaire/03-scope.md +154 -48
  40. package/templates/skills/business-analyse/questionnaire/10-documentation.md +1 -1
  41. package/templates/skills/business-analyse/questionnaire/14-risk-assumptions.md +135 -0
  42. package/templates/skills/business-analyse/questionnaire/15-success-metrics.md +136 -0
  43. package/templates/skills/business-analyse/questionnaire.md +55 -46
  44. package/templates/skills/business-analyse/steps/step-00-init.md +24 -2
  45. package/templates/skills/business-analyse/steps/step-01-cadrage.md +31 -20
  46. package/templates/skills/business-analyse/steps/step-03-specify.md +1 -0
  47. package/templates/skills/business-analyse/steps/step-05-handoff.md +103 -1
  48. package/templates/skills/business-analyse/steps/step-06-extract.md +518 -0
  49. package/templates/skills/check-version/SKILL.md +1 -1
  50. package/templates/skills/efcore/steps/db/step-deploy.md +22 -3
  51. package/templates/skills/efcore/steps/db/step-reset.md +27 -4
  52. package/templates/skills/efcore/steps/db/step-seed.md +46 -2
  53. package/templates/skills/efcore/steps/db/step-status.md +14 -0
  54. package/templates/skills/efcore/steps/migration/step-01-check.md +31 -5
  55. package/templates/skills/efcore/steps/migration/step-02-create.md +20 -4
  56. package/templates/skills/efcore/steps/rebase-snapshot/step-03-create.md +60 -0
  57. package/templates/skills/efcore/steps/shared/step-00-init.md +47 -8
  58. package/templates/skills/efcore/steps/squash/step-03-create.md +27 -5
  59. package/templates/skills/gitflow/SKILL.md +91 -29
  60. package/templates/skills/gitflow/_shared.md +144 -2
  61. package/templates/skills/gitflow/phases/status.md +11 -1
  62. package/templates/skills/gitflow/steps/step-commit.md +1 -1
  63. package/templates/skills/gitflow/steps/step-init.md +202 -39
  64. package/templates/skills/gitflow/templates/config.json +10 -1
  65. package/templates/skills/ralph-loop/steps/step-03-commit.md +2 -2
  66. package/templates/skills/validate-feature/SKILL.md +83 -0
  67. package/templates/skills/validate-feature/steps/step-01-compile.md +38 -0
  68. package/templates/skills/validate-feature/steps/step-02-unit-tests.md +45 -0
  69. package/templates/skills/validate-feature/steps/step-03-integration-tests.md +53 -0
  70. package/templates/skills/validate-feature/steps/step-04-api-smoke.md +157 -0
@@ -0,0 +1,518 @@
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
+ # Step 6: Extraction depuis le document interactif
9
+
10
+ ## REGLES D'EXECUTION
11
+
12
+ - TOUJOURS lire le fichier JSON exporte avant toute operation
13
+ - TOUJOURS mapper CHAQUE element sans exception (zero perte d'information)
14
+ - TOUJOURS utiliser ba-writer pour ecrire dans feature.json
15
+ - TOUJOURS afficher un resume comparatif avant/apres extraction
16
+ - TOUJOURS demander confirmation avant d'ecraser un feature.json existant
17
+ - COMMUNICATION en `{language}` (depuis metadata ou config)
18
+
19
+ ## VOTRE TACHE
20
+
21
+ 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.
22
+
23
+ ---
24
+
25
+ ## SEQUENCE D'EXECUTION
26
+
27
+ ### 1. Lire le fichier JSON exporte
28
+
29
+ ```
30
+ Lire le fichier passe en argument : {extract_path}
31
+ → Parser le JSON
32
+ → Valider la structure minimale : metadata, cadrage, modules
33
+ ```
34
+
35
+ **Structure attendue du JSON exporte :**
36
+ ```json
37
+ {
38
+ "metadata": {
39
+ "applicationName": "...",
40
+ "applicationId": "...",
41
+ "version": "...",
42
+ "createdAt": "...",
43
+ "lastModified": "...",
44
+ "exportedAt": "..."
45
+ },
46
+ "cadrage": {
47
+ "problem": { "description": "", "impactedPeople": "", "history": "", "trigger": "", "consequences": "" },
48
+ "current": { "tools": "", "painPoints": "", "errors": "", "steps": [] },
49
+ "vision": { "changes": "", "results": "", "successSign": "" },
50
+ "stakeholders": [{ "role": "", "function": "", "tasks": [], "frequency": "", "access": "", "frustrations": "" }],
51
+ "scope": {
52
+ "vital": [{ "name": "", "description": "" }],
53
+ "important": [],
54
+ "optional": [],
55
+ "excluded": []
56
+ },
57
+ "risks": [{ "description": "", "probability": "", "impact": "", "mitigation": "" }],
58
+ "assumptions": "",
59
+ "success": { "definition": "", "metrics": "", "timeline": "", "minimumConditions": "" }
60
+ },
61
+ "modules": [{ "code": "", "name": "", "description": "", "featureType": "", "priority": "", "entities": [], "status": "" }],
62
+ "dependencies": [{ "from": "", "to": "", "description": "" }],
63
+ "moduleSpecifications": {
64
+ "{code}": {
65
+ "module": {},
66
+ "useCases": [{ "id": "", "name": "", "actor": "", "steps": "", "alternative": "" }],
67
+ "businessRules": [{ "id": "", "name": "", "category": "", "statement": "", "example": "" }],
68
+ "entities": [{ "name": "", "description": "", "attributes": [{ "name": "", "description": "" }], "relationships": [] }],
69
+ "permissions": [],
70
+ "notes": "",
71
+ "mockupNotes": ""
72
+ }
73
+ },
74
+ "consolidation": {
75
+ "interactions": [],
76
+ "e2eFlows": [{ "name": "", "steps": [{ "module": "", "action": "" }], "actors": "" }]
77
+ }
78
+ }
79
+ ```
80
+
81
+ SI le fichier est invalide ou manquant → STOP avec message d'erreur.
82
+
83
+ ### 2. Determiner l'application et le contexte
84
+
85
+ ```
86
+ application_name = metadata.applicationName OU metadata.applicationId
87
+ version = metadata.version OU "1.0"
88
+ language = "fr" (par defaut, le document HTML est en francais)
89
+ ```
90
+
91
+ Verifier si un feature.json existe deja :
92
+ ```
93
+ ba-reader.findFeature(application_name)
94
+ ```
95
+
96
+ SI feature.json existe :
97
+ → Demander via AskUserQuestion :
98
+ ```
99
+ question: "Un feature.json existe deja pour cette application. Que souhaitez-vous faire ?"
100
+ header: "Conflit"
101
+ options:
102
+ - label: "Remplacer"
103
+ description: "Ecraser le feature.json existant avec les donnees du document interactif"
104
+ - label: "Fusionner"
105
+ description: "Fusionner les nouvelles donnees avec l'existant (priorite au document interactif)"
106
+ - label: "Nouvelle version"
107
+ description: "Creer une nouvelle version (v1.1) en conservant l'ancien"
108
+ ```
109
+
110
+ ### 3. Mapper le cadrage
111
+
112
+ **Transformation : HTML export → feature.json cadrage**
113
+
114
+ | Source (export JSON) | Destination (feature.json) |
115
+ |---------------------|---------------------------|
116
+ | `cadrage.problem.description` | `cadrage.problem` |
117
+ | `cadrage.problem.impactedPeople` | `cadrage.problem` (append) |
118
+ | `cadrage.problem.history` | `cadrage.problem` (append) |
119
+ | `cadrage.problem.trigger` | `cadrage.trigger` |
120
+ | `cadrage.problem.consequences` | `cadrage.problem` (append) |
121
+ | `cadrage.current.tools` | `cadrage.asIs` |
122
+ | `cadrage.current.steps[]` | `cadrage.asIs` (append process steps) |
123
+ | `cadrage.current.painPoints` | `cadrage.asIs` (append) |
124
+ | `cadrage.current.errors` | `cadrage.asIs` (append) |
125
+ | `cadrage.vision.changes` | `cadrage.toBe` |
126
+ | `cadrage.vision.results` | `cadrage.toBe` (append) |
127
+ | `cadrage.vision.successSign` | `cadrage.toBe` (append) |
128
+ | `cadrage.stakeholders[]` | `cadrage.stakeholders[]` (voir mapping detaille) |
129
+ | `cadrage.scope.vital[]` | `cadrage.globalScope.mustHave[]` |
130
+ | `cadrage.scope.important[]` | `cadrage.globalScope.shouldHave[]` |
131
+ | `cadrage.scope.optional[]` | `cadrage.globalScope.couldHave[]` |
132
+ | `cadrage.scope.excluded[]` | `cadrage.globalScope.outOfScope[]` |
133
+ | `cadrage.risks[]` | `cadrage.risks[]` (voir mapping detaille) |
134
+ | `cadrage.assumptions` | `cadrage.risks[]` (type: "assumption") |
135
+ | `cadrage.success.definition` | `cadrage.acceptanceCriteria[]` |
136
+ | `cadrage.success.metrics` | `cadrage.acceptanceCriteria[]` |
137
+ | `cadrage.success.timeline` | `cadrage.acceptanceCriteria[]` |
138
+ | `cadrage.success.minimumConditions` | `cadrage.acceptanceCriteria[]` |
139
+
140
+ **Mapping detaille des parties prenantes :**
141
+
142
+ Pour chaque `cadrage.stakeholders[i]` :
143
+ ```json
144
+ {
145
+ "role": stakeholders[i].role,
146
+ "function": stakeholders[i].function,
147
+ "involvement": mapAccessToInvolvement(stakeholders[i].access),
148
+ "tasks": stakeholders[i].tasks,
149
+ "frequency": stakeholders[i].frequency,
150
+ "painPoints": [stakeholders[i].frustrations]
151
+ }
152
+ ```
153
+
154
+ Mapping `access` → `involvement` :
155
+ | access (HTML) | involvement (feature.json) |
156
+ |--------------|---------------------------|
157
+ | admin | decision-maker |
158
+ | manager | approver |
159
+ | contributor | end-user |
160
+ | viewer | informed |
161
+
162
+ **Mapping detaille des risques :**
163
+
164
+ Pour chaque `cadrage.risks[i]` :
165
+ ```json
166
+ {
167
+ "id": "RISK-" + String(i + 1).padStart(3, '0'),
168
+ "type": "business",
169
+ "description": risks[i].description,
170
+ "probability": risks[i].probability,
171
+ "impact": risks[i].impact,
172
+ "priority": computePriority(risks[i].probability, risks[i].impact),
173
+ "mitigation": risks[i].mitigation
174
+ }
175
+ ```
176
+
177
+ Pour les hypotheses (texte libre `cadrage.assumptions`) :
178
+ ```
179
+ Decouper le texte par lignes
180
+ Pour chaque ligne non vide, creer un risque :
181
+ {
182
+ "id": "RISK-ASM-" + index,
183
+ "type": "assumption",
184
+ "description": ligne,
185
+ "probability": "medium",
186
+ "impact": "medium",
187
+ "priority": "medium",
188
+ "mitigation": "A verifier avant le demarrage du projet"
189
+ }
190
+ ```
191
+
192
+ **Mapping de la couverture :**
193
+
194
+ Construire `cadrage.coverageMatrix[]` a partir du scope :
195
+ ```
196
+ Pour chaque item dans scope.vital :
197
+ { "item": item.name, "category": "mustHave", "module": assignModule(item), "notes": item.description }
198
+ Pour chaque item dans scope.important :
199
+ { "item": item.name, "category": "shouldHave", "module": assignModule(item), "notes": item.description }
200
+ Pour chaque item dans scope.optional :
201
+ { "item": item.name, "category": "couldHave", "module": assignModule(item), "notes": item.description }
202
+ Pour chaque item dans scope.excluded :
203
+ { "item": item.name, "category": "outOfScope", "module": null, "notes": item.description }
204
+ ```
205
+
206
+ `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.
207
+
208
+ **Mapping des roles applicatifs :**
209
+
210
+ Deriver `cadrage.applicationRoles[]` a partir des profils stakeholders :
211
+ ```
212
+ Pour chaque stakeholder unique par niveau d'acces :
213
+ {
214
+ "role": "{App} " + formatRole(access),
215
+ "description": stakeholder.function,
216
+ "level": access,
217
+ "permissionPattern": "business.{app}." + (access === "admin" ? "*" : "...")
218
+ }
219
+ ```
220
+
221
+ **Ecriture :**
222
+ ```
223
+ ba-writer.enrichSection({
224
+ featureId: {feature_id},
225
+ section: "cadrage",
226
+ data: { problem, asIs, toBe, trigger, stakeholders, globalScope, applicationRoles, risks, acceptanceCriteria, coverageMatrix, codebaseContext }
227
+ })
228
+ ba-writer.updateStatus({feature_id}, "framed")
229
+ ```
230
+
231
+ ### 4. Mapper les modules
232
+
233
+ Pour chaque `modules[i]` du JSON exporte :
234
+ ```json
235
+ {
236
+ "code": modules[i].code,
237
+ "description": modules[i].description,
238
+ "featureType": modules[i].featureType,
239
+ "dependencies": deriveDependencies(modules[i].code),
240
+ "dependents": deriveDependents(modules[i].code),
241
+ "status": "pending",
242
+ "featureJsonPath": null,
243
+ "priority": modules[i].priority,
244
+ "sortOrder": computeSortOrder(modules[i].code),
245
+ "entities": modules[i].entities,
246
+ "estimatedComplexity": estimateComplexity(modules[i].code)
247
+ }
248
+ ```
249
+
250
+ `deriveDependencies(code)` : filtrer `dependencies[]` ou `from === code`, retourner les `to`
251
+ `deriveDependents(code)` : filtrer `dependencies[]` ou `to === code`, retourner les `from`
252
+ `computeSortOrder(code)` : depuis le tri topologique
253
+ `estimateComplexity(code)` : basee sur le nombre d'entites et de cas d'utilisation du module
254
+
255
+ **Construire le graphe de dependances :**
256
+ ```json
257
+ {
258
+ "edges": dependencies.map(d => ({ "from": d.from, "to": d.to, "type": "FK", "description": d.description })),
259
+ "topologicalOrder": computeTopologicalOrder(),
260
+ "layers": computeLayers()
261
+ }
262
+ ```
263
+
264
+ **Ecriture :**
265
+ ```
266
+ ba-writer.enrichModuleRegistry({
267
+ featureId: {feature_id},
268
+ modules: [mapped modules],
269
+ dependencyGraph: { edges, topologicalOrder, layers }
270
+ })
271
+ ba-writer.updateStatus({feature_id}, "decomposed")
272
+ ```
273
+
274
+ ### 5. Mapper les specifications par module
275
+
276
+ Pour chaque module dans l'ordre topologique :
277
+
278
+ #### 5a. Creer le feature.json du module
279
+
280
+ ```
281
+ ba-writer.create({
282
+ scope: "module",
283
+ applicationRef: {feature_id},
284
+ moduleCode: {module.code},
285
+ path: "docs/business/{app}/{module_code}/business-analyse/v1.0/feature.json"
286
+ })
287
+ ```
288
+
289
+ #### 5b. Mapper la section discovery
290
+
291
+ Deriver de la cadrage, filtree pour ce module (meme logique que step-03 section 2-ter).
292
+
293
+ #### 5c. Mapper les cas d'utilisation
294
+
295
+ Pour chaque `moduleSpecifications[code].useCases[i]` :
296
+ ```json
297
+ {
298
+ "id": "UC-{PREFIX}-" + String(i + 1).padStart(3, '0'),
299
+ "name": uc.name,
300
+ "primaryActor": uc.actor,
301
+ "permission": "business.{app}.{module}.{inferAction(uc.name)}",
302
+ "preconditions": [],
303
+ "postconditions": [],
304
+ "mainScenario": parseSteps(uc.steps),
305
+ "alternativeScenarios": uc.alternative ? [{ "name": "Cas alternatif", "steps": [uc.alternative] }] : [],
306
+ "errorScenarios": [],
307
+ "linkedRules": linkToBusinessRules(uc, moduleSpec.businessRules)
308
+ }
309
+ ```
310
+
311
+ `parseSteps(text)` : Decouper par lignes, retourner en tableau.
312
+ `inferAction(name)` : Extraire le verbe (Creer→create, Modifier→update, Supprimer→delete, Consulter→read, Valider→approve, Exporter→export).
313
+ `linkToBusinessRules(uc, rules)` : Chercher les regles dont le statement mentionne des concepts similaires au nom du UC.
314
+
315
+ #### 5d. Mapper les regles metier
316
+
317
+ Pour chaque `moduleSpecifications[code].businessRules[i]` :
318
+ ```json
319
+ {
320
+ "id": "BR-{CAT}-{PREFIX}-" + String(i + 1).padStart(3, '0'),
321
+ "name": br.name,
322
+ "category": br.category,
323
+ "statement": br.statement,
324
+ "priority": "must",
325
+ "conditions": extractConditions(br.statement),
326
+ "examples": br.example ? [{ "input": br.example, "expected": "Selon la regle" }] : [],
327
+ "testability": "Via test unitaire"
328
+ }
329
+ ```
330
+
331
+ `{CAT}` derive de `category` : validation→VAL, calculation→CALC, workflow→WF, security→SEC, data→DATA
332
+ `extractConditions(statement)` : Extraire les conditions depuis le texte "Si..." en tableau.
333
+
334
+ #### 5e. Mapper les entites
335
+
336
+ Pour chaque `moduleSpecifications[code].entities[i]` :
337
+ ```json
338
+ {
339
+ "name": toPascalCase(ent.name),
340
+ "description": ent.description,
341
+ "attributes": ent.attributes.map(a => ({
342
+ "name": toCamelCase(a.name),
343
+ "description": a.description,
344
+ "required": true,
345
+ "unique": false,
346
+ "validation": ""
347
+ })),
348
+ "relationships": parseRelationships(ent.relationships)
349
+ }
350
+ ```
351
+
352
+ `parseRelationships(rels)` : Pour chaque relation texte "Nom - Description", extraire :
353
+ ```json
354
+ { "target": toPascalCase(nom), "type": "1:N", "description": description }
355
+ ```
356
+
357
+ #### 5f. Mapper les permissions
358
+
359
+ Transformer le format `permissions: ["Role|Action"]` en matrice structuree :
360
+ ```json
361
+ {
362
+ "permissions": derivePermissionPaths(code, actions),
363
+ "roleAssignments": deriveRoleAssignments(code, permissions)
364
+ }
365
+ ```
366
+
367
+ #### 5g. Generer les sections, wireframes et seedDataCore
368
+
369
+ Inferer automatiquement a partir des entites et du type de module (meme logique que step-03 section 3a-infer).
370
+
371
+ #### 5h. Ecrire le feature.json du module
372
+
373
+ ```
374
+ ba-writer.enrichSection({ featureId: moduleFeatureId, section: "analysis", data: { objectives, entities, businessRules, processFlow, dataLifecycle } })
375
+ ba-writer.enrichSection({ featureId: moduleFeatureId, section: "specification", data: { actors, useCases, functionalRequirements, permissionMatrix, navigation, seedDataCore, sections, uiWireframes } })
376
+ ba-writer.updateModuleStatus({feature_id}, {module.code}, "specified")
377
+ ```
378
+
379
+ ### 6. Mapper la consolidation
380
+
381
+ Si plusieurs modules :
382
+ ```
383
+ ba-writer.enrichSection({
384
+ featureId: {feature_id},
385
+ section: "consolidation",
386
+ data: {
387
+ crossModuleInteractions: dependencies.map(d => ({
388
+ "fromModule": d.from, "toModule": d.to,
389
+ "interactionType": "FK-reference",
390
+ "description": d.description,
391
+ "entities": []
392
+ })),
393
+ e2eFlows: consolidation.e2eFlows.map(flow => ({
394
+ "name": flow.name,
395
+ "modules": [...new Set(flow.steps.map(s => s.module))],
396
+ "steps": flow.steps.map(s => ({
397
+ "module": s.module,
398
+ "action": s.action,
399
+ "permission": "",
400
+ "dataFlow": ""
401
+ }))
402
+ })),
403
+ permissionCoherence: { rolesConsistent: true, pathFormatConsistent: true, hierarchyRespected: true, conflicts: [], warnings: [] },
404
+ decision: { approved: true, reason: "Extracted from interactive document", approvedBy: "Client", approvedAt: new Date().toISOString() }
405
+ }
406
+ })
407
+ ba-writer.updateStatus({feature_id}, "consolidated")
408
+ ```
409
+
410
+ ### 7. Resume de l'extraction
411
+
412
+ Afficher un resume comparatif :
413
+ ```
414
+ ═══════════════════════════════════════════════════════════════
415
+ EXTRACTION TERMINEE - {application_name}
416
+ ═══════════════════════════════════════════════════════════════
417
+
418
+ | Element | Document client | Feature.json |
419
+ |------------------------|----------------|--------------|
420
+ | Probleme | {oui/non} | cadrage.problem |
421
+ | Situation actuelle | {oui/non} | cadrage.asIs |
422
+ | Vision | {oui/non} | cadrage.toBe |
423
+ | Parties prenantes | {count} | cadrage.stakeholders |
424
+ | Perimetre (vital) | {count} | globalScope.mustHave |
425
+ | Perimetre (important) | {count} | globalScope.shouldHave |
426
+ | Perimetre (optionnel) | {count} | globalScope.couldHave |
427
+ | Risques | {count} | cadrage.risks |
428
+ | Criteres de reussite | {count} | acceptanceCriteria |
429
+ | Domaines fonctionnels | {count} | modules |
430
+ | Dependances | {count} | dependencyGraph.edges |
431
+ | Cas d'utilisation | {total} | specification.useCases |
432
+ | Regles metier | {total} | analysis.businessRules |
433
+ | Entites | {total} | analysis.entities |
434
+ | Parcours E2E | {count} | consolidation.e2eFlows |
435
+
436
+ Fichiers generes :
437
+ - docs/business/{app}/business-analyse/v1.0/feature.json (master)
438
+ - docs/business/{app}/{module}/business-analyse/v1.0/feature.json (par module)
439
+
440
+ ═══════════════════════════════════════════════════════════════
441
+ ```
442
+
443
+ ### 8. Choix de la suite
444
+
445
+ ```
446
+ question: "L'extraction est terminee. Que souhaitez-vous faire ?"
447
+ header: "Suite"
448
+ options:
449
+ - label: "Enrichir avec le questionnaire"
450
+ description: "Lancer le cadrage approfondi (step-01) pour completer l'analyse avec des questions detaillees"
451
+ - label: "Passer au handoff"
452
+ description: "Generer directement le plan de developpement (step-05)"
453
+ - label: "Terminer"
454
+ description: "L'extraction suffit, je reprendrai manuellement"
455
+ ```
456
+
457
+ SI "Enrichir" → charger step-01-cadrage.md (les donnees existantes seront preservees)
458
+ SI "Handoff" → charger step-05-handoff.md
459
+ SI "Terminer" → EXIT
460
+
461
+ ---
462
+
463
+ ## FONCTIONS UTILITAIRES
464
+
465
+ ### toPascalCase(text)
466
+ "gestion des commandes" → "GestionDesCommandes"
467
+ "commande" → "Commande"
468
+
469
+ ### toCamelCase(text)
470
+ "Numero de commande" → "numeroDeCommande"
471
+ "Date" → "date"
472
+
473
+ ### computePriority(probability, impact)
474
+ | probability | impact | priority |
475
+ |------------|--------|----------|
476
+ | high | high | critical |
477
+ | high | medium | critical |
478
+ | high | low | medium |
479
+ | medium | high | critical |
480
+ | medium | medium | medium |
481
+ | medium | low | low |
482
+ | low | high | medium |
483
+ | low | medium | low |
484
+ | low | low | low |
485
+
486
+ ### inferAction(ucName)
487
+ Mots cles → action :
488
+ - creer, ajouter, nouveau → create
489
+ - modifier, editer, mettre a jour → update
490
+ - supprimer, retirer, annuler → delete
491
+ - consulter, voir, afficher, lister → read
492
+ - valider, approuver, confirmer → approve
493
+ - exporter, telecharger → export
494
+ - importer, charger → import
495
+ - defaut → read
496
+
497
+ ---
498
+
499
+ ## VALIDATION
500
+
501
+ Avant d'ecrire dans feature.json, verifier :
502
+ - Chaque stakeholder a au minimum : role, function
503
+ - Chaque use case a au minimum : name, actor
504
+ - Chaque business rule a au minimum : name, statement
505
+ - Chaque entite a au minimum : name
506
+ - Les IDs sont uniques (pas de doublons UC, BR, RISK)
507
+ - Les modules references dans les dependances existent
508
+
509
+ SI une validation echoue → afficher l'erreur et demander correction.
510
+
511
+ ---
512
+
513
+ ## GARANTIES
514
+
515
+ - **Zero perte** : chaque champ saisi dans le document HTML se retrouve dans le feature.json
516
+ - **Enrichissement** : les IDs, permissions et liens sont generes automatiquement
517
+ - **Conformite** : le feature.json resultant est conforme au schema
518
+ - **Reversibilite** : le JSON exporte original est conserve dans `metadata.sourceExport`
@@ -163,7 +163,7 @@ api-reference.html | vX.Y.Y | MISMATCH
163
163
 
164
164
  <gitflow_integration>
165
165
 
166
- This skill is automatically called during `/gitflow:11-finish` for release branches.
166
+ This skill is automatically called during `/gitflow finish` for release branches.
167
167
 
168
168
  If mismatches detected during release finish:
169
169
  - Warning displayed
@@ -19,6 +19,16 @@ Apply pending EF Core migrations to the local database.
19
19
  ### 1. Environment Check
20
20
 
21
21
  ```bash
22
+ # Validate required variables from step-00-init
23
+ for VAR_NAME in DBCONTEXT DBCONTEXT_TYPE INFRA_PROJECT STARTUP_PROJECT SELECTED_ENV; do
24
+ eval VAR_VALUE=\$$VAR_NAME
25
+ if [ -z "$VAR_VALUE" ]; then
26
+ echo "ERROR: Required variable $VAR_NAME is not set"
27
+ echo "Run step-00-init first"
28
+ exit 1
29
+ fi
30
+ done
31
+
22
32
  echo "Deploy Configuration"
23
33
  echo "===================="
24
34
  echo ""
@@ -37,12 +47,20 @@ block_production
37
47
  echo ""
38
48
  echo "Checking pending migrations..."
39
49
 
50
+ EF_STDERR=$(mktemp)
40
51
  PENDING=$(dotnet ef migrations list \
41
52
  --context "$DBCONTEXT" \
42
53
  --project "$INFRA_PROJECT" \
43
- --startup-project "$STARTUP_PROJECT" 2>/dev/null | \
54
+ --startup-project "$STARTUP_PROJECT" 2>"$EF_STDERR" | \
44
55
  grep -c "(Pending)" || echo "0")
45
56
 
57
+ # Check for real errors (not just build output)
58
+ if grep -qi "error\|exception\|failed" "$EF_STDERR" 2>/dev/null; then
59
+ echo "WARNING: EF Core reported errors:"
60
+ grep -i "error\|exception\|failed" "$EF_STDERR" | head -5
61
+ fi
62
+ rm -f "$EF_STDERR"
63
+
46
64
  echo "Pending: $PENDING migration(s)"
47
65
 
48
66
  if [ "$PENDING" -eq 0 ]; then
@@ -97,10 +115,11 @@ dotnet ef database update \
97
115
  --project "$INFRA_PROJECT" \
98
116
  --startup-project "$STARTUP_PROJECT" \
99
117
  --verbose
118
+ EXIT_CODE=$?
100
119
 
101
- if [ $? -ne 0 ]; then
120
+ if [ $EXIT_CODE -ne 0 ]; then
102
121
  echo ""
103
- echo "ERROR: Migration failed"
122
+ echo "ERROR: Migration failed (exit code: $EXIT_CODE)"
104
123
  echo ""
105
124
  echo "Troubleshooting:"
106
125
  echo " - Check database connection"
@@ -33,6 +33,16 @@ Completely reset the database: drop, recreate, and apply all migrations.
33
33
  ### 1. Environment Check
34
34
 
35
35
  ```bash
36
+ # Validate required variables from step-00-init
37
+ for VAR_NAME in DBCONTEXT DBCONTEXT_TYPE INFRA_PROJECT STARTUP_PROJECT SELECTED_ENV; do
38
+ eval VAR_VALUE=\$$VAR_NAME
39
+ if [ -z "$VAR_VALUE" ]; then
40
+ echo "ERROR: Required variable $VAR_NAME is not set"
41
+ echo "Run step-00-init first"
42
+ exit 1
43
+ fi
44
+ done
45
+
36
46
  echo "Reset Configuration"
37
47
  echo "==================="
38
48
  echo ""
@@ -111,9 +121,10 @@ dotnet ef database drop \
111
121
  --project "$INFRA_PROJECT" \
112
122
  --startup-project "$STARTUP_PROJECT" \
113
123
  --force
124
+ EXIT_CODE=$?
114
125
 
115
- if [ $? -ne 0 ]; then
116
- echo "ERROR: Drop failed"
126
+ if [ $EXIT_CODE -ne 0 ]; then
127
+ echo "ERROR: Drop failed (exit code: $EXIT_CODE)"
117
128
  echo "Database may be in use. Close connections and retry."
118
129
  exit 1
119
130
  fi
@@ -132,10 +143,11 @@ dotnet ef database update \
132
143
  --project "$INFRA_PROJECT" \
133
144
  --startup-project "$STARTUP_PROJECT" \
134
145
  --verbose
146
+ EXIT_CODE=$?
135
147
 
136
- if [ $? -ne 0 ]; then
148
+ if [ $EXIT_CODE -ne 0 ]; then
137
149
  echo ""
138
- echo "ERROR: Recreation failed"
150
+ echo "ERROR: Recreation failed (exit code: $EXIT_CODE)"
139
151
  exit 1
140
152
  fi
141
153
 
@@ -254,6 +266,17 @@ DBCONTEXT="ExtensionsDbContext"
254
266
 
255
267
  ---
256
268
 
269
+ ## OPTIONS:
270
+
271
+ | Option | Description |
272
+ |--------|-------------|
273
+ | `--env {name}` | Use appsettings.{name}.json |
274
+ | `--no-backup` | Skip backup step |
275
+ | `--context {name}` | Specify DbContext |
276
+ | `--seed` | Auto-seed after reset |
277
+
278
+ ---
279
+
257
280
  ## COMPLETION:
258
281
 
259
282
  Database reset complete. Fresh state with all migrations applied.