@atlashub/smartstack-cli 3.18.0 → 3.19.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/start.md +2 -2
- 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 +35 -26
- 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/references/start-local-config.md +6 -3
- package/templates/skills/gitflow/steps/step-start.md +2 -2
|
@@ -73,6 +73,98 @@
|
|
|
73
73
|
|
|
74
74
|
**MANDATORY for SmartForm:** `fields` with `component` type, `formLayout`
|
|
75
75
|
|
|
76
|
+
## Detail Page section (reached from list click)
|
|
77
|
+
|
|
78
|
+
> **RULE:** The detail page is NOT a sidebar navigation entry. It is reached by clicking a row in the `list` section. Its route includes `:id` parameter. Every module with a `list` section MUST have a companion detail page.
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"code": "detail",
|
|
83
|
+
"labels": { "fr": "Détail", "en": "Detail", "it": "Dettaglio", "de": "Detail" },
|
|
84
|
+
"route": "/business/{app}/{module}/detail/:id",
|
|
85
|
+
"icon": "file-text",
|
|
86
|
+
"permission": "business.{app}.{module}.read",
|
|
87
|
+
"wireframe": "{module}-detail",
|
|
88
|
+
"navigation": "hidden",
|
|
89
|
+
"useCases": ["UC-{PREFIX}-002"],
|
|
90
|
+
"businessRules": ["BR-VAL-{PREFIX}-001"],
|
|
91
|
+
"resources": [
|
|
92
|
+
{
|
|
93
|
+
"code": "{module}-detail-header",
|
|
94
|
+
"type": "DetailHeader",
|
|
95
|
+
"entity": "{MainEntity}",
|
|
96
|
+
"permission": "business.{app}.{module}.read",
|
|
97
|
+
"fields": ["code", "name", "status"],
|
|
98
|
+
"actions": [
|
|
99
|
+
{ "action": "edit", "icon": "edit", "permission": "business.{app}.{module}.update", "showWhen": {"status": ["draft"]} },
|
|
100
|
+
{ "action": "delete", "icon": "trash", "permission": "business.{app}.{module}.delete", "confirm": true }
|
|
101
|
+
],
|
|
102
|
+
"statusBadge": { "field": "status", "colorMap": "stateMachine:{Entity}" }
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"code": "{module}-detail-tabs",
|
|
106
|
+
"type": "TabPanel",
|
|
107
|
+
"entity": "{MainEntity}",
|
|
108
|
+
"permission": "business.{app}.{module}.read",
|
|
109
|
+
"tabs": [
|
|
110
|
+
{
|
|
111
|
+
"code": "info",
|
|
112
|
+
"label": {"fr": "Informations", "en": "Information", "it": "Informazioni", "de": "Informationen"},
|
|
113
|
+
"icon": "info",
|
|
114
|
+
"default": true,
|
|
115
|
+
"content": {
|
|
116
|
+
"type": "DetailCard",
|
|
117
|
+
"resourceRef": "{module}-info-card",
|
|
118
|
+
"fields": ["code", "name", "type", "description", "startDate", "createdAt"],
|
|
119
|
+
"editMode": {
|
|
120
|
+
"enabled": true,
|
|
121
|
+
"formRef": "{module}-form",
|
|
122
|
+
"permission": "business.{app}.{module}.update"
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"code": "{relation}",
|
|
128
|
+
"label": {"fr": "{RelationLabel}", "en": "{RelationLabel}"},
|
|
129
|
+
"icon": "list",
|
|
130
|
+
"content": {
|
|
131
|
+
"type": "SmartTable",
|
|
132
|
+
"resourceRef": "{module}-{relation}-grid",
|
|
133
|
+
"entity": "{RelatedEntity}",
|
|
134
|
+
"parentFilter": "{MainEntity}Id"
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"code": "history",
|
|
139
|
+
"label": {"fr": "Historique", "en": "History", "it": "Storico", "de": "Verlauf"},
|
|
140
|
+
"icon": "clock",
|
|
141
|
+
"showWhen": "auditable",
|
|
142
|
+
"content": {
|
|
143
|
+
"type": "Timeline",
|
|
144
|
+
"resourceRef": "{module}-history",
|
|
145
|
+
"source": "auditLog"
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**MANDATORY for detail section:**
|
|
155
|
+
- `navigation: "hidden"` — detail page is NOT shown in sidebar, reached by row click from list
|
|
156
|
+
- `route` MUST contain `:id` parameter
|
|
157
|
+
- At least one `TabPanel` resource with `tabs[]`
|
|
158
|
+
- First tab MUST be "info" with `DetailCard` + `editMode`
|
|
159
|
+
- One tab per 1:N relationship (auto-inferred from entity relationships)
|
|
160
|
+
- History tab if entity is auditable (has lifeCycles)
|
|
161
|
+
|
|
162
|
+
**Tab auto-generation rules:**
|
|
163
|
+
1. **Info tab** (always) — all entity attributes displayed as read-only fields, with edit toggle
|
|
164
|
+
2. **Relation tabs** (per 1:N relationship) — SmartTable filtered by `parentFilter`
|
|
165
|
+
3. **History tab** (if auditable) — Timeline from audit log
|
|
166
|
+
4. **Custom tabs** (from cadrage `detailTabs[]`) — any additional tabs specified during cadrage
|
|
167
|
+
|
|
76
168
|
## specification.uiWireframes[]
|
|
77
169
|
|
|
78
170
|
```json
|
|
@@ -108,3 +200,60 @@
|
|
|
108
200
|
**REQUIRED fields:** `screen`, `mockup`, `elements`, `section`, `componentMapping`, `layout` are ALL mandatory.
|
|
109
201
|
A wireframe without `componentMapping` or `layout` will FAIL validation in step 9.
|
|
110
202
|
**layout.regions[].components[].resourceRef** MUST match a `sections[].resources[].code`.
|
|
203
|
+
|
|
204
|
+
## Detail Page Wireframe
|
|
205
|
+
|
|
206
|
+
> **RULE:** For every `list` section, a companion detail wireframe MUST exist with `section: "detail"`.
|
|
207
|
+
|
|
208
|
+
```json
|
|
209
|
+
{
|
|
210
|
+
"screen": "{module}-detail",
|
|
211
|
+
"section": "detail",
|
|
212
|
+
"description": "Page de détail avec onglets — accessible depuis la liste par clic sur une ligne",
|
|
213
|
+
"mockupFormat": "ascii",
|
|
214
|
+
"mockup": "╔═══════════════════════════════════════════════════════════╗\n║ ← Retour à la liste ║\n╠═══════════════════════════════════════════════════════════╣\n║ {Entity} : {code} — {name} ● Statut [✏️] [🗑️] ║\n╠═══════════════════════════════════════════════════════════╣\n║ [ Informations ] [ {Relation} ] [ Historique ] ║\n╠═══════════════════════════════════════════════════════════╣\n║ ┌─────────────────────────────────────────────────────┐ ║\n║ │ Code: {code} │ ║\n║ │ Nom: {name} │ ║\n║ │ Type: {type} [Modifier] │ ║\n║ │ Description: {description} │ ║\n║ │ Créé le: {createdAt} │ ║\n║ └─────────────────────────────────────────────────────┘ ║\n╚═══════════════════════════════════════════════════════════╝",
|
|
215
|
+
"elements": [
|
|
216
|
+
{ "id": "elem-back", "type": "BackButton", "label": "Retour à la liste" },
|
|
217
|
+
{ "id": "elem-header", "type": "DetailHeader", "label": "En-tête entité" },
|
|
218
|
+
{ "id": "elem-status", "type": "StatusBadge", "label": "Badge statut" },
|
|
219
|
+
{ "id": "elem-tabs", "type": "TabPanel", "label": "Onglets de détail" },
|
|
220
|
+
{ "id": "elem-info", "type": "DetailCard", "label": "Carte informations" },
|
|
221
|
+
{ "id": "elem-edit", "type": "SmartForm", "label": "Formulaire d'édition" }
|
|
222
|
+
],
|
|
223
|
+
"actions": [
|
|
224
|
+
{ "trigger": "Click back", "action": "Navigate to list" },
|
|
225
|
+
{ "trigger": "Click edit", "action": "Toggle edit mode on info tab" },
|
|
226
|
+
{ "trigger": "Click tab", "action": "Switch tab content" },
|
|
227
|
+
{ "trigger": "Click status action", "action": "Trigger state transition (if lifeCycles)" }
|
|
228
|
+
],
|
|
229
|
+
"componentMapping": [
|
|
230
|
+
{ "wireframeElement": "BackButton", "reactComponent": "BackButton" },
|
|
231
|
+
{ "wireframeElement": "DetailHeader", "reactComponent": "EntityDetailHeader" },
|
|
232
|
+
{ "wireframeElement": "StatusBadge", "reactComponent": "StatusBadge" },
|
|
233
|
+
{ "wireframeElement": "TabPanel", "reactComponent": "Tabs" },
|
|
234
|
+
{ "wireframeElement": "DetailCard", "reactComponent": "EntityDetailCard" },
|
|
235
|
+
{ "wireframeElement": "SmartForm", "reactComponent": "SmartForm" }
|
|
236
|
+
],
|
|
237
|
+
"layout": {
|
|
238
|
+
"type": "page",
|
|
239
|
+
"regions": [
|
|
240
|
+
{ "id": "header", "position": "top", "components": [
|
|
241
|
+
{ "type": "BackButton", "target": "/business/{app}/{module}/list" },
|
|
242
|
+
{ "type": "DetailHeader", "resourceRef": "{module}-detail-header" },
|
|
243
|
+
{ "type": "StatusBadge", "resourceRef": "{module}-status" }
|
|
244
|
+
]},
|
|
245
|
+
{ "id": "tabs", "position": "main", "span": 12, "components": [
|
|
246
|
+
{ "type": "TabPanel", "resourceRef": "{module}-detail-tabs" }
|
|
247
|
+
]}
|
|
248
|
+
]
|
|
249
|
+
},
|
|
250
|
+
"permissionsRequired": ["business.{app}.{module}.read"]
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**Detail wireframe adaptation rules:**
|
|
255
|
+
- **Tabs** must match `sections[code=detail].resources[type=TabPanel].tabs[]`
|
|
256
|
+
- **Relation tabs** show a SmartTable of child entities filtered by parent ID
|
|
257
|
+
- **History tab** only included if entity has `lifeCycles` defined
|
|
258
|
+
- **Edit button** only shown if user has `update` permission
|
|
259
|
+
- **Status actions** only shown if entity has state machine transitions from current state
|
|
@@ -6,6 +6,7 @@ next_step: steps/step-02-decomposition.md
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
> **Context files:** `_shared.md` | `_elicitation.md` | `_architecture.md` | `_suggestions.md`
|
|
9
|
+
> **Reference (4d-bis):** `references/entity-architecture-decision.md` — Entity scoring, domain coherence, section patterns
|
|
9
10
|
|
|
10
11
|
# Step 1: Cadrage (Framing)
|
|
11
12
|
|
|
@@ -135,11 +136,12 @@ pre_analysis:
|
|
|
135
136
|
|
|
136
137
|
**Modules identifiés :**
|
|
137
138
|
- **{Module 1}** : {functional description}
|
|
138
|
-
-
|
|
139
|
-
-
|
|
139
|
+
- Section **list** : {entity}-grid, {entity}-filters, {entity}-form (création en modale)
|
|
140
|
+
- Page détail (onglets) : {Infos, {relation_tabs}...}
|
|
141
|
+
- {IF dashboard needed:} Section **dashboard** : {kpi-cards, charts...}
|
|
140
142
|
- **{Module 2}** : {functional description}
|
|
141
|
-
-
|
|
142
|
-
-
|
|
143
|
+
- Section **list** : {entity}-grid, {entity}-filters, {entity}-form
|
|
144
|
+
- Page détail (onglets) : {Infos, ...}
|
|
143
145
|
|
|
144
146
|
**Points que j'ai notés :**
|
|
145
147
|
- {specific point 1 from the brief, quoted verbatim when possible}
|
|
@@ -209,10 +211,31 @@ Ask in 1-2 batches. After each batch:
|
|
|
209
211
|
**Mandatory minimum:** Q3.2 (must-have), Q3.4 (exclusions), Q3.5 (main journey).
|
|
210
212
|
|
|
211
213
|
Ask in 1-2 batches. After each batch:
|
|
212
|
-
- If everything is "must-have" → apply
|
|
214
|
+
- If everything is "must-have" → **BLOCKING**: apply MoSCoW prioritization question (see POST-CHECK below)
|
|
213
215
|
- If no exclusions → probe: "What should this system explicitly NOT do?"
|
|
214
216
|
- If journey is too simple → detail: "What happens when something goes wrong? When someone cancels?"
|
|
215
217
|
|
|
218
|
+
> **BLOCKING RULE — MoSCoW DISTRIBUTION:**
|
|
219
|
+
> If the client classifies ALL features as "must-have", you MUST challenge this BEFORE proceeding.
|
|
220
|
+
> Ask via AskUserQuestion:
|
|
221
|
+
> ```
|
|
222
|
+
> question: "{language == 'fr'
|
|
223
|
+
> ? 'Toutes les fonctionnalités sont marquées indispensables. Si vous ne pouviez livrer que 60% du périmètre en v1, lesquelles pourraient attendre la v2 ?'
|
|
224
|
+
> : 'All features are marked must-have. If you could only deliver 60% of scope in v1, which ones could wait for v2?'}"
|
|
225
|
+
> header: "Priorisation"
|
|
226
|
+
> multiSelect: true
|
|
227
|
+
> options:
|
|
228
|
+
> - label: "{feature_1}"
|
|
229
|
+
> description: "{language == 'fr' ? 'Pourrait passer en Important (v1.x)' : 'Could move to Important (v1.x)'}"
|
|
230
|
+
> - label: "{feature_2}"
|
|
231
|
+
> description: "{language == 'fr' ? 'Pourrait passer en Optionnel (v2)' : 'Could move to Optional (v2)'}"
|
|
232
|
+
> - label: "{feature_3}"
|
|
233
|
+
> description: "{language == 'fr' ? 'Pourrait passer en Important (v1.x)' : 'Could move to Important (v1.x)'}"
|
|
234
|
+
> - label: "{language == 'fr' ? 'Tout est vraiment indispensable' : 'Everything is truly must-have'}"
|
|
235
|
+
> description: "{language == 'fr' ? 'Je confirme que toutes les fonctionnalités sont critiques pour la v1' : 'I confirm all features are critical for v1'}"
|
|
236
|
+
> ```
|
|
237
|
+
> If client moves items → update categories. If client confirms ALL mustHave → accept but log in changelog.
|
|
238
|
+
|
|
216
239
|
#### 4d. Challenge Implicit Assumptions (CRITICAL)
|
|
217
240
|
|
|
218
241
|
> **Apply elicitation techniques to challenge what the client considers "obvious".**
|
|
@@ -243,46 +266,174 @@ Ask challenge questions via AskUserQuestion (1-2 batches of max 4).
|
|
|
243
266
|
|
|
244
267
|
#### 4d-bis. Entity Sourcing Pattern (MANDATORY for detected dependencies)
|
|
245
268
|
|
|
246
|
-
> **When the analysis detects a referenced entity/concept (e.g., "Projets" referenced by activities, "Clients" referenced by orders), ALWAYS
|
|
247
|
-
> This
|
|
269
|
+
> **When the analysis detects a referenced entity/concept (e.g., "Projets" referenced by activities, "Clients" referenced by orders), ALWAYS analyze and recommend BEFORE asking the client.**
|
|
270
|
+
> This pattern detects potential new modules not mentioned in the original brief.
|
|
271
|
+
> **Reference:** Load [references/entity-architecture-decision.md](../references/entity-architecture-decision.md) for scoring grid, decision tree, and section patterns.
|
|
248
272
|
|
|
249
273
|
For EACH referenced entity/concept detected during phases 2-4 that is NOT already covered by an identified module:
|
|
250
274
|
|
|
251
|
-
|
|
275
|
+
##### PHASE 1 — ULTRATHINK: Silent Architecture Analysis (NO output to client)
|
|
276
|
+
|
|
277
|
+
> **The AI reasons about the entity BEFORE presenting options. This is internal thinking only.**
|
|
278
|
+
|
|
279
|
+
```
|
|
280
|
+
ULTRATHINK — Entity Architecture Analysis for {entity_name}:
|
|
281
|
+
|
|
282
|
+
1. DOMAIN COHERENCE (from decision tree in reference)
|
|
283
|
+
- Application domain: {app_description}
|
|
284
|
+
- Entity fit: CORE | SUPPORT | PERIPHERAL
|
|
285
|
+
- Justification: {1 sentence — why this entity is/isn't core to the app}
|
|
286
|
+
- Example: "Projets" in a time management app = CORE (without projects, time entries have no target)
|
|
287
|
+
- Example: "Codes d'imputation" in a time management app = SUPPORT (useful for accounting, but not central)
|
|
288
|
+
|
|
289
|
+
2. ENTITY SCORING (5 criteria, 0-3 each — from scoring grid in reference)
|
|
290
|
+
- Lifecycle: {score}/3 — {brief justification}
|
|
291
|
+
- Actors: {score}/3 — {brief justification}
|
|
292
|
+
- Relations: {score}/3 — {brief justification}
|
|
293
|
+
- Volume: {score}/3 — {brief justification}
|
|
294
|
+
- Autonomy: {score}/3 — {brief justification}
|
|
295
|
+
- TOTAL: {total}/15 → {classification: config_list | in_app | light_module | full_module}
|
|
296
|
+
|
|
297
|
+
3. PRE-CLASSIFICATION CHECK (from entity patterns in reference)
|
|
298
|
+
- Does {entity_name} match a known pattern? → {yes: which one | no: use scoring}
|
|
299
|
+
- Override needed? → {yes: why | no}
|
|
300
|
+
|
|
301
|
+
4. RECOMMENDATION
|
|
302
|
+
- Option: {config_list | in_app_section | new_module | external_system}
|
|
303
|
+
- Confidence: HIGH | MEDIUM | LOW
|
|
304
|
+
- Reasoning: {1-2 sentences}
|
|
305
|
+
- Risk if wrong choice: {what goes wrong if user picks a different option}
|
|
306
|
+
|
|
307
|
+
5. IF recommendation = new_module → PRE-BUILD ARCHITECTURE
|
|
308
|
+
- Module code: {PascalCase}
|
|
309
|
+
- Section `list`: {main entity grid + create action + navigation to detail}
|
|
310
|
+
- Detail page tabs: [{tab_name: content}] (accessible by clicking a row in list)
|
|
311
|
+
- Additional sections: [{code: justification}] (ONLY functional zones: dashboard, approve, import, rapport...)
|
|
312
|
+
- Dependencies: [{which modules reference/are referenced by this entity}]
|
|
313
|
+
- Topological position: layer {N} (foundation if no dependencies)
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
##### PHASE 2 — Present Analysis & Recommendation to Client
|
|
317
|
+
|
|
318
|
+
**BEFORE the AskUserQuestion, display the analysis as markdown:**
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
### {language == "fr" ? "Analyse" : "Analysis"} : {entity_plural}
|
|
322
|
+
|
|
323
|
+
{language == "fr"
|
|
324
|
+
? "Les **{entity_plural}** sont référencés par {parent_module} ({relationship_description})."
|
|
325
|
+
: "**{entity_plural}** are referenced by {parent_module} ({relationship_description})."}
|
|
326
|
+
|
|
327
|
+
{language == "fr" ? "**Mon analyse :**" : "**My analysis:**"}
|
|
328
|
+
- {language == "fr" ? "Cohérence domaine" : "Domain coherence"} : **{CORE|SUPPORT|PERIPHERAL}** — {justification}
|
|
329
|
+
- {language == "fr" ? "Score de complexité" : "Complexity score"} : **{score}/15** ({classification})
|
|
330
|
+
- {language == "fr" ? "Recommandation" : "Recommendation"} : **{recommended_option}** — {reasoning}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
**IF recommendation = new_module AND confidence >= MEDIUM, ALSO display:**
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
{language == "fr" ? "**Architecture proposée :**" : "**Proposed architecture:**"}
|
|
337
|
+
|
|
338
|
+
| {language == "fr" ? "Niveau" : "Level"} | {language == "fr" ? "Valeur" : "Value"} | {language == "fr" ? "Justification" : "Rationale"} |
|
|
339
|
+
|--------|--------|---------------|
|
|
340
|
+
| Context | `business` | {language == "fr" ? "Contexte métier standard" : "Standard business context"} |
|
|
341
|
+
| Application | `{app_code}` | {app_name} |
|
|
342
|
+
| Module | `{ModuleCode}` | {language == "fr" ? "{pourquoi ce découpage}" : "{why this decomposition}"} |
|
|
343
|
+
|
|
344
|
+
| Section | {language == "fr" ? "Justification" : "Rationale"} | Resources |
|
|
345
|
+
|---------|---------------|-----------|
|
|
346
|
+
| `list` | {language == "fr" ? "Page principale : grille, création, navigation vers détail" : "Main page: grid, create action, navigate to detail"} | {entity}-grid, {entity}-filters, {entity}-form |
|
|
347
|
+
| {additional_section} | {justification} | {resources} |
|
|
348
|
+
|
|
349
|
+
{language == "fr"
|
|
350
|
+
? "**Page détail** (onglets accessibles depuis la liste) :"
|
|
351
|
+
: "**Detail page** (tabs accessible from list):"}
|
|
352
|
+
|
|
353
|
+
| {language == "fr" ? "Onglet" : "Tab"} | {language == "fr" ? "Contenu" : "Content"} |
|
|
354
|
+
|--------|---------|
|
|
355
|
+
| {language == "fr" ? "Informations" : "Information"} | {language == "fr" ? "Fiche principale" : "Main record"} |
|
|
356
|
+
| {tab_name} | {tab_content} |
|
|
357
|
+
|
|
358
|
+
{language == "fr"
|
|
359
|
+
? "**Impact :** {ModuleName} deviendra une dépendance de {parent_module} (couche {N} du graphe)."
|
|
360
|
+
: "**Impact:** {ModuleName} will become a dependency of {parent_module} (layer {N} in the graph)."}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
##### PHASE 3 — Ask with Recommended Option First
|
|
364
|
+
|
|
365
|
+
**Order the options with the recommendation FIRST, marked "(Recommandé)" / "(Recommended)":**
|
|
366
|
+
|
|
252
367
|
```
|
|
253
368
|
question: "{language == 'fr'
|
|
254
|
-
? '
|
|
255
|
-
: '
|
|
369
|
+
? 'Comment souhaitez-vous gérer les {entity_plural} ?'
|
|
370
|
+
: 'How do you want to manage {entity_plural}?'}"
|
|
256
371
|
header: "{entity_name}"
|
|
257
372
|
options:
|
|
258
|
-
|
|
373
|
+
(ORDER: recommended option FIRST, then the 3 remaining options in logical order)
|
|
374
|
+
|
|
375
|
+
IF recommendation = new_module:
|
|
376
|
+
- label: "{language == 'fr' ? 'Nouveau module dédié (Recommandé)' : 'New dedicated module (Recommended)'}"
|
|
377
|
+
description: "{language == 'fr'
|
|
378
|
+
? 'Module {ModuleCode} avec page liste, détail par onglets, permissions dédiées'
|
|
379
|
+
: '{ModuleCode} module with list page, tabbed detail, dedicated permissions'}"
|
|
380
|
+
- label: "{language == 'fr' ? 'Géré dans l\'app' : 'Managed in app'}"
|
|
381
|
+
description: "..."
|
|
382
|
+
- label: "{language == 'fr' ? 'Système externe' : 'External system'}"
|
|
383
|
+
description: "..."
|
|
384
|
+
- label: "{language == 'fr' ? 'Liste simple en config' : 'Simple config list'}"
|
|
385
|
+
description: "..."
|
|
386
|
+
|
|
387
|
+
IF recommendation = config_list:
|
|
388
|
+
- label: "{language == 'fr' ? 'Liste simple en config (Recommandé)' : 'Simple config list (Recommended)'}"
|
|
259
389
|
description: "{language == 'fr'
|
|
260
|
-
? '
|
|
261
|
-
: '
|
|
390
|
+
? 'Table de référence administrable, pas de module dédié'
|
|
391
|
+
: 'Admin-managed reference table, no dedicated module'}"
|
|
392
|
+
- label: "{language == 'fr' ? 'Géré dans l\'app' : 'Managed in app'}"
|
|
393
|
+
description: "..."
|
|
262
394
|
- label: "{language == 'fr' ? 'Nouveau module dédié' : 'New dedicated module'}"
|
|
395
|
+
description: "..."
|
|
396
|
+
- label: "{language == 'fr' ? 'Système externe' : 'External system'}"
|
|
397
|
+
description: "..."
|
|
398
|
+
|
|
399
|
+
IF recommendation = in_app_section:
|
|
400
|
+
- label: "{language == 'fr' ? 'Géré dans l\'app (Recommandé)' : 'Managed in app (Recommended)'}"
|
|
263
401
|
description: "{language == 'fr'
|
|
264
|
-
? '
|
|
265
|
-
: '
|
|
402
|
+
? 'Accessible via un onglet dans la page détail de {parent_module}'
|
|
403
|
+
: 'Accessible via a tab in {parent_module} detail page'}"
|
|
404
|
+
- label: "{language == 'fr' ? 'Nouveau module dédié' : 'New dedicated module'}"
|
|
405
|
+
description: "..."
|
|
406
|
+
- label: "{language == 'fr' ? 'Liste simple en config' : 'Simple config list'}"
|
|
407
|
+
description: "..."
|
|
266
408
|
- label: "{language == 'fr' ? 'Système externe' : 'External system'}"
|
|
409
|
+
description: "..."
|
|
410
|
+
|
|
411
|
+
IF recommendation = external_system:
|
|
412
|
+
- label: "{language == 'fr' ? 'Système externe (Recommandé)' : 'External system (Recommended)'}"
|
|
267
413
|
description: "{language == 'fr'
|
|
268
414
|
? 'Les {entity_plural} viennent d\'un autre système (import ou API)'
|
|
269
415
|
: '{entity_plural} come from another system (import or API)'}"
|
|
416
|
+
- label: "{language == 'fr' ? 'Nouveau module dédié' : 'New dedicated module'}"
|
|
417
|
+
description: "..."
|
|
418
|
+
- label: "{language == 'fr' ? 'Géré dans l\'app' : 'Managed in app'}"
|
|
419
|
+
description: "..."
|
|
270
420
|
- label: "{language == 'fr' ? 'Liste simple en config' : 'Simple config list'}"
|
|
271
|
-
description: "
|
|
272
|
-
|
|
273
|
-
|
|
421
|
+
description: "..."
|
|
422
|
+
|
|
423
|
+
IF confidence = LOW (no clear recommendation):
|
|
424
|
+
(all 4 options in neutral order, NO "(Recommandé)" tag)
|
|
274
425
|
```
|
|
275
426
|
|
|
276
|
-
|
|
427
|
+
##### PHASE 4 — Process Answer
|
|
277
428
|
|
|
278
429
|
| Choice | Action |
|
|
279
430
|
|--------|--------|
|
|
280
|
-
| **
|
|
281
|
-
| **Nouveau module dédié** | **Add new module to `{pre_analysis}.detected_modules[]
|
|
431
|
+
| **Géré dans l'app** | Entity becomes a sub-entity of the parent module. Add as a **tab in the detail page** of the referencing module. Note in coverageMatrix with `parentModule` field. |
|
|
432
|
+
| **Nouveau module dédié** | **Add new module to `{pre_analysis}.detected_modules[]`** with the proposed architecture (sections, detail tabs, dependencies). Add to `coverageMatrix` as mustHave. The `list` section is ALWAYS the main section. Additional sections ONLY for distinct functional zones (dashboard, approve, import...). `create` and `edit` are ACTIONS within `list` and detail pages, NEVER standalone sections. |
|
|
282
433
|
| **Système externe** | Flag for integration specification. Add to `coverageMatrix` as integration. Load `questionnaire/05-integrations.md` if not already loaded. |
|
|
283
|
-
| **Liste simple en config** | Entity becomes a lookup/reference table (no dedicated module). Note in coverageMatrix as config data. |
|
|
434
|
+
| **Liste simple en config** | Entity becomes a lookup/reference table (no dedicated module, no section). Note in coverageMatrix as config data. |
|
|
284
435
|
|
|
285
|
-
> **CRITICAL:** The
|
|
436
|
+
> **CRITICAL:** The intelligence of this step is in the ULTRATHINK analysis. The AI must REASON about domain coherence, score the entity, and recommend — not just present 4 neutral options. The client can always override the recommendation, but they should benefit from expert architectural guidance.
|
|
286
437
|
|
|
287
438
|
#### 4e. Risks & Success Criteria (ALWAYS — from `questionnaire/14-risk-assumptions.md` and `questionnaire/15-success-metrics.md`)
|
|
288
439
|
|
|
@@ -445,12 +596,17 @@ BEFORE transitioning to step-02:
|
|
|
445
596
|
a. Create an entry in `cadrage.coverageMatrix[]`
|
|
446
597
|
b. Assign it to mustHave, shouldHave, couldHave, or outOfScope
|
|
447
598
|
c. Assign the module that will cover it (or null if cross-cutting)
|
|
448
|
-
d. **List anticipated sections** (Level 4)
|
|
599
|
+
d. **List anticipated sections** (Level 4) — ONLY functional zones (see `references/entity-architecture-decision.md` section 4)
|
|
449
600
|
e. **List anticipated resources** (Level 5) for each section
|
|
601
|
+
f. **List detail page tabs** — for entities accessible via click from `list`
|
|
602
|
+
|
|
603
|
+
> **SECTION RULE:** Sections are functional zones (list, dashboard, approve, import, rapport...).
|
|
604
|
+
> `create` and `edit` are ACTIONS within the `list` page (modal/drawer).
|
|
605
|
+
> `detail` is a page with tabs accessible by clicking a row in `list`, NOT a standalone section.
|
|
450
606
|
|
|
451
607
|
4. **OUTPUT the matrix as text** (do NOT put it inside AskUserQuestion — it won't render):
|
|
452
608
|
|
|
453
|
-
Print a markdown table with columns: **Fonctionnalité | Priorité | Module |
|
|
609
|
+
Print a markdown table with columns: **Fonctionnalité | Priorité | Module | Section | Resources clés | Onglets détail**
|
|
454
610
|
|
|
455
611
|
Example:
|
|
456
612
|
```
|
|
@@ -458,13 +614,15 @@ Example:
|
|
|
458
614
|
? "Voici la matrice de couverture enrichie. J'ai identifié {N} fonctionnalités :"
|
|
459
615
|
: "Here is the enriched coverage matrix. I identified {N} features:"}
|
|
460
616
|
|
|
461
|
-
| Fonctionnalité | Priorité | Module |
|
|
462
|
-
|
|
463
|
-
| Gestion des employés | mustHave | Employees | list
|
|
464
|
-
|
|
|
465
|
-
| Saisie d'absences | mustHave | TimeTracking | list
|
|
466
|
-
| Rapports temps |
|
|
467
|
-
|
|
|
617
|
+
| Fonctionnalité | Priorité | Module | Section | Resources clés | Onglets détail |
|
|
618
|
+
|---|---|---|---|---|---|
|
|
619
|
+
| Gestion des employés | mustHave | Employees | list | employee-grid, employee-filters, employee-form | Infos, Contrats, Documents |
|
|
620
|
+
| Suivi des activités | mustHave | TimeTracking | list | activity-grid, activity-filters, activity-form | Infos, Imputations |
|
|
621
|
+
| Saisie d'absences | mustHave | TimeTracking | list | absence-grid, absence-form, absence-calendar | Infos, Justificatifs |
|
|
622
|
+
| Rapports temps | shouldHave | TimeTracking | dashboard | time-kpi-cards, time-summary-chart | — |
|
|
623
|
+
| Validation absences | shouldHave | TimeTracking | approve | approval-queue, status-timeline | — |
|
|
624
|
+
| Export PDF/Excel | couldHave | TimeTracking | rapport | export-panel | — |
|
|
625
|
+
| Intégration paie | outOfScope | — | — | — | — |
|
|
468
626
|
```
|
|
469
627
|
|
|
470
628
|
5. **THEN** (after the table is displayed) ask via AskUserQuestion:
|
|
@@ -487,6 +645,36 @@ options:
|
|
|
487
645
|
- If a feature is in mustHave → it MUST have at least one anticipated section.
|
|
488
646
|
- Accepted suggestions from Phase 4 must appear in the matrix.
|
|
489
647
|
|
|
648
|
+
**POST-CHECK — PRIORITY DISTRIBUTION (BLOCKING):**
|
|
649
|
+
|
|
650
|
+
```
|
|
651
|
+
coverageItems = cadrage.coverageMatrix[]
|
|
652
|
+
mustHaveCount = coverageItems.filter(i => i.category === "mustHave").length
|
|
653
|
+
shouldHaveCount = coverageItems.filter(i => i.category === "shouldHave").length
|
|
654
|
+
couldHaveCount = coverageItems.filter(i => i.category === "couldHave").length
|
|
655
|
+
outOfScopeCount = coverageItems.filter(i => i.category === "outOfScope").length
|
|
656
|
+
|
|
657
|
+
IF shouldHaveCount === 0 AND couldHaveCount === 0 AND outOfScopeCount === 0:
|
|
658
|
+
→ FAIL: ALL {mustHaveCount} items are mustHave — no distribution.
|
|
659
|
+
→ ACTION: Return to Phase 3 section 4c and apply MoSCoW question.
|
|
660
|
+
→ DO NOT write cadrage until at least shouldHave OR outOfScope has ≥ 1 item.
|
|
661
|
+
→ EXCEPTION: If client explicitly confirmed "tout est indispensable" during
|
|
662
|
+
Phase 3 section 4c, accept but ADD a changelog entry:
|
|
663
|
+
"Client confirmed all {N} features as mustHave after MoSCoW challenge"
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
**POST-CHECK — CROSS-CUTTING COVERAGE (WARNING):**
|
|
667
|
+
|
|
668
|
+
```
|
|
669
|
+
FOR each item in coverageMatrix WHERE item.module === null:
|
|
670
|
+
IF item.category === "mustHave":
|
|
671
|
+
→ WARNING: "{item.item}" is mustHave but has no assigned module.
|
|
672
|
+
→ Ensure it is covered by infrastructure or a cross-cutting concern.
|
|
673
|
+
→ Add a note explaining HOW it will be implemented (e.g., "handled by platform notification service").
|
|
674
|
+
IF item.anticipatedSections.length === 0 AND item.category !== "outOfScope":
|
|
675
|
+
→ WARNING: "{item.item}" has no anticipated sections — will it be implemented?
|
|
676
|
+
```
|
|
677
|
+
|
|
490
678
|
---
|
|
491
679
|
|
|
492
680
|
## WRITE & SUMMARY
|
|
@@ -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
|
|