@atlashub/smartstack-cli 4.18.0 → 4.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/package.json +1 -1
  2. package/templates/agents/ba-reader.md +86 -80
  3. package/templates/agents/ba-writer.md +318 -415
  4. package/templates/agents/docs-context-reader.md +3 -3
  5. package/templates/mcp-scaffolding/frontend/nav-routes.ts.hbs +133 -0
  6. package/templates/mcp-scaffolding/frontend/routes.tsx.hbs +126 -0
  7. package/templates/skills/apex/SKILL.md +29 -16
  8. package/templates/skills/apex/_shared.md +62 -9
  9. package/templates/skills/apex/references/analysis-methods.md +8 -6
  10. package/templates/skills/apex/references/challenge-questions.md +5 -5
  11. package/templates/skills/apex/references/core-seed-data.md +68 -45
  12. package/templates/skills/apex/references/frontend-route-wiring-app-tsx.md +26 -21
  13. package/templates/skills/apex/references/parallel-execution.md +156 -0
  14. package/templates/skills/apex/references/person-extension-pattern.md +12 -12
  15. package/templates/skills/apex/references/post-checks.md +1748 -1726
  16. package/templates/skills/apex/references/smartstack-api.md +63 -57
  17. package/templates/skills/apex/references/smartstack-frontend-compliance.md +594 -0
  18. package/templates/skills/apex/references/smartstack-frontend.md +1246 -1842
  19. package/templates/skills/apex/references/smartstack-layers.md +98 -145
  20. package/templates/skills/apex/steps/step-00-init.md +30 -6
  21. package/templates/skills/apex/steps/step-01-analyze.md +27 -23
  22. package/templates/skills/apex/steps/step-02-plan.md +12 -12
  23. package/templates/skills/apex/steps/step-03-execute.md +198 -143
  24. package/templates/skills/apex/steps/step-04-examine.md +24 -93
  25. package/templates/skills/apex/steps/step-05-deep-review.md +16 -16
  26. package/templates/skills/apex/steps/step-06-resolve.md +9 -9
  27. package/templates/skills/apex/steps/step-07-tests.md +3 -1
  28. package/templates/skills/apex/steps/step-08-run-tests.md +1 -1
  29. package/templates/skills/business-analyse/SKILL.md +182 -301
  30. package/templates/skills/business-analyse/_shared.md +119 -336
  31. package/templates/skills/business-analyse/html/ba-interactive.html +706 -85
  32. package/templates/skills/business-analyse/html/build-html.js +41 -3
  33. package/templates/skills/business-analyse/html/src/partials/cadrage-context.html +34 -0
  34. package/templates/skills/business-analyse/html/src/partials/cadrage-risks.html +48 -0
  35. package/templates/skills/business-analyse/html/src/partials/cadrage-scope.html +49 -0
  36. package/templates/skills/business-analyse/html/src/partials/cadrage-stakeholders.html +55 -0
  37. package/templates/skills/business-analyse/html/src/partials/cadrage-success.html +34 -0
  38. package/templates/skills/business-analyse/html/src/partials/consol-datamodel.html +8 -0
  39. package/templates/skills/business-analyse/html/src/partials/consol-flows.html +29 -0
  40. package/templates/skills/business-analyse/html/src/partials/consol-interactions.html +8 -0
  41. package/templates/skills/business-analyse/html/src/partials/consol-permissions.html +8 -0
  42. package/templates/skills/business-analyse/html/src/partials/decomp-dependencies.html +38 -0
  43. package/templates/skills/business-analyse/html/src/partials/decomp-modules.html +51 -0
  44. package/templates/skills/business-analyse/html/src/partials/handoff-summary.html +24 -0
  45. package/templates/skills/business-analyse/html/src/partials/module-spec-container.html +4 -0
  46. package/templates/skills/business-analyse/html/src/scripts/01-data-init.js +17 -1
  47. package/templates/skills/business-analyse/html/src/scripts/02-navigation.js +32 -6
  48. package/templates/skills/business-analyse/html/src/scripts/05-render-specs.js +100 -63
  49. package/templates/skills/business-analyse/html/src/scripts/06-render-mockups.js +372 -0
  50. package/templates/skills/business-analyse/html/src/scripts/07-render-handoff.js +1 -1
  51. package/templates/skills/business-analyse/html/src/scripts/10-comments.js +41 -13
  52. package/templates/skills/business-analyse/html/src/styles/09-mockups-html.css +136 -0
  53. package/templates/skills/business-analyse/html/src/template.html +1 -1
  54. package/templates/skills/business-analyse/patterns/suggestion-catalog.md +7 -5
  55. package/templates/skills/business-analyse/questionnaire/01-context.md +11 -157
  56. package/templates/skills/business-analyse/questionnaire/02-stakeholders-scope.md +101 -0
  57. package/templates/skills/business-analyse/questionnaire/03-data-ui.md +92 -0
  58. package/templates/skills/business-analyse/questionnaire/04-risks-metrics.md +6 -0
  59. package/templates/skills/business-analyse/questionnaire/05-cross-module.md +69 -0
  60. package/templates/skills/business-analyse/questionnaire.md +22 -280
  61. package/templates/skills/business-analyse/react/application-viewer.md +2 -2
  62. package/templates/skills/business-analyse/react/components.md +4 -4
  63. package/templates/skills/business-analyse/react/i18n-template.md +1 -1
  64. package/templates/skills/business-analyse/react/schema.md +14 -14
  65. package/templates/skills/business-analyse/references/acceptance-criteria.md +21 -21
  66. package/templates/skills/business-analyse/references/analysis-semantic-checks.md +3 -3
  67. package/templates/skills/business-analyse/references/compilation-structure-cards.md +1 -1
  68. package/templates/skills/business-analyse/references/consolidation-structural-checks.md +5 -5
  69. package/templates/skills/business-analyse/references/deploy-data-build.md +12 -11
  70. package/templates/skills/business-analyse/references/deploy-modes.md +10 -10
  71. package/templates/skills/business-analyse/references/detection-strategies.md +6 -6
  72. package/templates/skills/business-analyse/references/html-data-mapping.md +15 -15
  73. package/templates/skills/business-analyse/references/naming-conventions.md +4 -4
  74. package/templates/skills/business-analyse/references/review-data-mapping.md +29 -29
  75. package/templates/skills/business-analyse/references/robustness-checks.md +36 -36
  76. package/templates/skills/business-analyse/references/spec-auto-inference.md +2 -2
  77. package/templates/skills/business-analyse/references/ui-dashboard-spec.md +1 -1
  78. package/templates/skills/business-analyse/references/ui-resource-cards.md +1 -1
  79. package/templates/skills/business-analyse/references/validation-checklist.md +3 -3
  80. package/templates/skills/business-analyse/references/wireframe-svg-style-guide.md +2 -2
  81. package/templates/skills/business-analyse/schemas/application-schema.json +8 -8
  82. package/templates/skills/business-analyse/schemas/feature-schema.json +3 -3
  83. package/templates/skills/business-analyse/schemas/index-schema.json +47 -0
  84. package/templates/skills/business-analyse/schemas/project-schema.json +6 -6
  85. package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +1 -1
  86. package/templates/skills/business-analyse/schemas/sections/handoff-schema.json +5 -3
  87. package/templates/skills/business-analyse/schemas/sections/metadata-schema.json +4 -4
  88. package/templates/skills/business-analyse/schemas/sections/specification-schema.json +1 -1
  89. package/templates/skills/business-analyse/schemas/shared/common-defs.json +4 -4
  90. package/templates/skills/business-analyse/steps/step-00-init.md +68 -77
  91. package/templates/skills/business-analyse/steps/step-01-cadrage.md +50 -216
  92. package/templates/skills/business-analyse/steps/step-02-structure.md +175 -0
  93. package/templates/skills/business-analyse/steps/step-03-specify.md +198 -0
  94. package/templates/skills/business-analyse/steps/step-04-consolidate.md +478 -0
  95. package/templates/skills/business-analyse/steps/step-05-deploy.md +220 -0
  96. package/templates/skills/business-analyse/steps/step-06-review.md +51 -69
  97. package/templates/skills/business-analyse/templates/tpl-frd.md +1 -1
  98. package/templates/skills/business-analyse/templates/tpl-handoff.md +20 -17
  99. package/templates/skills/business-analyse/templates/tpl-launch-displays.md +2 -2
  100. package/templates/skills/business-analyse/templates-react.md +2 -2
  101. package/templates/skills/derive-prd/SKILL.md +92 -0
  102. package/templates/skills/derive-prd/references/acceptance-criteria.md +169 -0
  103. package/templates/skills/derive-prd/references/entity-domain-mapping.md +115 -0
  104. package/templates/skills/{business-analyse → derive-prd}/references/handoff-file-templates.md +131 -120
  105. package/templates/skills/{business-analyse → derive-prd}/references/handoff-mappings.md +95 -95
  106. package/templates/skills/{business-analyse → derive-prd}/references/handoff-seeddata-generation.md +312 -312
  107. package/templates/skills/{business-analyse → derive-prd}/references/prd-generation.md +262 -263
  108. package/templates/skills/derive-prd/references/readiness-scoring.md +104 -0
  109. package/templates/skills/derive-prd/schemas/handoff-schema.json +95 -0
  110. package/templates/skills/derive-prd/steps/step-00-validate.md +130 -0
  111. package/templates/skills/derive-prd/steps/step-01-transform.md +206 -0
  112. package/templates/skills/derive-prd/steps/step-02-export.md +181 -0
  113. package/templates/skills/{business-analyse → derive-prd}/templates/tpl-progress.md +172 -172
  114. package/templates/skills/documentation/SKILL.md +7 -0
  115. package/templates/skills/ralph-loop/SKILL.md +2 -1
  116. package/templates/skills/ralph-loop/references/init-resume-recovery.md +1 -1
  117. package/templates/skills/ralph-loop/steps/step-01-task.md +2 -2
  118. package/templates/skills/apex/references/agent-teams-protocol.md +0 -203
  119. package/templates/skills/business-analyse/_architecture.md +0 -124
  120. package/templates/skills/business-analyse/_elicitation.md +0 -206
  121. package/templates/skills/business-analyse/_module-loop.md +0 -115
  122. package/templates/skills/business-analyse/_rules.md +0 -142
  123. package/templates/skills/business-analyse/_suggestions.md +0 -34
  124. package/templates/skills/business-analyse/questionnaire/00-application.md +0 -160
  125. package/templates/skills/business-analyse/questionnaire/00b-project.md +0 -85
  126. package/templates/skills/business-analyse/questionnaire/02-stakeholders.md +0 -189
  127. package/templates/skills/business-analyse/questionnaire/03-scope.md +0 -164
  128. package/templates/skills/business-analyse/questionnaire/04-data.md +0 -88
  129. package/templates/skills/business-analyse/questionnaire/05-integrations.md +0 -58
  130. package/templates/skills/business-analyse/questionnaire/06-security.md +0 -68
  131. package/templates/skills/business-analyse/questionnaire/07-ui.md +0 -76
  132. package/templates/skills/business-analyse/questionnaire/08-performance.md +0 -42
  133. package/templates/skills/business-analyse/questionnaire/09-constraints.md +0 -45
  134. package/templates/skills/business-analyse/questionnaire/10-documentation.md +0 -58
  135. package/templates/skills/business-analyse/questionnaire/11-data-lifecycle.md +0 -59
  136. package/templates/skills/business-analyse/questionnaire/12-migration.md +0 -58
  137. package/templates/skills/business-analyse/questionnaire/13-cross-module.md +0 -69
  138. package/templates/skills/business-analyse/questionnaire/14-risk-assumptions.md +0 -135
  139. package/templates/skills/business-analyse/questionnaire/15-success-metrics.md +0 -136
  140. package/templates/skills/business-analyse/references/agent-module-prompt.md +0 -366
  141. package/templates/skills/business-analyse/references/agent-pooling-best-practices.md +0 -557
  142. package/templates/skills/business-analyse/references/cache-warming-strategy.md +0 -566
  143. package/templates/skills/business-analyse/references/cadrage-challenge-patterns.md +0 -41
  144. package/templates/skills/business-analyse/references/cadrage-coverage-matrix.md +0 -74
  145. package/templates/skills/business-analyse/references/cadrage-pre-analysis.md +0 -115
  146. package/templates/skills/business-analyse/references/cadrage-shared-modules.md +0 -68
  147. package/templates/skills/business-analyse/references/cadrage-structure-cards.md +0 -85
  148. package/templates/skills/business-analyse/references/team-orchestration.md +0 -1093
  149. package/templates/skills/business-analyse/references/validate-incremental-html.md +0 -121
  150. package/templates/skills/business-analyse/steps/step-01b-applications.md +0 -419
  151. package/templates/skills/business-analyse/steps/step-02-decomposition.md +0 -387
  152. package/templates/skills/business-analyse/steps/step-03a-data.md +0 -16
  153. package/templates/skills/business-analyse/steps/step-03a1-setup.md +0 -486
  154. package/templates/skills/business-analyse/steps/step-03a2-analysis.md +0 -300
  155. package/templates/skills/business-analyse/steps/step-03b-ui.md +0 -405
  156. package/templates/skills/business-analyse/steps/step-03c-compile.md +0 -516
  157. package/templates/skills/business-analyse/steps/step-03d-validate.md +0 -691
  158. package/templates/skills/business-analyse/steps/step-04-consolidation.md +0 -17
  159. package/templates/skills/business-analyse/steps/step-04a-collect.md +0 -415
  160. package/templates/skills/business-analyse/steps/step-04b-analyze.md +0 -163
  161. package/templates/skills/business-analyse/steps/step-04c-decide.md +0 -186
  162. package/templates/skills/business-analyse/steps/step-05a-handoff.md +0 -937
  163. package/templates/skills/business-analyse/steps/step-05b-deploy.md +0 -522
  164. package/templates/skills/business-analyse/steps/step-05c-ralph-readiness.md +0 -703
