@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.
Files changed (93) hide show
  1. package/dist/index.js +111 -36
  2. package/dist/index.js.map +1 -1
  3. package/dist/mcp-entry.mjs +14 -3
  4. package/dist/mcp-entry.mjs.map +1 -1
  5. package/package.json +1 -1
  6. package/templates/agents/ba-reader.md +17 -15
  7. package/templates/agents/ba-writer.md +49 -51
  8. package/templates/skills/apex/_shared.md +1 -1
  9. package/templates/skills/apex/references/checks/backend-checks.sh +21 -7
  10. package/templates/skills/apex/references/checks/infrastructure-checks.sh +47 -10
  11. package/templates/skills/apex/references/frontend-route-wiring-app-tsx.md +3 -0
  12. package/templates/skills/apex/references/post-checks.md +5 -2
  13. package/templates/skills/apex/references/smartstack-frontend.md +53 -7
  14. package/templates/skills/apex/steps/step-00-init.md +74 -0
  15. package/templates/skills/apex/steps/step-03-execute.md +16 -4
  16. package/templates/skills/apex/steps/step-03b-layer1-seed.md +39 -6
  17. package/templates/skills/apex/steps/step-03c-layer2-backend.md +50 -5
  18. package/templates/skills/apex/steps/step-03d-layer3-frontend.md +102 -2
  19. package/templates/skills/application/references/frontend-route-wiring-app-tsx.md +3 -0
  20. package/templates/skills/business-analyse/SKILL.md +14 -0
  21. package/templates/skills/business-analyse/_shared.md +27 -0
  22. package/templates/skills/business-analyse/patterns/suggestion-catalog.md +34 -26
  23. package/templates/skills/business-analyse/questionnaire/01-context.md +13 -9
  24. package/templates/skills/business-analyse/questionnaire/02-stakeholders-scope.md +20 -27
  25. package/templates/skills/business-analyse/questionnaire.md +86 -9
  26. package/templates/skills/business-analyse/references/03-json-schemas.md +213 -0
  27. package/templates/skills/business-analyse/references/03-post-check-validation.md +144 -0
  28. package/templates/skills/business-analyse/references/03-smartstack-entity-guards.md +32 -0
  29. package/templates/skills/business-analyse/references/04-cross-module-validation.md +95 -0
  30. package/templates/skills/business-analyse/references/04-file-allocation.md +162 -0
  31. package/templates/skills/business-analyse/references/04-naming-audit-checks.md +174 -0
  32. package/templates/skills/business-analyse/references/04-semantic-validation-matrix.md +118 -0
  33. package/templates/skills/business-analyse/references/domain-research-playbook.md +234 -0
  34. package/templates/skills/business-analyse/references/entity-sourcing-presentation.md +166 -0
  35. package/templates/skills/business-analyse/references/init-resume-logic.md +70 -0
  36. package/templates/skills/business-analyse/references/module-completeness-challenge.md +174 -0
  37. package/templates/skills/business-analyse/references/multi-app-detection.md +149 -0
  38. package/templates/skills/business-analyse/references/portal-classification.md +52 -0
  39. package/templates/skills/business-analyse/references/validation-checklist.md +30 -1
  40. package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +37 -4
  41. package/templates/skills/business-analyse/steps/step-00-init.md +22 -190
  42. package/templates/skills/business-analyse/steps/step-01-cadrage.md +365 -269
  43. package/templates/skills/business-analyse/steps/step-02-structure.md +98 -20
  44. package/templates/skills/business-analyse/steps/step-03-specify.md +652 -229
  45. package/templates/skills/business-analyse/steps/step-04-consolidate.md +308 -287
  46. package/templates/skills/business-analyse-design/SKILL.md +10 -0
  47. package/templates/skills/business-analyse-design/references/screens-post-check.md +221 -0
  48. package/templates/skills/business-analyse-design/references/screens-type-mapping.md +138 -0
  49. package/templates/skills/business-analyse-design/references/smartcomponents-templates.md +225 -0
  50. package/templates/skills/{business-analyse → business-analyse-design}/references/spec-auto-inference.md +117 -117
  51. package/templates/skills/business-analyse-design/steps/step-01-screens.md +36 -162
  52. package/templates/skills/business-analyse-design/steps/step-02-wireframes.md +8 -7
  53. package/templates/skills/business-analyse-design/steps/step-03-navigation.md +89 -42
  54. package/templates/skills/business-analyse-develop/references/compact-loop.md +9 -0
  55. package/templates/skills/business-analyse-develop/references/handoff-quality-gate.md +132 -0
  56. package/templates/skills/business-analyse-develop/references/prd-v3-transformation.md +326 -0
  57. package/templates/skills/business-analyse-develop/references/report-reconciliation.md +140 -0
  58. package/templates/skills/business-analyse-develop/references/report-template.md +142 -0
  59. package/templates/skills/business-analyse-develop/steps/step-01-task.md +5 -177
  60. package/templates/skills/business-analyse-develop/steps/step-02-execute.md +17 -4
  61. package/templates/skills/business-analyse-develop/steps/step-03-commit.md +6 -2
  62. package/templates/skills/business-analyse-develop/steps/step-04-check.md +6 -0
  63. package/templates/skills/business-analyse-develop/steps/step-05-report.md +3 -269
  64. package/templates/skills/business-analyse-handoff/SKILL.md +10 -0
  65. package/templates/skills/business-analyse-handoff/references/agent-handoff-transform-prompt.md +208 -0
  66. package/templates/skills/business-analyse-handoff/references/context-isolation-pattern.md +47 -0
  67. package/templates/skills/business-analyse-handoff/references/handoff-file-inventory.md +49 -0
  68. package/templates/skills/business-analyse-handoff/references/handoff-global-validation.md +142 -0
  69. package/templates/skills/business-analyse-handoff/references/prd-validation-checks.md +125 -0
  70. package/templates/skills/business-analyse-handoff/references/project-index-update.md +98 -0
  71. package/templates/skills/business-analyse-handoff/steps/step-01-transform.md +9 -160
  72. package/templates/skills/business-analyse-handoff/steps/step-02-export.md +10 -99
  73. package/templates/skills/business-analyse-html/SKILL.md +10 -0
  74. package/templates/skills/business-analyse-html/html/ba-interactive.html +306 -81
  75. package/templates/skills/business-analyse-html/html/src/scripts/01-data-init.js +15 -2
  76. package/templates/skills/business-analyse-html/html/src/scripts/02-navigation.js +6 -46
  77. package/templates/skills/business-analyse-html/html/src/scripts/06-render-mockups.js +88 -33
  78. package/templates/skills/business-analyse-html/html/src/scripts/12-render-diagrams.js +116 -0
  79. package/templates/skills/business-analyse-html/html/src/styles/10-diagrams.css +73 -0
  80. package/templates/skills/business-analyse-html/html/src/template.html +2 -0
  81. package/templates/skills/business-analyse-html/references/02-embedded-artifacts-building.md +144 -0
  82. package/templates/skills/business-analyse-html/references/02-feature-data-building.md +141 -0
  83. package/templates/skills/business-analyse-html/references/02-mapping-tables.md +442 -0
  84. package/templates/skills/business-analyse-html/references/02-normalization-helpers.md +139 -0
  85. package/templates/skills/business-analyse-html/references/02-screen-format-detection.md +283 -0
  86. package/templates/skills/business-analyse-html/references/02-self-check-validation.md +199 -0
  87. package/templates/skills/business-analyse-html/references/data-build.md +22 -1
  88. package/templates/skills/business-analyse-html/references/data-mapping.md +40 -5
  89. package/templates/skills/business-analyse-html/steps/step-02-build-data.md +12 -555
  90. package/templates/skills/business-analyse-review/SKILL.md +10 -0
  91. package/templates/skills/business-analyse-status/SKILL.md +8 -0
  92. package/templates/skills/dev-start/SKILL.md +143 -307
  93. package/templates/skills/efcore/SKILL.md +13 -0
