@atlashub/smartstack-cli 4.74.0 → 4.75.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 +111 -36
- package/dist/index.js.map +1 -1
- package/dist/mcp-entry.mjs +14 -3
- package/dist/mcp-entry.mjs.map +1 -1
- package/package.json +1 -1
- package/templates/agents/ba-reader.md +17 -15
- package/templates/agents/ba-writer.md +49 -51
- package/templates/skills/apex/_shared.md +1 -1
- package/templates/skills/apex/references/checks/backend-checks.sh +21 -7
- package/templates/skills/apex/references/checks/infrastructure-checks.sh +47 -10
- package/templates/skills/apex/references/frontend-route-wiring-app-tsx.md +3 -0
- package/templates/skills/apex/references/post-checks.md +5 -2
- package/templates/skills/apex/references/smartstack-frontend.md +53 -7
- package/templates/skills/apex/steps/step-00-init.md +74 -0
- package/templates/skills/apex/steps/step-03-execute.md +16 -4
- package/templates/skills/apex/steps/step-03b-layer1-seed.md +39 -6
- package/templates/skills/apex/steps/step-03c-layer2-backend.md +50 -5
- package/templates/skills/apex/steps/step-03d-layer3-frontend.md +102 -2
- package/templates/skills/application/references/frontend-route-wiring-app-tsx.md +3 -0
- package/templates/skills/business-analyse/SKILL.md +14 -0
- package/templates/skills/business-analyse/_shared.md +27 -0
- package/templates/skills/business-analyse/patterns/suggestion-catalog.md +34 -26
- package/templates/skills/business-analyse/questionnaire/01-context.md +13 -9
- package/templates/skills/business-analyse/questionnaire/02-stakeholders-scope.md +20 -27
- package/templates/skills/business-analyse/questionnaire.md +86 -9
- package/templates/skills/business-analyse/references/03-json-schemas.md +213 -0
- package/templates/skills/business-analyse/references/03-post-check-validation.md +144 -0
- package/templates/skills/business-analyse/references/03-smartstack-entity-guards.md +32 -0
- package/templates/skills/business-analyse/references/04-cross-module-validation.md +95 -0
- package/templates/skills/business-analyse/references/04-file-allocation.md +162 -0
- package/templates/skills/business-analyse/references/04-naming-audit-checks.md +174 -0
- package/templates/skills/business-analyse/references/04-semantic-validation-matrix.md +118 -0
- package/templates/skills/business-analyse/references/domain-research-playbook.md +234 -0
- package/templates/skills/business-analyse/references/entity-sourcing-presentation.md +166 -0
- package/templates/skills/business-analyse/references/init-resume-logic.md +70 -0
- package/templates/skills/business-analyse/references/module-completeness-challenge.md +174 -0
- package/templates/skills/business-analyse/references/multi-app-detection.md +149 -0
- package/templates/skills/business-analyse/references/portal-classification.md +52 -0
- package/templates/skills/business-analyse/references/validation-checklist.md +30 -1
- package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +37 -4
- package/templates/skills/business-analyse/steps/step-00-init.md +22 -190
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +365 -269
- package/templates/skills/business-analyse/steps/step-02-structure.md +98 -20
- package/templates/skills/business-analyse/steps/step-03-specify.md +652 -229
- package/templates/skills/business-analyse/steps/step-04-consolidate.md +308 -287
- package/templates/skills/business-analyse-design/SKILL.md +10 -0
- package/templates/skills/business-analyse-design/references/screens-post-check.md +221 -0
- package/templates/skills/business-analyse-design/references/screens-type-mapping.md +138 -0
- package/templates/skills/business-analyse-design/references/smartcomponents-templates.md +225 -0
- package/templates/skills/{business-analyse → business-analyse-design}/references/spec-auto-inference.md +117 -117
- package/templates/skills/business-analyse-design/steps/step-01-screens.md +36 -162
- package/templates/skills/business-analyse-design/steps/step-02-wireframes.md +8 -7
- package/templates/skills/business-analyse-design/steps/step-03-navigation.md +89 -42
- package/templates/skills/business-analyse-develop/references/compact-loop.md +9 -0
- package/templates/skills/business-analyse-develop/references/handoff-quality-gate.md +132 -0
- package/templates/skills/business-analyse-develop/references/prd-v3-transformation.md +326 -0
- package/templates/skills/business-analyse-develop/references/report-reconciliation.md +140 -0
- package/templates/skills/business-analyse-develop/references/report-template.md +142 -0
- package/templates/skills/business-analyse-develop/steps/step-01-task.md +5 -177
- package/templates/skills/business-analyse-develop/steps/step-02-execute.md +17 -4
- package/templates/skills/business-analyse-develop/steps/step-03-commit.md +6 -2
- package/templates/skills/business-analyse-develop/steps/step-04-check.md +6 -0
- package/templates/skills/business-analyse-develop/steps/step-05-report.md +3 -269
- package/templates/skills/business-analyse-handoff/SKILL.md +10 -0
- package/templates/skills/business-analyse-handoff/references/agent-handoff-transform-prompt.md +208 -0
- package/templates/skills/business-analyse-handoff/references/context-isolation-pattern.md +47 -0
- package/templates/skills/business-analyse-handoff/references/handoff-file-inventory.md +49 -0
- package/templates/skills/business-analyse-handoff/references/handoff-global-validation.md +142 -0
- package/templates/skills/business-analyse-handoff/references/prd-validation-checks.md +125 -0
- package/templates/skills/business-analyse-handoff/references/project-index-update.md +98 -0
- package/templates/skills/business-analyse-handoff/steps/step-01-transform.md +9 -160
- package/templates/skills/business-analyse-handoff/steps/step-02-export.md +10 -99
- package/templates/skills/business-analyse-html/SKILL.md +10 -0
- package/templates/skills/business-analyse-html/html/ba-interactive.html +306 -81
- package/templates/skills/business-analyse-html/html/src/scripts/01-data-init.js +15 -2
- package/templates/skills/business-analyse-html/html/src/scripts/02-navigation.js +6 -46
- package/templates/skills/business-analyse-html/html/src/scripts/06-render-mockups.js +88 -33
- package/templates/skills/business-analyse-html/html/src/scripts/12-render-diagrams.js +116 -0
- package/templates/skills/business-analyse-html/html/src/styles/10-diagrams.css +73 -0
- package/templates/skills/business-analyse-html/html/src/template.html +2 -0
- package/templates/skills/business-analyse-html/references/02-embedded-artifacts-building.md +144 -0
- package/templates/skills/business-analyse-html/references/02-feature-data-building.md +141 -0
- package/templates/skills/business-analyse-html/references/02-mapping-tables.md +442 -0
- package/templates/skills/business-analyse-html/references/02-normalization-helpers.md +139 -0
- package/templates/skills/business-analyse-html/references/02-screen-format-detection.md +283 -0
- package/templates/skills/business-analyse-html/references/02-self-check-validation.md +199 -0
- package/templates/skills/business-analyse-html/references/data-build.md +22 -1
- package/templates/skills/business-analyse-html/references/data-mapping.md +40 -5
- package/templates/skills/business-analyse-html/steps/step-02-build-data.md +12 -555
- package/templates/skills/business-analyse-review/SKILL.md +10 -0
- package/templates/skills/business-analyse-status/SKILL.md +8 -0
- package/templates/skills/dev-start/SKILL.md +143 -307
- package/templates/skills/efcore/SKILL.md +13 -0
|
@@ -14,7 +14,7 @@ next_step: none
|
|
|
14
14
|
- ALWAYS validate permission coherence across modules
|
|
15
15
|
- ALWAYS execute semantic validation checks
|
|
16
16
|
- NEVER duplicate module content - work with summaries only
|
|
17
|
-
-
|
|
17
|
+
- ALWAYS ask for client approval, even for single-module projects (play devil's advocate)
|
|
18
18
|
|
|
19
19
|
## Context Recovery
|
|
20
20
|
|
|
@@ -50,98 +50,151 @@ IF status already "consolidated":
|
|
|
50
50
|
STOP
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
###
|
|
54
|
-
|
|
55
|
-
**2a. Load Module Index Files**
|
|
53
|
+
### 1b. Analysis Quality Self-Assessment (MANDATORY)
|
|
56
54
|
|
|
57
|
-
|
|
55
|
+
> **Score the analysis quality BEFORE presenting to the client.**
|
|
56
|
+
> This catches low-quality output before it reaches consolidation.
|
|
58
57
|
|
|
58
|
+
#### 1b-i. Research Coverage
|
|
59
59
|
```javascript
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
module
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
60
|
+
let researchScore = 0;
|
|
61
|
+
if (domain_research?.source === "built-in-only") {
|
|
62
|
+
researchScore = 2;
|
|
63
|
+
} else {
|
|
64
|
+
// +2 per application with Level 1 research
|
|
65
|
+
for (const app of applications) {
|
|
66
|
+
if (domain_research?.applications?.[app.code]) researchScore += 2;
|
|
67
|
+
}
|
|
68
|
+
// +1 per module with Level 2 research (cap at 4)
|
|
69
|
+
let moduleResearchCount = 0;
|
|
70
|
+
for (const module of completedModules) {
|
|
71
|
+
if (module.domainResearchSource !== "built-in-only") moduleResearchCount++;
|
|
72
|
+
}
|
|
73
|
+
researchScore += Math.min(moduleResearchCount, 4);
|
|
74
74
|
}
|
|
75
|
+
researchScore = Math.min(10, researchScore);
|
|
75
76
|
```
|
|
76
77
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
Build entity registry and validate cross-module references:
|
|
80
|
-
|
|
78
|
+
#### 1b-ii. Module Completeness (per app)
|
|
81
79
|
```javascript
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
80
|
+
for (const app of applications) {
|
|
81
|
+
const archetype = loadArchetype(app.type); // from module-completeness-challenge.md
|
|
82
|
+
const corePresent = archetype.coreModules.filter(m => appHasModule(app, m)).length;
|
|
83
|
+
const coreTotal = archetype.coreModules.length;
|
|
84
|
+
app.completenessScore = (corePresent / coreTotal) * 10;
|
|
85
|
+
// Penalty if CORE excluded without justification
|
|
86
|
+
const unjustified = archetype.coreModules.filter(m =>
|
|
87
|
+
!appHasModule(app, m) && !isExplicitlyExcluded(app, m)
|
|
88
|
+
);
|
|
89
|
+
if (unjustified.length > 0) app.completenessScore -= 3;
|
|
91
90
|
}
|
|
91
|
+
const avgModuleScore = average(applications.map(a => a.completenessScore));
|
|
92
|
+
```
|
|
92
93
|
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
#### 1b-iii. Section Depth (per module)
|
|
95
|
+
```javascript
|
|
95
96
|
for (const module of completedModules) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
}
|
|
97
|
+
const sectionCount = module.anticipatedSections?.length || 0;
|
|
98
|
+
if (module.featureType === "workflow") {
|
|
99
|
+
if (sectionCount < 5) module.sectionScore = 4;
|
|
100
|
+
else if (sectionCount < 7) module.sectionScore = 7;
|
|
101
|
+
else module.sectionScore = 9;
|
|
102
|
+
// Bonus for contextual views
|
|
103
|
+
const hasContextual = module.anticipatedSections?.some(s =>
|
|
104
|
+
["open-requests", "rejected", "history", "my-balance", "my-tasks", "overdue"].includes(s.code)
|
|
105
|
+
);
|
|
106
|
+
if (hasContextual) module.sectionScore = Math.min(10, module.sectionScore + 1);
|
|
107
|
+
} else {
|
|
108
|
+
module.sectionScore = sectionCount >= 3 ? 8 : sectionCount >= 2 ? 6 : 4;
|
|
111
109
|
}
|
|
112
110
|
}
|
|
111
|
+
const avgSectionScore = average(completedModules.map(m => m.sectionScore));
|
|
113
112
|
```
|
|
114
113
|
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
#### 1b-iv. Business Rule Depth (per module)
|
|
117
115
|
```javascript
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
116
|
+
for (const module of completedModules) {
|
|
117
|
+
const rules = module.rules || [];
|
|
118
|
+
const domainSpecific = rules.filter(r => r.domainSpecific === true || r.source === "domain-research").length;
|
|
119
|
+
const total = rules.length;
|
|
120
|
+
if (total === 0) { module.ruleScore = 0; continue; }
|
|
121
|
+
const genericRatio = (total - domainSpecific) / total;
|
|
122
|
+
if (genericRatio > 0.8) module.ruleScore = 3; // >80% generic = poor
|
|
123
|
+
else if (genericRatio > 0.5) module.ruleScore = 6; // 50-80% generic = acceptable
|
|
124
|
+
else module.ruleScore = 9; // <50% generic = excellent
|
|
126
125
|
}
|
|
126
|
+
const avgRuleScore = average(completedModules.map(m => m.ruleScore));
|
|
127
127
|
```
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
#### 1b-v. Global Quality Score
|
|
130
|
+
```javascript
|
|
131
|
+
const qualityScore = Math.round(
|
|
132
|
+
(researchScore + avgModuleScore + avgSectionScore + avgRuleScore) / 4
|
|
133
|
+
);
|
|
134
|
+
```
|
|
130
135
|
|
|
136
|
+
Display:
|
|
131
137
|
```
|
|
132
|
-
|
|
133
|
-
CROSS-MODULE INTERACTIONS VALIDATED
|
|
134
|
-
═══════════════════════════════════════════════════════════════
|
|
138
|
+
### Auto-evaluation qualite de l'analyse
|
|
135
139
|
|
|
136
|
-
|
|
|
137
|
-
|
|
138
|
-
|
|
|
139
|
-
|
|
|
140
|
+
| Dimension | Score | Detail |
|
|
141
|
+
|-----------|-------|--------|
|
|
142
|
+
| Recherche web | {researchScore}/10 | {N} apps recherchees, {M} modules recherches |
|
|
143
|
+
| Completude modules | {avgModuleScore}/10 | {details per app} |
|
|
144
|
+
| Profondeur sections | {avgSectionScore}/10 | {details per module} |
|
|
145
|
+
| Profondeur regles metier | {avgRuleScore}/10 | {domainSpecific}/{total} regles specifiques domaine |
|
|
146
|
+
| **GLOBAL** | **{qualityScore}/10** | |
|
|
147
|
+
```
|
|
140
148
|
|
|
141
|
-
Total: {count} cross-module references
|
|
142
|
-
Shared entities: {count}
|
|
143
|
-
═══════════════════════════════════════════════════════════════
|
|
144
149
|
```
|
|
150
|
+
IF qualityScore < 7:
|
|
151
|
+
WARNING: "Score qualite inferieur a 7/10.
|
|
152
|
+
Recommandation : relancer les etapes deficientes avec WebSearch active."
|
|
153
|
+
Display: "Dimensions a ameliorer: {list dimensions < 7}"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Store in `validation.json` as `qualityAssessment`.
|
|
157
|
+
|
|
158
|
+
### 1c. Business Process Coverage Validation (BLOCKING for multi-app)
|
|
159
|
+
|
|
160
|
+
> **Verify that all identified business processes are covered by modules.**
|
|
161
|
+
> A process step without a covering module = a GAP in the application.
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
IF cadrage._preAnalysis?.businessProcesses?.length > 0:
|
|
165
|
+
const gaps = [];
|
|
166
|
+
for (const process of cadrage._preAnalysis.businessProcesses) {
|
|
167
|
+
for (const step of process.steps) {
|
|
168
|
+
if (!step.covered) {
|
|
169
|
+
gaps.push({ process: process.name, step: step.name, apps: process.apps });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
Display:
|
|
175
|
+
### Couverture des processus metier
|
|
176
|
+
| Processus | Etapes | Couvertes | Gaps |
|
|
177
|
+
|-----------|--------|-----------|------|
|
|
178
|
+
{for each process: name, steps.length, covered count, gap names}
|
|
179
|
+
|
|
180
|
+
IF gaps.length > 0:
|
|
181
|
+
WARNING: "{gaps.length} etapes de processus non couvertes."
|
|
182
|
+
// Not BLOCKING at consolidation (should have been caught in step-01/02)
|
|
183
|
+
// But display as warning for final visibility
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Store in `validation.json` as `processCoverage`.
|
|
187
|
+
|
|
188
|
+
### 2. Cross-Module Interaction Analysis
|
|
189
|
+
|
|
190
|
+
→ **Load** `references/04-cross-module-validation.md` for FK validation rules, cycle detection, and interaction mapping.
|
|
191
|
+
|
|
192
|
+
**Execution:**
|
|
193
|
+
- Load module index files and granular JSON (entities, permissions)
|
|
194
|
+
- Build entity registry and detect shared entities
|
|
195
|
+
- Validate foreign key references across modules
|
|
196
|
+
- Detect circular dependencies (blocking error if any found)
|
|
197
|
+
- Display cross-module interaction map with validation status
|
|
145
198
|
|
|
146
199
|
### 3. Permission Coherence Check
|
|
147
200
|
|
|
@@ -184,45 +237,12 @@ const hierarchy = ["Admin", "Manager", "Contributor", "Viewer"];
|
|
|
184
237
|
|
|
185
238
|
### 4. Semantic Validation (MANDATORY)
|
|
186
239
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
```javascript
|
|
190
|
-
const semanticChecks = [
|
|
191
|
-
{ check: "permission-orpheline", severity: "WARNING" },
|
|
192
|
-
{ check: "uc-sans-fr", severity: "WARNING" },
|
|
193
|
-
{ check: "entity-sans-endpoint", severity: "WARNING" },
|
|
194
|
-
{ check: "uc-sans-scenario", severity: "WARNING" },
|
|
195
|
-
{ check: "role-sans-permissions", severity: "WARNING" },
|
|
196
|
-
{ check: "navigation-sans-traduction", severity: "ERROR" },
|
|
197
|
-
{ check: "lifecycle-terminal", severity: "WARNING" },
|
|
198
|
-
{ check: "schema-conformity", severity: "ERROR" },
|
|
199
|
-
{ check: "wireframe-coverage", severity: "ERROR" },
|
|
200
|
-
{ check: "entity-doublon", severity: "ERROR" },
|
|
201
|
-
{ check: "permission-fantome", severity: "ERROR" },
|
|
202
|
-
{ check: "dashboard-coverage", severity: "WARNING" },
|
|
203
|
-
{ check: "permission-uc-alignment", severity: "WARNING" }
|
|
204
|
-
];
|
|
205
|
-
|
|
206
|
-
for (const module of completedModules) {
|
|
207
|
-
for (const check of semanticChecks) {
|
|
208
|
-
const result = executeSemanticCheck(module, check);
|
|
209
|
-
if (result.status === "ERROR") {
|
|
210
|
-
errors.push({module: module.code, check: check.check, details: result.details});
|
|
211
|
-
} else if (result.status === "WARNING") {
|
|
212
|
-
warnings.push({module: module.code, check: check.check, details: result.details});
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
240
|
+
→ **Load** `references/04-semantic-validation-matrix.md` and execute ALL semantic validation checks.
|
|
216
241
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
ERROR(` [${error.module}] ${error.check}: ${error.details}`);
|
|
222
|
-
}
|
|
223
|
-
STOP - User must fix before proceeding
|
|
224
|
-
}
|
|
225
|
-
```
|
|
242
|
+
This includes:
|
|
243
|
+
- 13 semantic checks per module (permission orphans, UC coverage, entity doubles, permission ghosts, etc.)
|
|
244
|
+
- 5 contract verification checks (BR formulas, computed attributes, UC counts, permission counts, versioned attributes)
|
|
245
|
+
- Blocking rule: 0 ERROR → PASS, ≥1 ERROR → BLOCK (user must fix before proceeding)
|
|
226
246
|
|
|
227
247
|
### 5. Data Model Consolidation
|
|
228
248
|
|
|
@@ -259,6 +279,138 @@ Display("Global Entity Count: {count}")
|
|
|
259
279
|
Display("Global Relationships: {count}")
|
|
260
280
|
```
|
|
261
281
|
|
|
282
|
+
### 5a. Cross-Module Contracts (MANDATORY)
|
|
283
|
+
|
|
284
|
+
> **Generate explicit contracts for every cross-module FK dependency.**
|
|
285
|
+
> These contracts ensure both producer and consumer modules agree on the data shape.
|
|
286
|
+
> They prevent the #1 cross-module integration failure: wrong field type/name/nullability.
|
|
287
|
+
|
|
288
|
+
```javascript
|
|
289
|
+
const crossModuleContracts = [];
|
|
290
|
+
|
|
291
|
+
for (const rel of globalRelationships) {
|
|
292
|
+
// Only for cross-module relationships
|
|
293
|
+
if (rel.sourceModule !== rel.targetModule) {
|
|
294
|
+
// Resolve the FK field from the source entity's attributes
|
|
295
|
+
const sourceEntity = findEntity(rel.sourceModule, rel.sourceEntity);
|
|
296
|
+
const fkField = sourceEntity.attributes.find(a =>
|
|
297
|
+
a.name.toLowerCase() === (rel.targetEntity.toLowerCase() + 'id') ||
|
|
298
|
+
a.description?.includes('FK vers ' + rel.targetEntity)
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
crossModuleContracts.push({
|
|
302
|
+
consumer: `${rel.sourceModule}.${rel.sourceEntity}`,
|
|
303
|
+
provider: `${rel.targetModule}.${rel.targetEntity}`,
|
|
304
|
+
field: fkField?.name || `${rel.targetEntity.charAt(0).toLowerCase() + rel.targetEntity.slice(1)}Id`,
|
|
305
|
+
type: fkField?.type || "guid",
|
|
306
|
+
required: fkField?.required || false,
|
|
307
|
+
nullable: !fkField?.required,
|
|
308
|
+
resolvedVia: `FK → ${rel.targetEntity}.Id`,
|
|
309
|
+
cardinality: rel.cardinality,
|
|
310
|
+
cascadeDelete: rel.cascadeDelete,
|
|
311
|
+
description: `${rel.sourceEntity} references ${rel.targetEntity} from ${rel.targetModule}`
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Display:
|
|
318
|
+
```
|
|
319
|
+
### Contrats cross-module ({crossModuleContracts.length})
|
|
320
|
+
|
|
321
|
+
| Consumer | Provider | FK Field | Type | Required | Cascade |
|
|
322
|
+
|----------|----------|----------|------|----------|---------|
|
|
323
|
+
{for each contract: | {consumer} | {provider} | {field} | {type} | {required} | {cascadeDelete} |}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Store in `consolidation.json` as `crossModuleContracts[]`.
|
|
327
|
+
|
|
328
|
+
> These contracts are consumed by `/business-analyse-handoff` and `/business-analyse-develop`
|
|
329
|
+
> to ensure correct FK generation, DTO mapping, and navigation property creation across modules.
|
|
330
|
+
|
|
331
|
+
### 5b. Mermaid Diagram Generation (MANDATORY)
|
|
332
|
+
|
|
333
|
+
> Generate 3 types of Mermaid diagrams as text, stored in consolidation.json.
|
|
334
|
+
> These diagrams are rendered in the interactive HTML and exported with handoff.
|
|
335
|
+
|
|
336
|
+
#### 5b-i. ERD (Entity-Relationship Diagram)
|
|
337
|
+
|
|
338
|
+
From `globalEntities` and `globalRelationships` built in section 5, generate Mermaid ERD:
|
|
339
|
+
|
|
340
|
+
```javascript
|
|
341
|
+
let erd = "erDiagram\n";
|
|
342
|
+
for (const entity of globalEntities) {
|
|
343
|
+
erd += ` ${entity.name} {\n`;
|
|
344
|
+
for (const attr of entity.topAttributes) { // top 5-8 attributes
|
|
345
|
+
erd += ` ${attr.type} ${attr.name}\n`;
|
|
346
|
+
}
|
|
347
|
+
erd += " }\n";
|
|
348
|
+
}
|
|
349
|
+
for (const rel of globalRelationships) {
|
|
350
|
+
const card = rel.cardinality === "1:N" ? "||--o{" :
|
|
351
|
+
rel.cardinality === "N:1" ? "}o--||" :
|
|
352
|
+
rel.cardinality === "N:M" ? "}o--o{" : "||--||";
|
|
353
|
+
erd += ` ${rel.sourceEntity} ${card} ${rel.targetEntity} : "${rel.description}"\n`;
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Store as `consolidation.mermaidDiagrams.erd` (string).
|
|
358
|
+
|
|
359
|
+
#### 5b-ii. State Machine Diagrams (per entity lifecycle)
|
|
360
|
+
|
|
361
|
+
For EACH `lifeCycle` found in all modules' `usecases.json`:
|
|
362
|
+
|
|
363
|
+
```javascript
|
|
364
|
+
let sm = "stateDiagram-v2\n";
|
|
365
|
+
sm += ` [*] --> ${lifecycle.initialState}\n`;
|
|
366
|
+
for (const transition of lifecycle.transitions) {
|
|
367
|
+
sm += ` ${transition.from} --> ${transition.to} : ${transition.action}\n`;
|
|
368
|
+
}
|
|
369
|
+
for (const state of lifecycle.states.filter(s => s.isTerminal)) {
|
|
370
|
+
sm += ` ${state.id} --> [*]\n`;
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
Store as `consolidation.mermaidDiagrams.stateMachines[{entity}]` (string).
|
|
375
|
+
|
|
376
|
+
#### 5b-iii. Sequence Diagrams (per E2E flow)
|
|
377
|
+
|
|
378
|
+
For EACH e2eFlow identified in section 6:
|
|
379
|
+
|
|
380
|
+
```javascript
|
|
381
|
+
let seq = "sequenceDiagram\n";
|
|
382
|
+
for (const step of flow.steps) {
|
|
383
|
+
seq += ` ${step.actor || step.module}->>+${step.targetModule || "System"}: ${step.action}\n`;
|
|
384
|
+
if (step.result) {
|
|
385
|
+
seq += ` ${step.targetModule || "System"}-->>-${step.actor || step.module}: ${step.result}\n`;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Store as `consolidation.mermaidDiagrams.sequences[{flowName}]` (string).
|
|
391
|
+
|
|
392
|
+
#### 5b-iv. Storage
|
|
393
|
+
|
|
394
|
+
Write to `consolidation.json`:
|
|
395
|
+
|
|
396
|
+
```json
|
|
397
|
+
{
|
|
398
|
+
"mermaidDiagrams": {
|
|
399
|
+
"erd": "erDiagram\n Employee {\n guid id\n string code\n ...\n }\n ...",
|
|
400
|
+
"stateMachines": {
|
|
401
|
+
"Absence": "stateDiagram-v2\n [*] --> Draft\n Draft --> Submitted : submit\n ...",
|
|
402
|
+
"Invoice": "stateDiagram-v2\n [*] --> Draft\n ..."
|
|
403
|
+
},
|
|
404
|
+
"sequences": {
|
|
405
|
+
"CycleCommercial": "sequenceDiagram\n Commercial->>+CRM: Creer opportunite\n ...",
|
|
406
|
+
"CycleFacturation": "sequenceDiagram\n ..."
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
Display diagrams as markdown Mermaid code blocks for the client to preview before approval (section 9).
|
|
413
|
+
|
|
262
414
|
### 6. E2E Flow Validation
|
|
263
415
|
|
|
264
416
|
Identify business processes spanning multiple modules:
|
|
@@ -334,172 +486,15 @@ Les critères d'acceptation sont écrits dans `validation.json` au même niveau
|
|
|
334
486
|
|
|
335
487
|
### 7ter. Naming Audit (MANDATORY)
|
|
336
488
|
|
|
337
|
-
|
|
338
|
-
> during the BA must be reviewed for coherence, convention compliance, and clarity.
|
|
339
|
-
|
|
340
|
-
**7ter-a. Collect all names from the BA:**
|
|
341
|
-
|
|
342
|
-
```javascript
|
|
343
|
-
const namingRegistry = {
|
|
344
|
-
application: {
|
|
345
|
-
label: application_name,
|
|
346
|
-
code: applicationCode, // PascalCase
|
|
347
|
-
route: toKebabCase(applicationCode) // kebab-case
|
|
348
|
-
},
|
|
349
|
-
modules: completedModules.map(m => ({
|
|
350
|
-
label: m.name,
|
|
351
|
-
code: m.code, // PascalCase
|
|
352
|
-
route: toKebabCase(m.code) // kebab-case
|
|
353
|
-
})),
|
|
354
|
-
entities: completedModules.flatMap(m =>
|
|
355
|
-
m.entities.map(e => ({
|
|
356
|
-
name: e.name, // PascalCase (C# class name)
|
|
357
|
-
module: m.code,
|
|
358
|
-
tableName: e.tableName || pluralize(e.name) // Plural convention
|
|
359
|
-
}))
|
|
360
|
-
),
|
|
361
|
-
permissionRoots: [...new Set(
|
|
362
|
-
permissionPaths.map(p => p.path.split('.').slice(0, 2).join('.'))
|
|
363
|
-
)]
|
|
364
|
-
};
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
**7ter-b. Display naming recap table:**
|
|
368
|
-
|
|
369
|
-
```
|
|
370
|
-
═══════════════════════════════════════════════════════════════
|
|
371
|
-
NAMING AUDIT — {application_name}
|
|
372
|
-
═══════════════════════════════════════════════════════════════
|
|
373
|
-
|
|
374
|
-
APPLICATION
|
|
375
|
-
| Label | Code (PascalCase) | Route (kebab-case) |
|
|
376
|
-
|-------|-------------------|--------------------|
|
|
377
|
-
| {application_name} | {applicationCode} | /{route} |
|
|
378
|
-
|
|
379
|
-
MODULES
|
|
380
|
-
| # | Label | Code (PascalCase) | Route (kebab-case) |
|
|
381
|
-
|---|-------|-------------------|--------------------|
|
|
382
|
-
{for each module: index | label | code | /app-route/module-route}
|
|
383
|
-
|
|
384
|
-
ENTITIES
|
|
385
|
-
| Entity (PascalCase) | Module | Table (plural) |
|
|
386
|
-
|----------------------|--------|----------------|
|
|
387
|
-
{for each entity: name | module | tableName}
|
|
388
|
-
|
|
389
|
-
PERMISSION ROOTS
|
|
390
|
-
{for each root: path}
|
|
391
|
-
═══════════════════════════════════════════════════════════════
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
**7ter-c. Coherence checks:**
|
|
395
|
-
|
|
396
|
-
```javascript
|
|
397
|
-
const namingIssues = [];
|
|
398
|
-
|
|
399
|
-
// 1. Duplicate entity names across modules
|
|
400
|
-
const entityNames = namingRegistry.entities.map(e => e.name);
|
|
401
|
-
const duplicates = entityNames.filter((n, i) => entityNames.indexOf(n) !== i);
|
|
402
|
-
if (duplicates.length > 0) {
|
|
403
|
-
namingIssues.push({ severity: "ERROR", issue: `Duplicate entity names: ${[...new Set(duplicates)].join(', ')}` });
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
// 2. Module code vs label coherence (code should derive logically from label)
|
|
407
|
-
for (const mod of namingRegistry.modules) {
|
|
408
|
-
if (!mod.code || mod.code.length < 2) {
|
|
409
|
-
namingIssues.push({ severity: "ERROR", issue: `Module "${mod.label}" has invalid code: "${mod.code}"` });
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// 3. Permission root alignment with module codes
|
|
414
|
-
for (const root of namingRegistry.permissionRoots) {
|
|
415
|
-
const [appSegment, moduleSegment] = root.split('.');
|
|
416
|
-
const matchingModule = namingRegistry.modules.find(m =>
|
|
417
|
-
m.code.toLowerCase() === moduleSegment.toLowerCase()
|
|
418
|
-
);
|
|
419
|
-
if (!matchingModule) {
|
|
420
|
-
namingIssues.push({ severity: "WARNING", issue: `Permission root "${root}" has no matching module code` });
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// 4. Route collision detection
|
|
425
|
-
const allRoutes = namingRegistry.modules.map(m =>
|
|
426
|
-
`/${namingRegistry.application.route}/${m.route}`
|
|
427
|
-
);
|
|
428
|
-
const routeDuplicates = allRoutes.filter((r, i) => allRoutes.indexOf(r) !== i);
|
|
429
|
-
if (routeDuplicates.length > 0) {
|
|
430
|
-
namingIssues.push({ severity: "ERROR", issue: `Route collisions: ${routeDuplicates.join(', ')}` });
|
|
431
|
-
}
|
|
432
|
-
```
|
|
433
|
-
|
|
434
|
-
**7ter-d. MCP validation:**
|
|
435
|
-
|
|
436
|
-
```
|
|
437
|
-
mcp__smartstack__validate_conventions({
|
|
438
|
-
checks: ["tables"],
|
|
439
|
-
context: {
|
|
440
|
-
applicationCode: applicationCode,
|
|
441
|
-
modules: namingRegistry.modules.map(m => m.code),
|
|
442
|
-
entities: namingRegistry.entities.map(e => e.name)
|
|
443
|
-
}
|
|
444
|
-
})
|
|
445
|
-
|
|
446
|
-
→ Merge MCP findings into namingIssues[]
|
|
447
|
-
```
|
|
489
|
+
→ **Load** `references/04-naming-audit-checks.md` for all naming validation rules and user interaction flows.
|
|
448
490
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
{for each issue}
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
Ask via AskUserQuestion:
|
|
460
|
-
```
|
|
461
|
-
question: "{language == 'fr'
|
|
462
|
-
? 'Validez-vous les noms ci-dessus pour l\\'ensemble de l\\'application ?'
|
|
463
|
-
: 'Do you approve all the names above for the entire application?'}"
|
|
464
|
-
header: "Naming Audit"
|
|
465
|
-
options:
|
|
466
|
-
- label: "{language == 'fr' ? 'Approuvé' : 'Approved'}"
|
|
467
|
-
description: "{language == 'fr' ? 'Tous les noms sont corrects' : 'All names are correct'}"
|
|
468
|
-
- label: "{language == 'fr' ? 'Renommer certains éléments' : 'Rename some elements'}"
|
|
469
|
-
description: "{language == 'fr' ? 'Corriger des noms avant de finaliser' : 'Fix names before finalizing'}"
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
**IF "Renommer certains éléments":**
|
|
473
|
-
|
|
474
|
-
Ask via AskUserQuestion (open-ended):
|
|
475
|
-
```
|
|
476
|
-
question: "{language == 'fr'
|
|
477
|
-
? 'Quels éléments souhaitez-vous renommer ? (ex: \"Module Ventes → Commerce\", \"Entity Invoice → BillingDocument\")'
|
|
478
|
-
: 'Which elements do you want to rename? (e.g., \"Module Sales → Commerce\", \"Entity Invoice → BillingDocument\")'}"
|
|
479
|
-
header: "Renaming"
|
|
480
|
-
```
|
|
481
|
-
|
|
482
|
-
Process user response:
|
|
483
|
-
1. Parse rename instructions
|
|
484
|
-
2. Update `applicationCode`, module codes, entity names, permission paths accordingly in JSON files via ba-writer
|
|
485
|
-
3. Re-run 7ter-c and 7ter-d checks on updated names
|
|
486
|
-
4. Re-display the naming recap table for final confirmation
|
|
487
|
-
|
|
488
|
-
**IF "Approuvé":**
|
|
489
|
-
→ Store naming audit result in `validation.json`:
|
|
490
|
-
```javascript
|
|
491
|
-
ba-writer.enrichSection({
|
|
492
|
-
featureId: {feature_id},
|
|
493
|
-
section: "namingAudit",
|
|
494
|
-
data: {
|
|
495
|
-
auditedAt: now(),
|
|
496
|
-
issues: namingIssues,
|
|
497
|
-
approved: true,
|
|
498
|
-
renames: [] // or list of applied renames
|
|
499
|
-
}
|
|
500
|
-
});
|
|
501
|
-
```
|
|
502
|
-
→ Continue to section 8
|
|
491
|
+
This includes:
|
|
492
|
+
- Collect all application, module, entity, and permission names into a registry
|
|
493
|
+
- Display naming recap table (application code, module routes, entity tables, permission roots)
|
|
494
|
+
- Execute coherence checks (duplicate entities, route collisions, permission root alignment)
|
|
495
|
+
- Run MCP `validate_conventions` on entity/module names
|
|
496
|
+
- Present findings via AskUserQuestion with approval and rename options
|
|
497
|
+
- Process rename instructions if needed, re-validate, and continue to section 8
|
|
503
498
|
|
|
504
499
|
### 8. Consolidation Summary Display
|
|
505
500
|
|
|
@@ -537,16 +532,10 @@ RISKS
|
|
|
537
532
|
|
|
538
533
|
### 9. Client Approval (BLOCKING)
|
|
539
534
|
|
|
540
|
-
**
|
|
535
|
+
**Toujours demander l'approbation** — meme pour un module unique, jouer l'avocat du diable :
|
|
536
|
+
proposer au moins 1 cas non mentionne ou 1 question de completude avant validation.
|
|
541
537
|
|
|
542
|
-
|
|
543
|
-
IF completedModules.length === 1:
|
|
544
|
-
Display: "Module unique - consolidation automatique ✓"
|
|
545
|
-
approval = { approved: true, reason: "Single module", approvedAt: now() }
|
|
546
|
-
SKIP to section 10
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
**Multi-Module Mode:** Ask via AskUserQuestion:
|
|
538
|
+
Ask via AskUserQuestion:
|
|
550
539
|
|
|
551
540
|
```
|
|
552
541
|
question: "La consolidation est complète. Validez-vous l'ensemble ?"
|
|
@@ -568,6 +557,14 @@ IF "Modifier les interactions":
|
|
|
568
557
|
|
|
569
558
|
### 10. Write Consolidation Data
|
|
570
559
|
|
|
560
|
+
→ **Load** `references/04-file-allocation.md` for strict data allocation rules.
|
|
561
|
+
|
|
562
|
+
**MANDATORY:** Data must be written to correct files:
|
|
563
|
+
- `consolidation.json`: crossModuleInteractions, sharedEntities, permissionCoherence, e2eFlows, decision
|
|
564
|
+
- `validation.json`: semanticChecks, contractChecks, namingAudit, acceptanceCriteria, globalRiskAssessment
|
|
565
|
+
|
|
566
|
+
Mixing contents across files = BLOCKING ERROR.
|
|
567
|
+
|
|
571
568
|
```javascript
|
|
572
569
|
ba-writer.enrichSection({
|
|
573
570
|
featureId: {feature_id},
|
|
@@ -594,10 +591,6 @@ ba-writer.enrichSection({
|
|
|
594
591
|
warnings: []
|
|
595
592
|
},
|
|
596
593
|
e2eFlows: e2eFlows,
|
|
597
|
-
globalRiskAssessment: risks,
|
|
598
|
-
semanticChecks: [
|
|
599
|
-
{ check: "permission-orpheline", status: "PASS|WARNING", details: "..." }
|
|
600
|
-
],
|
|
601
594
|
decision: {
|
|
602
595
|
approved: approval.approved,
|
|
603
596
|
reason: approval.reason,
|
|
@@ -607,6 +600,34 @@ ba-writer.enrichSection({
|
|
|
607
600
|
}
|
|
608
601
|
});
|
|
609
602
|
|
|
603
|
+
// Write validation.json — quality/audit data for downstream skills (C1)
|
|
604
|
+
ba-writer.enrichSection({
|
|
605
|
+
featureId: {feature_id},
|
|
606
|
+
section: "validation",
|
|
607
|
+
data: {
|
|
608
|
+
semanticChecks: semanticChecks.map(check => ({
|
|
609
|
+
check: check.check,
|
|
610
|
+
status: errors.some(e => e.check === check.check) ? "ERROR"
|
|
611
|
+
: warnings.some(w => w.check === check.check) ? "WARNING" : "PASS",
|
|
612
|
+
details: [...errors, ...warnings]
|
|
613
|
+
.filter(r => r.check === check.check)
|
|
614
|
+
.map(r => `[${r.module}] ${r.details}`)
|
|
615
|
+
})),
|
|
616
|
+
contractChecks: [...errors, ...warnings].filter(r =>
|
|
617
|
+
["br-calc-sans-formula", "computed-sans-br-calc", "uc-count-critical",
|
|
618
|
+
"uc-count-low", "permission-count-low", "missing-versioned-attributes"].includes(r.check)
|
|
619
|
+
),
|
|
620
|
+
namingAudit: {
|
|
621
|
+
auditedAt: now(),
|
|
622
|
+
issues: namingIssues,
|
|
623
|
+
approved: true,
|
|
624
|
+
renames: []
|
|
625
|
+
},
|
|
626
|
+
acceptanceCriteria: acceptanceCriteria, // from section 7bis
|
|
627
|
+
globalRiskAssessment: risks // from section 7
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
|
|
610
631
|
// Add changelog entry
|
|
611
632
|
ba-writer.enrichSection({
|
|
612
633
|
featureId: {feature_id},
|
|
@@ -681,7 +702,7 @@ BA workflow complete. Next steps:
|
|
|
681
702
|
- ✓ Permission coherence validated
|
|
682
703
|
- ✓ Semantic checks: 0 errors
|
|
683
704
|
- ✓ Naming audit completed and approved
|
|
684
|
-
- ✓ Client approval obtained
|
|
705
|
+
- ✓ Client approval obtained
|
|
685
706
|
- ✓ Consolidation section written to validation.json
|
|
686
707
|
- ✓ Status updated to "consolidated"
|
|
687
708
|
- ✓ Workflow state saved for resume support
|