@@ -1,312 +1,312 @@
1
- # SeedData Core Generation for Handoff
2
-
3
- Complete reference for generating `seedDataCore` from feature.json modules, application roles, and coverage matrix.
4
-
5
- ## Helper Functions
6
-
7
- ### PascalCase to Human Readable
8
-
9
- ```javascript
10
- function toHumanReadable(pascalCase) {
11
- return pascalCase
12
- .replace(/([a-z])([A-Z])/g, '$1 $2')
13
- .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2');
14
- }
15
- ```
16
-
17
- ### PascalCase to Kebab Case
18
-
19
- ```javascript
20
- function toKebabCase(code) {
21
- return code
22
- .replace(/([a-z])([A-Z])/g, '$1-$2')
23
- .toLowerCase();
24
- }
25
- ```
26
-
27
- ## SeedDataCore Template
28
-
29
- ```javascript
30
- const appCode = master.metadata.application;
31
- const appLabel = toHumanReadable(appCode);
32
- const appDesc = master.cadrage?.problem?.split('.')[0] || `Gestion ${appLabel}`;
33
- const lang = master.metadata.language || "fr";
34
-
35
- const seedDataCore = {
36
- // Application-level navigation (MANDATORY — one entry per application)
37
- navigationApplications: (() => {
38
- if (workflow.mode === "project") {
39
- // Multi-app: one navigation entry per application
40
- return projectFeature.applications.map((app, idx) => {
41
- const appLabel = toHumanReadable(app.code);
42
- return {
43
- code: app.code.toLowerCase(),
44
- name: app.code,
45
- labels: {
46
- fr: lang === "fr" ? (app.name || appLabel) : appLabel,
47
- en: lang === "en" ? (app.name || appLabel) : appLabel,
48
- it: appLabel,
49
- de: appLabel
50
- },
51
- description: {
52
- fr: lang === "fr" ? (app.description || `Gestion ${appLabel}`) : `Gestion ${appLabel}`,
53
- en: lang === "en" ? (app.description || `${appLabel} management`) : `${appLabel} management`,
54
- it: `Gestione ${appLabel}`,
55
- de: `${appLabel} Verwaltung`
56
- },
57
- icon: app.icon || inferIconFromApplication({ metadata: { application: app.code } }) || "layout-grid",
58
- iconType: "lucide",
59
- route: `/${toKebabCase(app.code)}`,
60
- displayOrder: (idx + 1) * 10
61
- };
62
- });
63
- } else {
64
- // Single-app: one navigation entry
65
- return [{
66
- code: appCode.toLowerCase(),
67
- name: appCode,
68
- labels: {
69
- fr: lang === "fr" ? (master.cadrage?.applicationName || appLabel) : appLabel,
70
- en: lang === "en" ? (master.cadrage?.applicationName || appLabel) : appLabel,
71
- it: appLabel,
72
- de: appLabel
73
- },
74
- description: {
75
- fr: lang === "fr" ? appDesc : `Gestion ${appLabel}`,
76
- en: lang === "en" ? appDesc : `${appLabel} management`,
77
- it: `Gestione ${appLabel}`,
78
- de: `${appLabel} Verwaltung`
79
- },
80
- icon: inferIconFromApplication(master) || "layout-grid",
81
- iconType: "lucide",
82
- route: `/${toKebabCase(appCode)}`,
83
- displayOrder: 1
84
- }];
85
- }
86
- })(),
87
-
88
- navigationModules: (() => {
89
- if (workflow.mode === "project") {
90
- let order = 0;
91
- return projectFeature.applications.flatMap(app => {
92
- return (app.modules || []).map(m => ({
93
- code: m.code,
94
- applicationCode: app.code,
95
- label: m.name || m.code,
96
- description: m.description,
97
- icon: inferIconFromModule(m) || "folder",
98
- iconType: "lucide",
99
- route: `/${toKebabCase(app.code)}/${toKebabCase(m.code)}`,
100
- displayOrder: (++order) * 10
101
- }));
102
- });
103
- } else {
104
- return master.modules.map((m, i) => ({
105
- code: m.code,
106
- label: m.name || m.code,
107
- description: m.description,
108
- icon: inferIconFromModule(m) || "folder",
109
- iconType: "lucide",
110
- route: `/${toKebabCase(appCode)}/${toKebabCase(m.code)}`,
111
- displayOrder: (i + 1) * 10
112
- }));
113
- }
114
- })(),
115
-
116
- navigationSections: (() => {
117
- const buildSections = (modules, appCode) =>
118
- modules.flatMap(m =>
119
- (m.anticipatedSections || []).map((s, j) => ({
120
- moduleCode: m.code,
121
- code: s.code,
122
- label: s.description?.split(':')[0] || s.code,
123
- description: s.description || "",
124
- route: s.code === "list"
125
- ? `/${toKebabCase(appCode)}/${toKebabCase(m.code)}`
126
- : s.code === "detail"
127
- ? `/${toKebabCase(appCode)}/${toKebabCase(m.code)}/:id`
128
- : `/${toKebabCase(appCode)}/${toKebabCase(m.code)}/${toKebabCase(s.code)}`,
129
- displayOrder: (j + 1) * 10,
130
- navigation: s.code === "detail" ? "hidden" : "visible"
131
- }))
132
- );
133
-
134
- if (workflow.mode === "project") {
135
- return projectFeature.applications.flatMap(app =>
136
- buildSections(app.modules || [], app.code)
137
- );
138
- } else {
139
- return buildSections(master.modules, appCode);
140
- }
141
- })(),
142
-
143
- navigationResources: master.cadrage.coverageMatrix
144
- .filter(cm => cm.module && cm.anticipatedResources?.length > 0)
145
- .flatMap(cm =>
146
- cm.anticipatedResources.map((r, k) => ({
147
- moduleCode: cm.module,
148
- sectionCode: cm.anticipatedSections?.[0] || "list",
149
- code: r,
150
- label: r.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase()),
151
- displayOrder: (k + 1) * 10
152
- }))
153
- ),
154
-
155
- navigationTranslations: master.modules.flatMap(m => {
156
- const langs = ["fr", "en", "it", "de"];
157
- return langs.map(lang => ({
158
- moduleCode: m.code,
159
- language: lang,
160
- label: lang === master.metadata.language ? (m.name || m.code) : m.code,
161
- description: lang === master.metadata.language ? m.description : ""
162
- }));
163
- }),
164
-
165
- permissions: (() => {
166
- const buildPermissions = (modules, appCode) =>
167
- modules.flatMap(m => {
168
- const basePath = `${toKebabCase(appCode)}.${toKebabCase(m.code)}`;
169
- const actions = ['read', 'create', 'update', 'delete'];
170
- return [
171
- { path: `${basePath}.*`, action: '*', description: `Full ${m.name || m.code} access` },
172
- ...actions.map(action => ({
173
- path: `${basePath}.${action}`,
174
- action: action,
175
- description: `${action.charAt(0).toUpperCase() + action.slice(1)} ${m.name || m.code}`
176
- }))
177
- ];
178
- });
179
-
180
- if (workflow.mode === "project") {
181
- return projectFeature.applications.flatMap(app =>
182
- buildPermissions(app.modules || [], app.code)
183
- );
184
- } else {
185
- return buildPermissions(master.modules, appCode);
186
- }
187
- })(),
188
-
189
- rolePermissions: (() => {
190
- const buildRolePermissions = (roles, modules, appCode) =>
191
- roles.map(role => ({
192
- role: role.role,
193
- level: role.level,
194
- permissions: modules.map(m => `${toKebabCase(appCode)}.${toKebabCase(m.code)}.${
195
- role.level === 'admin' ? '*' :
196
- role.level === 'manager' ? 'read,create,update' :
197
- role.level === 'contributor' ? 'read,create' : 'read'
198
- }`)
199
- }));
200
-
201
- if (workflow.mode === "project") {
202
- return projectFeature.applications.flatMap(app =>
203
- buildRolePermissions(app.applicationRoles || [], app.modules || [], app.code)
204
- );
205
- } else {
206
- return buildRolePermissions(master.cadrage.applicationRoles, master.modules, appCode);
207
- }
208
- })(),
209
-
210
- permissionConstants: (() => {
211
- const buildConstants = (modules, appCode) =>
212
- modules.flatMap(m =>
213
- ['Read', 'Create', 'Update', 'Delete', 'Validate', 'Export'].map(action => ({
214
- module: m.code,
215
- application: appCode,
216
- action: action,
217
- constant: `${appCode}${m.code}${action}`,
218
- path: `${toKebabCase(appCode)}.${toKebabCase(m.code)}.${action.toLowerCase()}`
219
- }))
220
- );
221
-
222
- if (workflow.mode === "project") {
223
- return projectFeature.applications.flatMap(app =>
224
- buildConstants(app.modules || [], app.code)
225
- );
226
- } else {
227
- return buildConstants(master.modules, appCode);
228
- }
229
- })()
230
- };
231
- ```
232
-
233
- ## Icon Inference Functions
234
-
235
- ### Application Level
236
-
237
- ```javascript
238
- function inferIconFromApplication(master) {
239
- const appLC = (master.metadata.application || '').toLowerCase();
240
- const iconMap = {
241
- 'humanresource': 'users', 'rh': 'users', 'hr': 'users', 'personnel': 'users',
242
- 'sales': 'shopping-cart', 'vente': 'shopping-cart', 'commerce': 'shopping-cart',
243
- 'finance': 'wallet', 'comptabilite': 'calculator', 'accounting': 'calculator',
244
- 'inventory': 'warehouse', 'stock': 'package', 'logistic': 'truck',
245
- 'crm': 'building-2', 'customer': 'building', 'client': 'building-2',
246
- 'project': 'folder-kanban', 'task': 'check-square', 'gestion': 'layout-grid',
247
- 'admin': 'shield', 'support': 'headphones', 'maintenance': 'wrench',
248
- 'production': 'factory', 'quality': 'badge-check', 'document': 'file-text',
249
- 'fleet': 'car', 'vehicle': 'car', 'transport': 'truck',
250
- 'education': 'graduation-cap', 'formation': 'graduation-cap', 'training': 'graduation-cap'
251
- };
252
- for (const [keyword, icon] of Object.entries(iconMap)) {
253
- if (appLC.includes(keyword)) return icon;
254
- }
255
- return "layout-grid"; // fallback — NEVER null
256
- }
257
- ```
258
-
259
- ### Module Level
260
-
261
- ```javascript
262
- function inferIconFromModule(module) {
263
- const codeLC = module.code.toLowerCase();
264
- const iconMap = {
265
- 'employee': 'users', 'staff': 'users', 'personnel': 'users', 'user': 'users',
266
- 'project': 'folder-kanban', 'task': 'check-square', 'work': 'briefcase',
267
- 'time': 'clock', 'schedule': 'calendar', 'planning': 'calendar-days',
268
- 'absence': 'calendar-off', 'leave': 'calendar-off', 'vacation': 'palm-tree',
269
- 'finance': 'wallet', 'billing': 'receipt', 'invoice': 'file-text',
270
- 'inventory': 'warehouse', 'stock': 'package', 'product': 'shopping-bag',
271
- 'customer': 'building', 'client': 'building-2', 'contact': 'contact',
272
- 'report': 'bar-chart', 'dashboard': 'layout-dashboard', 'analytics': 'trending-up',
273
- 'document': 'file-text', 'notification': 'bell', 'setting': 'settings',
274
- 'order': 'shopping-cart', 'vehicle': 'car', 'maintenance': 'wrench',
275
- 'audit': 'shield-check', 'workflow': 'git-branch', 'approval': 'check-circle'
276
- };
277
- for (const [keyword, icon] of Object.entries(iconMap)) {
278
- if (codeLC.includes(keyword)) return icon;
279
- }
280
- return "folder"; // fallback — NEVER null
281
- }
282
- ```
283
-
284
- ## POST-CHECK (BLOCKING for icons/application, warning for counts)
285
-
286
- ```javascript
287
- IF !seedDataCore.navigationApplications || seedDataCore.navigationApplications.length === 0:
288
- BLOCKING ERROR: "navigationApplications is empty — Application navigation will NOT be seeded. Menu will show (nothing) → Modules."
289
- IF seedDataCore.navigationApplications[0].icon === null || seedDataCore.navigationApplications[0].icon === undefined:
290
- BLOCKING ERROR: "Application icon is null — ralph-loop will render empty navigation"
291
- IF !seedDataCore.navigationApplications[0].labels?.fr || !seedDataCore.navigationApplications[0].labels?.en:
292
- BLOCKING ERROR: "Application labels missing fr/en — translations will fail"
293
- IF seedDataCore.navigationModules.length !== master.modules.length:
294
- WARNING: seedDataCore has ${seedDataCore.navigationModules.length} nav modules but ${master.modules.length} modules exist
295
- IF seedDataCore.permissions.length === 0:
296
- WARNING: seedDataCore has 0 permissions — applicationRoles may be missing
297
- IF seedDataCore.navigationModules.some(m => !m.icon || m.icon === null):
298
- BLOCKING ERROR: "Navigation modules with null icons detected — ralph-loop will render empty navigation"
299
- → Fix: Re-run inferIconFromModule() for modules with null icons
300
- IF seedDataCore.navigationSections.length === 0:
301
- WARNING: "0 navigation sections — every module should have at least 1 section (e.g., 'list')"
302
- ```
303
-
304
- ## Writing to Feature.json
305
-
306
- ```javascript
307
- ba-writer.enrichSection({
308
- featureId: {feature_id},
309
- section: "seedDataCore",
310
- data: seedDataCore
311
- })
312
- ```
1
+ # SeedData Core Generation for Handoff
2
+
3
+ Complete reference for generating `seedDataCore` from module JSON files, application roles, and coverage matrix.
4
+
5
+ ## Helper Functions
6
+
7
+ ### PascalCase to Human Readable
8
+
9
+ ```javascript
10
+ function toHumanReadable(pascalCase) {
11
+ return pascalCase
12
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
13
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2');
14
+ }
15
+ ```
16
+
17
+ ### PascalCase to Kebab Case
18
+
19
+ ```javascript
20
+ function toKebabCase(code) {
21
+ return code
22
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
23
+ .toLowerCase();
24
+ }
25
+ ```
26
+
27
+ ## SeedDataCore Template
28
+
29
+ ```javascript
30
+ const appCode = master.metadata.application;
31
+ const appLabel = toHumanReadable(appCode);
32
+ const appDesc = master.cadrage?.problem?.split('.')[0] || `Gestion ${appLabel}`;
33
+ const lang = master.metadata.language || "fr";
34
+
35
+ const seedDataCore = {
36
+ // Application-level navigation (MANDATORY — one entry per application)
37
+ navigationApplications: (() => {
38
+ if (workflow.mode === "project") {
39
+ // Multi-app: one navigation entry per application
40
+ return projectFeature.applications.map((app, idx) => {
41
+ const appLabel = toHumanReadable(app.code);
42
+ return {
43
+ code: app.code.toLowerCase(),
44
+ name: app.code,
45
+ labels: {
46
+ fr: lang === "fr" ? (app.name || appLabel) : appLabel,
47
+ en: lang === "en" ? (app.name || appLabel) : appLabel,
48
+ it: appLabel,
49
+ de: appLabel
50
+ },
51
+ description: {
52
+ fr: lang === "fr" ? (app.description || `Gestion ${appLabel}`) : `Gestion ${appLabel}`,
53
+ en: lang === "en" ? (app.description || `${appLabel} management`) : `${appLabel} management`,
54
+ it: `Gestione ${appLabel}`,
55
+ de: `${appLabel} Verwaltung`
56
+ },
57
+ icon: app.icon || inferIconFromApplication({ metadata: { application: app.code } }) || "layout-grid",
58
+ iconType: "lucide",
59
+ route: `/${toKebabCase(app.code)}`,
60
+ displayOrder: (idx + 1) * 10
61
+ };
62
+ });
63
+ } else {
64
+ // Single-app: one navigation entry
65
+ return [{
66
+ code: appCode.toLowerCase(),
67
+ name: appCode,
68
+ labels: {
69
+ fr: lang === "fr" ? (master.cadrage?.applicationName || appLabel) : appLabel,
70
+ en: lang === "en" ? (master.cadrage?.applicationName || appLabel) : appLabel,
71
+ it: appLabel,
72
+ de: appLabel
73
+ },
74
+ description: {
75
+ fr: lang === "fr" ? appDesc : `Gestion ${appLabel}`,
76
+ en: lang === "en" ? appDesc : `${appLabel} management`,
77
+ it: `Gestione ${appLabel}`,
78
+ de: `${appLabel} Verwaltung`
79
+ },
80
+ icon: inferIconFromApplication(master) || "layout-grid",
81
+ iconType: "lucide",
82
+ route: `/${toKebabCase(appCode)}`,
83
+ displayOrder: 1
84
+ }];
85
+ }
86
+ })(),
87
+
88
+ navigationModules: (() => {
89
+ if (workflow.mode === "project") {
90
+ let order = 0;
91
+ return projectFeature.applications.flatMap(app => {
92
+ return (app.modules || []).map(m => ({
93
+ code: m.code,
94
+ applicationCode: app.code,
95
+ label: m.name || m.code,
96
+ description: m.description,
97
+ icon: inferIconFromModule(m) || "folder",
98
+ iconType: "lucide",
99
+ route: `/${toKebabCase(app.code)}/${toKebabCase(m.code)}`,
100
+ displayOrder: (++order) * 10
101
+ }));
102
+ });
103
+ } else {
104
+ return master.modules.map((m, i) => ({
105
+ code: m.code,
106
+ label: m.name || m.code,
107
+ description: m.description,
108
+ icon: inferIconFromModule(m) || "folder",
109
+ iconType: "lucide",
110
+ route: `/${toKebabCase(appCode)}/${toKebabCase(m.code)}`,
111
+ displayOrder: (i + 1) * 10
112
+ }));
113
+ }
114
+ })(),
115
+
116
+ navigationSections: (() => {
117
+ const buildSections = (modules, appCode) =>
118
+ modules.flatMap(m =>
119
+ (m.anticipatedSections || []).map((s, j) => ({
120
+ moduleCode: m.code,
121
+ code: s.code,
122
+ label: s.description?.split(':')[0] || s.code,
123
+ description: s.description || "",
124
+ route: s.code === "list"
125
+ ? `/${toKebabCase(appCode)}/${toKebabCase(m.code)}`
126
+ : s.code === "detail"
127
+ ? `/${toKebabCase(appCode)}/${toKebabCase(m.code)}/:id`
128
+ : `/${toKebabCase(appCode)}/${toKebabCase(m.code)}/${toKebabCase(s.code)}`,
129
+ displayOrder: (j + 1) * 10,
130
+ navigation: s.code === "detail" ? "hidden" : "visible"
131
+ }))
132
+ );
133
+
134
+ if (workflow.mode === "project") {
135
+ return projectFeature.applications.flatMap(app =>
136
+ buildSections(app.modules || [], app.code)
137
+ );
138
+ } else {
139
+ return buildSections(master.modules, appCode);
140
+ }
141
+ })(),
142
+
143
+ navigationResources: master.cadrage.coverageMatrix
144
+ .filter(cm => cm.module && cm.anticipatedResources?.length > 0)
145
+ .flatMap(cm =>
146
+ cm.anticipatedResources.map((r, k) => ({
147
+ moduleCode: cm.module,
148
+ sectionCode: cm.anticipatedSections?.[0] || "list",
149
+ code: r,
150
+ label: r.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase()),
151
+ displayOrder: (k + 1) * 10
152
+ }))
153
+ ),
154
+
155
+ navigationTranslations: master.modules.flatMap(m => {
156
+ const langs = ["fr", "en", "it", "de"];
157
+ return langs.map(lang => ({
158
+ moduleCode: m.code,
159
+ language: lang,
160
+ label: lang === master.metadata.language ? (m.name || m.code) : m.code,
161
+ description: lang === master.metadata.language ? m.description : ""
162
+ }));
163
+ }),
164
+
165
+ permissions: (() => {
166
+ const buildPermissions = (modules, appCode) =>
167
+ modules.flatMap(m => {
168
+ const basePath = `${toKebabCase(appCode)}.${toKebabCase(m.code)}`;
169
+ const actions = ['read', 'create', 'update', 'delete'];
170
+ return [
171
+ { path: `${basePath}.*`, action: '*', description: `Full ${m.name || m.code} access` },
172
+ ...actions.map(action => ({
173
+ path: `${basePath}.${action}`,
174
+ action: action,
175
+ description: `${action.charAt(0).toUpperCase() + action.slice(1)} ${m.name || m.code}`
176
+ }))
177
+ ];
178
+ });
179
+
180
+ if (workflow.mode === "project") {
181
+ return projectFeature.applications.flatMap(app =>
182
+ buildPermissions(app.modules || [], app.code)
183
+ );
184
+ } else {
185
+ return buildPermissions(master.modules, appCode);
186
+ }
187
+ })(),
188
+
189
+ rolePermissions: (() => {
190
+ const buildRolePermissions = (roles, modules, appCode) =>
191
+ roles.map(role => ({
192
+ role: role.role,
193
+ level: role.level,
194
+ permissions: modules.map(m => `${toKebabCase(appCode)}.${toKebabCase(m.code)}.${
195
+ role.level === 'admin' ? '*' :
196
+ role.level === 'manager' ? 'read,create,update' :
197
+ role.level === 'contributor' ? 'read,create' : 'read'
198
+ }`)
199
+ }));
200
+
201
+ if (workflow.mode === "project") {
202
+ return projectFeature.applications.flatMap(app =>
203
+ buildRolePermissions(app.applicationRoles || [], app.modules || [], app.code)
204
+ );
205
+ } else {
206
+ return buildRolePermissions(master.cadrage.applicationRoles, master.modules, appCode);
207
+ }
208
+ })(),
209
+
210
+ permissionConstants: (() => {
211
+ const buildConstants = (modules, appCode) =>
212
+ modules.flatMap(m =>
213
+ ['Read', 'Create', 'Update', 'Delete', 'Validate', 'Export'].map(action => ({
214
+ module: m.code,
215
+ application: appCode,
216
+ action: action,
217
+ constant: `${appCode}${m.code}${action}`,
218
+ path: `${toKebabCase(appCode)}.${toKebabCase(m.code)}.${action.toLowerCase()}`
219
+ }))
220
+ );
221
+
222
+ if (workflow.mode === "project") {
223
+ return projectFeature.applications.flatMap(app =>
224
+ buildConstants(app.modules || [], app.code)
225
+ );
226
+ } else {
227
+ return buildConstants(master.modules, appCode);
228
+ }
229
+ })()
230
+ };
231
+ ```
232
+
233
+ ## Icon Inference Functions
234
+
235
+ ### Application Level
236
+
237
+ ```javascript
238
+ function inferIconFromApplication(master) {
239
+ const appLC = (master.metadata.application || '').toLowerCase();
240
+ const iconMap = {
241
+ 'humanresource': 'users', 'rh': 'users', 'hr': 'users', 'personnel': 'users',
242
+ 'sales': 'shopping-cart', 'vente': 'shopping-cart', 'commerce': 'shopping-cart',
243
+ 'finance': 'wallet', 'comptabilite': 'calculator', 'accounting': 'calculator',
244
+ 'inventory': 'warehouse', 'stock': 'package', 'logistic': 'truck',
245
+ 'crm': 'building-2', 'customer': 'building', 'client': 'building-2',
246
+ 'project': 'folder-kanban', 'task': 'check-square', 'gestion': 'layout-grid',
247
+ 'admin': 'shield', 'support': 'headphones', 'maintenance': 'wrench',
248
+ 'production': 'factory', 'quality': 'badge-check', 'document': 'file-text',
249
+ 'fleet': 'car', 'vehicle': 'car', 'transport': 'truck',
250
+ 'education': 'graduation-cap', 'formation': 'graduation-cap', 'training': 'graduation-cap'
251
+ };
252
+ for (const [keyword, icon] of Object.entries(iconMap)) {
253
+ if (appLC.includes(keyword)) return icon;
254
+ }
255
+ return "layout-grid"; // fallback — NEVER null
256
+ }
257
+ ```
258
+
259
+ ### Module Level
260
+
261
+ ```javascript
262
+ function inferIconFromModule(module) {
263
+ const codeLC = module.code.toLowerCase();
264
+ const iconMap = {
265
+ 'employee': 'users', 'staff': 'users', 'personnel': 'users', 'user': 'users',
266
+ 'project': 'folder-kanban', 'task': 'check-square', 'work': 'briefcase',
267
+ 'time': 'clock', 'schedule': 'calendar', 'planning': 'calendar-days',
268
+ 'absence': 'calendar-off', 'leave': 'calendar-off', 'vacation': 'palm-tree',
269
+ 'finance': 'wallet', 'billing': 'receipt', 'invoice': 'file-text',
270
+ 'inventory': 'warehouse', 'stock': 'package', 'product': 'shopping-bag',
271
+ 'customer': 'building', 'client': 'building-2', 'contact': 'contact',
272
+ 'report': 'bar-chart', 'dashboard': 'layout-dashboard', 'analytics': 'trending-up',
273
+ 'document': 'file-text', 'notification': 'bell', 'setting': 'settings',
274
+ 'order': 'shopping-cart', 'vehicle': 'car', 'maintenance': 'wrench',
275
+ 'audit': 'shield-check', 'workflow': 'git-branch', 'approval': 'check-circle'
276
+ };
277
+ for (const [keyword, icon] of Object.entries(iconMap)) {
278
+ if (codeLC.includes(keyword)) return icon;
279
+ }
280
+ return "folder"; // fallback — NEVER null
281
+ }
282
+ ```
283
+
284
+ ## POST-CHECK (BLOCKING for icons/application, warning for counts)
285
+
286
+ ```javascript
287
+ IF !seedDataCore.navigationApplications || seedDataCore.navigationApplications.length === 0:
288
+ BLOCKING ERROR: "navigationApplications is empty — Application navigation will NOT be seeded. Menu will show (nothing) → Modules."
289
+ IF seedDataCore.navigationApplications[0].icon === null || seedDataCore.navigationApplications[0].icon === undefined:
290
+ BLOCKING ERROR: "Application icon is null — ralph-loop will render empty navigation"
291
+ IF !seedDataCore.navigationApplications[0].labels?.fr || !seedDataCore.navigationApplications[0].labels?.en:
292
+ BLOCKING ERROR: "Application labels missing fr/en — translations will fail"
293
+ IF seedDataCore.navigationModules.length !== master.modules.length:
294
+ WARNING: seedDataCore has ${seedDataCore.navigationModules.length} nav modules but ${master.modules.length} modules exist
295
+ IF seedDataCore.permissions.length === 0:
296
+ WARNING: seedDataCore has 0 permissions — applicationRoles may be missing
297
+ IF seedDataCore.navigationModules.some(m => !m.icon || m.icon === null):
298
+ BLOCKING ERROR: "Navigation modules with null icons detected — ralph-loop will render empty navigation"
299
+ → Fix: Re-run inferIconFromModule() for modules with null icons
300
+ IF seedDataCore.navigationSections.length === 0:
301
+ WARNING: "0 navigation sections — every module should have at least 1 section (e.g., 'list')"
302
+ ```
303
+
304
+ ## Writing to index.json
305
+
306
+ ```javascript
307
+ ba-writer.enrichSection({
308
+ featureId: {feature_id},
309
+ section: "specification.seedDataCore",
310
+ data: seedDataCore
311
+ })
312
+ ```