@@ -0,0 +1,144 @@
1
+ # POST-CHECK Validation (step-03-specify)
2
+
3
+ Before advancing to step 04, run these validations for EACH module:
4
+
5
+ ```javascript
6
+ const errors = [];
7
+ const warnings = [];
8
+
9
+ for (const mod of modules) {
10
+ // mod.dir = resolveModuleDir(applicationCode, mod.code)
11
+ // e.g., docs/projet-rh/v1.0/human-resources/employees/
12
+ const ent = READ(mod.dir + '/entities.json')?.entities || [];
13
+ const ucs = READ(mod.dir + '/usecases.json')?.useCases || [];
14
+ const brs = READ(mod.dir + '/rules.json')?.rules || [];
15
+ const perms = READ(mod.dir + '/permissions.json');
16
+ const sections = mod.anticipatedSections || [];
17
+ const sectionCodes = new Set(sections.map(s => s.code));
18
+
19
+ // Mandatory checks (BLOCKING)
20
+ if (ent.length === 0) errors.push(mod.code + ": 0 entities");
21
+ if (ucs.length === 0) errors.push(mod.code + ": 0 use cases");
22
+ if (brs.length === 0) errors.push(mod.code + ": 0 business rules");
23
+ if (!perms?.permissionPaths?.length) errors.push(mod.code + ": no permissions");
24
+
25
+ // sectionCode validation
26
+ for (const uc of ucs) {
27
+ if (!uc.sectionCode) errors.push(mod.code + ": UC '" + uc.id + "' missing sectionCode");
28
+ else if (!sectionCodes.has(uc.sectionCode)) errors.push(mod.code + ": UC '" + uc.id + "' sectionCode '" + uc.sectionCode + "' not in anticipatedSections");
29
+ }
30
+ for (const br of brs) {
31
+ if (!br.sectionCode) errors.push(mod.code + ": BR '" + br.id + "' missing sectionCode");
32
+ else if (!sectionCodes.has(br.sectionCode)) errors.push(mod.code + ": BR '" + br.id + "' sectionCode '" + br.sectionCode + "' not in anticipatedSections");
33
+ }
34
+
35
+ // Entity attribute checks
36
+ for (const e of ent) {
37
+ for (const a of (e.attributes || [])) {
38
+ if (!a.type) warnings.push(mod.code + ": entity " + e.name + " attr '" + a.name + "' missing type");
39
+ if (a.type === 'enum' && !a.defaultValue) errors.push(mod.code + ": enum attr '" + a.name + "' missing defaultValue");
40
+ // FK naming convention: must end with "Id"
41
+ if ((a.type === 'guid' || a.type === 'string') && a.foreignKey && !a.name.endsWith('Id'))
42
+ warnings.push(mod.code + ": entity " + e.name + " FK attr '" + a.name + "' should end with 'Id'");
43
+ }
44
+ // Person Extension Pattern check
45
+ const personFields = ['firstName', 'lastName', 'email', 'phoneNumber', 'phone'];
46
+ const foundPersonFields = (e.attributes || []).filter(a => personFields.includes(a.name));
47
+ if (foundPersonFields.length >= 3 && !e.personRoleConfig) {
48
+ errors.push(mod.code + ": entity '" + e.name + "' has " + foundPersonFields.length +
49
+ " person fields (" + foundPersonFields.map(f => f.name).join(", ") +
50
+ ") but no personRoleConfig — use Person Extension Pattern (entity-architecture-decision.md section 0). " +
51
+ "Person fields (firstName, lastName, email) belong on auth_Users, not on the domain entity.");
52
+ }
53
+ }
54
+
55
+ // Canonical usecases key check
56
+ const rawUCFile = READ(mod.dir + '/usecases.json');
57
+ if (rawUCFile && !rawUCFile.useCases && rawUCFile.usecases) {
58
+ errors.push(mod.code + ": usecases.json uses 'usecases' key instead of canonical 'useCases' — fix before proceeding");
59
+ }
60
+ // Check steps serialization format
61
+ for (const uc of ucs) {
62
+ if (uc.steps && Array.isArray(uc.steps) && uc.steps.length > 0 && typeof uc.steps[0] === 'object') {
63
+ errors.push(mod.code + ": UC '" + uc.id + "' uses steps[] with objects — must use mainScenario[] with strings");
64
+ }
65
+ if (uc.actor && !uc.primaryActor) {
66
+ warnings.push(mod.code + ": UC '" + uc.id + "' uses 'actor' instead of canonical 'primaryActor'");
67
+ }
68
+ }
69
+
70
+ // Cross-reference checks
71
+ for (const uc of ucs) {
72
+ for (const brRef of (uc.businessRules || [])) {
73
+ if (!brs.find(br => br.id === brRef)) warnings.push(mod.code + ": UC '" + uc.id + "' references non-existent BR '" + brRef + "'");
74
+ }
75
+ }
76
+
77
+ // Section permission checks
78
+ for (const section of sections) {
79
+ if (section.sectionType === 'view') {
80
+ const viewPerms = (perms?.permissionPaths || []).filter(p => p.includes('.' + section.code + '.'));
81
+ if (viewPerms.length > 0) errors.push(mod.code + ": view section '" + section.code + "' has " + viewPerms.length + " permissions (should inherit)");
82
+ }
83
+ }
84
+
85
+ // Quality gate: UC count (C6 — BLOCKING if < 4, WARNING if < 6)
86
+ if (ucs.length > 0 && ucs.length < 4) {
87
+ errors.push(mod.code + ": only " + ucs.length + " use cases (minimum: 4)");
88
+ } else if (ucs.length > 0 && ucs.length < 6) {
89
+ warnings.push(mod.code + ": only " + ucs.length + " use cases (recommended: >= 6)");
90
+ }
91
+
92
+ // Quality gate: Permission path count (C7 — WARNING if < 5)
93
+ const permPaths = perms?.permissionPaths || [];
94
+ if (permPaths.length > 0 && permPaths.length < 5) {
95
+ warnings.push(mod.code + ": only " + permPaths.length + " permission paths (recommended: >= 5 — check for missing Export/Import)");
96
+ }
97
+
98
+ // Quality gate: Entity count (C9 — WARNING if single entity)
99
+ if (ent.length === 1) {
100
+ warnings.push(mod.code + ": single entity module — verify this is intentional (config/lookup OK)");
101
+ }
102
+
103
+ // Quality gate: BR-CALC must have formula (C13 — BLOCKING)
104
+ for (const br of brs) {
105
+ if ((br.category === 'calculation' || (br.id && br.id.includes('CALC'))) && !br.formula) {
106
+ errors.push(mod.code + ": BR '" + br.id + "' is a calculation rule but missing 'formula' field");
107
+ }
108
+ }
109
+
110
+ // Quality gate: Computed attributes must have BR-CALC (C11 — BLOCKING)
111
+ for (const e of ent) {
112
+ for (const a of (e.attributes || [])) {
113
+ if (a.computed === true) {
114
+ const hasBRCalc = brs.some(br =>
115
+ (br.category === 'calculation' || (br.id && br.id.includes('CALC'))) &&
116
+ (br.entities || []).includes(e.name)
117
+ );
118
+ if (!hasBRCalc) errors.push(mod.code + ": " + e.name + ".'" + a.name + "' is computed:true but no BR-CALC references " + e.name);
119
+ }
120
+ }
121
+ }
122
+
123
+ // Quality gate: Versioned attributes detection (C15 — WARNING)
124
+ for (const e of ent) {
125
+ for (const a of (e.attributes || [])) {
126
+ if (['salary', 'rate', 'grade', 'price', 'tarif'].some(k => a.name.toLowerCase().includes(k))) {
127
+ if (!e.versionedAttributes?.length)
128
+ warnings.push(mod.code + ": " + e.name + ".'" + a.name + "' may need versioning but no versionedAttributes defined");
129
+ }
130
+ }
131
+ }
132
+ }
133
+
134
+ if (errors.length > 0) {
135
+ Display("POST-CHECK FAILED (" + errors.length + " errors):");
136
+ errors.forEach(e => Display(" ✗ " + e));
137
+ BLOCKING_ERROR("Fix all errors before advancing to step 04");
138
+ }
139
+ if (warnings.length > 0) {
140
+ Display("POST-CHECK warnings (" + warnings.length + "):");
141
+ warnings.forEach(w => Display(" ⚠ " + w));
142
+ }
143
+ Display("POST-CHECK PASS: " + modules.length + " modules validated");
144
+ ```
@@ -0,0 +1,32 @@
1
+ # SmartStack Entity Convention Guards (step-03-specify)
2
+
3
+ Before finalizing each entity, apply these rules:
4
+
5
+ ## B-bis-1. Person Extension Pattern
6
+
7
+ (ref: `entity-architecture-decision.md` section 0)
8
+
9
+ IF the entity matches a person role (Employee, Customer, Manager, Consultant, etc.):
10
+ - **DO NOT** add firstName, lastName, email, phoneNumber as direct attributes
11
+ - **DO** add `userId` (type: `string`, FK to auth_Users — ASP.NET Identity uses string IDs)
12
+ - **DO** add `personRoleConfig` metadata with variant (mandatory/optional)
13
+ - Personal fields come from User, not from the domain entity
14
+
15
+ ## B-bis-2. Versioned Sensitive Data
16
+
17
+ IF the entity has attributes that change over time with audit requirements (salary, rate, grade):
18
+ - **DO NOT** put them directly on the entity as single fields
19
+ - **DO** extract into a versioned satellite table (e.g., Employee → Salary with effectiveDate)
20
+ - Mark with `"versionedAttributes"` in entity spec
21
+
22
+ ## B-bis-3. SmartStack Socle Entities (NEVER redefine)
23
+
24
+ - Users/Identity → `auth_Users` (managed by SmartStack Identity)
25
+ - Tenants → `tenant_Tenants` (managed by SmartStack Core)
26
+ - Departments → `ref_Departments` or `rh_Departments` (check if exists in target DB)
27
+
28
+ ## B-bis-4. Foreign Key Conventions
29
+
30
+ - All FK attributes MUST end with `Id` suffix (e.g., `departmentId`, `userId`)
31
+ - FK to Identity users MUST use type `string` (ASP.NET Identity convention, NOT guid)
32
+ - FK to domain entities MUST use type `guid`
@@ -0,0 +1,95 @@
1
+ # Cross-Module Validation Rules
2
+
3
+ > **Purpose:** Define FK validation, circular dependency detection, and dependency graph checks
4
+ > that must be executed before consolidation approval.
5
+
6
+ ## Module Index Files & Granular Data Loading
7
+
8
+ For each completed module, read `index.json` and discover granular files:
9
+
10
+ ```javascript
11
+ const moduleFiles = {
12
+ entities: "entities.json",
13
+ rules: "rules.json",
14
+ usecases: "usecases.json",
15
+ permissions: "permissions.json",
16
+ screens: "screens.json"
17
+ };
18
+
19
+ for (const module of completedModules) {
20
+ const index = ba-reader.readSection(module.code, "index");
21
+ module.files = index.files;
22
+ // Load only files needed for consolidation
23
+ module.entities = ba-reader.readSection(module.code, "entities");
24
+ module.permissions = ba-reader.readSection(module.code, "permissions");
25
+ }
26
+ ```
27
+
28
+ ## Foreign Key References & Shared Entities Validation
29
+
30
+ Build entity registry and validate cross-module references:
31
+
32
+ ```javascript
33
+ const entityRegistry = {};
34
+ for (const module of completedModules) {
35
+ entityRegistry[module.code] = {
36
+ entities: module.entities.map(e => ({
37
+ name: e.name,
38
+ attributes: e.attributes.map(a => a.name),
39
+ pk: e.attributes.find(a => a.name === "Id" || a.unique)?.name || "Id"
40
+ }))
41
+ };
42
+ }
43
+
44
+ // Detect shared entities
45
+ const sharedEntities = [];
46
+ for (const module of completedModules) {
47
+ for (const entity of module.entities) {
48
+ for (const rel of entity.relationships || []) {
49
+ if (rel.target.includes(".")) {
50
+ const [targetModule, targetEntity] = rel.target.split(".");
51
+ if (!entityRegistry[targetModule]) {
52
+ BLOCKING_ERROR(`Module ${module.code}: references non-existent module "${targetModule}"`);
53
+ }
54
+ sharedEntities.push({
55
+ entity: targetEntity,
56
+ definedIn: targetModule,
57
+ referencedBy: module.code,
58
+ referenceType: rel.type
59
+ });
60
+ }
61
+ }
62
+ }
63
+ }
64
+ ```
65
+
66
+ ## Circular Dependency Detection
67
+
68
+ ```javascript
69
+ const cycles = detectCycles(dependencyGraph);
70
+ if (cycles.length > 0) {
71
+ BLOCKING_ERROR("Circular dependencies detected:");
72
+ for (const cycle of cycles) {
73
+ ERROR(` ${cycle.join(" → ")}`);
74
+ }
75
+ ACTIONS: Review dependencies, move shared entities to Core module, or use event-driven communication
76
+ STOP - DO NOT PROCEED
77
+ }
78
+ ```
79
+
80
+ ## Cross-Module Interactions Display
81
+
82
+ ```
83
+ ═══════════════════════════════════════════════════════════════
84
+ CROSS-MODULE INTERACTIONS VALIDATED
85
+ ═══════════════════════════════════════════════════════════════
86
+
87
+ | Source Module | Target | Type | Status |
88
+ |---------------|--------|------|--------|
89
+ | Orders | Customers.Customer | FK (N:1) | ✓ RESOLVED |
90
+ | Invoices | Customers.Customer | FK (N:1) | ✓ RESOLVED |
91
+
92
+ Total: {count} cross-module references
93
+ Shared entities: {count}
94
+ ═══════════════════════════════════════════════════════════════
95
+ ```
@@ -0,0 +1,162 @@
1
+ # File Allocation Rules
2
+
3
+ > **Critical reference:** Defines which validation data belongs in `consolidation.json` vs `validation.json`.
4
+ > Mixing contents across files is a BLOCKING ERROR.
5
+
6
+ ## Strict Allocation Table
7
+
8
+ ```
9
+ +==============================================================================+
10
+ | FILE ALLOCATION REFERENCE — MANDATORY |
11
+ +==============================================================================+
12
+ | |
13
+ | consolidation.json contient UNIQUEMENT : |
14
+ | - crossModuleInteractions |
15
+ | - sharedEntities |
16
+ | - permissionCoherence |
17
+ | - e2eFlows |
18
+ | - decision (approval) |
19
+ | |
20
+ | validation.json contient UNIQUEMENT : |
21
+ | - semanticChecks |
22
+ | - contractChecks |
23
+ | - namingAudit |
24
+ | - acceptanceCriteria |
25
+ | - globalRiskAssessment |
26
+ | |
27
+ | INTERDICTION de melanger les contenus entre les deux fichiers. |
28
+ | Toute cle ecrite dans le mauvais fichier = ERREUR BLOQUANTE. |
29
+ | |
30
+ +==============================================================================+
31
+ ```
32
+
33
+ ## Data Structures
34
+
35
+ ### consolidation.json structure
36
+
37
+ ```javascript
38
+ {
39
+ crossModuleInteractions: [
40
+ {
41
+ fromModule: string,
42
+ toModule: string,
43
+ interactionType: "FK-reference|event|shared-lookup",
44
+ description: string,
45
+ entities: string[]
46
+ }
47
+ ],
48
+ sharedEntities: [
49
+ {
50
+ entity: string,
51
+ ownerModule: string,
52
+ referencedBy: string[],
53
+ sharedFields: string[]
54
+ }
55
+ ],
56
+ permissionCoherence: {
57
+ rolesConsistent: boolean,
58
+ pathFormatConsistent: boolean,
59
+ hierarchyRespected: boolean,
60
+ conflicts: any[],
61
+ warnings: any[]
62
+ },
63
+ e2eFlows: [
64
+ {
65
+ name: string,
66
+ modules: string[],
67
+ steps: object[]
68
+ }
69
+ ],
70
+ decision: {
71
+ approved: boolean,
72
+ reason: string,
73
+ approvedBy: string,
74
+ approvedAt: string
75
+ }
76
+ }
77
+ ```
78
+
79
+ ### validation.json structure
80
+
81
+ ```javascript
82
+ {
83
+ semanticChecks: [
84
+ {
85
+ check: string,
86
+ status: "PASS|WARNING|ERROR",
87
+ details: string[]
88
+ }
89
+ ],
90
+ contractChecks: [
91
+ {
92
+ module: string,
93
+ check: string,
94
+ details: string
95
+ }
96
+ ],
97
+ namingAudit: {
98
+ auditedAt: string,
99
+ issues: object[],
100
+ approved: boolean,
101
+ renames: object[]
102
+ },
103
+ acceptanceCriteria: [
104
+ {
105
+ module: string,
106
+ criteria: string,
107
+ type: "functional|business-rule|performance|security"
108
+ }
109
+ ],
110
+ globalRiskAssessment: [
111
+ {
112
+ risk: string,
113
+ severity: "low|medium|high",
114
+ mitigation?: string
115
+ }
116
+ ]
117
+ }
118
+ ```
119
+
120
+ ## Data Writing Pattern
121
+
122
+ Write consolidation.json:
123
+ ```javascript
124
+ ba-writer.enrichSection({
125
+ featureId: {feature_id},
126
+ section: "consolidation",
127
+ data: {
128
+ crossModuleInteractions: [...],
129
+ sharedEntities: [...],
130
+ permissionCoherence: {...},
131
+ e2eFlows: [...],
132
+ decision: {...}
133
+ }
134
+ });
135
+ ```
136
+
137
+ Write validation.json:
138
+ ```javascript
139
+ ba-writer.enrichSection({
140
+ featureId: {feature_id},
141
+ section: "validation",
142
+ data: {
143
+ semanticChecks: [...],
144
+ contractChecks: [...],
145
+ namingAudit: {...},
146
+ acceptanceCriteria: [...],
147
+ globalRiskAssessment: [...]
148
+ }
149
+ });
150
+ ```
151
+
152
+ ## Validation Checklist
153
+
154
+ Before writing either file, verify:
155
+
156
+ - ✓ No keys from consolidation.json appear in validation.json
157
+ - ✓ No keys from validation.json appear in consolidation.json
158
+ - ✓ All cross-module FK references are in consolidation.json (not validation.json)
159
+ - ✓ All semantic check results are in validation.json (not consolidation.json)
160
+ - ✓ All naming audit results are in validation.json (not consolidation.json)
161
+ - ✓ Client approval decision is in consolidation.json (not validation.json)
162
+ - ✓ Risk assessment is in validation.json (not consolidation.json)
@@ -0,0 +1,174 @@
1
+ # Naming Audit Checks
2
+
3
+ > **Purpose:** Validate that all application names, module codes, entity names, and permission paths follow conventions,
4
+ > derive logically from their labels, and are free of collisions.
5
+
6
+ ## Naming Registry Collection
7
+
8
+ Collect all names from the BA:
9
+
10
+ ```javascript
11
+ const namingRegistry = {
12
+ application: {
13
+ label: application_name,
14
+ code: applicationCode, // PascalCase
15
+ route: toKebabCase(applicationCode) // kebab-case
16
+ },
17
+ modules: completedModules.map(m => ({
18
+ label: m.name,
19
+ code: m.code, // PascalCase
20
+ route: toKebabCase(m.code) // kebab-case
21
+ })),
22
+ entities: completedModules.flatMap(m =>
23
+ m.entities.map(e => ({
24
+ name: e.name, // PascalCase (C# class name)
25
+ module: m.code,
26
+ tableName: e.tableName || pluralize(e.name) // Plural convention
27
+ }))
28
+ ),
29
+ permissionRoots: [...new Set(
30
+ permissionPaths.map(p => p.path.split('.').slice(0, 2).join('.'))
31
+ )]
32
+ };
33
+ ```
34
+
35
+ ## Naming Recap Display
36
+
37
+ ```
38
+ ═══════════════════════════════════════════════════════════════
39
+ NAMING AUDIT — {application_name}
40
+ ═══════════════════════════════════════════════════════════════
41
+
42
+ APPLICATION
43
+ | Label | Code (PascalCase) | Route (kebab-case) |
44
+ |-------|-------------------|--------------------|
45
+ | {application_name} | {applicationCode} | /{route} |
46
+
47
+ MODULES
48
+ | # | Label | Code (PascalCase) | Route (kebab-case) |
49
+ |---|-------|-------------------|--------------------|
50
+ {for each module: index | label | code | /app-route/module-route}
51
+
52
+ ENTITIES
53
+ | Entity (PascalCase) | Module | Table (plural) |
54
+ |----------------------|--------|----------------|
55
+ {for each entity: name | module | tableName}
56
+
57
+ PERMISSION ROOTS
58
+ {for each root: path}
59
+ ═══════════════════════════════════════════════════════════════
60
+ ```
61
+
62
+ ## Coherence Checks
63
+
64
+ ```javascript
65
+ const namingIssues = [];
66
+
67
+ // 1. Duplicate entity names across modules
68
+ const entityNames = namingRegistry.entities.map(e => e.name);
69
+ const duplicates = entityNames.filter((n, i) => entityNames.indexOf(n) !== i);
70
+ if (duplicates.length > 0) {
71
+ namingIssues.push({ severity: "ERROR", issue: `Duplicate entity names: ${[...new Set(duplicates)].join(', ')}` });
72
+ }
73
+
74
+ // 2. Module code vs label coherence (code should derive logically from label)
75
+ for (const mod of namingRegistry.modules) {
76
+ if (!mod.code || mod.code.length < 2) {
77
+ namingIssues.push({ severity: "ERROR", issue: `Module "${mod.label}" has invalid code: "${mod.code}"` });
78
+ }
79
+ }
80
+
81
+ // 3. Permission root alignment with module codes
82
+ for (const root of namingRegistry.permissionRoots) {
83
+ const [appSegment, moduleSegment] = root.split('.');
84
+ const matchingModule = namingRegistry.modules.find(m =>
85
+ m.code.toLowerCase() === moduleSegment.toLowerCase()
86
+ );
87
+ if (!matchingModule) {
88
+ namingIssues.push({ severity: "WARNING", issue: `Permission root "${root}" has no matching module code` });
89
+ }
90
+ }
91
+
92
+ // 4. Route collision detection
93
+ const allRoutes = namingRegistry.modules.map(m =>
94
+ `/${namingRegistry.application.route}/${m.route}`
95
+ );
96
+ const routeDuplicates = allRoutes.filter((r, i) => allRoutes.indexOf(r) !== i);
97
+ if (routeDuplicates.length > 0) {
98
+ namingIssues.push({ severity: "ERROR", issue: `Route collisions: ${routeDuplicates.join(', ')}` });
99
+ }
100
+ ```
101
+
102
+ ## MCP Validation
103
+
104
+ ```
105
+ mcp__smartstack__validate_conventions({
106
+ checks: ["tables"],
107
+ context: {
108
+ applicationCode: applicationCode,
109
+ modules: namingRegistry.modules.map(m => m.code),
110
+ entities: namingRegistry.entities.map(e => e.name)
111
+ }
112
+ })
113
+
114
+ → Merge MCP findings into namingIssues[]
115
+ ```
116
+
117
+ ## User Confirmation Flow
118
+
119
+ **IF namingIssues.length > 0:**
120
+
121
+ Display issues table:
122
+ ```
123
+ | # | Severity | Issue |
124
+ |---|----------|-------|
125
+ {for each issue}
126
+ ```
127
+
128
+ Ask via AskUserQuestion:
129
+ ```
130
+ question: "{language == 'fr'
131
+ ? 'Validez-vous les noms ci-dessus pour l\\'ensemble de l\\'application ?'
132
+ : 'Do you approve all the names above for the entire application?'}"
133
+ header: "Naming Audit"
134
+ options:
135
+ - label: "{language == 'fr' ? 'Approuvé' : 'Approved'}"
136
+ description: "{language == 'fr' ? 'Tous les noms sont corrects' : 'All names are correct'}"
137
+ - label: "{language == 'fr' ? 'Renommer certains éléments' : 'Rename some elements'}"
138
+ description: "{language == 'fr' ? 'Corriger des noms avant de finaliser' : 'Fix names before finalizing'}"
139
+ ```
140
+
141
+ **IF "Renommer certains éléments":**
142
+
143
+ Ask via AskUserQuestion (open-ended):
144
+ ```
145
+ question: "{language == 'fr'
146
+ ? 'Quels éléments souhaitez-vous renommer ? (ex: \"Module Ventes → Commerce\", \"Entity Invoice → BillingDocument\")'
147
+ : 'Which elements do you want to rename? (e.g., \"Module Sales → Commerce\", \"Entity Invoice → BillingDocument\")'}"
148
+ header: "Renaming"
149
+ ```
150
+
151
+ Process user response:
152
+ 1. Parse rename instructions
153
+ 2. Update `applicationCode`, module codes, entity names, permission paths accordingly in JSON files via ba-writer
154
+ 3. Re-run coherence checks on updated names
155
+ 4. Re-run MCP validation on updated names
156
+ 5. Re-display the naming recap table for final confirmation
157
+
158
+ **IF "Approuvé":**
159
+
160
+ Store naming audit result in `validation.json`:
161
+ ```javascript
162
+ ba-writer.enrichSection({
163
+ featureId: {feature_id},
164
+ section: "namingAudit",
165
+ data: {
166
+ auditedAt: now(),
167
+ issues: namingIssues,
168
+ approved: true,
169
+ renames: [] // or list of applied renames
170
+ }
171
+ });
172
+ ```
173
+
174
+ Continue to next section.