@atlashub/smartstack-cli 4.18.0 → 4.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) 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 +703 -82
  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 +31 -5
  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/10-comments.js +41 -13
  51. package/templates/skills/business-analyse/html/src/styles/09-mockups-html.css +136 -0
  52. package/templates/skills/business-analyse/patterns/suggestion-catalog.md +7 -5
  53. package/templates/skills/business-analyse/questionnaire/02-stakeholders-scope.md +142 -0
  54. package/templates/skills/business-analyse/questionnaire/03-data-ui.md +94 -0
  55. package/templates/skills/business-analyse/questionnaire/04-risks-metrics.md +150 -0
  56. package/templates/skills/business-analyse/questionnaire/05-cross-module.md +69 -0
  57. package/templates/skills/business-analyse/questionnaire.md +23 -280
  58. package/templates/skills/business-analyse/react/application-viewer.md +2 -2
  59. package/templates/skills/business-analyse/react/components.md +4 -4
  60. package/templates/skills/business-analyse/react/i18n-template.md +1 -1
  61. package/templates/skills/business-analyse/react/schema.md +14 -14
  62. package/templates/skills/business-analyse/references/acceptance-criteria.md +21 -21
  63. package/templates/skills/business-analyse/references/analysis-semantic-checks.md +3 -3
  64. package/templates/skills/business-analyse/references/compilation-structure-cards.md +1 -1
  65. package/templates/skills/business-analyse/references/consolidation-structural-checks.md +5 -5
  66. package/templates/skills/business-analyse/references/deploy-data-build.md +12 -11
  67. package/templates/skills/business-analyse/references/deploy-modes.md +10 -10
  68. package/templates/skills/business-analyse/references/detection-strategies.md +6 -6
  69. package/templates/skills/business-analyse/references/html-data-mapping.md +15 -15
  70. package/templates/skills/business-analyse/references/naming-conventions.md +4 -4
  71. package/templates/skills/business-analyse/references/review-data-mapping.md +29 -29
  72. package/templates/skills/business-analyse/references/robustness-checks.md +36 -36
  73. package/templates/skills/business-analyse/references/spec-auto-inference.md +2 -2
  74. package/templates/skills/business-analyse/references/ui-dashboard-spec.md +1 -1
  75. package/templates/skills/business-analyse/references/ui-resource-cards.md +1 -1
  76. package/templates/skills/business-analyse/references/validation-checklist.md +3 -3
  77. package/templates/skills/business-analyse/references/wireframe-svg-style-guide.md +2 -2
  78. package/templates/skills/business-analyse/schemas/application-schema.json +8 -8
  79. package/templates/skills/business-analyse/schemas/feature-schema.json +3 -3
  80. package/templates/skills/business-analyse/schemas/index-schema.json +47 -0
  81. package/templates/skills/business-analyse/schemas/project-schema.json +6 -6
  82. package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +1 -1
  83. package/templates/skills/business-analyse/schemas/sections/handoff-schema.json +5 -3
  84. package/templates/skills/business-analyse/schemas/sections/metadata-schema.json +4 -4
  85. package/templates/skills/business-analyse/schemas/sections/specification-schema.json +1 -1
  86. package/templates/skills/business-analyse/schemas/shared/common-defs.json +4 -4
  87. package/templates/skills/business-analyse/steps/step-00-init.md +68 -77
  88. package/templates/skills/business-analyse/steps/step-01-cadrage.md +54 -180
  89. package/templates/skills/business-analyse/steps/step-02-structure.md +175 -0
  90. package/templates/skills/business-analyse/steps/step-03-specify.md +198 -0
  91. package/templates/skills/business-analyse/steps/step-04-consolidate.md +478 -0
  92. package/templates/skills/business-analyse/steps/step-05-deploy.md +220 -0
  93. package/templates/skills/business-analyse/steps/step-06-review.md +51 -69
  94. package/templates/skills/business-analyse/templates/tpl-frd.md +1 -1
  95. package/templates/skills/business-analyse/templates/tpl-handoff.md +20 -17
  96. package/templates/skills/business-analyse/templates/tpl-launch-displays.md +2 -2
  97. package/templates/skills/business-analyse/templates-react.md +2 -2
  98. package/templates/skills/derive-prd/SKILL.md +92 -0
  99. package/templates/skills/derive-prd/references/acceptance-criteria.md +169 -0
  100. package/templates/skills/derive-prd/references/entity-domain-mapping.md +115 -0
  101. package/templates/skills/{business-analyse → derive-prd}/references/handoff-file-templates.md +131 -120
  102. package/templates/skills/{business-analyse → derive-prd}/references/handoff-mappings.md +95 -95
  103. package/templates/skills/{business-analyse → derive-prd}/references/handoff-seeddata-generation.md +312 -312
  104. package/templates/skills/{business-analyse → derive-prd}/references/prd-generation.md +262 -263
  105. package/templates/skills/derive-prd/references/readiness-scoring.md +104 -0
  106. package/templates/skills/derive-prd/schemas/handoff-schema.json +95 -0
  107. package/templates/skills/derive-prd/steps/step-00-validate.md +130 -0
  108. package/templates/skills/derive-prd/steps/step-01-transform.md +206 -0
  109. package/templates/skills/derive-prd/steps/step-02-export.md +181 -0
  110. package/templates/skills/{business-analyse → derive-prd}/templates/tpl-progress.md +172 -172
  111. package/templates/skills/ralph-loop/SKILL.md +2 -1
  112. package/templates/skills/ralph-loop/references/init-resume-recovery.md +1 -1
  113. package/templates/skills/ralph-loop/steps/step-01-task.md +2 -2
  114. package/templates/skills/apex/references/agent-teams-protocol.md +0 -203
  115. package/templates/skills/business-analyse/_architecture.md +0 -124
  116. package/templates/skills/business-analyse/_elicitation.md +0 -206
  117. package/templates/skills/business-analyse/_module-loop.md +0 -115
  118. package/templates/skills/business-analyse/_rules.md +0 -142
  119. package/templates/skills/business-analyse/_suggestions.md +0 -34
  120. package/templates/skills/business-analyse/questionnaire/00-application.md +0 -160
  121. package/templates/skills/business-analyse/questionnaire/00b-project.md +0 -85
  122. package/templates/skills/business-analyse/questionnaire/02-stakeholders.md +0 -189
  123. package/templates/skills/business-analyse/questionnaire/03-scope.md +0 -164
  124. package/templates/skills/business-analyse/questionnaire/04-data.md +0 -88
  125. package/templates/skills/business-analyse/questionnaire/05-integrations.md +0 -58
  126. package/templates/skills/business-analyse/questionnaire/06-security.md +0 -68
  127. package/templates/skills/business-analyse/questionnaire/07-ui.md +0 -76
  128. package/templates/skills/business-analyse/questionnaire/08-performance.md +0 -42
  129. package/templates/skills/business-analyse/questionnaire/09-constraints.md +0 -45
  130. package/templates/skills/business-analyse/questionnaire/10-documentation.md +0 -58
  131. package/templates/skills/business-analyse/questionnaire/11-data-lifecycle.md +0 -59
  132. package/templates/skills/business-analyse/questionnaire/12-migration.md +0 -58
  133. package/templates/skills/business-analyse/questionnaire/13-cross-module.md +0 -69
  134. package/templates/skills/business-analyse/questionnaire/14-risk-assumptions.md +0 -135
  135. package/templates/skills/business-analyse/questionnaire/15-success-metrics.md +0 -136
  136. package/templates/skills/business-analyse/references/agent-module-prompt.md +0 -366
  137. package/templates/skills/business-analyse/references/agent-pooling-best-practices.md +0 -557
  138. package/templates/skills/business-analyse/references/cache-warming-strategy.md +0 -566
  139. package/templates/skills/business-analyse/references/cadrage-challenge-patterns.md +0 -41
  140. package/templates/skills/business-analyse/references/cadrage-coverage-matrix.md +0 -74
  141. package/templates/skills/business-analyse/references/cadrage-pre-analysis.md +0 -115
  142. package/templates/skills/business-analyse/references/cadrage-shared-modules.md +0 -68
  143. package/templates/skills/business-analyse/references/cadrage-structure-cards.md +0 -85
  144. package/templates/skills/business-analyse/references/team-orchestration.md +0 -1093
  145. package/templates/skills/business-analyse/references/validate-incremental-html.md +0 -121
  146. package/templates/skills/business-analyse/steps/step-01b-applications.md +0 -419
  147. package/templates/skills/business-analyse/steps/step-02-decomposition.md +0 -387
  148. package/templates/skills/business-analyse/steps/step-03a-data.md +0 -16
  149. package/templates/skills/business-analyse/steps/step-03a1-setup.md +0 -486
  150. package/templates/skills/business-analyse/steps/step-03a2-analysis.md +0 -300
  151. package/templates/skills/business-analyse/steps/step-03b-ui.md +0 -405
  152. package/templates/skills/business-analyse/steps/step-03c-compile.md +0 -516
  153. package/templates/skills/business-analyse/steps/step-03d-validate.md +0 -691
  154. package/templates/skills/business-analyse/steps/step-04-consolidation.md +0 -17
  155. package/templates/skills/business-analyse/steps/step-04a-collect.md +0 -415
  156. package/templates/skills/business-analyse/steps/step-04b-analyze.md +0 -163
  157. package/templates/skills/business-analyse/steps/step-04c-decide.md +0 -186
  158. package/templates/skills/business-analyse/steps/step-05a-handoff.md +0 -937
  159. package/templates/skills/business-analyse/steps/step-05b-deploy.md +0 -522
  160. package/templates/skills/business-analyse/steps/step-05c-ralph-readiness.md +0 -703
