@atlashub/smartstack-cli 3.18.0 → 3.20.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/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/agents/gitflow/cleanup.md +5 -1
- package/templates/agents/gitflow/finish.md +2 -0
- package/templates/agents/gitflow/init-clone.md +13 -0
- package/templates/agents/gitflow/init-validate.md +14 -0
- package/templates/agents/gitflow/start.md +2 -2
- package/templates/agents/gitflow/status.md +6 -0
- package/templates/skills/business-analyse/SKILL.md +1 -1
- package/templates/skills/business-analyse/_shared.md +46 -20
- package/templates/skills/business-analyse/html/ba-interactive.html +57 -107
- package/templates/skills/business-analyse/html/src/scripts/01-data-init.js +13 -0
- package/templates/skills/business-analyse/html/src/scripts/02-navigation.js +1 -1
- package/templates/skills/business-analyse/html/src/scripts/03-render-cadrage.js +11 -20
- package/templates/skills/business-analyse/html/src/scripts/11-review-panel.js +1 -3
- package/templates/skills/business-analyse/html/src/template.html +31 -83
- package/templates/skills/business-analyse/patterns/suggestion-catalog.md +71 -3
- package/templates/skills/business-analyse/references/cadrage-pre-analysis.md +11 -8
- package/templates/skills/business-analyse/references/cadrage-structure-cards.md +7 -5
- package/templates/skills/business-analyse/references/deploy-data-build.md +42 -14
- package/templates/skills/business-analyse/references/deploy-modes.md +1 -1
- package/templates/skills/business-analyse/references/entity-architecture-decision.md +218 -0
- package/templates/skills/business-analyse/references/robustness-checks.md +2 -1
- package/templates/skills/business-analyse/references/spec-auto-inference.md +70 -16
- package/templates/skills/business-analyse/references/ui-resource-cards.md +149 -0
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +220 -32
- package/templates/skills/business-analyse/steps/step-02-decomposition.md +51 -29
- package/templates/skills/business-analyse/steps/step-03a1-setup.md +122 -32
- package/templates/skills/business-analyse/steps/step-03a2-analysis.md +8 -0
- package/templates/skills/business-analyse/steps/step-03b-ui.md +68 -5
- package/templates/skills/business-analyse/steps/step-05a-handoff.md +99 -2
- package/templates/skills/business-analyse/steps/step-05b-deploy.md +35 -1
- package/templates/skills/business-analyse/steps/step-05c-ralph-readiness.md +4 -1
- package/templates/skills/business-analyse/steps/step-06-review.md +2 -1
- package/templates/skills/business-analyse/templates/tpl-handoff.md +5 -4
- package/templates/skills/business-analyse/templates/tpl-launch-displays.md +4 -1
- package/templates/skills/business-analyse/templates-frd.md +5 -4
- package/templates/skills/gitflow/_shared.md +65 -17
- package/templates/skills/gitflow/phases/status.md +8 -3
- package/templates/skills/gitflow/references/start-local-config.md +6 -3
- package/templates/skills/gitflow/steps/step-start.md +5 -2
|
@@ -61,6 +61,7 @@ For each mustHave/shouldHave scope item:
|
|
|
61
61
|
> ```json
|
|
62
62
|
> {
|
|
63
63
|
> "code": "PascalCase",
|
|
64
|
+
> "name": "Human-readable display name (e.g., 'Gestion du temps', 'Ressources Humaines')",
|
|
64
65
|
> "description": "1-2 sentence description",
|
|
65
66
|
> "featureType": "data-centric|integration|ui-centric|workflow|reporting|full-module",
|
|
66
67
|
> "dependencies": ["OtherModule"],
|
|
@@ -72,18 +73,20 @@ For each mustHave/shouldHave scope item:
|
|
|
72
73
|
> "entities": ["Anticipated entity names"],
|
|
73
74
|
> "estimatedComplexity": "simple|medium|complex",
|
|
74
75
|
> "anticipatedSections": [
|
|
75
|
-
> { "code": "list", "description": "Main
|
|
76
|
-
> { "code": "
|
|
77
|
-
>
|
|
78
|
-
> ]
|
|
76
|
+
> { "code": "list", "description": "Main page: grid, create action (modal), click to detail", "resources": ["entity-grid", "entity-filters", "entity-form"] },
|
|
77
|
+
> { "code": "dashboard", "description": "Module KPIs and overview (if needed)", "resources": ["entity-kpi-cards", "entity-charts"] }
|
|
78
|
+
> ],
|
|
79
|
+
> "detailTabs": ["Informations", "RelatedEntity1", "Historique"]
|
|
79
80
|
> }
|
|
80
81
|
> ```
|
|
81
|
-
> **MANDATORY fields:** `code`, `description`, `featureType`, `dependencies`, `dependents`, `status`, `priority`, `sortOrder`, `entities`, `estimatedComplexity`
|
|
82
|
+
> **MANDATORY fields:** `code`, `name`, `description`, `featureType`, `dependencies`, `dependents`, `status`, `priority`, `sortOrder`, `entities`, `estimatedComplexity`
|
|
83
|
+
> **`name` vs `code`:** `code` is PascalCase for file paths/keys (e.g., "GestionTemps"). `name` is the human-readable label shown in navigation and HTML (e.g., "Gestion du temps"). They are ALWAYS both required.
|
|
82
84
|
> **OPTIONAL fields:** `anticipatedSections` (from cadrage coverageMatrix, enriched here with resources)
|
|
83
85
|
> **status:** Always `"pending"` at creation (updated to `"in-progress"` → `"specified"` → `"validated"` by step-03/04)
|
|
84
86
|
> **sortOrder:** Integer from topological sort (0 = foundation layer)
|
|
85
87
|
> **featureJsonPath:** Set to null at creation; updated to actual path when module feature.json is created in step-03
|
|
86
|
-
> **anticipatedSections:** Array of `{ code, description, resources[] }` objects. Derived from `cadrage.coverageMatrix[].anticipatedSections` aggregated per module, then refined during decomposition.
|
|
88
|
+
> **anticipatedSections:** Array of `{ code, description, resources[] }` objects. ONLY functional zones: `list` (always), `dashboard`, `approve`, `import`, `rapport`, `planning`. NEVER `create`, `edit`, or `detail` (those are actions/pages within `list`). Derived from `cadrage.coverageMatrix[].anticipatedSections` aggregated per module, then refined during decomposition.
|
|
89
|
+
> **detailTabs:** Array of tab names for the detail page (reached by clicking a row in `list`). Always includes "Informations". Add relationship tabs based on entity relations.
|
|
87
90
|
|
|
88
91
|
**Complexity estimation rules:**
|
|
89
92
|
| Criteria | Simple | Medium | Complex |
|
|
@@ -104,16 +107,17 @@ Display the identified modules as markdown:
|
|
|
104
107
|
? "**Préfixe de table :** `{metadata.tablePrefix}` — toutes les tables de cette application seront préfixées (ex: `{metadata.tablePrefix}Customers`, `{metadata.tablePrefix}Orders`)"
|
|
105
108
|
: "**Table prefix:** `{metadata.tablePrefix}` — all tables in this application will be prefixed (e.g., `{metadata.tablePrefix}Customers`, `{metadata.tablePrefix}Orders`)"}
|
|
106
109
|
|
|
107
|
-
| # |
|
|
108
|
-
|
|
109
|
-
| 1 | Customers | data-centric | must | medium | list
|
|
110
|
-
| 2 | Products | data-centric | must | simple | list
|
|
111
|
-
| 3 | Orders | workflow | must | complex | list,
|
|
112
|
-
| 4 | Invoices | workflow | should | medium | list,
|
|
110
|
+
| # | Code | Nom | Type | Priorité | Complexité | Sections | Onglets détail | Entités |
|
|
111
|
+
|---|------|-----|------|----------|------------|----------|----------------|---------|
|
|
112
|
+
| 1 | Customers | Clients | data-centric | must | medium | list | Infos, Adresses, Contacts | Customer, Address, Contact |
|
|
113
|
+
| 2 | Products | Produits | data-centric | must | simple | list | Infos, Catégories | Product, Category |
|
|
114
|
+
| 3 | Orders | Commandes | workflow | must | complex | list, approve | Infos, Lignes, Historique | Order, OrderLine |
|
|
115
|
+
| 4 | Invoices | Facturation | workflow | should | medium | list, dashboard | Infos, Lignes, Paiements | Invoice, InvoiceLine, Payment |
|
|
113
116
|
```
|
|
114
117
|
|
|
115
|
-
> **Sections
|
|
116
|
-
>
|
|
118
|
+
> **Sections = functional zones only:** `list` (always), `dashboard`, `approve`, `import`, `rapport`, `planning`.
|
|
119
|
+
> **Onglets detail** = tabs in the detail page (reached by clicking a row in list).
|
|
120
|
+
> NEVER list `create`, `edit`, or `detail` as sections — they are actions/pages within `list`.
|
|
117
121
|
|
|
118
122
|
Ask via AskUserQuestion:
|
|
119
123
|
```
|
|
@@ -205,22 +209,27 @@ Products ───┘
|
|
|
205
209
|
|
|
206
210
|
### Ordre de traitement
|
|
207
211
|
|
|
208
|
-
| Ordre | Module | Dépend de | Complexité | Sections
|
|
209
|
-
|
|
210
|
-
| 1 | Customers | (aucune) | medium | list
|
|
211
|
-
| 2 | Products | (aucune) | simple | list
|
|
212
|
-
| 3 | Orders | Customers, Products | complex | list,
|
|
213
|
-
| 4 | Invoices | Orders, Customers | medium | list,
|
|
212
|
+
| Ordre | Module | Dépend de | Complexité | Sections | Onglets détail |
|
|
213
|
+
|-------|--------|-----------|------------|----------|----------------|
|
|
214
|
+
| 1 | Customers | (aucune) | medium | list | Infos, Adresses, Contacts |
|
|
215
|
+
| 2 | Products | (aucune) | simple | list | Infos, Catégories |
|
|
216
|
+
| 3 | Orders | Customers, Products | complex | list, approve | Infos, Lignes, Historique |
|
|
217
|
+
| 4 | Invoices | Orders, Customers | medium | list, dashboard | Infos, Lignes, Paiements |
|
|
214
218
|
|
|
215
219
|
### Détail des sections et resources par module
|
|
216
220
|
|
|
217
221
|
**Module : {module_name}**
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
|
222
|
-
|
|
|
223
|
-
|
|
222
|
+
|
|
223
|
+
| Section | Description | Resources |
|
|
224
|
+
|---------|-------------|-----------|
|
|
225
|
+
| list | Page principale : grille + création + navigation détail | {entity}-grid, {entity}-filters, {entity}-form |
|
|
226
|
+
| {section_2} | {functional zone description} | {resources} |
|
|
227
|
+
|
|
228
|
+
| Onglet détail | Contenu |
|
|
229
|
+
|---------------|---------|
|
|
230
|
+
| Informations | Fiche principale de l'entité |
|
|
231
|
+
| {relation_tab} | {sous-entités ou entités liées} |
|
|
232
|
+
| Historique | Journal des modifications |
|
|
224
233
|
|
|
225
234
|
(Repeat for each module)
|
|
226
235
|
|
|
@@ -284,10 +293,12 @@ Create: docs/business/{app}/{module_code}/business-analyse/v1.0/
|
|
|
284
293
|
|
|
285
294
|
> Module feature.json files will be created by step-03 when each module is processed.
|
|
286
295
|
|
|
287
|
-
### 9. Display Summary
|
|
296
|
+
### 9. Display Summary & AUTOCHAIN
|
|
288
297
|
|
|
289
298
|
```
|
|
290
|
-
|
|
299
|
+
═══════════════════════════════════════════════════════════
|
|
300
|
+
DECOMPOSITION COMPLETE - {feature_id}
|
|
301
|
+
═══════════════════════════════════════════════════════════
|
|
291
302
|
|
|
292
303
|
| Aspect | Value |
|
|
293
304
|
|--------|-------|
|
|
@@ -300,8 +311,16 @@ Create: docs/business/{app}/{module_code}/business-analyse/v1.0/
|
|
|
300
311
|
{numbered list of modules}
|
|
301
312
|
|
|
302
313
|
→ Starting iterative specification with {first_module}...
|
|
314
|
+
═══════════════════════════════════════════════════════════
|
|
303
315
|
```
|
|
304
316
|
|
|
317
|
+
**AUTOCHAIN — DO NOT STOP HERE:**
|
|
318
|
+
- Do NOT ask "shall I continue?" or "voulez-vous que je continue?"
|
|
319
|
+
- Do NOT summarize what's coming next
|
|
320
|
+
- Do NOT wait for user input
|
|
321
|
+
- The user ALREADY validated at step 6 — that was the checkpoint
|
|
322
|
+
- IMMEDIATELY load step-03a1-setup.md
|
|
323
|
+
|
|
305
324
|
---
|
|
306
325
|
|
|
307
326
|
## SINGLE-MODULE MODE
|
|
@@ -316,6 +335,9 @@ When `workflow.mode = "module"` or only 1 scope item identified:
|
|
|
316
335
|
|
|
317
336
|
---
|
|
318
337
|
|
|
319
|
-
## NEXT STEP
|
|
338
|
+
## NEXT STEP (MANDATORY — NO PAUSE)
|
|
320
339
|
|
|
321
340
|
Load: `./step-03a1-setup.md`
|
|
341
|
+
|
|
342
|
+
> **FORBIDDEN:** Asking any question between decomposition summary and step-03 load.
|
|
343
|
+
> The client checkpoint was at step 6. Do NOT add another one.
|
|
@@ -6,6 +6,7 @@ next_step: steps/step-03a2-analysis.md
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
> **Context files:** `_shared.md` | `_elicitation.md` | `_architecture.md` | `_module-loop.md`
|
|
9
|
+
> **Reference (5-bis):** `references/entity-architecture-decision.md` — Entity scoring, domain coherence, section patterns
|
|
9
10
|
|
|
10
11
|
# Step 3a1: Setup - Module Initialization
|
|
11
12
|
|
|
@@ -198,31 +199,36 @@ Total: {N} requirements mapped to this module
|
|
|
198
199
|
|
|
199
200
|
For each module, propose standard sections based on module type:
|
|
200
201
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
|
205
|
-
|
|
206
|
-
|
|
|
207
|
-
|
|
|
202
|
+
> **RULE:** Sections = functional zones only. `list` is ALWAYS present (default).
|
|
203
|
+
> `create`/`edit` = actions within the `list` page (modal/drawer). `detail` = tabbed page from list click.
|
|
204
|
+
|
|
205
|
+
| Module Type | Sections (functional zones) | Detail page tabs (from list click) |
|
|
206
|
+
|-------------|---------------------------|-----------------------------------|
|
|
207
|
+
| data-centric | list | Infos, {relations} |
|
|
208
|
+
| workflow | list, approve | Infos, {relations}, Historique |
|
|
209
|
+
| integration | list | Infos, Config, Logs, Sync |
|
|
210
|
+
| reporting | dashboard | — |
|
|
211
|
+
| full-module | list, dashboard, approve | Infos, {relations}, Historique |
|
|
212
|
+
|
|
213
|
+
**Section `list` is automatic and ALWAYS included.** Ask ONLY about additional functional sections:
|
|
208
214
|
|
|
209
215
|
Ask via AskUserQuestion:
|
|
210
216
|
|
|
211
217
|
```
|
|
212
|
-
question: "
|
|
218
|
+
question: "{language == 'fr'
|
|
219
|
+
? 'Le module {currentModule} aura une page liste (avec création et détail par onglets). Quelles sections fonctionnelles supplémentaires souhaitez-vous ?'
|
|
220
|
+
: 'Module {currentModule} will have a list page (with create and tabbed detail). Which additional functional sections do you want?'}"
|
|
213
221
|
header: "Sections"
|
|
214
222
|
multiSelect: true
|
|
215
223
|
options:
|
|
216
|
-
- label: "Liste"
|
|
217
|
-
description: "Page de liste avec filtres, tri et pagination"
|
|
218
|
-
- label: "Détail"
|
|
219
|
-
description: "Page de détail d'un enregistrement"
|
|
220
|
-
- label: "Création/Édition"
|
|
221
|
-
description: "Formulaire de création et de modification"
|
|
222
|
-
- label: "Validation/Approbation"
|
|
223
|
-
description: "Workflow de validation avec changement de statut"
|
|
224
224
|
- label: "Dashboard"
|
|
225
|
-
description: "Tableau de bord avec KPIs, graphiques
|
|
225
|
+
description: "{language == 'fr' ? 'Tableau de bord avec KPIs, graphiques et métriques clés' : 'Dashboard with KPIs, charts and key metrics'}"
|
|
226
|
+
- label: "Validation/Approbation"
|
|
227
|
+
description: "{language == 'fr' ? 'File d\'approbation avec workflow de changement de statut' : 'Approval queue with status change workflow'}"
|
|
228
|
+
- label: "Import en masse"
|
|
229
|
+
description: "{language == 'fr' ? 'Import CSV/Excel avec mapping et validation' : 'CSV/Excel import with mapping and validation'}"
|
|
230
|
+
- label: "{language == 'fr' ? 'Aucune (liste seule)' : 'None (list only)'}"
|
|
231
|
+
description: "{language == 'fr' ? 'Le module n\'a besoin que de la page liste avec détail' : 'Module only needs the list page with detail'}"
|
|
226
232
|
```
|
|
227
233
|
|
|
228
234
|
#### 3a-depth. Determine Specification Depth
|
|
@@ -285,7 +291,7 @@ See [references/spec-auto-inference.md](../references/spec-auto-inference.md) fo
|
|
|
285
291
|
- Entity attribute → SmartTable column mapping (9 type rules)
|
|
286
292
|
- Entity attribute → SmartForm field mapping (8 type rules)
|
|
287
293
|
- Auto-generated sections per featureType (5 types)
|
|
288
|
-
-
|
|
294
|
+
- Component generation rules (list section, create form in modal, detail page with tabs, dashboard section)
|
|
289
295
|
- Status/lifecycle enhancement rules
|
|
290
296
|
|
|
291
297
|
Write auto-generated sections to `specification.sections[]` via ba-writer.enrichSection()
|
|
@@ -351,40 +357,124 @@ options:
|
|
|
351
357
|
|
|
352
358
|
#### 5-bis. Unresolved Entity Dependencies (New Module Detection)
|
|
353
359
|
|
|
354
|
-
> **When an entity reference is detected that does NOT belong to any completed or planned module, apply the Entity Sourcing Pattern
|
|
360
|
+
> **When an entity reference is detected that does NOT belong to any completed or planned module, apply the SAME intelligent Entity Sourcing Pattern as step-01-cadrage (section 4d-bis).**
|
|
361
|
+
> **Reference:** Load [references/entity-architecture-decision.md](../references/entity-architecture-decision.md) for scoring grid, decision tree, and section patterns.
|
|
355
362
|
|
|
356
363
|
For each entity referenced by {currentModule} that is NOT covered by any existing/planned module:
|
|
357
364
|
|
|
365
|
+
##### A. ULTRATHINK: Silent Analysis (NO output to client)
|
|
366
|
+
|
|
367
|
+
> **Same intelligence as cadrage 4d-bis. Score the entity, assess domain coherence, recommend.**
|
|
368
|
+
|
|
369
|
+
```
|
|
370
|
+
ULTRATHINK — Entity Architecture Analysis for {entity_name} (discovered during specification of {currentModule}):
|
|
371
|
+
|
|
372
|
+
1. DOMAIN COHERENCE
|
|
373
|
+
- Application domain: {app_description}
|
|
374
|
+
- Entity fit: CORE | SUPPORT | PERIPHERAL
|
|
375
|
+
- Justification: {1 sentence}
|
|
376
|
+
|
|
377
|
+
2. ENTITY SCORING (5 criteria, 0-3 each — from scoring grid in reference)
|
|
378
|
+
- Lifecycle: {score}/3
|
|
379
|
+
- Actors: {score}/3
|
|
380
|
+
- Relations: {score}/3
|
|
381
|
+
- Volume: {score}/3
|
|
382
|
+
- Autonomy: {score}/3
|
|
383
|
+
- TOTAL: {total}/15 → {classification}
|
|
384
|
+
|
|
385
|
+
3. PRE-CLASSIFICATION CHECK (from entity patterns in reference, section 10 of suggestion-catalog)
|
|
386
|
+
- Match? → {yes: which pattern | no: use scoring}
|
|
387
|
+
|
|
388
|
+
4. RECOMMENDATION
|
|
389
|
+
- Option: {in_this_module | new_module | external_system | config_list}
|
|
390
|
+
- Confidence: HIGH | MEDIUM | LOW
|
|
391
|
+
- Reasoning: {1-2 sentences}
|
|
392
|
+
|
|
393
|
+
5. IF recommendation = new_module → PRE-BUILD ARCHITECTURE
|
|
394
|
+
- Module code: {PascalCase}
|
|
395
|
+
- Section `list` + detail page tabs
|
|
396
|
+
- Additional sections (ONLY functional zones)
|
|
397
|
+
- Impact on dependency graph
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
##### B. Present Analysis & Recommendation
|
|
401
|
+
|
|
402
|
+
**BEFORE AskUserQuestion, display as markdown:**
|
|
403
|
+
|
|
404
|
+
```
|
|
405
|
+
### {language == "fr" ? "Analyse" : "Analysis"} : {entity_plural}
|
|
406
|
+
|
|
407
|
+
{language == "fr"
|
|
408
|
+
? "Pendant la spécification de **{currentModule}**, j'ai détecté une référence aux **{entity_plural}** qui ne font partie d'aucun module existant."
|
|
409
|
+
: "During specification of **{currentModule}**, I detected a reference to **{entity_plural}** not covered by any existing module."}
|
|
410
|
+
|
|
411
|
+
{language == "fr" ? "**Mon analyse :**" : "**My analysis:**"}
|
|
412
|
+
- {language == "fr" ? "Cohérence domaine" : "Domain coherence"} : **{CORE|SUPPORT|PERIPHERAL}** — {justification}
|
|
413
|
+
- {language == "fr" ? "Score de complexité" : "Complexity score"} : **{score}/15** ({classification})
|
|
414
|
+
- **{language == "fr" ? "Recommandation" : "Recommendation"}** : **{recommended_option}** — {reasoning}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
**IF recommendation = new_module AND confidence >= MEDIUM, ALSO display the architecture proposal** (same format as cadrage 4d-bis Phase 2: Context/Application/Module table + Sections table + Detail tabs table + Impact).
|
|
418
|
+
|
|
419
|
+
##### C. Ask with Recommended Option First
|
|
420
|
+
|
|
358
421
|
```
|
|
359
422
|
question: "{language == 'fr'
|
|
360
|
-
? '
|
|
361
|
-
: '
|
|
423
|
+
? 'Comment souhaitez-vous gérer les {entity_plural} ?'
|
|
424
|
+
: 'How do you want to manage {entity_plural}?'}"
|
|
362
425
|
header: "{entity_name}"
|
|
363
426
|
options:
|
|
364
|
-
|
|
427
|
+
(ORDER: recommended option FIRST with "(Recommandé)"/"(Recommended)", then remaining 3)
|
|
428
|
+
|
|
429
|
+
IF recommendation = new_module:
|
|
430
|
+
- label: "{language == 'fr' ? 'Nouveau module dédié (Recommandé)' : 'New dedicated module (Recommended)'}"
|
|
365
431
|
description: "{language == 'fr'
|
|
366
|
-
? '
|
|
367
|
-
: '
|
|
368
|
-
- label: "{language == 'fr' ? '
|
|
432
|
+
? 'Module {ModuleCode} avec page liste, détail par onglets, permissions dédiées'
|
|
433
|
+
: '{ModuleCode} module with list page, tabbed detail, dedicated permissions'}"
|
|
434
|
+
- label: "{language == 'fr' ? 'Dans ce module' : 'In this module'}"
|
|
369
435
|
description: "{language == 'fr'
|
|
370
|
-
? '
|
|
371
|
-
: '
|
|
436
|
+
? 'Onglet dans la page détail de {currentModule}'
|
|
437
|
+
: 'Tab in {currentModule} detail page'}"
|
|
372
438
|
- label: "{language == 'fr' ? 'Système externe' : 'External system'}"
|
|
373
|
-
description: "
|
|
374
|
-
? 'Import ou API depuis un autre système'
|
|
375
|
-
: 'Import or API from another system'}"
|
|
439
|
+
description: "..."
|
|
376
440
|
- label: "{language == 'fr' ? 'Liste de référence' : 'Reference list'}"
|
|
441
|
+
description: "..."
|
|
442
|
+
|
|
443
|
+
IF recommendation = config_list:
|
|
444
|
+
- label: "{language == 'fr' ? 'Liste de référence (Recommandé)' : 'Reference list (Recommended)'}"
|
|
377
445
|
description: "{language == 'fr'
|
|
378
446
|
? 'Table de lookup configurable par l\'admin'
|
|
379
447
|
: 'Admin-configurable lookup table'}"
|
|
448
|
+
- (3 remaining options in logical order)
|
|
449
|
+
|
|
450
|
+
IF recommendation = in_this_module:
|
|
451
|
+
- label: "{language == 'fr' ? 'Dans ce module (Recommandé)' : 'In this module (Recommended)'}"
|
|
452
|
+
description: "{language == 'fr'
|
|
453
|
+
? 'Onglet dans la page détail de {currentModule}'
|
|
454
|
+
: 'Tab in {currentModule} detail page'}"
|
|
455
|
+
- (3 remaining options)
|
|
456
|
+
|
|
457
|
+
IF confidence = LOW:
|
|
458
|
+
(all 4 options in neutral order, NO "(Recommandé)" tag)
|
|
380
459
|
```
|
|
381
460
|
|
|
461
|
+
##### D. Process Answer
|
|
462
|
+
|
|
463
|
+
| Choice | Action |
|
|
464
|
+
|--------|--------|
|
|
465
|
+
| **Dans ce module** | Entity becomes a sub-entity of {currentModule}. Add as a **tab in the detail page**. Add to this module's `analysis.entities[]`. |
|
|
466
|
+
| **Nouveau module dédié** | Add new module to master `modules[]` via ba-writer with proposed architecture (sections, detail tabs, dependencies). The `list` section is ALWAYS the main section. Additional sections ONLY for functional zones. |
|
|
467
|
+
| **Système externe** | Flag for integration. Add to `coverageMatrix` as integration. |
|
|
468
|
+
| **Liste de référence** | Lookup table, admin-managed. No module, no section. |
|
|
469
|
+
|
|
382
470
|
**IF "Nouveau module dédié" is selected:**
|
|
383
471
|
1. Add new module to master `modules[]` via ba-writer (status: "pending", sortOrder: after current module)
|
|
384
472
|
2. Update dependency graph: current module depends on the new module
|
|
385
|
-
3. **
|
|
473
|
+
3. **Display:**
|
|
386
474
|
```
|
|
387
|
-
"
|
|
475
|
+
"{language == 'fr'
|
|
476
|
+
? '⚠ Nouveau module {ModuleCode} ajouté au graphe de dépendances. Il sera spécifié après {currentModule}.'
|
|
477
|
+
: '⚠ New module {ModuleCode} added to dependency graph. It will be specified after {currentModule}.'}"
|
|
388
478
|
```
|
|
389
479
|
4. Update `metadata.workflow.moduleOrder` to include the new module (inserted after its dependents)
|
|
390
480
|
|
|
@@ -6,6 +6,7 @@ next_step: steps/step-03b-ui.md
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
> **Context files:** `_shared.md` | `_elicitation.md` | `_architecture.md` | `_module-loop.md`
|
|
9
|
+
> **Reference (check 7):** `references/entity-architecture-decision.md` — Entity scoring for unresolved relationship targets
|
|
9
10
|
|
|
10
11
|
# Step 3a2: Analysis - Entities & Business Logic
|
|
11
12
|
|
|
@@ -151,6 +152,13 @@ Before proceeding to step-03b-ui.md, VERIFY:
|
|
|
151
152
|
4. **Module status in master** = "in-progress" (set by section 2 above)
|
|
152
153
|
5. **Master modules[].featureJsonPath** for this module ≠ null (set by ba-writer.create)
|
|
153
154
|
6. **Sections identified** with clear roles and entities assigned
|
|
155
|
+
7. **Unresolved relationship targets (BLOCKING)** — For EACH entity's `relationships[].target`:
|
|
156
|
+
- Check if the target entity exists in THIS module's `entities[]`
|
|
157
|
+
- OR in a completed/planned module's `entities[]`
|
|
158
|
+
- OR is a known config list / external system reference
|
|
159
|
+
- **IF unresolved:** Apply the Entity Sourcing Pattern from step-03a1 section 5-bis
|
|
160
|
+
(ULTRATHINK scoring + domain coherence + recommendation + AskUserQuestion)
|
|
161
|
+
- This catches entities discovered DURING analysis that weren't identified in setup
|
|
154
162
|
|
|
155
163
|
**IF any check fails → FIX before proceeding.** Do NOT load step-03b-ui with incomplete data.
|
|
156
164
|
|
|
@@ -199,6 +199,64 @@ A wireframe without `componentMapping` or `layout` will FAIL validation in step
|
|
|
199
199
|
|
|
200
200
|
> **IF client rejects a mockup:** Revise and re-propose until validated. Do NOT proceed without client approval on the layout.
|
|
201
201
|
|
|
202
|
+
### 3b-detail. Generate Detail Page Wireframe (MANDATORY for each list section)
|
|
203
|
+
|
|
204
|
+
> **BLOCKING RULE:** Every module with a `list` section MUST also have a detail page wireframe. The detail page is NOT a separate navigation entry — it is reached by clicking a row in the list. Its wireframe goes in `specification.uiWireframes[]` with `section: "detail"`.
|
|
205
|
+
|
|
206
|
+
**Procedural sequence (MANDATORY):**
|
|
207
|
+
|
|
208
|
+
1. **Determine detail tabs** from these sources (in priority order):
|
|
209
|
+
a. `coverageMatrix[].detailTabs` from cadrage (if specified)
|
|
210
|
+
b. Entity relationships: one tab per 1:N relationship (SmartTable of children)
|
|
211
|
+
c. Auto-inferred: Info tab (always first), History tab (if entity has lifeCycles)
|
|
212
|
+
|
|
213
|
+
2. **Generate** an ASCII mockup for the detail page with tabbed layout:
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
╔═══════════════════════════════════════════════════════════╗
|
|
217
|
+
║ ← Retour à la liste ║
|
|
218
|
+
╠═══════════════════════════════════════════════════════════╣
|
|
219
|
+
║ {Entity} : {code} — {name} ● {Statut} [✏️ 🗑️] ║
|
|
220
|
+
╠═══════════════════════════════════════════════════════════╣
|
|
221
|
+
║ [ Informations ] [ {Relation1} ] [ Historique ] ║
|
|
222
|
+
╠═══════════════════════════════════════════════════════════╣
|
|
223
|
+
║ ║
|
|
224
|
+
║ ┌── Informations ────────────────────────────────────┐ ║
|
|
225
|
+
║ │ Code │ VAL-001 │ ║
|
|
226
|
+
║ │ Nom │ Exemple de nom │ ║
|
|
227
|
+
║ │ Type │ Standard │ ║
|
|
228
|
+
║ │ Responsable │ Jean Dupont │ ║
|
|
229
|
+
║ │ Date début │ 15.01.2026 │ ║
|
|
230
|
+
║ │ Description │ Lorem ipsum dolor sit amet... │ ║
|
|
231
|
+
║ └────────────────────────────────────────────────────┘ ║
|
|
232
|
+
║ [ Modifier ] ║
|
|
233
|
+
║ ║
|
|
234
|
+
╚═══════════════════════════════════════════════════════════╝
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Adaptation rules for the detail mockup:
|
|
238
|
+
- **Header**: entity code + name + status badge (if lifeCycles) + action buttons (edit, delete)
|
|
239
|
+
- **Back button**: navigates to `/business/{app}/{module}/list`
|
|
240
|
+
- **Tabs**: one per identified tab (Info + relations + history)
|
|
241
|
+
- **Info tab content**: all entity attributes as label:value pairs (read-only by default)
|
|
242
|
+
- **Edit button**: toggles the Info tab into SmartForm edit mode
|
|
243
|
+
- **Relation tab content**: show a SmartTable for each 1:N child entity filtered by parent ID
|
|
244
|
+
- **History tab content**: Timeline/audit log (only if entity has lifeCycles)
|
|
245
|
+
|
|
246
|
+
3. **For entities with state machine (lifeCycles)**, add transition buttons in the header:
|
|
247
|
+
```
|
|
248
|
+
║ {Entity}: {code} — {name} ● Brouillon [Soumettre] [✏️] ║
|
|
249
|
+
```
|
|
250
|
+
Transition buttons are contextual: only show actions allowed from the current state.
|
|
251
|
+
|
|
252
|
+
4. **Display** the detail mockup in conversation with header `### {Module} — Détail — Wireframe` and validate with client alongside the list wireframe.
|
|
253
|
+
|
|
254
|
+
5. **Store** in `specification.uiWireframes[]` with `section: "detail"`.
|
|
255
|
+
See [references/ui-resource-cards.md](../references/ui-resource-cards.md) "Detail Page Wireframe" for exact JSON format.
|
|
256
|
+
|
|
257
|
+
6. **Create the detail section** in `specification.sections[]` with `navigation: "hidden"` and route `/business/{app}/{module}/detail/:id`.
|
|
258
|
+
See [references/ui-resource-cards.md](../references/ui-resource-cards.md) "Detail Page section" for exact JSON format.
|
|
259
|
+
|
|
202
260
|
### 3b-bis. Wireframe-to-Component Mapping
|
|
203
261
|
|
|
204
262
|
After client validates the mockup, map each wireframe element to a SmartStack React component:
|
|
@@ -212,6 +270,10 @@ After client validates the mockup, map each wireframe element to a SmartStack Re
|
|
|
212
270
|
| ActionButton | `Button` + `RequirePermission` | Always wrapped in permission check |
|
|
213
271
|
| StatusBadge | `StatusBadge` | Uses entity lifecycle states |
|
|
214
272
|
| DetailCard | `EntityDetailCard` | Standard detail layout |
|
|
273
|
+
| DetailHeader | `EntityDetailHeader` | Entity title + status badge + actions |
|
|
274
|
+
| BackButton | `BackButton` | Navigate back to list |
|
|
275
|
+
| TabPanel | `Tabs` | Tabbed content container |
|
|
276
|
+
| Timeline | `AuditTimeline` | History/audit log display |
|
|
215
277
|
| Form | `SmartForm` | FluentValidation-backed |
|
|
216
278
|
| KpiCard | `StatCard` (Recharts) | Dashboard KPI display |
|
|
217
279
|
| Chart:bar/line/pie | Recharts `BarChart`/`LineChart`/`PieChart` | CSS variables for colors |
|
|
@@ -248,9 +310,9 @@ For EACH wireframe generated in 3b, generate a `layout` object alongside the ASC
|
|
|
248
310
|
|
|
249
311
|
For each section, identify what resources/components are needed:
|
|
250
312
|
|
|
251
|
-
- List section → DataGrid, FilterBar, SearchInput, ExportButton
|
|
252
|
-
- Detail
|
|
253
|
-
- Create
|
|
313
|
+
- List section → DataGrid, FilterBar, SearchInput, ExportButton, CreateButton
|
|
314
|
+
- Detail page (from list click) → BackButton, DetailHeader, StatusBadge, TabPanel, DetailCard, SmartForm (edit mode), SmartTable (relation tabs), Timeline (history tab)
|
|
315
|
+
- Create (in list) → SmartForm (modal/drawer), ValidationMessages, SubmitButton
|
|
254
316
|
- Approve section → StatusTransitionPanel, CommentBox, ApproveRejectButtons
|
|
255
317
|
- Dashboard section → StatCard, RechartsChart (Bar/Line/Pie/Area), DashboardGrid, FilterBar
|
|
256
318
|
|
|
@@ -269,8 +331,9 @@ See [references/ui-dashboard-spec.md](../references/ui-dashboard-spec.md) for th
|
|
|
269
331
|
|
|
270
332
|
Before proceeding to step-03c-compile.md, VERIFY:
|
|
271
333
|
|
|
272
|
-
1. **Wireframes displayed and validated** — ALL wireframes were output as visible ASCII art in the conversation AND validated by the client via AskUserQuestion
|
|
273
|
-
2. **Wireframes exist for all sections** in `specification.uiWireframes[]`
|
|
334
|
+
1. **Wireframes displayed and validated** — ALL wireframes (list AND detail) were output as visible ASCII art in the conversation AND validated by the client via AskUserQuestion
|
|
335
|
+
2. **Wireframes exist for all sections** in `specification.uiWireframes[]` — INCLUDING a `section: "detail"` wireframe for every module that has a `list` section
|
|
336
|
+
2b. **Detail page companion check (BLOCKING)** — For EACH section with `code: "list"`, verify there is a matching wireframe with `section: "detail"` AND a section with `code: "detail"` + `navigation: "hidden"` + route containing `:id`. Missing detail page = FAIL.
|
|
274
337
|
3. **All wireframes have componentMapping** with smarter mapping rules
|
|
275
338
|
4. **All wireframes have layout** with regions and resourceRef references
|
|
276
339
|
5. **All resource references** in layout.regions[].components[].resourceRef exist in sections[].resources[]
|
|
@@ -304,7 +304,104 @@ Total endpoints = count of specification.apiEndpoints[] across all modules.
|
|
|
304
304
|
"✓ Handoff module {i+1}/{N} : {moduleCode} ({fileCount} fichiers, {brCount} BRs mappées)"
|
|
305
305
|
```
|
|
306
306
|
|
|
307
|
-
#### 7b.
|
|
307
|
+
#### 7b. Generate seedDataCore (MANDATORY for master feature.json)
|
|
308
|
+
|
|
309
|
+
> **The seedDataCore provides ralph-loop with the exact navigation, permissions, and translations to seed.**
|
|
310
|
+
> Without seedDataCore, ralph-loop must INVENT this data — leading to inconsistencies.
|
|
311
|
+
|
|
312
|
+
```
|
|
313
|
+
// Derive seedDataCore from modules[], applicationRoles[], and coverageMatrix[]
|
|
314
|
+
|
|
315
|
+
const seedDataCore = {
|
|
316
|
+
navigationModules: master.modules.map((m, i) => ({
|
|
317
|
+
code: m.code,
|
|
318
|
+
label: m.name || m.code,
|
|
319
|
+
description: m.description,
|
|
320
|
+
icon: null, // set by ralph-loop
|
|
321
|
+
iconType: "lucide",
|
|
322
|
+
route: `/business/${master.metadata.application.toLowerCase()}/${m.code.toLowerCase()}`,
|
|
323
|
+
displayOrder: (i + 1) * 10
|
|
324
|
+
})),
|
|
325
|
+
|
|
326
|
+
navigationSections: master.modules.flatMap(m =>
|
|
327
|
+
(m.anticipatedSections || []).map((s, j) => ({
|
|
328
|
+
moduleCode: m.code,
|
|
329
|
+
code: s.code,
|
|
330
|
+
label: s.description?.split(':')[0] || s.code,
|
|
331
|
+
description: s.description || "",
|
|
332
|
+
route: s.code === "detail" ? null : `/${s.code}`,
|
|
333
|
+
displayOrder: (j + 1) * 10,
|
|
334
|
+
navigation: s.code === "detail" ? "hidden" : "visible"
|
|
335
|
+
}))
|
|
336
|
+
),
|
|
337
|
+
|
|
338
|
+
navigationResources: master.cadrage.coverageMatrix
|
|
339
|
+
.filter(cm => cm.module && cm.anticipatedResources?.length > 0)
|
|
340
|
+
.flatMap(cm =>
|
|
341
|
+
cm.anticipatedResources.map((r, k) => ({
|
|
342
|
+
moduleCode: cm.module,
|
|
343
|
+
sectionCode: cm.anticipatedSections?.[0] || "list",
|
|
344
|
+
code: r,
|
|
345
|
+
label: r.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase()),
|
|
346
|
+
displayOrder: (k + 1) * 10
|
|
347
|
+
}))
|
|
348
|
+
),
|
|
349
|
+
|
|
350
|
+
navigationTranslations: master.modules.flatMap(m => {
|
|
351
|
+
const langs = ["fr", "en"]; // minimum required
|
|
352
|
+
return langs.map(lang => ({
|
|
353
|
+
moduleCode: m.code,
|
|
354
|
+
language: lang,
|
|
355
|
+
label: lang === master.metadata.language ? (m.name || m.code) : m.code,
|
|
356
|
+
description: lang === master.metadata.language ? m.description : ""
|
|
357
|
+
}));
|
|
358
|
+
}),
|
|
359
|
+
|
|
360
|
+
permissions: master.cadrage.applicationRoles.flatMap(role =>
|
|
361
|
+
master.modules.map(m => ({
|
|
362
|
+
role: role.role,
|
|
363
|
+
module: m.code,
|
|
364
|
+
pattern: role.permissionPattern.replace('*', `${m.code.toLowerCase()}.*`),
|
|
365
|
+
level: role.level
|
|
366
|
+
}))
|
|
367
|
+
),
|
|
368
|
+
|
|
369
|
+
rolePermissions: master.cadrage.applicationRoles.map(role => ({
|
|
370
|
+
role: role.role,
|
|
371
|
+
level: role.level,
|
|
372
|
+
permissions: master.modules.map(m => `business.${master.metadata.application.toLowerCase()}.${m.code.toLowerCase()}.${
|
|
373
|
+
role.level === 'admin' ? '*' :
|
|
374
|
+
role.level === 'manager' ? 'read,create,update,validate' :
|
|
375
|
+
role.level === 'contributor' ? 'read,create,update' : 'read'
|
|
376
|
+
}`)
|
|
377
|
+
})),
|
|
378
|
+
|
|
379
|
+
permissionConstants: master.modules.flatMap(m =>
|
|
380
|
+
['Read', 'Create', 'Update', 'Delete', 'Validate', 'Export'].map(action => ({
|
|
381
|
+
module: m.code,
|
|
382
|
+
action: action,
|
|
383
|
+
constant: `${master.metadata.application}${m.code}${action}`,
|
|
384
|
+
path: `business.${master.metadata.application.toLowerCase()}.${m.code.toLowerCase()}.${action.toLowerCase()}`
|
|
385
|
+
}))
|
|
386
|
+
)
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
ba-writer.enrichSection({
|
|
390
|
+
featureId: {feature_id},
|
|
391
|
+
section: "seedDataCore",
|
|
392
|
+
data: seedDataCore
|
|
393
|
+
})
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**POST-CHECK (non-blocking):**
|
|
397
|
+
```
|
|
398
|
+
IF seedDataCore.navigationModules.length !== master.modules.length:
|
|
399
|
+
WARNING: seedDataCore has ${seedDataCore.navigationModules.length} nav modules but ${master.modules.length} modules exist
|
|
400
|
+
IF seedDataCore.permissions.length === 0:
|
|
401
|
+
WARNING: seedDataCore has 0 permissions — applicationRoles may be missing
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
#### 7c. Master Handoff (after ALL modules written + seedDataCore generated)
|
|
308
405
|
|
|
309
406
|
```
|
|
310
407
|
ba-writer.enrichSection({
|
|
@@ -329,7 +426,7 @@ ba-writer.enrichSection({
|
|
|
329
426
|
})
|
|
330
427
|
```
|
|
331
428
|
|
|
332
|
-
####
|
|
429
|
+
#### 7d. Final Verification (BLOCKING)
|
|
333
430
|
|
|
334
431
|
```
|
|
335
432
|
count = 0
|
|
@@ -326,6 +326,37 @@ After writing the HTML file, verify:
|
|
|
326
326
|
fi
|
|
327
327
|
```
|
|
328
328
|
|
|
329
|
+
7. **WIREFRAME KEY ALIGNMENT** — wireframe keys MUST match module codes exactly
|
|
330
|
+
```
|
|
331
|
+
FOR each module in FEATURE_DATA.modules:
|
|
332
|
+
moduleCode = module.code (e.g., "GestionTemps")
|
|
333
|
+
IF EMBEDDED_ARTIFACTS.wireframes[moduleCode] is undefined OR empty:
|
|
334
|
+
BLOCKING_ERROR("Wireframe key mismatch: module code '${moduleCode}' not found in EMBEDDED_ARTIFACTS.wireframes")
|
|
335
|
+
BLOCKING_ERROR("Available wireframe keys: ${Object.keys(EMBEDDED_ARTIFACTS.wireframes).join(', ')}")
|
|
336
|
+
→ FIX: Rename the wireframe key to match module.code exactly
|
|
337
|
+
```
|
|
338
|
+
> **Why this matters:** The HTML renders wireframes via `EMBEDDED_ARTIFACTS.wireframes[code]`. If the key doesn't match the module code (e.g., "TimeTracking" vs "GestionTemps"), the wireframes tab shows "Aucune maquette disponible" even though data exists.
|
|
339
|
+
|
|
340
|
+
8. **MODULE COMPLETENESS** — every module must have spec data AND wireframes in HTML
|
|
341
|
+
```
|
|
342
|
+
FOR each module in master.modules[]:
|
|
343
|
+
IF FEATURE_DATA.moduleSpecs[module.code] is undefined:
|
|
344
|
+
BLOCKING_ERROR("Module '${module.code}' missing from FEATURE_DATA.moduleSpecs")
|
|
345
|
+
IF EMBEDDED_ARTIFACTS.wireframes[module.code] is undefined:
|
|
346
|
+
BLOCKING_ERROR("Module '${module.code}' missing from EMBEDDED_ARTIFACTS.wireframes")
|
|
347
|
+
IF module.featureJsonPath is null:
|
|
348
|
+
BLOCKING_ERROR("Module '${module.code}' has no per-module feature.json (featureJsonPath is null)")
|
|
349
|
+
|
|
350
|
+
expectedModules = master.modules.map(m => m.code).sort()
|
|
351
|
+
specModules = Object.keys(FEATURE_DATA.moduleSpecs).sort()
|
|
352
|
+
wireframeModules = Object.keys(EMBEDDED_ARTIFACTS.wireframes).sort()
|
|
353
|
+
|
|
354
|
+
IF expectedModules.join(',') !== specModules.join(','):
|
|
355
|
+
BLOCKING_ERROR("Module mismatch: expected [${expectedModules}] but moduleSpecs has [${specModules}]")
|
|
356
|
+
IF expectedModules.join(',') !== wireframeModules.join(','):
|
|
357
|
+
BLOCKING_ERROR("Module mismatch: expected [${expectedModules}] but wireframes has [${wireframeModules}]")
|
|
358
|
+
```
|
|
359
|
+
|
|
329
360
|
**IF ANY CHECK FAILS → DO NOT PROCEED. Fix the data mapping and regenerate.**
|
|
330
361
|
|
|
331
362
|
---
|
|
@@ -366,7 +397,10 @@ Effort: {total_days} days ({total_hours} hours)
|
|
|
366
397
|
|
|
367
398
|
5. Une fois validé, lancer le développement:
|
|
368
399
|
|
|
369
|
-
/ralph-loop
|
|
400
|
+
/ralph-loop
|
|
401
|
+
|
|
402
|
+
Note: /ralph-loop -r sert UNIQUEMENT à reprendre une boucle interrompue.
|
|
403
|
+
Après un /business-analyse, toujours utiliser /ralph-loop (sans -r).
|
|
370
404
|
|
|
371
405
|
═══════════════════════════════════════════════════════════════
|
|
372
406
|
```
|