@@ -1,937 +0,0 @@
1
- ---
2
- name: step-05a-handoff
3
- description: Build development handoff data, map business rules to code, write handoff to feature.json
4
- model: sonnet
5
- next_step: steps/step-05b-deploy.md
6
- ---
7
-
8
- > **Context files:** `_shared.md` | `_architecture.md`
9
-
10
- # Step 5a: Handoff - Build & Write
11
-
12
- ## MANDATORY EXECUTION RULES
13
-
14
- - **ALWAYS** verify status = "consolidated" before proceeding
15
- - **ALWAYS** ask user for implementation strategy preference (multi-module only)
16
- - **ALWAYS** derive prd.json from feature.json (NEVER independently)
17
- - **NEVER** invent entities/FRs/BRs not in feature.json
18
- - **ALL** API routes from specification.apiEndpoints (exact copy)
19
- - **Permission** paths from specification.permissionMatrix (full format)
20
- - **ALWAYS** generate CORE SeedData entries: 2 app-level (NavigationApplication + ApplicationRoles) + per module (NavigationModule + NavigationSections + Permissions + Roles)
21
-
22
- ## YOUR TASK
23
-
24
- Build the development handoff data: verify consolidation, choose implementation strategy, calculate complexity, map specification to files (7 categories), map business rules to code, generate API endpoint summary, and write handoff to EACH module feature.json.
25
-
26
- ---
27
-
28
- ## EXECUTION SEQUENCE
29
-
30
- ### 1. Verify Consolidation Passed
31
-
32
- Use ba-reader to locate the feature and verify consolidation status:
33
-
34
- ```
35
- // Determine feature source based on workflow mode
36
- IF workflow.mode === "project":
37
- projectFeature = ba-reader.findProjectFeature()
38
- // Verify ALL applications are specified
39
- FOR each app in projectFeature.applications:
40
- appFeature = ba-reader.findFeature(app.featureJsonPath)
41
- IF appFeature.status !== "consolidated":
42
- BLOCKING ERROR: "Application {app.code} not consolidated (status: {appFeature.status})"
43
- → Return to step-04a-collect.md
44
- // Use project-level feature for overall consolidation
45
- feature = projectFeature
46
- ELSE:
47
- ba-reader.findFeature({feature_id})
48
- → Check status = "consolidated"
49
- ```
50
-
51
- **IF** status ≠ "consolidated" → **STOP**. Return to step-04a-collect.md.
52
-
53
- Display validation summary:
54
-
55
- ```
56
- ✓ Consolidation: APPROVED
57
- ✓ Applications: {app_count} (project mode only)
58
- ✓ Modules: {count} specified and validated
59
- ✓ Cross-module: interactions mapped
60
- ✓ Cross-application: interactions mapped (project mode only)
61
- ✓ Permissions: coherent
62
- → Proceeding to handoff...
63
- ```
64
-
65
- Include:
66
- - Number of applications (project mode only)
67
- - Number of modules across all applications
68
- - Number of entities across all modules
69
- - Number of use cases across all modules
70
- - Number of business rules across all modules
71
- - Cross-module interaction count
72
- - Cross-application interaction count (project mode only)
73
-
74
- ---
75
-
76
- ### 1b. Cache Warming for Handoff & Deploy
77
-
78
- > **Performance Optimization:** Pre-load handoff templates and references to reduce redundant reads during handoff generation.
79
- > This step runs ONCE at start of step-05a, files retained through step-05b.
80
-
81
- ```
82
- // Pre-load handoff & deploy references (Bucket 5)
83
- const handoffRefs = [
84
- "~/.claude/skills/business-analyse/references/handoff-file-templates.md",
85
- "~/.claude/skills/business-analyse/references/handoff-mappings.md",
86
- "~/.claude/skills/business-analyse/references/deploy-data-build.md",
87
- "~/.claude/skills/business-analyse/references/deploy-modes.md",
88
- "~/.claude/skills/business-analyse/references/html-data-mapping.md"
89
- ];
90
-
91
- for (const file of handoffRefs) {
92
- read(file); // Pre-load into cache
93
- }
94
-
95
- // Pre-load HTML template (large file, loaded once)
96
- read("~/.claude/skills/business-analyse/html/ba-interactive.html");
97
-
98
- Display: "✓ Cache warmed: handoff templates (139KB, 6 files)"
99
- Display: " Expected token savings: ~3,000 tokens (handoff refs read 2× → 1×)"
100
- Display: " Retention: through step-05b (deploy)"
101
- ```
102
-
103
- **Rationale:**
104
-
105
- - Handoff templates are read 2× during step-05a + step-05b (without caching)
106
- - HTML template (85KB) is read once but benefits from explicit pre-load (faster deploy)
107
- - Token savings: ~3,000 tokens for handoff process
108
- - Cache retained until session end (needed for both handoff and deploy steps)
109
-
110
- **Why NOT loaded at step-00:**
111
- - Large files (139KB total), especially ba-interactive.html (85KB)
112
- - Only used at END of workflow (steps 05a, 05b)
113
- - Low re-use (1-2× each)
114
- - Loading at step-05a is more efficient (just-in-time caching)
115
-
116
- See [references/cache-warming-strategy.md](../references/cache-warming-strategy.md) § Bucket 5 for details.
117
-
118
- ---
119
-
120
- ### 2. Implementation Strategy Choice (Multi-Module/Multi-App)
121
-
122
- **IF** more than 1 module defined in feature.json (or project mode with multiple applications):
123
-
124
- Ask via AskUserQuestion:
125
-
126
- ```
127
- question: "Quelle stratégie d'implémentation préférez-vous ?"
128
- header: "Stratégie d'implémentation"
129
- options:
130
- - label: "Module par module (Recommandé)"
131
- description: "Implémenter chaque module complètement avant de passer au suivant. Suit l'ordre topologique des dépendances."
132
- - label: "Couche par couche"
133
- description: "Implémenter toutes les entités, puis tous les services, puis tous les contrôleurs, etc. Plus de parallélisation possible mais plus complexe."
134
- - label: "Hybride"
135
- description: "Modules fondation en premier (couche par couche), puis modules dépendants (module par module)"
136
- - label: "Application par application (Recommandé multi-app)"
137
- description: "Implémenter chaque application complètement avant de passer à la suivante. Suit l'ordre topologique inter-applications."
138
- ```
139
-
140
- > **Note:** "Application par application" only appears for project mode with 2+ applications.
141
-
142
- Store the chosen strategy in `handoff.implementationStrategy`.
143
-
144
- **IF** only 1 module → default to "Module par module" (no choice needed).
145
-
146
- ---
147
-
148
- ### 3. Calculate Complexity
149
-
150
- For each module in feature.json.modules[], calculate:
151
-
152
- ```json
153
- {
154
- "complexity": "simple|medium|complex",
155
- "complexityDetails": {
156
- "entities": {count},
157
- "useCases": {count},
158
- "businessRules": {count},
159
- "calculated": "{level} (≤X entities, ≤Y UCs, ≤Z BRs)"
160
- }
161
- }
162
- ```
163
-
164
- | Criteria | Simple | Medium | Complex |
165
- |----------|--------|--------|---------|
166
- | Entities | ≤3 | ≤6 | >6 |
167
- | Use Cases | ≤5 | ≤12 | >12 |
168
- | Business Rules | ≤10 | ≤20 | >20 |
169
-
170
- **Global complexity** = highest complexity across all modules.
171
-
172
- Example:
173
- - Module A: 4 entities, 6 use cases, 8 BRs → **simple**
174
- - Module B: 8 entities, 15 use cases, 25 BRs → **complex**
175
- - Overall: **complex**
176
-
177
- ---
178
-
179
- ### 4. Map Specification to Files
180
-
181
- > **IMPORTANT:** Generate `handoff.filesToCreate` as structured object with 8 categories.
182
- > Each file entry is `{path, type, linkedFRs, linkedUCs, module}`. NO free text.
183
- > Read `.smartstack/config.json` to extract baseNamespace for project namespace.
184
-
185
- **Order by topological dependency** (modules with no deps first, then dependents).
186
-
187
- For **EACH module** in topological order:
188
-
189
- > **PATH HIERARCHY CONVENTION:** All backend file paths MUST include the application hierarchy.
190
- > Derive from module feature.json metadata:
191
- > - `{ApplicationName}` = `metadata.application` (e.g., `"HumanResources"`)
192
- > - `{ModuleName}` = `metadata.module` (e.g., `"Projects"`)
193
- >
194
- > **Example** for application=HumanResources, module=Projects:
195
- > - Domain: `src/Domain/Entities/HumanResources/Projects/Project.cs`
196
- > - Application: `src/Application/Services/HumanResources/Projects/ProjectService.cs`
197
- > - Infrastructure: `src/Infrastructure/Persistence/Configurations/HumanResources/Projects/ProjectConfiguration.cs`
198
- > - API: `src/API/Controllers/HumanResources/ProjectsController.cs`
199
- > - Tests: `src/Tests/Unit/Domain/HumanResources/Projects/ProjectTests.cs`
200
-
201
- #### 4.1-4.8 File Category Templates
202
-
203
- See [references/handoff-file-templates.md](../references/handoff-file-templates.md) for the complete JSON templates for all 8 categories:
204
-
205
- | Category | Source | Key rules |
206
- |----------|--------|-----------|
207
- | **4.1 Domain** | `analysis.entities[]` | Entities, ValueObjects, Enums, Exceptions |
208
- | **4.2 Application** | `analysis.useCases[]` | Services, DTOs, Validators |
209
- | **4.3 Infrastructure** | `analysis.entities[]` | EF Configurations, DbSet, DI. **DEPENDENCY:** Each EF config task MUST `dependsOn` its corresponding domain entity task. |
210
- | **4.4 API** | `specification.apiEndpoints[]` | Controllers |
211
- | **4.5 Frontend** | `specification.uiWireframes[]` | Pages, Components, Hooks + wireframe traceability |
212
- | **4.6 SeedData** | `specification.seedDataCore` | 2 app-level + per module CORE (NavigationModule + NavigationSections + Permissions + Roles) + business + IClientSeedDataProvider |
213
- | **4.7 Tests** | All layers | Unit, Integration, Security tests |
214
- | **4.8 Documentation** | `cadrage.documentation` | Technical docs, user guides, tooltips (doc-data.ts). Peut être `[]` si aucune doc requise. |
215
-
216
- > **Catégorie `documentation` :** Inclure les fichiers identifiés en step-01-cadrage §4g.
217
- > - Si `cadrage.documentation.userDocumentation.needed = false` ET `cadrage.documentation.technicalDocumentation.needed = false` → `"documentation": []`
218
- > - Sinon, lister les fichiers attendus : `doc-data.ts` (tooltips in-app), guides Markdown, specs API supplémentaires.
219
-
220
- #### Route Convention (CRITICAL)
221
-
222
- > **MANDATORY:** All NavigationModule/Section routes MUST use kebab-case transformation.
223
- > See [references/naming-conventions.md](../references/naming-conventions.md) for complete guide.
224
-
225
- **Problem:**
226
- - Module codes in feature.json are **PascalCase** (e.g., `"HumanResources"`)
227
- - Routes in seed data MUST be **kebab-case** (e.g., `"/human-resources"`)
228
- - Failing to transform causes 404 when clicking menu items
229
-
230
- **Solution:**
231
-
232
- When generating `seedDataCore` for handoff, transform PascalCase codes to kebab-case routes:
233
-
234
- ```javascript
235
- // Transform module codes to kebab-case routes
236
- function toKebabCase(code) {
237
- return code
238
- .replace(/([a-z])([A-Z])/g, '$1-$2')
239
- .toLowerCase();
240
- }
241
-
242
- // Example usage in seedDataCore generation
243
- const moduleCode = "TimeManagement"; // PascalCase (C#)
244
- const appCode = "HumanResources"; // PascalCase (C#)
245
-
246
- const route = `/${toKebabCase(appCode)}/${toKebabCase(moduleCode)}`;
247
- // Result: "/human-resources/time-management"
248
- ```
249
-
250
- **Validation:** All kebab-case routes in seed data MUST NOT include `/business/` prefix.
251
-
252
- Example in NavigationModule:
253
- ```csharp
254
- route = "/human-resources"; // ✓ Correct (kebab-case module code only)
255
- route = "/business/human-resources"; // ✗ WRONG (contains /business/)
256
- ```
257
-
258
- **Include in task instructions:**
259
-
260
- For NavigationSeedData tasks in `handoff.filesToCreate`, add:
261
-
262
- ```json
263
- {
264
- "path": "Infrastructure/Persistence/Seeding/Data/{Module}/NavigationSeedData.cs",
265
- "type": "SeedData",
266
- "category": "core",
267
- "instructions": "Generate NavigationModule seed data. CRITICAL: Use ToKebabCase() helper for Route property. Example: Route = ToKebabCase($\"/{app}/{module}\"). See core-seed-data.md template."
268
- }
269
- ```
270
-
271
- **Validation:**
272
- - ralph-loop POST-CHECK validates routes after generation (see step-02-execute.md)
273
- - MCP `validate_frontend_routes` detects case mismatches
274
- - Convention documented in naming-conventions.md
275
-
276
- **Critical rules:**
277
- - All backend paths include `{ApplicationName}/` hierarchy
278
- - Frontend pages MUST have `linkedWireframes[]` + `wireframeAcceptanceCriteria`
279
- - SeedData: 2 app-level CORE (NavigationApplication + ApplicationRoles) + per-module CORE (NavigationModule + NavigationSections + Permissions + Roles) + IClientSeedDataProvider for client projects
280
- - **Acceptance Criteria Mapping:** Each task's `acceptanceCriteria` MUST be derived from its own `linkedFRs[]` entries (lookup FR → `acceptanceCriteria`). NEVER map by sequential FR index — use the task's explicit linkedFRs to resolve the correct criteria.
281
- - Path convention: `Persistence/Seeding/Data/` (NEVER `Data/SeedData/`)
282
-
283
- ---
284
-
285
- ### 5. Map Business Rules to Code
286
-
287
- See [references/handoff-mappings.md](../references/handoff-mappings.md) — Section "Business Rules to Code Mapping".
288
-
289
- For each BR in `analysis.businessRules[]` of EACH module, generate:
290
- - **ruleId**, **title**, **module**, **severity** (critical/high/medium/low)
291
- - **implementationPoints**: Array of `{layer, component, method, implementation}` across Domain, Application, Infrastructure, API, Frontend
292
-
293
- ---
294
-
295
- ### 6. API Endpoint Summary
296
-
297
- > **ABSOLUTE RULE:** Copy **EXACTLY** from `specification.apiEndpoints[]`. **NEVER** reinvent routes.
298
-
299
- See [references/handoff-mappings.md](../references/handoff-mappings.md) — Section "API Endpoint Summary".
300
-
301
- For each endpoint: operation, method, route, linkedUC, linkedFR, permissions, requestSchema, responseSchema, errorCodes, module.
302
-
303
- Total endpoints = count of specification.apiEndpoints[] across all modules.
304
-
305
- ### 6b. Frontend Task Splitting (MANDATORY)
306
-
307
- > **CRITICAL:** Frontend MUST be split into discrete tasks, NOT bundled as a single mega-task.
308
- > A single mega-task covering 5-8 files prevents granular error recovery in ralph-loop.
309
-
310
- For each module, generate these SEPARATE frontend file entries (not one monolithic entry):
311
-
312
- ```json
313
- "frontend": [
314
- { "path": "src/pages/{App}/{Mod}/{ListPage}Page.tsx", "type": "Page", "linkedWireframes": ["{module}-list"], "module": "{moduleCode}", "skill": "/ui-components" },
315
- { "path": "src/pages/{App}/{Mod}/{Entity}CreatePage.tsx", "type": "Page", "linkedWireframes": ["{module}-create"], "module": "{moduleCode}", "skill": "/ui-components", "fkFields": ["EmployeeId→Employee", "DepartmentId→Department"] },
316
- { "path": "src/pages/{App}/{Mod}/{Entity}EditPage.tsx", "type": "Page", "linkedWireframes": ["{module}-edit"], "module": "{moduleCode}", "skill": "/ui-components", "fkFields": ["EmployeeId→Employee", "DepartmentId→Department"] },
317
- { "path": "src/pages/{App}/{Mod}/{DetailPage}Page.tsx", "type": "Page", "linkedWireframes": ["{module}-detail"], "module": "{moduleCode}", "skill": "/ui-components" },
318
- { "path": "src/hooks/use{Module}.ts", "type": "Hook", "module": "{moduleCode}" },
319
- { "path": "src/i18n/locales/fr/{moduleLower}.json", "type": "I18n", "language": "fr", "module": "{moduleCode}" },
320
- { "path": "src/i18n/locales/en/{moduleLower}.json", "type": "I18n", "language": "en", "module": "{moduleCode}" },
321
- { "path": "src/i18n/locales/it/{moduleLower}.json", "type": "I18n", "language": "it", "module": "{moduleCode}" },
322
- { "path": "src/i18n/locales/de/{moduleLower}.json", "type": "I18n", "language": "de", "module": "{moduleCode}" }
323
- ]
324
- ```
325
-
326
- **FK fields in forms:** Create/Edit page entries MUST include `"fkFields"` array listing FK properties and their target entities (format: `"PropertyId→TargetEntity"`). This tells ralph-loop to use `EntityLookup` component instead of plain text inputs. Derive FK fields from `analysis.entities[].relationships[]` where `type = "N:1"` or from properties ending in `Id` with a navigation property. See `smartstack-frontend.md` section 6 for the EntityLookup pattern.
327
-
328
- **Page generation:** ALL pages MUST use `/ui-components` skill (indicated by `"skill"` field). NEVER write raw TSX without the skill patterns.
329
-
330
- **I18n generation:** 4 JSON files per module with identical key structures. `{moduleLower}` = lowercase module code. Keys: actions, labels, columns, form, errors, validation, messages, empty. See `smartstack-frontend.md` template.
331
-
332
- Additional per-section pages (dashboard, import, etc.) are separate entries.
333
-
334
- **Route wiring task (MANDATORY — separate entry):**
335
- ```json
336
- { "path": "src/App.tsx", "type": "RouteWiring", "module": "{moduleCode}", "description": "Wire {module} routes into App.tsx application route block. BLOCKING: pages without route wiring = blank pages." }
337
- ```
338
-
339
- ### 6c. Cross-Module PRD (MANDATORY for multi-module features)
340
-
341
- > **CRITICAL:** Cross-module integration tasks MUST exist in a dedicated PRD file.
342
- > Without this, ralph-loop will NOT execute E2E tests or FK validation.
343
-
344
- > **FORMAT:** Must use ralph-loop v3 format with `tasks[]` array (NOT `implementation.filesToCreate`).
345
- > Ralph's step-01 v3 fast path requires `$version === "3.0.0"` AND `tasks[]` to be present.
346
- > A PRD with only `implementation.filesToCreate` will be silently ignored by ralph-loop.
347
-
348
- Generate `.ralph/prd-CrossModule.json` with:
349
- ```json
350
- {
351
- "$version": "3.0.0",
352
- "feature": "CrossModule Integration Tests",
353
- "status": "pending",
354
- "project": { "module": "CrossModule", "application": "{AppName}" },
355
- "config": { "max_iterations": 10, "current_iteration": 1 },
356
- "metadata": { "sourceFeatureJson": "{path to master feature.json}" },
357
- "tasks": [
358
- {
359
- "id": "CM-001",
360
- "description": "Generate FK validation integration tests across all modules",
361
- "status": "pending",
362
- "category": "test",
363
- "dependencies": [],
364
- "acceptance_criteria": "ForeignKeyValidationTests.cs created, all FK references validated across modules, dotnet test passes",
365
- "started_at": null, "completed_at": null, "iteration": null,
366
- "commit_hash": null, "files_changed": [], "validation": null, "error": null
367
- },
368
- {
369
- "id": "CM-002",
370
- "description": "Generate permission matrix integration tests (cross-module access control)",
371
- "status": "pending",
372
- "category": "test",
373
- "dependencies": ["CM-001"],
374
- "acceptance_criteria": "PermissionMatrixTests.cs created, all cross-module permission paths validated, dotnet test passes",
375
- "started_at": null, "completed_at": null, "iteration": null,
376
- "commit_hash": null, "files_changed": [], "validation": null, "error": null
377
- },
378
- {
379
- "id": "CM-003",
380
- "description": "Generate E2E flow integration tests covering multi-module user journeys",
381
- "status": "pending",
382
- "category": "test",
383
- "dependencies": ["CM-001", "CM-002"],
384
- "acceptance_criteria": "E2EFlowTests.cs created, end-to-end flows tested, dotnet test passes",
385
- "started_at": null, "completed_at": null, "iteration": null,
386
- "commit_hash": null, "files_changed": [], "validation": null, "error": null
387
- }
388
- ],
389
- "history": [],
390
- "created": "{ISO timestamp}",
391
- "updated_at": "{ISO timestamp}"
392
- }
393
- ```
394
-
395
- Add to progress.txt after all module tasks.
396
-
397
- ### 6d. Cross-Application PRD (Project Mode Only)
398
-
399
- > **Only generated when `workflow.mode === "project"`.**
400
- > Contains cross-application integration tests and shared entity validation.
401
-
402
- > **FORMAT:** Same v3 `tasks[]` format as 6c above — NOT `implementation.filesToCreate`.
403
-
404
- Generate `.ralph/prd-CrossApplication.json` with:
405
- ```json
406
- {
407
- "$version": "3.0.0",
408
- "feature": "CrossApplication Integration Tests",
409
- "status": "pending",
410
- "project": { "module": "CrossApplication", "application": "{ProjectName}" },
411
- "config": { "max_iterations": 10, "current_iteration": 1 },
412
- "metadata": { "sourceFeatureJson": "{path to project feature.json}" },
413
- "tasks": [
414
- {
415
- "id": "CA-001",
416
- "description": "Generate shared entity validation tests across all applications",
417
- "status": "pending",
418
- "category": "test",
419
- "dependencies": [],
420
- "acceptance_criteria": "SharedEntityValidationTests.cs created, shared entities consistent across apps, dotnet test passes",
421
- "started_at": null, "completed_at": null, "iteration": null,
422
- "commit_hash": null, "files_changed": [], "validation": null, "error": null
423
- },
424
- {
425
- "id": "CA-002",
426
- "description": "Generate cross-application permission integration tests",
427
- "status": "pending",
428
- "category": "test",
429
- "dependencies": ["CA-001"],
430
- "acceptance_criteria": "CrossAppPermissionTests.cs created, inter-app permissions validated, dotnet test passes",
431
- "started_at": null, "completed_at": null, "iteration": null,
432
- "commit_hash": null, "files_changed": [], "validation": null, "error": null
433
- },
434
- {
435
- "id": "CA-003",
436
- "description": "Generate cross-application E2E flow tests",
437
- "status": "pending",
438
- "category": "test",
439
- "dependencies": ["CA-001", "CA-002"],
440
- "acceptance_criteria": "CrossAppE2EFlowTests.cs created, multi-app user journeys tested, dotnet test passes",
441
- "started_at": null, "completed_at": null, "iteration": null,
442
- "commit_hash": null, "files_changed": [], "validation": null, "error": null
443
- }
444
- ],
445
- "history": [],
446
- "created": "{ISO timestamp}",
447
- "updated_at": "{ISO timestamp}"
448
- }
449
- ```
450
-
451
- Write to: `.ralph/prd-CrossApplication.json`
452
-
453
- > This PRD is generated IN ADDITION to the per-module cross-module PRD.
454
- > It validates interactions between applications, not just between modules within the same application.
455
-
456
- ---
457
-
458
- ### 7. Write Handoff to Feature.json
459
-
460
- > **BLOCKING RULE: The handoff MUST be written in EACH module feature.json.**
461
- > A handoff at master level alone is INSUFFICIENT. Ralph-loop consumes module-level handoffs.
462
- > An empty module handoff (`"handoff": {}`) is a CRITICAL BUG that blocks all downstream generation.
463
-
464
- #### 7a. Module Handoff Loop (MANDATORY)
465
-
466
- > **STRUCTURE CARD: handoff** — Field names are EXACT. Include ALL fields below.
467
- > **PATH RULE:** All backend paths MUST include `{ApplicationName}/` hierarchy (see section 4).
468
- > ```json
469
- > {
470
- > "complexity": "simple|medium|complex",
471
- > "filesToCreate": {
472
- > "domain": [{"path": "src/Domain/Entities/{App}/{Mod}/{Entity}.cs", "type": "Entity|ValueObject|Enum", "linkedFRs": [], "linkedUCs": [], "module": "..."}],
473
- > "application": [{"path": "src/Application/Services/{App}/{Mod}/{Svc}Service.cs", "type": "Service|Dto|Validator", "linkedFRs": [], "linkedUCs": [], "module": "..."}],
474
- > "infrastructure": [{"path": "src/Infrastructure/Persistence/Configurations/{App}/{Mod}/{Entity}Configuration.cs", "type": "EFConfiguration", "linkedFRs": [], "module": "..."}],
475
- > "api": [{"path": "src/API/Controllers/{App}/{Entity}Controller.cs", "type": "ApiController", "linkedUCs": [], "linkedFRs": [], "module": "..."}],
476
- > "frontend": [{"path": "src/pages/{App}/{Mod}/{Page}Page.tsx", "type": "Page|Component|Hook|DashboardPage|I18n", "linkedUCs": [], "linkedWireframes": [], "module": "...", "skill": "/ui-components"}],
477
- > "seedData": [{"path": "src/Infrastructure/Persistence/Seeding/Data/{Mod}/...SeedData.cs", "type": "SeedData", "category": "core|business", "source": "...", "module": "..."}],
478
- > "tests": [{"path": "src/Tests/Unit/Domain/{App}/{Mod}/{Entity}Tests.cs", "type": "UnitTests|IntegrationTests|SecurityTests", "linkedFRs": [], "linkedUCs": [], "module": "..."}]
479
- > },
480
- > "brToCodeMapping": [{"ruleId": "BR-...", "files": ["path1", "path2"], "implementation": "description"}],
481
- > "apiEndpointSummary": [{"method": "GET|POST|PUT|DELETE", "path": "/api/...", "permission": "{app}.{module}.{action}", "linkedUC": "UC-..."}],
482
- > "prdFile": ".ralph/prd-{module}.json",
483
- > "totalFiles": 0,
484
- > "totalTasks": 0,
485
- > "handedOffAt": "{ISO timestamp}"
486
- > }
487
- > ```
488
- > **MANDATORY fields:** ALL of the above. `filesToCreate` MUST have all 7 categories (even if empty arrays).
489
- > **FORBIDDEN:** `handoff: {}` (empty object is a CRITICAL BUG). Missing `brToCodeMapping` or `apiEndpointSummary`.
490
-
491
- **For i = 0; i < modules.length; i++:**
492
-
493
- ```
494
- 1. moduleCode = modules[i].code
495
- 2. moduleFeatureId = modules[i].featureJsonPath or find via ba-reader.findFeature()
496
- 3. Read the module feature.json via ba-reader.findFeature(moduleFeatureId)
497
- 4. Build the handoff payload for THIS module:
498
- - complexity (from section 3 calculation)
499
- - filesToCreate (full 7-category structure from section 4, filtered for this module)
500
- - brToCodeMapping (from section 5, filtered for this module)
501
- - apiEndpointSummary (from section 6, filtered for this module)
502
- - prdFile path
503
- - totalFiles count
504
- - totalTasks count
505
- - handedOffAt timestamp
506
-
507
- 5. Write via ba-writer:
508
- ba-writer.enrichModuleHandoff({
509
- moduleFeatureId: {moduleFeatureId},
510
- handoffData: {
511
- complexity: "{simple|medium|complex}",
512
- filesToCreate: {...},
513
- brToCodeMapping: [...],
514
- apiEndpointSummary: [...],
515
- prdFile: ".ralph/prd-{moduleCode}.json",
516
- totalFiles: {count},
517
- totalTasks: {count},
518
- handedOffAt: "{ISO timestamp}"
519
- }
520
- })
521
-
522
- 6. VERIFICATION (MANDATORY - done automatically by enrichModuleHandoff):
523
- - handoff !== {}
524
- - handoff.filesToCreate has 7 categories
525
- - handoff.brToCodeMapping.length > 0
526
- IF verification fails → STOP, report error, do NOT continue
527
-
528
- 7. Display progress:
529
- "✓ Handoff module {i+1}/{N} : {moduleCode} ({fileCount} fichiers, {brCount} BRs mappées)"
530
- ```
531
-
532
- #### 7b. Generate seedDataCore (MANDATORY for master feature.json)
533
-
534
- > **Reference:** Load `references/handoff-seeddata-generation.md` for complete seedDataCore generation logic.
535
-
536
- **The seedDataCore provides ralph-loop with the exact navigation, permissions, and translations to seed.**
537
- Without seedDataCore, ralph-loop must INVENT this data — leading to inconsistencies.
538
-
539
- The reference includes:
540
- - Helper functions (toHumanReadable, toKebabCase)
541
- - Complete seedDataCore template with all 9 arrays
542
- - Icon inference for application and module levels
543
- - POST-CHECK validation rules (BLOCKING for icons/application, warning for counts)
544
-
545
- Key points:
546
- - Icons must NEVER be null (use fallback if not inferred)
547
- - All 9 seedDataCore arrays must be present (even if empty for multi-module scenarios)
548
- - PROJECT MODE: Generate one entry per application from project feature.json
549
- - SINGLE-APP MODE: Generate one entry from master feature.json
550
-
551
- ```
552
- // Derive seedDataCore from modules[], applicationRoles[], and coverageMatrix[]
553
-
554
- // Helper: PascalCase → "Human Readable" (e.g., "HumanResources" → "Human Resources")
555
- function toHumanReadable(pascalCase) {
556
- return pascalCase
557
- .replace(/([a-z])([A-Z])/g, '$1 $2')
558
- .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2');
559
- }
560
-
561
- const appCode = master.metadata.application;
562
- const appLabel = toHumanReadable(appCode);
563
- const appDesc = master.cadrage?.problem?.split('.')[0] || `Gestion ${appLabel}`;
564
- const lang = master.metadata.language || "fr";
565
-
566
- const seedDataCore = {
567
- // Application-level navigation (MANDATORY — one entry per application)
568
- // PROJECT MODE: Generate one entry per application from project feature.json
569
- // SINGLE-APP MODE: Generate one entry from master feature.json
570
- navigationApplications: (() => {
571
- if (workflow.mode === "project") {
572
- // Multi-app: one navigation entry per application
573
- return projectFeature.applications.map((app, idx) => {
574
- const appLabel = toHumanReadable(app.code);
575
- return {
576
- code: app.code.toLowerCase(),
577
- name: app.code,
578
- labels: {
579
- fr: lang === "fr" ? (app.name || appLabel) : appLabel,
580
- en: lang === "en" ? (app.name || appLabel) : appLabel,
581
- it: appLabel,
582
- de: appLabel
583
- },
584
- description: {
585
- fr: lang === "fr" ? (app.description || `Gestion ${appLabel}`) : `Gestion ${appLabel}`,
586
- en: lang === "en" ? (app.description || `${appLabel} management`) : `${appLabel} management`,
587
- it: `Gestione ${appLabel}`,
588
- de: `${appLabel} Verwaltung`
589
- },
590
- icon: app.icon || inferIconFromApplication({ metadata: { application: app.code } }) || "layout-grid",
591
- iconType: "lucide",
592
- route: `/${toKebabCase(app.code)}`,
593
- displayOrder: (idx + 1) * 10
594
- };
595
- });
596
- } else {
597
- // Single-app: one navigation entry
598
- return [{
599
- code: appCode.toLowerCase(),
600
- name: appCode,
601
- labels: {
602
- fr: lang === "fr" ? (master.cadrage?.applicationName || appLabel) : appLabel,
603
- en: lang === "en" ? (master.cadrage?.applicationName || appLabel) : appLabel,
604
- it: appLabel,
605
- de: appLabel
606
- },
607
- description: {
608
- fr: lang === "fr" ? appDesc : `Gestion ${appLabel}`,
609
- en: lang === "en" ? appDesc : `${appLabel} management`,
610
- it: `Gestione ${appLabel}`,
611
- de: `${appLabel} Verwaltung`
612
- },
613
- icon: inferIconFromApplication(master) || "layout-grid",
614
- iconType: "lucide",
615
- route: `/${toKebabCase(appCode)}`,
616
- displayOrder: 1
617
- }];
618
- }
619
- })(),
620
-
621
- // PROJECT MODE: Flatten modules from ALL applications
622
- // SINGLE-APP MODE: Use master.modules directly
623
- navigationModules: (() => {
624
- if (workflow.mode === "project") {
625
- let order = 0;
626
- return projectFeature.applications.flatMap(app => {
627
- return (app.modules || []).map(m => ({
628
- code: m.code,
629
- applicationCode: app.code,
630
- label: m.name || m.code,
631
- description: m.description,
632
- icon: inferIconFromModule(m) || "folder",
633
- iconType: "lucide",
634
- route: `/${toKebabCase(app.code)}/${toKebabCase(m.code)}`,
635
- displayOrder: (++order) * 10
636
- }));
637
- });
638
- } else {
639
- return master.modules.map((m, i) => ({
640
- code: m.code,
641
- label: m.name || m.code,
642
- description: m.description,
643
- icon: inferIconFromModule(m) || "folder",
644
- iconType: "lucide",
645
- route: `/${toKebabCase(appCode)}/${toKebabCase(m.code)}`,
646
- displayOrder: (i + 1) * 10
647
- }));
648
- }
649
- })(),
650
-
651
- navigationSections: (() => {
652
- const buildSections = (modules, appCode) =>
653
- modules.flatMap(m =>
654
- (m.anticipatedSections || []).map((s, j) => ({
655
- moduleCode: m.code,
656
- code: s.code,
657
- label: s.description?.split(':')[0] || s.code,
658
- description: s.description || "",
659
- route: s.code === "list"
660
- ? `/${toKebabCase(appCode)}/${toKebabCase(m.code)}`
661
- : s.code === "detail"
662
- ? `/${toKebabCase(appCode)}/${toKebabCase(m.code)}/:id`
663
- : `/${toKebabCase(appCode)}/${toKebabCase(m.code)}/${toKebabCase(s.code)}`,
664
- displayOrder: (j + 1) * 10,
665
- navigation: s.code === "detail" ? "hidden" : "visible"
666
- }))
667
- );
668
-
669
- if (workflow.mode === "project") {
670
- return projectFeature.applications.flatMap(app =>
671
- buildSections(app.modules || [], app.code)
672
- );
673
- } else {
674
- return buildSections(master.modules, appCode);
675
- }
676
- })(),
677
-
678
- navigationResources: master.cadrage.coverageMatrix
679
- .filter(cm => cm.module && cm.anticipatedResources?.length > 0)
680
- .flatMap(cm =>
681
- cm.anticipatedResources.map((r, k) => ({
682
- moduleCode: cm.module,
683
- sectionCode: cm.anticipatedSections?.[0] || "list",
684
- code: r,
685
- label: r.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase()),
686
- displayOrder: (k + 1) * 10
687
- }))
688
- ),
689
-
690
- navigationTranslations: master.modules.flatMap(m => {
691
- const langs = ["fr", "en", "it", "de"]; // all supported languages
692
- return langs.map(lang => ({
693
- moduleCode: m.code,
694
- language: lang,
695
- label: lang === master.metadata.language ? (m.name || m.code) : m.code,
696
- description: lang === master.metadata.language ? m.description : ""
697
- }));
698
- }),
699
-
700
- // PROJECT MODE: permissions scoped per application context
701
- // SINGLE-APP MODE: all permissions under {app}
702
- permissions: (() => {
703
- const buildPermissions = (modules, appCode) =>
704
- modules.flatMap(m => {
705
- const basePath = `${toKebabCase(appCode)}.${toKebabCase(m.code)}`;
706
- const actions = ['read', 'create', 'update', 'delete'];
707
- return [
708
- { path: `${basePath}.*`, action: '*', description: `Full ${m.name || m.code} access` },
709
- ...actions.map(action => ({
710
- path: `${basePath}.${action}`,
711
- action: action,
712
- description: `${action.charAt(0).toUpperCase() + action.slice(1)} ${m.name || m.code}`
713
- }))
714
- ];
715
- });
716
-
717
- if (workflow.mode === "project") {
718
- return projectFeature.applications.flatMap(app =>
719
- buildPermissions(app.modules || [], app.code)
720
- );
721
- } else {
722
- return buildPermissions(master.modules, appCode);
723
- }
724
- })(),
725
-
726
- rolePermissions: (() => {
727
- const buildRolePermissions = (roles, modules, appCode) =>
728
- roles.map(role => ({
729
- role: role.role,
730
- level: role.level,
731
- permissions: modules.map(m => `${toKebabCase(appCode)}.${toKebabCase(m.code)}.${
732
- role.level === 'admin' ? '*' :
733
- role.level === 'manager' ? 'read,create,update' :
734
- role.level === 'contributor' ? 'read,create' : 'read'
735
- }`)
736
- }));
737
-
738
- if (workflow.mode === "project") {
739
- return projectFeature.applications.flatMap(app =>
740
- buildRolePermissions(app.applicationRoles || [], app.modules || [], app.code)
741
- );
742
- } else {
743
- return buildRolePermissions(master.cadrage.applicationRoles, master.modules, appCode);
744
- }
745
- })(),
746
-
747
- permissionConstants: (() => {
748
- const buildConstants = (modules, appCode) =>
749
- modules.flatMap(m =>
750
- ['Read', 'Create', 'Update', 'Delete', 'Validate', 'Export'].map(action => ({
751
- module: m.code,
752
- application: appCode,
753
- action: action,
754
- constant: `${appCode}${m.code}${action}`,
755
- path: `${toKebabCase(appCode)}.${toKebabCase(m.code)}.${action.toLowerCase()}`
756
- }))
757
- );
758
-
759
- if (workflow.mode === "project") {
760
- return projectFeature.applications.flatMap(app =>
761
- buildConstants(app.modules || [], app.code)
762
- );
763
- } else {
764
- return buildConstants(master.modules, appCode);
765
- }
766
- })()
767
- };
768
-
769
- // Icon inference functions are defined in the reference
770
- // inferIconFromApplication(master) - Application level icons
771
- // inferIconFromModule(module) - Module level icons
772
- // See references/handoff-seeddata-generation.md for complete implementation
773
-
774
- ba-writer.enrichSection({
775
- featureId: {feature_id},
776
- section: "seedDataCore",
777
- data: seedDataCore
778
- })
779
- ```
780
-
781
- **POST-CHECK (BLOCKING for icons/application, warning for counts):**
782
- ```
783
- IF !seedDataCore.navigationApplications || seedDataCore.navigationApplications.length === 0:
784
- BLOCKING ERROR: "navigationApplications is empty — Application navigation will NOT be seeded. Menu will show (nothing) → Modules."
785
- IF seedDataCore.navigationApplications[0].icon === null || seedDataCore.navigationApplications[0].icon === undefined:
786
- BLOCKING ERROR: "Application icon is null — ralph-loop will render empty navigation"
787
- IF !seedDataCore.navigationApplications[0].labels?.fr || !seedDataCore.navigationApplications[0].labels?.en:
788
- BLOCKING ERROR: "Application labels missing fr/en — translations will fail"
789
- IF seedDataCore.navigationModules.length !== master.modules.length:
790
- WARNING: seedDataCore has ${seedDataCore.navigationModules.length} nav modules but ${master.modules.length} modules exist
791
- IF seedDataCore.permissions.length === 0:
792
- WARNING: seedDataCore has 0 permissions — applicationRoles may be missing
793
- IF seedDataCore.navigationModules.some(m => !m.icon || m.icon === null):
794
- BLOCKING ERROR: "Navigation modules with null icons detected — ralph-loop will render empty navigation"
795
- → Fix: Re-run inferIconFromModule() for modules with null icons
796
- IF seedDataCore.navigationSections.length === 0:
797
- WARNING: "0 navigation sections — every module should have at least 1 section (e.g., 'list')"
798
- ```
799
-
800
- #### 7c. Master Handoff (after ALL modules written + seedDataCore generated)
801
-
802
- ```
803
- // Write handoff to application-level feature.json (single-app mode)
804
- // OR to each application feature.json + project feature.json (project mode)
805
-
806
- IF workflow.mode === "project":
807
- // Write handoff to EACH application feature.json
808
- FOR each app in projectFeature.applications:
809
- ba-writer.enrichSection({
810
- featureId: app.featureJsonPath,
811
- section: "handoff",
812
- data: {
813
- status: "handed-off",
814
- complexity: "{app-level complexity}",
815
- implementationStrategy: "{strategy}",
816
- moduleCount: app.modules.length,
817
- moduleOrder: app.modules.map(m => m.code),
818
- totalFilesToCreate: {sum across app modules},
819
- totalTasks: {sum across app modules},
820
- prdFiles: app.modules.map(m => ({ module: m.code, path: `.ralph/prd-${m.code}.json` })),
821
- handedOffAt: "{ISO timestamp}"
822
- }
823
- })
824
-
825
- // Write project-level handoff summary
826
- ba-writer.enrichSection({
827
- featureId: {project_id},
828
- section: "handoff",
829
- data: {
830
- status: "handed-off",
831
- complexity: "{global complexity}",
832
- implementationStrategy: "{strategy}",
833
- applicationCount: projectFeature.applications.length,
834
- applicationOrder: projectFeature.applicationDependencyGraph.topologicalOrder,
835
- totalModuleCount: {sum of all app module counts},
836
- totalFilesToCreate: {sum across ALL applications and modules},
837
- totalTasks: {sum across ALL applications and modules},
838
- prdStructure: "per-module",
839
- prdFiles: [
840
- ...allModulePrdFiles,
841
- { module: "CrossModule", path: ".ralph/prd-CrossModule.json" },
842
- { module: "CrossApplication", path: ".ralph/prd-CrossApplication.json" }
843
- ],
844
- progressTrackerPath: ".ralph/progress.txt",
845
- handedOffAt: "{ISO timestamp}"
846
- }
847
- })
848
- ELSE:
849
- ba-writer.enrichSection({
850
- featureId: {feature_id},
851
- section: "handoff",
852
- data: {
853
- status: "handed-off",
854
- complexity: "{simple|medium|complex}",
855
- implementationStrategy: "{strategy}",
856
- moduleCount: {count},
857
- moduleOrder: [...],
858
- totalFilesToCreate: {sum across all modules},
859
- totalTasks: {sum across all modules},
860
- prdStructure: "per-module | consolidated",
861
- prdFiles: [
862
- { module: "{module1}", path: ".ralph/prd-{module1}.json" },
863
- { module: "{module2}", path: ".ralph/prd-{module2}.json" }
864
- ],
865
- progressTrackerPath: ".ralph/progress.txt",
866
- handedOffAt: "{ISO timestamp}"
867
- }
868
- })
869
- ```
870
-
871
- #### 7d. PRD Metadata Contract (MANDATORY)
872
-
873
- > **Ralph-loop quality gate** (`step-01 section 1b`) reads `prd.metadata.sourceFeatureJson` to locate
874
- > the feature.json and verify `handoff.status === "handed-off"`. This field MUST be written by
875
- > `ss derive-prd` into each generated PRD's `metadata` section.
876
-
877
- Verify that the `ss derive-prd` MCP tool writes the following into each generated PRD:
878
- ```json
879
- {
880
- "metadata": {
881
- "sourceFeatureJson": "{absolute or relative path to this module's feature.json}",
882
- "moduleCode": "{module code}",
883
- "application": "{application name}"
884
- }
885
- }
886
- ```
887
-
888
- **If `sourceFeatureJson` is absent from the generated PRD**, ralph-loop falls back to a file search
889
- (`findFile('docs/business/**/business-analyse/**/feature.json')`). This works for single-feature projects
890
- but may return the wrong feature.json in multi-feature projects. Report this to the MCP team if observed.
891
-
892
- ---
893
-
894
- #### 7e. Final Verification (BLOCKING)
895
-
896
- ```
897
- count = 0
898
- FOR each module in modules[]:
899
- Read module feature.json
900
- IF module.handoff !== {} AND module.status === "handed-off":
901
- count++
902
-
903
- IF count < modules.length:
904
- → BLOCKING ERROR: {modules.length - count} modules missing handoff
905
- → List the missing modules by name
906
- → DO NOT proceed to step-05b
907
- → Return to 7a for missing modules only
908
-
909
- IF count === modules.length:
910
- ba-writer.updateStatus({feature_id}, "handed-off")
911
- Display: "✓ Handoff complet: {count}/{modules.length} modules avec handoff valide"
912
- ```
913
-
914
- Status journey: analyze → consolidate → handed-off
915
-
916
- ---
917
-
918
- ## SELF-VERIFICATION
919
-
920
- Before proceeding to step-05b-deploy.md, VERIFY:
921
-
922
- 1. **filesToCreate** has all 7 categories populated (domain, application, infrastructure, api, frontend, seedData, tests) for each module
923
- 2. **Complexity** calculated for all modules
924
- 3. **Implementation strategy** chosen (for multi-module features)
925
- 4. **ALL module feature.json** have `handoff.brToCodeMapping.length > 0`
926
- 5. **ALL module feature.json** have `handoff.apiEndpointSummary.length > 0`
927
- 6. **ALL module feature.json** status = "handed-off"
928
- 7. **Master feature.json** has `handoff` section with implementationStrategy, moduleOrder, totalFilesToCreate
929
- 8. **Master status** = "handed-off"
930
-
931
- **IF any check fails → FIX before proceeding.**
932
-
933
- ---
934
-
935
- ## NEXT STEP
936
-
937
- Load: `steps/step-05b-deploy.md`